slop 1.3.1 → 1.4.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/.yardopts +1 -0
- data/README.md +35 -15
- data/lib/slop/option.rb +20 -45
- data/lib/slop/options.rb +37 -0
- data/lib/slop.rb +48 -8
- data/slop.gemspec +1 -1
- data/test/slop_test.rb +23 -4
- metadata +3 -3
- data/lib/slop/version.rb +0 -3
data/.yardopts
CHANGED
data/README.md
CHANGED
@@ -103,12 +103,12 @@ Parsing
|
|
103
103
|
|
104
104
|
Slop's pretty good at parsing, let's take a look at what it'll extract for you
|
105
105
|
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
106
|
+
Slop.parse do
|
107
|
+
on 's', 'server', true
|
108
|
+
on 'p', 'port', true, :as => :integer
|
109
|
+
on 'username', true, :matches => /[^a-zA-Z]+$/
|
110
|
+
on 'password', true
|
111
|
+
end
|
112
112
|
|
113
113
|
Now throw some options at it:
|
114
114
|
|
@@ -129,12 +129,12 @@ Callbacks
|
|
129
129
|
If you'd like to trigger an event when an option is used, you can pass a
|
130
130
|
block to your option. Here's how:
|
131
131
|
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
132
|
+
Slop.parse do
|
133
|
+
on :V, :version, 'Print the version' do
|
134
|
+
puts 'Version 1.0.0'
|
135
|
+
exit
|
136
|
+
end
|
137
|
+
end
|
138
138
|
|
139
139
|
Now when using the `--version` option on the command line, the trigger will
|
140
140
|
be called and its contents executed.
|
@@ -176,6 +176,26 @@ to return a false value.
|
|
176
176
|
opts[:verbose] #=> false
|
177
177
|
opts.verbose? #=> false
|
178
178
|
|
179
|
+
Short Switches
|
180
|
+
--------------
|
181
|
+
|
182
|
+
Want to enable multiple switches at once like rsync does? By default Slop will
|
183
|
+
parse `-abcd` as the option `a` with the argument `bcd`, this can be disabled
|
184
|
+
by passing the `:multiple_switches` option to a new Slop object.
|
185
|
+
|
186
|
+
opts = Slop.new(:strict, :multiple_switches) do
|
187
|
+
on :a, 'First switch'
|
188
|
+
on :b, 'Second switch'
|
189
|
+
on :c, 'Third switch'
|
190
|
+
end
|
191
|
+
|
192
|
+
opts.parse
|
193
|
+
|
194
|
+
# Using `-ac`
|
195
|
+
opts[:a] #=> true
|
196
|
+
opts[:b] #=> false
|
197
|
+
opts[:c] #=> true
|
198
|
+
|
179
199
|
Ugh, Symbols
|
180
200
|
------------
|
181
201
|
|
@@ -233,7 +253,7 @@ You can of course also parse lists into options. Here's how:
|
|
233
253
|
You can also change both the split delimiter and limit
|
234
254
|
|
235
255
|
opts = Slop.parse do
|
236
|
-
|
256
|
+
opt :people, true, :as => Array, :delimiter => ':', :limit => 2)
|
237
257
|
end
|
238
258
|
|
239
259
|
# ARGV is `--people lee:injekt:bob`
|
@@ -260,8 +280,8 @@ Significantly, however, Slop will still parse the valid options:
|
|
260
280
|
on :n, :name, 'Your name'
|
261
281
|
end
|
262
282
|
|
263
|
-
|
264
|
-
|
283
|
+
begin
|
284
|
+
slop.parse(%w/--foo --bar -z/)
|
265
285
|
rescue Slop::InvalidOptionError => e
|
266
286
|
puts "\n#{e.message}\n\n"
|
267
287
|
puts slop
|
data/lib/slop/option.rb
CHANGED
@@ -1,59 +1,28 @@
|
|
1
1
|
class Slop
|
2
|
-
class Options < Array
|
3
|
-
|
4
|
-
# @param [Boolean] symbols true to cast hash keys to symbols
|
5
|
-
# @return [Hash]
|
6
|
-
def to_hash(symbols)
|
7
|
-
out = {}
|
8
|
-
each do |option|
|
9
|
-
key = option.key
|
10
|
-
key = key.to_sym if symbols
|
11
|
-
out[key] = option.argument_value
|
12
|
-
end
|
13
|
-
out
|
14
|
-
end
|
15
|
-
|
16
|
-
# @param [Object] flag
|
17
|
-
# @return [Option] the option assoiated with this flag
|
18
|
-
def [](flag)
|
19
|
-
item = flag.to_s
|
20
|
-
if item =~ /\A\d+\z/
|
21
|
-
slice item.to_i
|
22
|
-
else
|
23
|
-
find do |option|
|
24
|
-
option.short_flag == item || option.long_flag == item
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
# @return [String]
|
30
|
-
def to_help
|
31
|
-
heads = reject {|x| x.tail }
|
32
|
-
tails = select {|x| x.tail }
|
33
|
-
(heads + tails).map(&:to_s).join("\n")
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
2
|
class Option
|
38
3
|
|
39
|
-
# @return [String, #to_s]
|
4
|
+
# @return [String, #to_s] The short flag used for this option
|
40
5
|
attr_reader :short_flag
|
41
6
|
|
42
|
-
# @return [String, #to_s]
|
7
|
+
# @return [String, #to_s] The long flag used for this option
|
43
8
|
attr_reader :long_flag
|
44
9
|
|
45
|
-
# @return [String]
|
10
|
+
# @return [String] This options description
|
46
11
|
attr_reader :description
|
47
12
|
|
48
|
-
# @return [Proc, #call]
|
13
|
+
# @return [Proc, #call] The object to execute when this option is used
|
49
14
|
attr_reader :callback
|
50
15
|
|
51
|
-
# @return [Boolean]
|
16
|
+
# @return [Boolean] True if the option should be grouped at the
|
17
|
+
# tail of the help list
|
52
18
|
attr_reader :tail
|
53
19
|
|
54
|
-
# @return [
|
20
|
+
# @return [Regexp] If provided, an options argument **must** match this
|
21
|
+
# regexp, otherwise Slop will raise an InvalidArgumentError
|
55
22
|
attr_reader :match
|
56
23
|
|
24
|
+
# @overload argument_value=(value)
|
25
|
+
# Set this options argument value
|
57
26
|
attr_writer :argument_value
|
58
27
|
|
59
28
|
# @param [Slop] slop
|
@@ -66,9 +35,9 @@ class Slop
|
|
66
35
|
# @option options [Boolean] :argument
|
67
36
|
# @option options [Object] :default
|
68
37
|
# @option options [Proc, #call] :callback
|
69
|
-
# @option options [String, #to_s] :delimiter
|
70
|
-
# @option options [Integer] :limit
|
71
|
-
# @option options [Boolean] :tail
|
38
|
+
# @option options [String, #to_s] :delimiter (',')
|
39
|
+
# @option options [Integer] :limit (0)
|
40
|
+
# @option options [Boolean] :tail (false)
|
72
41
|
# @option options [Regexp] :match
|
73
42
|
def initialize(slop, short, long, description, argument, options={}, &blk)
|
74
43
|
@slop = slop
|
@@ -102,7 +71,7 @@ class Slop
|
|
102
71
|
@expects_argument || @options[:argument]
|
103
72
|
end
|
104
73
|
|
105
|
-
# @return [Boolean] true if this option
|
74
|
+
# @return [Boolean] true if this option accepts an optional argument
|
106
75
|
def accepts_optional_argument?
|
107
76
|
@options[:optional]
|
108
77
|
end
|
@@ -140,10 +109,15 @@ class Slop
|
|
140
109
|
@forced = true
|
141
110
|
end
|
142
111
|
|
112
|
+
# @return [Boolean] true if this argument value has been forced
|
143
113
|
def forced?
|
144
114
|
@forced
|
145
115
|
end
|
146
116
|
|
117
|
+
# This option in a nice pretty string, including a short flag, long
|
118
|
+
# flag, and description (if they exist).
|
119
|
+
# @see Slop#help
|
120
|
+
# @return [String]
|
147
121
|
def to_s
|
148
122
|
out = " "
|
149
123
|
out += @short_flag ? "-#{@short_flag}, " : ' ' * 4
|
@@ -161,6 +135,7 @@ class Slop
|
|
161
135
|
"#{out}#{@description}"
|
162
136
|
end
|
163
137
|
|
138
|
+
# @return [String]
|
164
139
|
def inspect
|
165
140
|
"#<Slop::Option short_flag=#{@short_flag.inspect} " +
|
166
141
|
"long_flag=#{@long_flag.inspect} " +
|
data/lib/slop/options.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
class Slop
|
2
|
+
class Options < Array
|
3
|
+
|
4
|
+
# @param [Boolean] symbols true to cast hash keys to symbols
|
5
|
+
# @return [Hash]
|
6
|
+
def to_hash(symbols)
|
7
|
+
out = {}
|
8
|
+
each do |option|
|
9
|
+
key = option.key
|
10
|
+
key = key.to_sym if symbols
|
11
|
+
out[key] = option.argument_value
|
12
|
+
end
|
13
|
+
out
|
14
|
+
end
|
15
|
+
|
16
|
+
# @param [Object] flag The short/long flag representing the option
|
17
|
+
# @return [Option] the option assoiated with this flag
|
18
|
+
def [](flag)
|
19
|
+
item = flag.to_s
|
20
|
+
if item =~ /\A\d+\z/
|
21
|
+
slice item.to_i
|
22
|
+
else
|
23
|
+
find do |option|
|
24
|
+
option.short_flag == item || option.long_flag == item
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
# @see Slop#help
|
30
|
+
# @return [String] All options in a pretty help string
|
31
|
+
def to_help
|
32
|
+
heads = reject {|x| x.tail }
|
33
|
+
tails = select {|x| x.tail }
|
34
|
+
(heads + tails).map(&:to_s).join("\n")
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
data/lib/slop.rb
CHANGED
@@ -1,13 +1,23 @@
|
|
1
|
+
require 'slop/options'
|
1
2
|
require 'slop/option'
|
2
|
-
require 'slop/version'
|
3
3
|
|
4
4
|
class Slop
|
5
5
|
include Enumerable
|
6
6
|
|
7
|
+
# Raised when an option expects an argument and none is given
|
7
8
|
class MissingArgumentError < RuntimeError; end
|
9
|
+
|
10
|
+
# Raised when an option specifies the `:match` attribute and this
|
11
|
+
# options argument does not match this regexp
|
8
12
|
class InvalidArgumentError < RuntimeError; end
|
13
|
+
|
14
|
+
# Raised when the `:strict` option is enabled and an unknown
|
15
|
+
# or unspecified option is used
|
9
16
|
class InvalidOptionError < RuntimeError; end
|
10
17
|
|
18
|
+
# @return [String] The current version string
|
19
|
+
VERSION = '1.4.0'
|
20
|
+
|
11
21
|
# Parses the items from a CLI format into a friendly object.
|
12
22
|
#
|
13
23
|
# @param [Array] items Items to parse into options.
|
@@ -38,21 +48,29 @@ class Slop
|
|
38
48
|
attr_accessor :longest_flag
|
39
49
|
|
40
50
|
# @param [Hash] options
|
41
|
-
# @option
|
42
|
-
# @option
|
51
|
+
# @option opts [Boolean] :help Automatically add the `help` option
|
52
|
+
# @option opts [Boolean] :strict Strict mode raises when a non listed
|
43
53
|
# option is found, false by default
|
44
|
-
|
54
|
+
# @option opts [Boolean] :multiple_switches Allows `-abc` to be processed
|
55
|
+
# as the options 'a', 'b', 'c' and will force their argument values to
|
56
|
+
# true. By default Slop with parse this as 'a' with the argument 'bc'
|
57
|
+
def initialize(*opts, &block)
|
58
|
+
sloptions = {}
|
59
|
+
sloptions.merge! opts.pop if opts.last.is_a? Hash
|
60
|
+
opts.each { |o| sloptions[o] = true }
|
61
|
+
|
45
62
|
@options = Options.new
|
46
63
|
@banner = nil
|
47
64
|
@longest_flag = 0
|
48
|
-
@strict =
|
65
|
+
@strict = sloptions[:strict]
|
49
66
|
@invalid_options = []
|
67
|
+
@multiple_switches = sloptions[:multiple_switches]
|
50
68
|
|
51
69
|
if block_given?
|
52
70
|
block.arity == 1 ? yield(self) : instance_eval(&block)
|
53
71
|
end
|
54
72
|
|
55
|
-
if
|
73
|
+
if sloptions[:help]
|
56
74
|
on :h, :help, 'Print this help message', :tail => true do
|
57
75
|
puts help
|
58
76
|
exit
|
@@ -201,8 +219,13 @@ private
|
|
201
219
|
unless option
|
202
220
|
case item
|
203
221
|
when /\A-[^-]/
|
204
|
-
|
205
|
-
|
222
|
+
if @multiple_switches
|
223
|
+
enable_multiple_switches(item)
|
224
|
+
next
|
225
|
+
else
|
226
|
+
flag, argument = flag.split('', 2)
|
227
|
+
option = @options[flag]
|
228
|
+
end
|
206
229
|
when /\A--([^=]+)=(.+)\z/
|
207
230
|
option = @options[$1]
|
208
231
|
argument = $2
|
@@ -270,6 +293,23 @@ private
|
|
270
293
|
@invalid_options << flag if item[/\A--?/] && @strict
|
271
294
|
end
|
272
295
|
|
296
|
+
def enable_multiple_switches(item)
|
297
|
+
item[1..-1].split('').each do |switch|
|
298
|
+
if option = @options[switch]
|
299
|
+
if option.expects_argument?
|
300
|
+
raise MissingArgumentError,
|
301
|
+
"'-#{switch}' expects an argument, used in multiple_switch context"
|
302
|
+
else
|
303
|
+
option.argument_value = true
|
304
|
+
end
|
305
|
+
else
|
306
|
+
if @strict
|
307
|
+
raise InvalidOptionError, "Unknown option '-#{switch}'"
|
308
|
+
end
|
309
|
+
end
|
310
|
+
end
|
311
|
+
end
|
312
|
+
|
273
313
|
def clean_options(args)
|
274
314
|
options = []
|
275
315
|
|
data/slop.gemspec
CHANGED
data/test/slop_test.rb
CHANGED
@@ -5,14 +5,18 @@ class SlopTest < TestCase
|
|
5
5
|
Slop.new.send(:clean_options, args)
|
6
6
|
end
|
7
7
|
|
8
|
-
def parse(items, &block)
|
9
|
-
Slop.parse(items, &block)
|
10
|
-
end
|
11
|
-
|
12
8
|
test 'includes Enumerable' do
|
13
9
|
assert Slop.included_modules.include?(Enumerable)
|
14
10
|
end
|
15
11
|
|
12
|
+
test 'new accepts a hash or array of symbols' do
|
13
|
+
slop = Slop.new :strict, :multiple_switches => true
|
14
|
+
|
15
|
+
[ :@multiple_switches, :@strict ].each do |var|
|
16
|
+
assert slop.instance_variable_get var
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
16
20
|
test 'parse returns a Slop object' do
|
17
21
|
slop = Slop.parse([])
|
18
22
|
assert_kind_of Slop, slop
|
@@ -26,6 +30,21 @@ class SlopTest < TestCase
|
|
26
30
|
slop.each { |option| assert option }
|
27
31
|
end
|
28
32
|
|
33
|
+
test 'multiple switches with the :multiple_switches flag' do
|
34
|
+
slop = Slop.new :multiple_switches => true, :strict => true
|
35
|
+
%w/a b c/.each { |f| slop.on f }
|
36
|
+
slop.on :z, true
|
37
|
+
slop.parse %w/-abc/
|
38
|
+
|
39
|
+
%w/a b c/.each do |flag|
|
40
|
+
assert slop[flag]
|
41
|
+
assert slop.send(flag + '?')
|
42
|
+
end
|
43
|
+
|
44
|
+
assert_raises(Slop::InvalidOptionError, /d/) { slop.parse %w/-abcd/ }
|
45
|
+
assert_raises(Slop::MissingArgumentError, /z/) { slop.parse %w/-abcz/ }
|
46
|
+
end
|
47
|
+
|
29
48
|
test 'passing a block' do
|
30
49
|
assert Slop.new {}
|
31
50
|
slop = nil
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: slop
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 1.
|
5
|
+
version: 1.4.0
|
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-03
|
13
|
+
date: 2011-04-03 00:00:00 +01:00
|
14
14
|
default_executable:
|
15
15
|
dependencies: []
|
16
16
|
|
@@ -31,7 +31,7 @@ files:
|
|
31
31
|
- Rakefile
|
32
32
|
- lib/slop.rb
|
33
33
|
- lib/slop/option.rb
|
34
|
-
- lib/slop/
|
34
|
+
- lib/slop/options.rb
|
35
35
|
- slop.gemspec
|
36
36
|
- test/helper.rb
|
37
37
|
- test/option_test.rb
|
data/lib/slop/version.rb
DELETED