slop 1.4.0 → 1.4.1

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  Slop
2
2
  ====
3
3
 
4
- Slop is a simple option collector with an easy to remember syntax and friendly API.
4
+ Slop is a simple option parser with an easy to remember syntax and friendly API.
5
5
 
6
6
  Installation
7
7
  ------------
@@ -18,49 +18,49 @@ Installation
18
18
 
19
19
  Usage
20
20
  -----
21
- # parse assumes ARGV, otherwise you can pass it your own Array
22
- opts = Slop.parse do
23
- on :v, :verbose, 'Enable verbose mode' # boolean value
24
- on :n, :name, 'Your name', true # compulsory argument
25
- on :s, :sex, 'Your sex', :optional => false # the same thing
26
- on :a, :age, 'Your age', :optional => true # optional argument
27
- end
28
-
29
- # if ARGV is `-v --name 'lee jarvis' -s male`
30
- opts.verbose? #=> true
31
- opts.name? #=> true
32
- opts[:name] #=> 'lee jarvis'
33
- opts.age? #=> false
34
- opts[:age] #=> nil
21
+ # parse assumes ARGV, otherwise you can pass it your own Array
22
+ opts = Slop.parse do
23
+ on :v, :verbose, 'Enable verbose mode' # boolean value
24
+ on :n, :name, 'Your name', true # compulsory argument
25
+ on :s, :sex, 'Your sex', :optional => false # the same thing
26
+ on :a, :age, 'Your age', :optional => true # optional argument
27
+ end
28
+
29
+ # if ARGV is `-v --name 'lee jarvis' -s male`
30
+ opts.verbose? #=> true
31
+ opts.name? #=> true
32
+ opts[:name] #=> 'lee jarvis'
33
+ opts.age? #=> false
34
+ opts[:age] #=> nil
35
35
 
36
36
  You can also return your options as a Hash
37
37
 
38
- opts.to_hash #=> {'name' => 'Lee Jarvis', 'verbose' => true, 'age' => nil, 'sex' => 'male'}
38
+ opts.to_hash #=> {'name' => 'Lee Jarvis', 'verbose' => true, 'age' => nil, 'sex' => 'male'}
39
39
 
40
- # Symbols
41
- opts.to_hash(true) #=> {:name => 'Lee Jarvis', :verbose => true, :age => nil, :sex => 'male'}
40
+ # Symbols
41
+ opts.to_hash(true) #=> {:name => 'Lee Jarvis', :verbose => true, :age => nil, :sex => 'male'}
42
42
 
43
43
  If you don't like the method `on` (because it sounds like the option **expects**
44
44
  a block), you can use the `opt` or `option` alternatives.
45
45
 
46
- on :v, :verbose
47
- opt :v, :verbose
48
- option :v, :verbose
46
+ on :v, :verbose
47
+ opt :v, :verbose
48
+ option :v, :verbose
49
49
 
50
50
  If you don't like that Slop evaluates your block, or you want slop access
51
51
  inside of your block without referring to `self`, you can pass a block argument to
52
52
  `parse`.
53
53
 
54
- Slop.parse do |opts|
55
- opts.on :v, :verbose
56
- opts.on :n, :name, 'Your name', true
57
- end
54
+ Slop.parse do |opts|
55
+ opts.on :v, :verbose
56
+ opts.on :n, :name, 'Your name', true
57
+ end
58
58
 
59
59
  If you want some pretty output for the user to see your options, you can just
60
60
  send the Slop object to `puts` or use the `help` method.
61
61
 
62
- puts opts
63
- puts opts.help
62
+ puts opts
63
+ puts opts.help
64
64
 
65
65
  Will output something like
66
66
 
@@ -70,14 +70,18 @@ Will output something like
70
70
 
71
71
  You can also add a banner using the `banner` method
72
72
 
73
- opts = Slop.parse
74
- opts.banner = "Usage: foo.rb [options]"
73
+ opts = Slop.parse
74
+ opts.banner = "Usage: foo.rb [options]"
75
+
76
+ or
77
+
78
+ opts = Slop.parse do
79
+ banner "Usage: foo.rb [options]"
80
+ end
75
81
 
76
82
  or
77
83
 
78
- opts = Slop.parse do
79
- banner "Usage: foo.rb [options]"
80
- end
84
+ opts = Slop.new "Usage: foo.rb [options]"
81
85
 
82
86
  Helpful Help
83
87
  ------------
@@ -116,12 +120,12 @@ Now throw some options at it:
116
120
 
117
121
  Here's what we'll get back
118
122
 
