slop 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/LICENSE +20 -0
- data/README.md +101 -0
- data/lib/slop.rb +147 -0
- data/lib/slop/option.rb +115 -0
- data/spec/option_spec.rb +5 -0
- data/spec/slop_spec.rb +104 -0
- metadata +85 -0
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2010 Lee Jarvis
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,101 @@
|
|
1
|
+
Slop
|
2
|
+
====
|
3
|
+
|
4
|
+
Slop is a simple option parser with an easy to remember syntax and friendly API.
|
5
|
+
|
6
|
+
**NOTE** This software is still in beta, it contains bugs and lacks core
|
7
|
+
features
|
8
|
+
|
9
|
+
Installation
|
10
|
+
------------
|
11
|
+
|
12
|
+
### Rubygems
|
13
|
+
|
14
|
+
gem install slop
|
15
|
+
|
16
|
+
### GitHub
|
17
|
+
|
18
|
+
git clone git://github.com/injekt/slop.git
|
19
|
+
cd slop
|
20
|
+
gem build slop.gemspec
|
21
|
+
gem install slop-<version>.gem
|
22
|
+
|
23
|
+
Usage
|
24
|
+
-----
|
25
|
+
|
26
|
+
s = Slop.parse(ARGV) do
|
27
|
+
option :v, :verbose, "Enable verbose mode", :default => false
|
28
|
+
option :n, :name, "Your name", true # compulsory argument
|
29
|
+
option :c, :country, "Your country", argument => true # the same thing
|
30
|
+
|
31
|
+
option :a, :age, "Your age", true, :optional => true # optional argument
|
32
|
+
option :address, "Your address", :optional => true # the same
|
33
|
+
|
34
|
+
# shortcut option aliases
|
35
|
+
opt :height, "Your height"
|
36
|
+
o :weight, "Your weight
|
37
|
+
end
|
38
|
+
|
39
|
+
# using `--name Lee -a 100`
|
40
|
+
s.options_hash #=> {:verbose=>false, :name=>"Lee", :age=>"100", :address=>nil}
|
41
|
+
s.value_for(:name) #=> "Lee"
|
42
|
+
option = s.option_for(:name)
|
43
|
+
option.description #=> "Your name"
|
44
|
+
|
45
|
+
# You can also use switch values to set options according to arguments
|
46
|
+
s = Slop.parse(ARGV) do
|
47
|
+
option :v, :verbose, :default => false, :switch => true
|
48
|
+
option :applicable_age, :default => 10, :switch => 20
|
49
|
+
end
|
50
|
+
|
51
|
+
# without `-v`
|
52
|
+
s.value_for(:verbose) #=> false
|
53
|
+
|
54
|
+
# using `-v`
|
55
|
+
s.value_for(:verbose) #=> true
|
56
|
+
|
57
|
+
# using `--applicable_age`
|
58
|
+
s.value_for(:applicable_age) #=> 20
|
59
|
+
|
60
|
+
Casting
|
61
|
+
-------
|
62
|
+
|
63
|
+
If you want to return values of specific types, for example a Symbol or Integer
|
64
|
+
you can pass the `:as` attribute to your option.
|
65
|
+
|
66
|
+
s = Slop.parse("--age 20") do
|
67
|
+
opt :age, true, :as => Integer # :int/:integer both also work
|
68
|
+
end
|
69
|
+
s.value_for(:age) #=> 20 # not "20"
|
70
|
+
|
71
|
+
Slop will also check your default attributes type to see if it can cast the new
|
72
|
+
value to the same type.
|
73
|
+
|
74
|
+
s = Slop.parse("--port 110") do
|
75
|
+
opt :port, true, :default => 80
|
76
|
+
end
|
77
|
+
s.value_for(:port) #=> 110
|
78
|
+
|
79
|
+
Lists
|
80
|
+
-----
|
81
|
+
|
82
|
+
You can of course also parse lists into options. Here's how:
|
83
|
+
|
84
|
+
s = Slop.parse("--people lee,injekt") do
|
85
|
+
opt :people, true, :as => Array
|
86
|
+
end
|
87
|
+
s.value_for(:people) #=> ["lee", "injekt"]
|
88
|
+
|
89
|
+
You can also change both the split delimiter and limit
|
90
|
+
|
91
|
+
s = Slop.parse("--people lee:injekt:bob") do
|
92
|
+
opt :people, true, :as => Array, :delimiter => ':', :limit => 2
|
93
|
+
end
|
94
|
+
s.value_for(:people) #=> ["lee", "injekt:bob"]
|
95
|
+
|
96
|
+
Contributing
|
97
|
+
------------
|
98
|
+
|
99
|
+
If you'd like to contribute to Slop (it's **really** appreciated) please fork
|
100
|
+
the GitHub repository, create your feature/bugfix branch, add specs, and send
|
101
|
+
me a pull request. I'd be more than happy to look at it.
|
data/lib/slop.rb
ADDED
@@ -0,0 +1,147 @@
|
|
1
|
+
require 'set'
|
2
|
+
|
3
|
+
require 'slop/option'
|
4
|
+
|
5
|
+
class Slop
|
6
|
+
VERSION = '0.1.0'
|
7
|
+
|
8
|
+
class MissingArgumentError < ArgumentError; end
|
9
|
+
|
10
|
+
# @return [Set]
|
11
|
+
attr_reader :options
|
12
|
+
|
13
|
+
def self.parse(values=[], &blk)
|
14
|
+
new(&blk).parse(values)
|
15
|
+
end
|
16
|
+
|
17
|
+
def initialize(&blk)
|
18
|
+
@options = Set.new
|
19
|
+
instance_eval(&blk) if block_given?
|
20
|
+
end
|
21
|
+
|
22
|
+
# add an option
|
23
|
+
def option(*args, &blk)
|
24
|
+
opts = args.pop if args.last.is_a?(Hash)
|
25
|
+
opts ||= {}
|
26
|
+
|
27
|
+
if args.size > 4
|
28
|
+
raise ArgumentError, "Argument size must be no more than 4"
|
29
|
+
end
|
30
|
+
|
31
|
+
args.unshift nil if args.first.size > 1
|
32
|
+
args.push nil if args.size == 2
|
33
|
+
args.push false if args.size == 3
|
34
|
+
if args[2] == true
|
35
|
+
args[2] = nil
|
36
|
+
args[3] = true
|
37
|
+
end
|
38
|
+
|
39
|
+
attributes = [:flag, :option, :description, :argument]
|
40
|
+
options = Hash[attributes.zip(args)]
|
41
|
+
options.merge!(opts)
|
42
|
+
options[:as] = options[:default].class if options.key?(:default)
|
43
|
+
yield options if block_given?
|
44
|
+
|
45
|
+
@options << Option.new(options)
|
46
|
+
end
|
47
|
+
alias :opt :option
|
48
|
+
alias :o :option
|
49
|
+
|
50
|
+
# add an argument
|
51
|
+
def argument(*args)
|
52
|
+
|
53
|
+
end
|
54
|
+
alias :arg :argument
|
55
|
+
alias :args :argument
|
56
|
+
alias :arguments :argument
|
57
|
+
|
58
|
+
# Parse an Array (usually ARGV) of options
|
59
|
+
#
|
60
|
+
# @param [Array, #split] Array or String of options to parse
|
61
|
+
def parse(values=[])
|
62
|
+
values = values.split(/\s+/) if values.respond_to?(:split)
|
63
|
+
|
64
|
+
values.each do |value|
|
65
|
+
if value[1] == '-' or value[0] == '-'
|
66
|
+
opt = value.size == 2 ? value[1] : value[2..-1]
|
67
|
+
next unless option = option_for(opt) # skip unknown values for now
|
68
|
+
index = values.index(value)
|
69
|
+
|
70
|
+
if option.has_switch?
|
71
|
+
option.switch_argument_value
|
72
|
+
end
|
73
|
+
|
74
|
+
if option.requires_argument?
|
75
|
+
value = values.at(index + 1)
|
76
|
+
|
77
|
+
unless option.optional_argument?
|
78
|
+
if not value or value[0] == '-' or value[1] == '-'
|
79
|
+
raise MissingArgumentError,
|
80
|
+
"#{option.key} requires a compulsory argument, none given"
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
unless !value or value[0] == '-' or value[1] == '-'
|
85
|
+
option.argument_value = values.delete_at(values.index(value))
|
86
|
+
end
|
87
|
+
end
|
88
|
+
else
|
89
|
+
# not a flag or option, parse as an argument
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
self
|
94
|
+
end
|
95
|
+
|
96
|
+
# traverse options
|
97
|
+
def each_option
|
98
|
+
@options.each {|o| yield o }
|
99
|
+
end
|
100
|
+
|
101
|
+
# A simple Hash of options with option labels or flags as keys
|
102
|
+
# and option values as.. values.
|
103
|
+
#
|
104
|
+
# @return [Hash]
|
105
|
+
def options_hash
|
106
|
+
out = {}
|
107
|
+
each_option do |opt|
|
108
|
+
if opt.requires_argument? or opt.has_default?
|
109
|
+
out[opt.key] = opt.argument_value || opt.default
|
110
|
+
end
|
111
|
+
end
|
112
|
+
out
|
113
|
+
end
|
114
|
+
alias :to_hash :options_hash
|
115
|
+
|
116
|
+
# Find an option using its flag or label
|
117
|
+
#
|
118
|
+
# @example
|
119
|
+
# s = Slop.new do
|
120
|
+
# option :n, :name, "Your name"
|
121
|
+
# end
|
122
|
+
#
|
123
|
+
# s.option_for(:name).description #=> "Your name"
|
124
|
+
#
|
125
|
+
# @return [Option] the option flag or label
|
126
|
+
def option_for(flag)
|
127
|
+
@options.find do |opt|
|
128
|
+
opt.has_flag?(flag) || opt.has_option?(flag)
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
# Find an options argument using the option name.
|
133
|
+
# Essentially this is the same as `s.options_hash[:name]`
|
134
|
+
#
|
135
|
+
# @example When passing --name Lee
|
136
|
+
# s = Slop.new do
|
137
|
+
# option :n, :name, true
|
138
|
+
# end
|
139
|
+
#
|
140
|
+
# s.value_for(:name) #=> "Lee"
|
141
|
+
#
|
142
|
+
#
|
143
|
+
def value_for(flag)
|
144
|
+
return unless option = option_for(flag)
|
145
|
+
option.argument_value
|
146
|
+
end
|
147
|
+
end
|
data/lib/slop/option.rb
ADDED
@@ -0,0 +1,115 @@
|
|
1
|
+
class Slop
|
2
|
+
class Option
|
3
|
+
|
4
|
+
attr_reader :flag
|
5
|
+
attr_reader :option
|
6
|
+
attr_reader :description
|
7
|
+
attr_reader :argument_value
|
8
|
+
attr_reader :default
|
9
|
+
|
10
|
+
def initialize(options={}, &blk)
|
11
|
+
@options = options
|
12
|
+
@flag = options[:flag]
|
13
|
+
@option = options[:option] || options[:opt]
|
14
|
+
@description = options[:description] || options[:desc]
|
15
|
+
@argument = options[:argument] || false
|
16
|
+
@optional = options[:optional] || options[:optional_argument]
|
17
|
+
@argument ||= @optional
|
18
|
+
@default = options[:default]
|
19
|
+
@as = options[:as]
|
20
|
+
|
21
|
+
# Array properties
|
22
|
+
@delimiter = options[:delimiter] || ','
|
23
|
+
@limit = options[:limit] || 1
|
24
|
+
|
25
|
+
@argument_value = nil
|
26
|
+
end
|
27
|
+
|
28
|
+
# Set the argument value
|
29
|
+
# @param [Object] value
|
30
|
+
def argument_value=(value)
|
31
|
+
@argument_value = value
|
32
|
+
end
|
33
|
+
|
34
|
+
# @return [Object] the argument value after it's been cast
|
35
|
+
# according to the `:as` option
|
36
|
+
def argument_value
|
37
|
+
@argument_value ||= @default
|
38
|
+
return unless @argument_value
|
39
|
+
|
40
|
+
case @as.to_s
|
41
|
+
when 'array', 'Array'; @argument_value.split(@delimiter, @limit)
|
42
|
+
when 'integer', 'int', 'Integer'; @argument_value.to_i
|
43
|
+
when 'symbol', 'sym', 'Symbol' ; @argument_value.to_sym
|
44
|
+
else
|
45
|
+
@argument_value
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# @param [to_s] flag
|
50
|
+
# @return [Boolean] true if this option contains a flag
|
51
|
+
def has_flag?(flag)
|
52
|
+
@flag.to_s == flag.to_s
|
53
|
+
end
|
54
|
+
|
55
|
+
# @param [to_s] option
|
56
|
+
# @return [Boolean] true if this option contains an option label
|
57
|
+
def has_option?(option)
|
58
|
+
@option.to_s == option.to_s
|
59
|
+
end
|
60
|
+
|
61
|
+
# @return [Boolean] true if this option has a default value
|
62
|
+
def has_default?
|
63
|
+
!@default.nil?
|
64
|
+
end
|
65
|
+
|
66
|
+
# @return [Boolean] true if this option has a switch value
|
67
|
+
def has_switch?
|
68
|
+
!!@options[:switch]
|
69
|
+
end
|
70
|
+
|
71
|
+
# does the option require an argument?
|
72
|
+
# @return [Boolean]
|
73
|
+
def requires_argument?
|
74
|
+
!!@argument
|
75
|
+
end
|
76
|
+
|
77
|
+
# Is the argument optional?
|
78
|
+
# @return [Boolean]
|
79
|
+
def optional_argument?
|
80
|
+
@options[:optional]
|
81
|
+
end
|
82
|
+
|
83
|
+
# Replace options argument value with the switch value supplied, used
|
84
|
+
# when supplying the `switch` option making switch flags easy to alter
|
85
|
+
#
|
86
|
+
# @example
|
87
|
+
# option :v, :verbose, :default => false, :switch => true
|
88
|
+
#
|
89
|
+
# Now when the `-v` or `--verbose` option is supplied, verbose will
|
90
|
+
# be set to `true`, rather than the default `false` option
|
91
|
+
def switch_argument_value
|
92
|
+
@argument_value = @option[:switch]
|
93
|
+
end
|
94
|
+
|
95
|
+
# return a key for an option, prioritize
|
96
|
+
# option before flag as it's more descriptive
|
97
|
+
def key
|
98
|
+
@option || @flag
|
99
|
+
end
|
100
|
+
|
101
|
+
def to_s
|
102
|
+
str = "\t"
|
103
|
+
str << "-#{@flag}" if @flag
|
104
|
+
str << "\t"
|
105
|
+
str << "--#{@option}\t\t" if @option
|
106
|
+
str << "#{@description}" if @description
|
107
|
+
str << "\n"
|
108
|
+
end
|
109
|
+
|
110
|
+
def inspect
|
111
|
+
"#<#{self.class}: #{@options}>"
|
112
|
+
end
|
113
|
+
|
114
|
+
end
|
115
|
+
end
|
data/spec/option_spec.rb
ADDED
data/spec/slop_spec.rb
ADDED
@@ -0,0 +1,104 @@
|
|
1
|
+
require File.expand_path('../../lib/slop', __FILE__)
|
2
|
+
|
3
|
+
describe Slop do
|
4
|
+
before :all do
|
5
|
+
@slop = Slop.new do
|
6
|
+
option :v, :verbose, "Enable verbose mode"
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
describe "option" do
|
11
|
+
it "adds an option" do
|
12
|
+
@slop.options.find do |opt|
|
13
|
+
opt.flag == :v
|
14
|
+
end.should be_kind_of(Slop::Option)
|
15
|
+
end
|
16
|
+
|
17
|
+
it "adds an option with a block to alter option attributes" do
|
18
|
+
s = Slop.new do
|
19
|
+
option :n, :name, "Set your name!", true do |o|
|
20
|
+
o[:default] = "Lee"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
s.option_for(:name).default.should == "Lee"
|
24
|
+
end
|
25
|
+
|
26
|
+
it "takes no more than 4 arguments" do
|
27
|
+
lambda do
|
28
|
+
Slop.new { option :a, :b, :c, :d, :e }
|
29
|
+
end.should raise_error(ArgumentError, "Argument size must be no more than 4")
|
30
|
+
end
|
31
|
+
|
32
|
+
it "does not parse option values unless option.argument is true" do
|
33
|
+
Slop.parse("--name Lee") { opt :name }.value_for(:name).should be_nil
|
34
|
+
Slop.parse("--name Lee") { opt :name, true }.value_for(:name).should == "Lee"
|
35
|
+
Slop.parse("--name Lee") { opt :name, :argument => true }.value_for(:name).should == "Lee"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe "option_for" do
|
40
|
+
it "returns an option" do
|
41
|
+
@slop.option_for(:v).should be_kind_of(Slop::Option)
|
42
|
+
end
|
43
|
+
|
44
|
+
it "returns nil otherwise" do
|
45
|
+
@slop.option_for(:nothing).should be_nil
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
describe "value_for" do
|
50
|
+
it "returns the value of an option" do
|
51
|
+
s = Slop.parse("--name Lee") do
|
52
|
+
opt :n, :name, "Your name", true
|
53
|
+
end
|
54
|
+
s.value_for(:name).should == "Lee"
|
55
|
+
end
|
56
|
+
|
57
|
+
it "returns a default option if none is given" do
|
58
|
+
Slop.new { opt :name, true, :default => "Lee" }.value_for(:name).should == "Lee"
|
59
|
+
end
|
60
|
+
|
61
|
+
it "returns nil if an option does not exist" do
|
62
|
+
Slop.new.value_for(:name).should be_nil
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
describe "parse" do
|
67
|
+
it "returns self (Slop)" do
|
68
|
+
Slop.parse.should be_kind_of(Slop)
|
69
|
+
end
|
70
|
+
|
71
|
+
it "parses a string" do
|
72
|
+
Slop.parse("--name Lee") { opt :name, true }.value_for(:name).should == "Lee"
|
73
|
+
end
|
74
|
+
|
75
|
+
it "parses an array" do
|
76
|
+
Slop.parse(%w"--name Lee") { opt :name, true }.value_for(:name).should == "Lee"
|
77
|
+
end
|
78
|
+
|
79
|
+
it "raises MissingArgumentError if no argument is given to a compulsory option" do
|
80
|
+
lambda { Slop.parse("--name") { opt :name, true } }.should raise_error(Slop::MissingArgumentError, /name/)
|
81
|
+
end
|
82
|
+
|
83
|
+
it "does not raise MissingArgumentError if the optional attribute is true" do
|
84
|
+
Slop.parse("--name") { opt :name, true, :optional => true }.value_for(:name).should be_nil
|
85
|
+
end
|
86
|
+
|
87
|
+
it "does not require argument to be true if optional is true" do
|
88
|
+
Slop.parse("--name Lee") { opt :name, :optional => true }.value_for(:name).should == "Lee"
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
describe "options" do
|
93
|
+
it "returns a set" do
|
94
|
+
@slop.options.should be_kind_of Set
|
95
|
+
end
|
96
|
+
|
97
|
+
it "contains a set of Slop::Option" do
|
98
|
+
@slop.options.each do |opt|
|
99
|
+
opt.should be_kind_of(Slop::Option)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
metadata
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: slop
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 1
|
8
|
+
- 0
|
9
|
+
version: 0.1.0
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Lee Jarvis
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2010-11-26 00:00:00 +00:00
|
18
|
+
default_executable:
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: rspec
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
25
|
+
requirements:
|
26
|
+
- - "="
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
segments:
|
29
|
+
- 2
|
30
|
+
- 1
|
31
|
+
- 0
|
32
|
+
version: 2.1.0
|
33
|
+
type: :development
|
34
|
+
version_requirements: *id001
|
35
|
+
description: ""
|
36
|
+
email: lee@jarvis.co
|
37
|
+
executables: []
|
38
|
+
|
39
|
+
extensions: []
|
40
|
+
|
41
|
+
extra_rdoc_files: []
|
42
|
+
|
43
|
+
files:
|
44
|
+
- LICENSE
|
45
|
+
- README.md
|
46
|
+
- lib/slop.rb
|
47
|
+
- lib/slop/option.rb
|
48
|
+
- spec/slop_spec.rb
|
49
|
+
- spec/option_spec.rb
|
50
|
+
has_rdoc: true
|
51
|
+
homepage: http://rubydoc.info/github/injekt/slop
|
52
|
+
licenses: []
|
53
|
+
|
54
|
+
post_install_message:
|
55
|
+
rdoc_options: []
|
56
|
+
|
57
|
+
require_paths:
|
58
|
+
- lib
|
59
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
60
|
+
none: false
|
61
|
+
requirements:
|
62
|
+
- - ">="
|
63
|
+
- !ruby/object:Gem::Version
|
64
|
+
segments:
|
65
|
+
- 1
|
66
|
+
- 9
|
67
|
+
- 1
|
68
|
+
version: 1.9.1
|
69
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
70
|
+
none: false
|
71
|
+
requirements:
|
72
|
+
- - ">="
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
segments:
|
75
|
+
- 0
|
76
|
+
version: "0"
|
77
|
+
requirements: []
|
78
|
+
|
79
|
+
rubyforge_project:
|
80
|
+
rubygems_version: 1.3.7
|
81
|
+
signing_key:
|
82
|
+
specification_version: 3
|
83
|
+
summary: Option parsing made easy
|
84
|
+
test_files: []
|
85
|
+
|