slop 3.3.2 → 3.3.3
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES.md +7 -0
- data/lib/slop.rb +7 -4
- data/lib/slop/commands.rb +24 -2
- data/lib/slop/option.rb +23 -4
- data/slop.gemspec +1 -1
- data/test/commands_test.rb +15 -3
- data/test/helper.rb +2 -0
- data/test/option_test.rb +10 -9
- data/test/slop_test.rb +13 -0
- metadata +4 -4
data/CHANGES.md
CHANGED
data/lib/slop.rb
CHANGED
@@ -4,7 +4,7 @@ require 'slop/commands'
|
|
4
4
|
class Slop
|
5
5
|
include Enumerable
|
6
6
|
|
7
|
-
VERSION = '3.3.
|
7
|
+
VERSION = '3.3.3'
|
8
8
|
|
9
9
|
# The main Error class, all Exception classes inherit from this class.
|
10
10
|
class Error < StandardError; end
|
@@ -433,7 +433,7 @@ class Slop
|
|
433
433
|
elsif option.accepts_optional_argument?
|
434
434
|
argument ||= items.at(index + 1)
|
435
435
|
|
436
|
-
if argument && argument =~ /\A([
|
436
|
+
if argument && argument =~ /\A([^\-?]|-\d)+/
|
437
437
|
execute_option(option, argument, index, item)
|
438
438
|
else
|
439
439
|
option.call(nil)
|
@@ -467,7 +467,9 @@ class Slop
|
|
467
467
|
end
|
468
468
|
|
469
469
|
if argument
|
470
|
-
|
470
|
+
unless item && item.end_with?("=#{argument}")
|
471
|
+
@trash << index + 1 unless option.argument_in_value
|
472
|
+
end
|
471
473
|
option.value = argument
|
472
474
|
else
|
473
475
|
option.value = option.count > 0
|
@@ -511,6 +513,7 @@ class Slop
|
|
511
513
|
case flag
|
512
514
|
when /\A--?([^=]+)=(.+)\z/, /\A-([a-zA-Z])(.+)\z/, /\A--no-(.+)\z/
|
513
515
|
option, argument = fetch_option($1), ($2 || false)
|
516
|
+
option.argument_in_value = true if option
|
514
517
|
end
|
515
518
|
end
|
516
519
|
|
@@ -525,7 +528,7 @@ class Slop
|
|
525
528
|
# Returns nothing.
|
526
529
|
def autocreate(items, index)
|
527
530
|
flag = items[index]
|
528
|
-
|
531
|
+
if !fetch_option(flag) && !@trash.include?(index)
|
529
532
|
option = build_option(Array(flag))
|
530
533
|
argument = items[index + 1]
|
531
534
|
option.config[:argument] = (argument && argument !~ /\A--?/)
|
data/lib/slop/commands.rb
CHANGED
@@ -2,7 +2,7 @@ class Slop
|
|
2
2
|
class Commands
|
3
3
|
include Enumerable
|
4
4
|
|
5
|
-
attr_reader :config, :commands
|
5
|
+
attr_reader :config, :commands, :arguments
|
6
6
|
attr_writer :banner
|
7
7
|
|
8
8
|
# Create a new instance of Slop::Commands and optionally build
|
@@ -37,6 +37,7 @@ class Slop
|
|
37
37
|
@config = config
|
38
38
|
@commands = {}
|
39
39
|
@banner = nil
|
40
|
+
@triggered_command = nil
|
40
41
|
|
41
42
|
if block_given?
|
42
43
|
block.arity == 1 ? yield(self) : instance_eval(&block)
|
@@ -94,6 +95,19 @@ class Slop
|
|
94
95
|
end
|
95
96
|
alias get []
|
96
97
|
|
98
|
+
# Check for a command presence.
|
99
|
+
#
|
100
|
+
# Examples:
|
101
|
+
#
|
102
|
+
# cmds.parse %w( foo )
|
103
|
+
# cmds.present?(:foo) #=> true
|
104
|
+
# cmds.present?(:bar) #=> false
|
105
|
+
#
|
106
|
+
# Returns true if the given key is present in the parsed arguments.
|
107
|
+
def present?(key)
|
108
|
+
key.to_s == @triggered_command
|
109
|
+
end
|
110
|
+
|
97
111
|
# Parse a list of items.
|
98
112
|
#
|
99
113
|
# items - The Array of items to parse.
|
@@ -149,7 +163,8 @@ class Slop
|
|
149
163
|
# Returns the Array of items (with options removed if bang == true).
|
150
164
|
def parse_items(items, bang = false)
|
151
165
|
if opts = commands[items[0].to_s]
|
152
|
-
items.shift
|
166
|
+
@triggered_command = items.shift
|
167
|
+
execute_arguments(items, bang)
|
153
168
|
bang ? opts.parse!(items) : opts.parse(items)
|
154
169
|
execute_global_opts(items, bang)
|
155
170
|
else
|
@@ -165,6 +180,13 @@ class Slop
|
|
165
180
|
items
|
166
181
|
end
|
167
182
|
|
183
|
+
# Returns nothing.
|
184
|
+
def execute_arguments(items, bang)
|
185
|
+
@arguments = items.take_while { |arg| !arg.start_with?('-') }
|
186
|
+
items.shift(@arguments.size) if bang
|
187
|
+
end
|
188
|
+
|
189
|
+
# Returns nothing.
|
168
190
|
def execute_global_opts(items, bang)
|
169
191
|
if global_opts = commands['global']
|
170
192
|
bang ? global_opts.parse!(items) : global_opts.parse(items)
|
data/lib/slop/option.rb
CHANGED
@@ -18,8 +18,7 @@ class Slop
|
|
18
18
|
}
|
19
19
|
|
20
20
|
attr_reader :short, :long, :description, :config, :types
|
21
|
-
attr_accessor :count
|
22
|
-
attr_writer :value
|
21
|
+
attr_accessor :count, :argument_in_value
|
23
22
|
|
24
23
|
# Incapsulate internal option information, mainly used to store
|
25
24
|
# option specific configuration data, most of the meat of this
|
@@ -39,13 +38,13 @@ class Slop
|
|
39
38
|
@config = DEFAULT_OPTIONS.merge(config)
|
40
39
|
@count = 0
|
41
40
|
@callback = block_given? ? block : config[:callback]
|
41
|
+
@value = nil
|
42
42
|
|
43
43
|
@types = {
|
44
44
|
:string => proc { |v| v.to_s },
|
45
45
|
:symbol => proc { |v| v.to_sym },
|
46
46
|
:integer => proc { |v| value_to_integer(v) },
|
47
47
|
:float => proc { |v| value_to_float(v) },
|
48
|
-
:array => proc { |v| v.split(@config[:delimiter], @config[:limit]) },
|
49
48
|
:range => proc { |v| value_to_range(v) },
|
50
49
|
:count => proc { |v| @count }
|
51
50
|
}
|
@@ -55,7 +54,10 @@ class Slop
|
|
55
54
|
end
|
56
55
|
|
57
56
|
@config.each_key do |key|
|
58
|
-
|
57
|
+
predicate = :"#{key}?"
|
58
|
+
unless self.class.method_defined? predicate
|
59
|
+
self.class.send(:define_method, predicate) { !!@config[key] }
|
60
|
+
end
|
59
61
|
end
|
60
62
|
end
|
61
63
|
|
@@ -81,6 +83,23 @@ class Slop
|
|
81
83
|
@callback.call(*objects) if @callback.respond_to?(:call)
|
82
84
|
end
|
83
85
|
|
86
|
+
# Set the new argument value for this option.
|
87
|
+
#
|
88
|
+
# We use this setter method to handle concatenating lists. That is,
|
89
|
+
# when an array type is specified and used more than once, values from
|
90
|
+
# both options will be grouped together and flattened into a single array.
|
91
|
+
def value=(new_value)
|
92
|
+
if config[:as].to_s.downcase == 'array'
|
93
|
+
@value ||= []
|
94
|
+
|
95
|
+
if new_value.respond_to?(:split)
|
96
|
+
@value.concat new_value.split(config[:delimiter], config[:limit])
|
97
|
+
end
|
98
|
+
else
|
99
|
+
@value = new_value
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
84
103
|
# Fetch the argument value for this option.
|
85
104
|
#
|
86
105
|
# Returns the Object once any type conversions have taken place.
|
data/slop.gemspec
CHANGED
data/test/commands_test.rb
CHANGED
@@ -27,6 +27,12 @@ class CommandsTest < TestCase
|
|
27
27
|
assert_equal 'Force creation', @commands[:new].fetch_option(:force).description
|
28
28
|
end
|
29
29
|
|
30
|
+
test "checking for a command presence" do
|
31
|
+
@commands.parse %w( new --force )
|
32
|
+
assert @commands.present?(:new)
|
33
|
+
refute @commands.present?(:version)
|
34
|
+
end
|
35
|
+
|
30
36
|
test "to_hash" do
|
31
37
|
assert_equal({
|
32
38
|
:new => { :force => nil, :outdir => nil },
|
@@ -77,14 +83,20 @@ class CommandsTest < TestCase
|
|
77
83
|
items = %w( foo bar baz )
|
78
84
|
assert_equal items, @commands.parse(items)
|
79
85
|
|
80
|
-
items = %w( new --force )
|
86
|
+
items = %w( new file --force )
|
81
87
|
assert_equal items, @commands.parse(items)
|
82
88
|
end
|
83
89
|
|
84
90
|
test "parse! removes options/arguments" do
|
85
|
-
items = %w( new --outdir foo )
|
91
|
+
items = %w( new file --outdir foo )
|
86
92
|
@commands.parse!(items)
|
87
93
|
assert_equal [], items
|
88
94
|
end
|
89
95
|
|
90
|
-
|
96
|
+
test "command arguments" do
|
97
|
+
items = %w( new file1 file2 --outdir foo )
|
98
|
+
@commands.parse(items)
|
99
|
+
assert_equal %w( file1 file2 ), @commands.arguments
|
100
|
+
end
|
101
|
+
|
102
|
+
end
|
data/test/helper.rb
CHANGED
data/test/option_test.rb
CHANGED
@@ -71,14 +71,14 @@ class OptionTest < TestCase
|
|
71
71
|
end
|
72
72
|
|
73
73
|
test "range type cast" do
|
74
|
-
assert_equal
|
75
|
-
assert_equal
|
76
|
-
assert_equal
|
77
|
-
assert_equal
|
78
|
-
assert_equal
|
79
|
-
assert_equal
|
80
|
-
assert_equal
|
81
|
-
assert_equal
|
74
|
+
assert_equal((1..10), option_value(%w/-r 1..10/, :r=, :as => Range))
|
75
|
+
assert_equal((1..10), option_value(%w/-r 1-10/, :r=, :as => Range))
|
76
|
+
assert_equal((1..10), option_value(%w/-r 1,10/, :r=, :as => Range))
|
77
|
+
assert_equal((1...10), option_value(%w/-r 1...10/, :r=, :as => Range))
|
78
|
+
assert_equal((-1..10), option_value(%w/-r -1..10/, :r=, :as => Range))
|
79
|
+
assert_equal((1..-10), option_value(%w/-r 1..-10/, :r=, :as => Range))
|
80
|
+
assert_equal((1..1), option_value(%w/-r 1/, :r=, :as => Range))
|
81
|
+
assert_equal((-1..10), option_value(%w/-r -1..10/, :r, :as => Range, :optional_argument => true))
|
82
82
|
|
83
83
|
opts = Slop.new(:strict => true) { on :r=, :as => Range }
|
84
84
|
assert_raises(Slop::InvalidArgumentError) { opts.parse %w/-r abc/ }
|
@@ -86,6 +86,7 @@ class OptionTest < TestCase
|
|
86
86
|
|
87
87
|
test "array type cast" do
|
88
88
|
assert_equal %w/lee john bill/, option_value(%w/-p lee,john,bill/, :p=, :as => Array)
|
89
|
+
assert_equal %w/lee john bill jeff jill/, option_value(%w/-p lee,john,bill -p jeff,jill/, :p=, :as => Array)
|
89
90
|
assert_equal %w/lee john bill/, option_value(%w/-p lee:john:bill/, :p=, :as => Array, :delimiter => ':')
|
90
91
|
assert_equal %w/lee john,bill/, option_value(%w/-p lee,john,bill/, :p=, :as => Array, :limit => 2)
|
91
92
|
assert_equal %w/lee john:bill/, option_value(%w/-p lee:john:bill/, :p=, :as => Array, :limit => 2, :delimiter => ':')
|
@@ -109,7 +110,7 @@ class OptionTest < TestCase
|
|
109
110
|
|
110
111
|
test "using a default value as fallback" do
|
111
112
|
opts = Slop.new
|
112
|
-
|
113
|
+
opts.on :f, :argument => :optional, :default => 'foo'
|
113
114
|
opts.parse %w'-f'
|
114
115
|
assert_equal 'foo', opts[:f]
|
115
116
|
end
|
data/test/slop_test.rb
CHANGED
@@ -47,6 +47,11 @@ class SlopTest < TestCase
|
|
47
47
|
slop = Slop.new { on :foo= }
|
48
48
|
slop.parse %w' --foo=bar '
|
49
49
|
assert_equal 'bar', slop[:foo]
|
50
|
+
|
51
|
+
slop = Slop.new(:multiple_switches => false) { on :f=; on :b= }
|
52
|
+
slop.parse %w' -fabc -bdef '
|
53
|
+
assert_equal 'abc', slop[:f]
|
54
|
+
assert_equal 'def', slop[:b]
|
50
55
|
end
|
51
56
|
|
52
57
|
test "fetch_option" do
|
@@ -175,6 +180,14 @@ class SlopTest < TestCase
|
|
175
180
|
assert opts.fetch_option(:foo).autocreated?
|
176
181
|
assert_equal 'bar', opts.fetch_option(:foo).value
|
177
182
|
refute opts.fetch_option(:baz).expects_argument?
|
183
|
+
assert_equal nil, opts.fetch_option(:bar)
|
184
|
+
|
185
|
+
opts = Slop.new :autocreate => true do
|
186
|
+
on :f, :foo=
|
187
|
+
end
|
188
|
+
opts.parse %w[ --foo bar --baz stuff ]
|
189
|
+
assert_equal 'bar', opts[:foo]
|
190
|
+
assert_equal 'stuff', opts[:baz]
|
178
191
|
end
|
179
192
|
|
180
193
|
test "option terminator" do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: slop
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.3.
|
4
|
+
version: 3.3.3
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-08-29 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|
@@ -78,7 +78,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
78
78
|
version: '0'
|
79
79
|
segments:
|
80
80
|
- 0
|
81
|
-
hash:
|
81
|
+
hash: 3713237527878732625
|
82
82
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
83
83
|
none: false
|
84
84
|
requirements:
|
@@ -87,7 +87,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
87
87
|
version: '0'
|
88
88
|
segments:
|
89
89
|
- 0
|
90
|
-
hash:
|
90
|
+
hash: 3713237527878732625
|
91
91
|
requirements: []
|
92
92
|
rubyforge_project:
|
93
93
|
rubygems_version: 1.8.23
|