119
- {
120
- :server=>"ftp://foobar.com",
121
- :port=>1234,
122
- :username=>"FooBar",
123
- :password=>"hello there"
124
- }
123
+ {
124
+ :server=>"ftp://foobar.com",
125
+ :port=>1234,
126
+ :username=>"FooBar",
127
+ :password=>"hello there"
128
+ }
125
129
 
126
130
  Callbacks
127
131
  ---------
@@ -147,17 +151,17 @@ they're found, just like
147
151
  [OptionParser](http://rubydoc.info/stdlib/optparse/1.9.2/OptionParser:order)
148
152
  does it.
149
153
 
150
- opts = Slop.new do
151
- on :n, :name, :optional => false
152
- end
154
+ opts = Slop.new do
155
+ on :n, :name, :optional => false
156
+ end
153
157
 
154
- opts.parse do |arg|
155
- puts arg
156
- end
158
+ opts.parse do |arg|
159
+ puts arg
160
+ end
157
161
 
158
- # if ARGV is `foo --name Lee bar`
159
- foo
160
- bar
162
+ # if ARGV is `foo --name Lee bar`
163
+ foo
164
+ bar
161
165
 
162
166
  Negative Options
163
167
  ----------------
@@ -165,16 +169,16 @@ Negative Options
165
169
  Slop also allows you to prefix `--no-` to an option which will force the option
166
170
  to return a false value.
167
171
 
168
- opts = Slop.parse do
169
- on :v, :verbose, :default => true
170
- end
172
+ opts = Slop.parse do
173
+ on :v, :verbose, :default => true
174
+ end
171
175
 
172
- # with no command line options
173
- opts[:verbose] #=> true
176
+ # with no command line options
177
+ opts[:verbose] #=> true
174
178
 
175
- # with `--no-verbose`
176
- opts[:verbose] #=> false
177
- opts.verbose? #=> false
179
+ # with `--no-verbose`
180
+ opts[:verbose] #=> false
181
+ opts.verbose? #=> false
178
182
 
179
183
  Short Switches
180
184
  --------------
@@ -196,16 +200,49 @@ by passing the `:multiple_switches` option to a new Slop object.
196
200
  opts[:b] #=> false
197
201
  opts[:c] #=> true
198
202
 
203
+ Lists
204
+ -----
205
+
206
+ You can of course also parse lists into options. Here's how:
207
+
208
+ opts = Slop.parse do
209
+ opt :people, true, :as => Array
210
+ end
211
+
212
+ # ARGV is `--people lee,john,bill`
213
+ opts[:people] #=> ['lee', 'john', 'bill']
214
+
215
+ You can also change both the split delimiter and limit
216
+
217
+ opts = Slop.parse do
218
+ opt :people, true, :as => Array, :delimiter => ':', :limit => 2)
219
+ end
220
+
221
+ # ARGV is `--people lee:injekt:bob`
222
+ opts[:people] #=> ["lee", "injekt:bob"]
223
+
224
+ Ranges
225
+ ------
226
+
227
+ What would Slop be if it didn't know what ranges were?
228
+
229
+ opts = Slop.parse do
230
+ opt :r, :range, true, :as => Range
231
+ end
232
+
233
+ # ARGV is `--range 1..10` or 1-10, or 1,10 (yes Slop supports them all)
234
+ opts[:range].to_a #=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
235
+
199
236
  Ugh, Symbols
200
237
  ------------
201
238
 
202
239
  Fine, don't use them
203
240
 
204
- Slop.parse do
205
- on :n, :name, 'Your name'
206
- on 'n', 'name', 'Your name'
207
- on '-n', '--name', 'Your name'
208
- end
241
+ Slop.parse do
242
+ on :n, :name, 'Your name'
243
+ on 'n', 'name', 'Your name'
244
+ on '-n', '--name', 'Your name'
245
+ end
209
246
 
210
247
  All of these options will do the same thing
211
248
 
@@ -214,9 +251,9 @@ Ugh, Blocks
214
251
 
215
252
  C'mon man, this is Ruby, GTFO if you don't like blocks.
216
253
 
217
- opts = Slop.new
218
- opts.on :v, :verbose
219
- opts.parse
254
+ opts = Slop.new
255
+ opts.on :v, :verbose
256
+ opts.parse
220
257
 
221
258
  Smart
222
259
  -----
@@ -225,39 +262,18 @@ Slop is pretty smart when it comes to building your options, for example if you
225
262
  want your option to have a flag attribute, but no `--option` attribute, you
226
263
  can do this:
227
264
 
228
- on :n, "Your name"
265
+ on :n, "Your name"
229
266
 
230
267
  and Slop will detect a description in place of an option, so you don't have to
