slop 1.4.0 → 1.4.1

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/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