slop 1.0.0 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +3 -1
- data/Rakefile +1 -1
- data/lib/slop.rb +27 -18
- data/lib/slop/option.rb +8 -4
- data/lib/slop/version.rb +1 -1
- data/test/option_test.rb +2 -4
- data/test/slop_test.rb +27 -0
- metadata +14 -3
data/README.md
CHANGED
@@ -151,13 +151,15 @@ You can also change both the split delimiter and limit
|
|
151
151
|
opts = Slop.parse do
|
152
152
|
opt :people, true, :as => Array, :delimiter => ':', :limit => 2)
|
153
153
|
end
|
154
|
+
|
155
|
+
# ARGV is `--people lee:injekt:bob`
|
154
156
|
opts[:people] #=> ["lee", "injekt:bob"]
|
155
157
|
|
156
158
|
Woah woah, why you hating on OptionParser?
|
157
159
|
------------------------------------------
|
158
160
|
|
159
161
|
I'm not, honestly! I love OptionParser. I really do, it's a fantastic library.
|
160
|
-
So why did I build Slop? Well, I find myself using OptionParser to
|
162
|
+
So why did I build Slop? Well, I find myself using OptionParser to simply
|
161
163
|
gather a bunch of key/value options, usually you would do something like this:
|
162
164
|
|
163
165
|
require 'optparse'
|
data/Rakefile
CHANGED
@@ -3,7 +3,7 @@ task :test do
|
|
3
3
|
require 'slop'
|
4
4
|
require 'minitest/autorun'
|
5
5
|
begin; require 'turn'; rescue LoadError; end
|
6
|
-
Dir.glob("test/**/*_test.rb").each { |test|
|
6
|
+
Dir.glob("test/**/*_test.rb").each { |test| require "./#{test}" }
|
7
7
|
end
|
8
8
|
|
9
9
|
task :default => :test
|
data/lib/slop.rb
CHANGED
@@ -23,7 +23,7 @@ class Slop
|
|
23
23
|
# @see Slop#option
|
24
24
|
def self.parse(items=ARGV, &block)
|
25
25
|
slop = new(&block)
|
26
|
-
slop.parse
|
26
|
+
slop.parse items
|
27
27
|
slop
|
28
28
|
end
|
29
29
|
|
@@ -35,6 +35,7 @@ class Slop
|
|
35
35
|
@options = Options.new
|
36
36
|
@banner = nil
|
37
37
|
@longest_flag = 0
|
38
|
+
@items = []
|
38
39
|
|
39
40
|
if block_given?
|
40
41
|
block.arity == 1 ? yield(self) : instance_eval(&block)
|
@@ -59,14 +60,20 @@ class Slop
|
|
59
60
|
#
|
60
61
|
# @param items
|
61
62
|
def parse(items=ARGV)
|
62
|
-
parse_items
|
63
|
+
@items = parse_items items, block_given?
|
64
|
+
|
65
|
+
if block_given?
|
66
|
+
@items.each { |item| yield item }
|
67
|
+
end
|
68
|
+
|
69
|
+
@items
|
63
70
|
end
|
64
71
|
|
65
72
|
# Parse a list of options, removing parsed options from the original Array.
|
66
73
|
#
|
67
74
|
# @parse items
|
68
75
|
def parse!(items=ARGV)
|
69
|
-
parse_items
|
76
|
+
parse_items items, true
|
70
77
|
end
|
71
78
|
|
72
79
|
# Enumerable interface
|
@@ -111,7 +118,8 @@ class Slop
|
|
111
118
|
options = args.pop if args.last.is_a?(Hash)
|
112
119
|
options ||= {}
|
113
120
|
|
114
|
-
|
121
|
+
short, long, desc, arg = clean_options(args)
|
122
|
+
option = Option.new(self, short, long, desc, arg, options, &block)
|
115
123
|
@options << option
|
116
124
|
|
117
125
|
option
|
@@ -124,10 +132,15 @@ class Slop
|
|
124
132
|
# @return [Hash] Returns a hash with each specified option as a symbolic key with an associated value.
|
125
133
|
# @example
|
126
134
|
# opts.to_hash
|
135
|
+
# #=> { 'name' => 'Emily' }
|
136
|
+
#
|
137
|
+
# # symbols!
|
138
|
+
# opts.to_hash(true)
|
127
139
|
# #=> { :name => 'Emily' }
|
128
|
-
def to_hash
|
129
|
-
@options.to_hash
|
140
|
+
def to_hash(symbols=nil)
|
141
|
+
@options.to_hash(symbols)
|
130
142
|
end
|
143
|
+
alias :to_h :to_hash
|
131
144
|
|
132
145
|
# Allows you to check whether an option was specified in the parsed list.
|
133
146
|
#
|
@@ -140,11 +153,7 @@ class Slop
|
|
140
153
|
# #=> false
|
141
154
|
# @see Slop#[]
|
142
155
|
def method_missing(meth, *args, &block)
|
143
|
-
|
144
|
-
!!self[meth.to_s.chomp('?')]
|
145
|
-
else
|
146
|
-
super
|
147
|
-
end
|
156
|
+
meth.to_s[/\?$/] ? !!self[meth.to_s.chomp('?')] : super
|
148
157
|
end
|
149
158
|
|
150
159
|
# Returns the banner followed by available options listed on the next line.
|
@@ -171,8 +180,9 @@ private
|
|
171
180
|
|
172
181
|
items.each do |item|
|
173
182
|
flag = item.to_s.sub(/^--?/, '')
|
183
|
+
option = @options[flag]
|
174
184
|
|
175
|
-
if option
|
185
|
+
if option
|
176
186
|
trash << item if delete
|
177
187
|
option.argument_value = true
|
178
188
|
|
@@ -182,18 +192,18 @@ private
|
|
182
192
|
|
183
193
|
if argument
|
184
194
|
option.argument_value = argument
|
185
|
-
option.callback.call
|
195
|
+
option.callback.call option.argument_value if option.callback
|
186
196
|
else
|
187
197
|
option.argument_value = nil
|
188
198
|
if option.accepts_optional_argument?
|
189
|
-
option.callback.call
|
199
|
+
option.callback.call nil if option.callback
|
190
200
|
else
|
191
201
|
raise MissingArgumentError,
|
192
202
|
"'#{flag}' expects an argument, none given"
|
193
203
|
end
|
194
204
|
end
|
195
205
|
elsif option.callback
|
196
|
-
option.callback.call
|
206
|
+
option.callback.call nil
|
197
207
|
end
|
198
208
|
end
|
199
209
|
end
|
@@ -201,8 +211,6 @@ private
|
|
201
211
|
items.delete_if { |item| trash.include? item }
|
202
212
|
end
|
203
213
|
|
204
|
-
# @param [Array] args
|
205
|
-
# @return [Array]
|
206
214
|
def clean_options(args)
|
207
215
|
options = []
|
208
216
|
|
@@ -215,7 +223,8 @@ private
|
|
215
223
|
end
|
216
224
|
|
217
225
|
long = args.first
|
218
|
-
|
226
|
+
boolean = long.is_a?(TrueClass) || long.is_a?(FalseClass)
|
227
|
+
if !boolean && long.to_s =~ /\A(--?)?[a-zA-Z0-9_-]+\z/
|
219
228
|
options.push args.shift.to_s.sub(/^--?/, '')
|
220
229
|
else
|
221
230
|
options.push nil
|
data/lib/slop/option.rb
CHANGED
@@ -1,15 +1,19 @@
|
|
1
1
|
class Slop
|
2
2
|
class Options < Array
|
3
|
-
def to_hash
|
4
|
-
|
5
|
-
|
3
|
+
def to_hash(symbols)
|
4
|
+
out = {}
|
5
|
+
each do |option|
|
6
|
+
key = option.key
|
7
|
+
key = key.to_sym if symbols
|
8
|
+
out[key] = option.argument_value
|
6
9
|
end
|
10
|
+
out
|
7
11
|
end
|
8
12
|
|
9
13
|
def [](item)
|
10
14
|
item = item.to_s
|
11
15
|
if item =~ /^\d+$/
|
12
|
-
slice
|
16
|
+
slice item.to_i
|
13
17
|
else
|
14
18
|
find do |option|
|
15
19
|
option.short_flag == item || option.long_flag == item
|
data/lib/slop/version.rb
CHANGED
data/test/option_test.rb
CHANGED
@@ -60,12 +60,10 @@ class OptionTest < TestCase
|
|
60
60
|
)
|
61
61
|
end
|
62
62
|
|
63
|
-
test '
|
63
|
+
test 'casting' do
|
64
64
|
assert_equal :foo, option_value(%w/--name foo/, :name, true, :as => Symbol)
|
65
|
-
end
|
66
|
-
|
67
|
-
test 'returns an integer with :as => Integer' do
|
68
65
|
assert_equal 30, option_value(%w/--age 30/, :age, true, :as => Integer)
|
66
|
+
assert_equal "1.0", option_value(%w/--id 1/, :id, true, :as => Float).to_s
|
69
67
|
end
|
70
68
|
|
71
69
|
test 'printing options' do
|
data/test/slop_test.rb
CHANGED
@@ -33,6 +33,15 @@ class SlopTest < TestCase
|
|
33
33
|
assert_kind_of Slop, slop
|
34
34
|
end
|
35
35
|
|
36
|
+
test 'yielding non-options when a block is passed to "parse"' do
|
37
|
+
opts = Slop.new do
|
38
|
+
on :name, true
|
39
|
+
end
|
40
|
+
opts.parse(%w/--name lee a/) do |v|
|
41
|
+
assert_equal 'a', v
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
36
45
|
test 'setting the banner' do
|
37
46
|
slop = Slop.new
|
38
47
|
slop.banner = "foo bar"
|
@@ -44,6 +53,15 @@ class SlopTest < TestCase
|
|
44
53
|
assert_equal "", slop.to_s
|
45
54
|
end
|
46
55
|
|
56
|
+
test 'storing long option lengths' do
|
57
|
+
slop = Slop.new
|
58
|
+
assert_equal 0, slop.longest_flag
|
59
|
+
slop.opt(:name)
|
60
|
+
assert_equal 4, slop.longest_flag
|
61
|
+
slop.opt(:username)
|
62
|
+
assert_equal 8, slop.longest_flag
|
63
|
+
end
|
64
|
+
|
47
65
|
test '#parse does not remove parsed items' do
|
48
66
|
items = %w/--foo/
|
49
67
|
Slop.new { |opt| opt.on :foo }.parse(items)
|
@@ -125,6 +143,7 @@ class SlopTest < TestCase
|
|
125
143
|
slop.parse %w/--name lee --version/
|
126
144
|
|
127
145
|
assert_equal({'name' => 'lee', 'version' => true, 'verbose' => false}, slop.to_hash)
|
146
|
+
assert_equal({:name => 'lee', :version => true, :verbose => false}, slop.to_hash(true))
|
128
147
|
end
|
129
148
|
|
130
149
|
test 'iterating options' do
|
@@ -153,4 +172,12 @@ class SlopTest < TestCase
|
|
153
172
|
|
154
173
|
assert slop.to_s =~ /^Usage: foo/
|
155
174
|
end
|
175
|
+
|
176
|
+
test 'passing argument values to blocks' do
|
177
|
+
name = nil
|
178
|
+
opts = Slop.new
|
179
|
+
opts.on :name, true, :callback => proc {|n| name = n}
|
180
|
+
opts.parse %w/--name lee/
|
181
|
+
assert_equal 'lee', name
|
182
|
+
end
|
156
183
|
end
|
metadata
CHANGED
@@ -1,8 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: slop
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
+
hash: 19
|
4
5
|
prerelease:
|
5
|
-
|
6
|
+
segments:
|
7
|
+
- 1
|
8
|
+
- 1
|
9
|
+
- 0
|
10
|
+
version: 1.1.0
|
6
11
|
platform: ruby
|
7
12
|
authors:
|
8
13
|
- Lee Jarvis
|
@@ -10,7 +15,7 @@ autorequire:
|
|
10
15
|
bindir: bin
|
11
16
|
cert_chain: []
|
12
17
|
|
13
|
-
date: 2011-03-
|
18
|
+
date: 2011-03-17 00:00:00 +00:00
|
14
19
|
default_executable:
|
15
20
|
dependencies: []
|
16
21
|
|
@@ -50,17 +55,23 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
50
55
|
requirements:
|
51
56
|
- - ">="
|
52
57
|
- !ruby/object:Gem::Version
|
58
|
+
hash: 3
|
59
|
+
segments:
|
60
|
+
- 0
|
53
61
|
version: "0"
|
54
62
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
55
63
|
none: false
|
56
64
|
requirements:
|
57
65
|
- - ">="
|
58
66
|
- !ruby/object:Gem::Version
|
67
|
+
hash: 3
|
68
|
+
segments:
|
69
|
+
- 0
|
59
70
|
version: "0"
|
60
71
|
requirements: []
|
61
72
|
|
62
73
|
rubyforge_project:
|
63
|
-
rubygems_version: 1.
|
74
|
+
rubygems_version: 1.6.2
|
64
75
|
signing_key:
|
65
76
|
specification_version: 3
|
66
77
|
summary: Option gathering made easy
|