231
268
  do this:
232
269
 
233
- on :n, nil, "Your name", true
270
+ on :n, nil, "Your name", true
234
271
 
235
272
  You can also try other variations:
236
273
 
237
- on :name, "Your name"
238
- on :n, :name
239
- on :name, true
240
-
241
- Lists
242
- -----
243
-
244
- You can of course also parse lists into options. Here's how:
245
-
246
- opts = Slop.parse do
247
- opt :people, true, :as => Array
248
- end
249
-
250
- # ARGV is `--people lee,john,bill`
251
- opts[:people] #=> ['lee', 'john', 'bill']
252
-
253
- You can also change both the split delimiter and limit
254
-
255
- opts = Slop.parse do
256
- opt :people, true, :as => Array, :delimiter => ':', :limit => 2)
257
- end
258
-
259
- # ARGV is `--people lee:injekt:bob`
260
- opts[:people] #=> ["lee", "injekt:bob"]
274
+ on :name, "Your name"
275
+ on :n, :name
276
+ on :name, true
261
277
 
262
278
  Strict Mode
263
279
  -----------
@@ -306,33 +322,33 @@ I'm not, honestly! I love OptionParser. I really do, it's a fantastic library.
306
322
  So why did I build Slop? Well, I find myself using OptionParser to simply
307
323
  gather a bunch of key/value options, usually you would do something like this:
308
324
 
309
- require 'optparse'
325
+ require 'optparse'
310
326
 
311
- things = {}
327
+ things = {}
312
328
 
313
- opt = OptionParser.new do |opt|
314
- opt.on('-n', '--name NAME', 'Your name') do |name|
315
- things[:name] = name
316
- end
329
+ opt = OptionParser.new do |opt|
330
+ opt.on('-n', '--name NAME', 'Your name') do |name|
331
+ things[:name] = name
332
+ end
317
333
 
318
- opt.on('-a', '--age AGE', 'Your age') do |age|
319
- things[:age] = age
320
- end
334
+ opt.on('-a', '--age AGE', 'Your age') do |age|
335
+ things[:age] = age
336
+ end
321
337
 
322
- # you get the point
323
- end
338
+ # you get the point
339
+ end
324
340
 
325
- opt.parse
326
- # do something with things
341
+ opt.parse
342
+ things #=> { :name => 'lee', :age => 105 }
327
343
 
328
344
  Which is all great and stuff, but it can lead to some repetition, the same
329
345
  thing in Slop:
330
346
 
331
- require 'slop'
347
+ require 'slop'
332
348
 
333
- opts = Slop.parse do
334
- on :n, :name, 'Your name', true
335
- on :a, :age, 'Your age', true
336
- end
349
+ opts = Slop.parse do
350
+ on :n, :name, 'Your name', true
351
+ on :a, :age, 'Your age', true
352
+ end
337
353
 
338
- things = opts.to_hash
354
+ opts.to_hash(true) #=> { :name => 'lee', :age => 105 }
@@ -16,7 +16,7 @@ class Slop
16
16
  class InvalidOptionError < RuntimeError; end
17
17
 
18
18
  # @return [String] The current version string
19
- VERSION = '1.4.0'
19
+ VERSION = '1.4.1'
20
20
 
21
21
  # Parses the items from a CLI format into a friendly object.
22
22
  #
@@ -57,10 +57,10 @@ class Slop
57
57
  def initialize(*opts, &block)
58
58
  sloptions = {}
59
59
  sloptions.merge! opts.pop if opts.last.is_a? Hash
60
+ @banner = opts.shift if opts[0].respond_to?(:to_str)
60
61
  opts.each { |o| sloptions[o] = true }
61
62
 
62
63
  @options = Options.new
63
- @banner = nil
64
64
  @longest_flag = 0
65
65
  @strict = sloptions[:strict]
66
66
  @invalid_options = []
@@ -163,7 +163,7 @@ class Slop
163
163
  # # symbols!
164
164
  # opts.to_hash(true) #=> { :name => 'Emily' }
165
165
  # @return [Hash]
166
- def to_hash(symbols=nil)
166
+ def to_hash(symbols=false)
167
167
  @options.to_hash(symbols)
168
168
  end
169
169
  alias :to_h :to_hash
@@ -195,7 +195,7 @@ class Slop
195
195
  end
196
196
  alias :help :to_s
197
197
 
198
- private
198
+ private
199
199
 
200
200
  def self.initialize_and_parse(items, delete, options, &block)
201
201
  if items.is_a?(Hash) && options.empty?
@@ -322,8 +322,8 @@ private
322
322
  end
323
323
 
324
324
  long = args.first
325
- boolean = long.is_a?(TrueClass) || long.is_a?(FalseClass)
326
- if !boolean && long.to_s =~ /\A(--?)?[a-zA-Z0-9_-]+\z/
325
+ boolean = [true, false].include?(long)
326
+ if !boolean && long.to_s =~ /\A(?:--?)?[a-zA-Z0-9_-]+\z/
327
327
  options.push args.shift.to_s.sub(/\A--?/, '')
328
328
  else
329
329
  options.push nil
@@ -331,8 +331,6 @@ private
331
331
 
332
332
  options.push args.first.respond_to?(:to_sym) ? args.shift : nil
333
333
  options.push args.shift ? true : false # force true/false
334
-
335
- options
336
334
  end
337
335
 
338
336
  def raise_if_invalid_options
@@ -91,6 +91,8 @@ class Slop
91
91
  case @options[:as].to_s.downcase
92
92
  when 'array'
93
93
  value.split @delimiter, @limit
94
+ when 'range'
95
+ value_to_range value
94
96
  when 'string'; value.to_s
95
97
  when 'symbol'; value.to_s.to_sym
96
98
  when 'integer'; value.to_s.to_i
@@ -141,5 +143,18 @@ class Slop
141
143
  "long_flag=#{@long_flag.inspect} " +
142
144
  "description=#{@description.inspect}>"
143
145
  end
146
+
147
+ private
148
+
149
+ def value_to_range(value)
150
+ case value.to_s
151
+ when /\A(\d+?)(?:\.\.|-|,)(\d+)\z/
152
+ Integer($1) .. Integer($2)
153
+ when /\A(\d+?)\.\.\.(\d+)\z/
154
+ Integer($1) ... Integer($2)
155
+ else
156
+ value
157
+ end
158
+ end
144
159
  end
145
160
  end
@@ -67,6 +67,17 @@ class OptionTest < TestCase
67
67
  assert_equal "1.0", option_value(%w/--id 1/, :id, true, :as => Float).to_s
68
68
  end
69
69
 
70
+ test 'ranges' do
71
+ assert_equal (1..10), option_value(%w/-r 1..10/, :r, true, :as => Range)
72
+ assert_equal (1..10), option_value(%w/-r 1-10/, :r, true, :as => Range)
73
+ assert_equal (1..10), option_value(%w/-r 1,10/, :r, true, :as => Range)
74
+ assert_equal (1...10), option_value(%w/-r 1...10/, :r, true, :as => Range)
75
+
76
+ # default back to the string unless a regex is successful
77
+ # maybe this should raise is Slop#strict?
78
+ assert_equal "1abc10", option_value(%w/-r 1abc10/, :r, true, :as => Range)
79
+ end
80
+
70
81
  test 'printing options' do
71
82
  slop = Slop.new
72
83
  slop.opt :n, :name, 'Your name', true
@@ -5,6 +5,14 @@ class SlopTest < TestCase
5
5
  Slop.new.send(:clean_options, args)
6
6
  end
7
7
 
8
+ def temp_argv(items)
9
+ old_argv = ARGV.clone
10
+ ARGV.replace items
11
+ yield
12
+ ensure
13
+ ARGV.replace old_argv
14
+ end
15
+
8
16
  test 'includes Enumerable' do
9
17
  assert Slop.included_modules.include?(Enumerable)
10
18
  end
@@ -30,6 +38,12 @@ class SlopTest < TestCase
30
38
  slop.each { |option| assert option }
31
39
  end
32
40
 
41
+ test 'defaulting to ARGV' do
42
+ temp_argv(%w/--name lee/) do
43
+ assert_equal('lee', Slop.parse { on :name, true }[:name])
44
+ end
45
+ end
46
+
33
47
  test 'multiple switches with the :multiple_switches flag' do
34
48
  slop = Slop.new :multiple_switches => true, :strict => true
35
49
  %w/a b c/.each { |f| slop.on f }
@@ -88,6 +102,9 @@ class SlopTest < TestCase
88
102
 
89
103
  slop.banner = nil
90
104
  assert_equal "", slop.to_s
105
+
106
+ slop = Slop.new "foo bar"
107
+ assert_equal "foo bar", slop.banner
91
108
  end
92
109
 
93
110
  test 'storing long option lengths' do
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: slop
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 1.4.0
5
+ version: 1.4.1
6
6
  platform: ruby
7
7
  authors:
8
8
  - Lee Jarvis
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2011-04-03 00:00:00 +01:00
13
+ date: 2011-04-14 00:00:00 +01:00
14
14
  default_executable:
15
15
  dependencies: []
16
16