slop 1.5.3 → 1.5.4

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -127,8 +127,8 @@ Here's what we'll get back
127
127
  :password=>"hello there"
128
128
  }
129
129
 
130
- Callbacks
131
- ---------
130
+ Events
131
+ ------
132
132
 
133
133
  If you'd like to trigger an event when an option is used, you can pass a
134
134
  block to your option. Here's how:
data/Rakefile CHANGED
@@ -1,9 +1,6 @@
1
1
  task :test do
2
- $LOAD_PATH.unshift './lib'
3
- require 'slop'
4
- require 'minitest/autorun'
5
- begin; require 'turn'; rescue LoadError; end
6
- Dir.glob("test/**/*_test.rb").each { |test| require "./#{test}" }
2
+ $:.unshift './test'
3
+ Dir.glob("test/*_test.rb").each { |test| require "./#{test}" }
7
4
  end
8
5
 
9
6
  task :default => :test
@@ -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.5.3'
19
+ VERSION = '1.5.4'
20
20
 
21
21
  # Parses the items from a CLI format into a friendly object.
22
22
  #
@@ -72,7 +72,7 @@ class Slop
72
72
  def initialize(*opts, &block)
73
73
  sloptions = {}
74
74
  sloptions.merge! opts.pop if opts.last.is_a? Hash
75
- @banner = opts.shift if opts[0].respond_to?(:to_str)
75
+ sloptions[:banner] = opts.shift if opts[0].respond_to?(:to_str)
76
76
  opts.each { |o| sloptions[o] = true }
77
77
 
78
78
  @options = Options.new
@@ -81,7 +81,7 @@ class Slop
81
81
  @longest_flag = 0
82
82
  @invalid_options = []
83
83
 
84
- @banner ||= sloptions[:banner]
84
+ @banner = sloptions[:banner]
85
85
  @strict = sloptions[:strict]
86
86
  @multiple_switches = sloptions[:multiple_switches]
87
87
  @on_empty = sloptions[:on_empty]
@@ -109,7 +109,7 @@ class Slop
109
109
  # opts = Slop.parse do
110
110
  # banner "Usage - ruby foo.rb [arguments]"
111
111
  # end
112
- # @return [String] Returns current banner.
112
+ # @return [String] The current banner.
113
113
  def banner(text=nil)
114
114
  @banner = text if text
115
115
  @banner
@@ -134,16 +134,17 @@ class Slop
134
134
  @options.each(&block)
135
135
  end
136
136
 
137
- # Return the value of an option via the subscript operator.
138
- #
139
137
  # @param [Symbol] key Option symbol.
140
138
  # @example
141
139
  # opts[:name] #=> "Emily"
142
- # @return [Object] Returns the value associated with that option.
140
+ # opts.get(:name) #=> "Emily"
141
+ # @return [Object] Returns the value associated with that option. If an
142
+ # option doesn't exist, a command will instead be searched for
143
143
  def [](key)
144
144
  option = @options[key]
145
145
  option ? option.argument_value : @commands[key]
146
146
  end
147
+ alias :get :[]
147
148
 
148
149
  # Specify an option with a short or long version, description and type.
149
150
  #
@@ -245,7 +246,16 @@ class Slop
245
246
  # @return [Boolean] Whether the desired option was specified.
246
247
  def method_missing(meth, *args, &block)
247
248
  super unless meth.to_s =~ /\?\z/
248
- !!self[meth.to_s.chomp '?']
249
+ present? meth.to_s.chomp '?'
250
+ end
251
+
252
+ # Check if an option is specified in the parsed list. Does the same as
253
+ # Slop#option? but a convenience method for unacceptable method names.
254
+ #
255
+ # @param [Object] The object name to check
256
+ # @return [Boolean] true if this option is present
257
+ def present?(option_name)
258
+ !!get(option_name)
249
259
  end
250
260
 
251
261
  # Returns the banner followed by available options listed on the next line.
@@ -263,6 +273,11 @@ class Slop
263
273
  end
264
274
  alias :help :to_s
265
275
 
276
+ def inspect
277
+ "#<Slop config_options=#{@sloptions.inspect}\n " +
278
+ options.map(&:inspect).join("\n ") + "\n>"
279
+ end
280
+
266
281
  private
267
282
 
268
283
  class << self
@@ -315,14 +330,15 @@ class Slop
315
330
  end
316
331
 
317
332
  if option
318
- trash << item
319
- next if option.forced?
333
+ option.count += 1
334
+ trash << index
335
+ next if option.forced
320
336
  option.argument_value = true
321
337
 
322
338
  if option.expects_argument? || option.accepts_optional_argument?
323
339
  argument ||= items.at(index + 1)
324
340
  check_valid_argument!(option, argument)
325
- trash << argument
341
+ trash << index + 1
326
342
 
327
343
  if argument
328
344
  check_matching_argument!(option, argument)
@@ -337,11 +353,11 @@ class Slop
337
353
  end
338
354
  else
339
355
  check_invalid_option!(item, flag)
340
- block.call(item) if block_given? && !trash.include?(item)
356
+ block.call(item) if block_given? && !trash.include?(index)
341
357
  end
342
358
  end
343
359
 
344
- items.delete_if { |item| trash.include? item } if delete
360
+ items.reject!.with_index { |o, i| trash.include?(i) } if delete
345
361
  raise_if_invalid_options!
346
362
  items
347
363
  end
@@ -24,11 +24,17 @@ class Slop
24
24
  # @return [Object] true/false, or an optional help string to append
25
25
  attr_reader :help
26
26
 
27
+ # @return [Boolean] true if this options argument value has been forced
28
+ attr_reader :forced
29
+
27
30
  # @overload argument_value=(value)
28
31
  # Set this options argument value
29
32
  # @param [Object] value The value you'd like applied to this option
30
33
  attr_writer :argument_value
31
34
 
35
+ # @return [Integer] The amount of times this option has been invoked
36
+ attr_accessor :count
37
+
32
38
  # @param [Slop] slop
33
39
  # @param [String, #to_s] short
34
40
  # @param [String, #to_s] long
@@ -56,26 +62,19 @@ class Slop
56
62
 
57
63
  @tail = options[:tail]
58
64
  @match = options[:match]
65
+ @delimiter = options[:delimiter] || ','
66
+ @limit = options[:limit] || 0
59
67
  @help = options[:help]
60
68
  @help = true if @help.nil?
61
69
 
62
70
  @forced = false
63
71
  @argument_value = nil
64
-
65
- @delimiter = options[:delimiter] || ','
66
- @limit = options[:limit] || 0
67
-
68
- if @long_flag && @long_flag.size > @slop.longest_flag
69
- if @help.respond_to? :to_str
70
- size = @long_flag.size + @help.size
71
- else
72
- size = @long_flag.size
73
- end
74
- @slop.longest_flag = size
75
- end
72
+ @count = 0
76
73
 
77
74
  @callback = blk if block_given?
78
75
  @callback ||= options[:callback]
76
+
77
+ build_longest_flag
79
78
  end
80
79
 
81
80
  # @return [Boolean] true if this option expects an argument
@@ -105,9 +104,9 @@ class Slop
105
104
  value.split @delimiter, @limit
106
105
  when 'range'
107
106
  value_to_range value
108
- when 'string'; value.to_s
109
- when 'symbol'; value.to_s.to_sym
110
- when 'integer'; value.to_s.to_i
107
+ when 'string', 'str'; value.to_s
108
+ when 'symbol', 'sym'; value.to_s.to_sym
109
+ when 'integer', 'int'; value.to_s.to_i
111
110
  when 'float'; value.to_s.to_f
112
111
  else
113
112
  value
@@ -123,11 +122,6 @@ class Slop
123
122
  @forced = true
124
123
  end
125
124
 
126
- # @return [Boolean] true if this argument value has been forced
127
- def forced?
128
- @forced
129
- end
130
-
131
125
  # This option in a nice pretty string, including a short flag, long
132
126
  # flag, and description (if they exist).
133
127
  # @see Slop#help
@@ -176,5 +170,16 @@ class Slop
176
170
  value
177
171
  end
178
172
  end
173
+
174
+ def build_longest_flag
175
+ if @long_flag && @long_flag.size > @slop.longest_flag
176
+ if @help.respond_to? :to_str
177
+ size = @long_flag.size + @help.size
178
+ else
179
+ size = @long_flag.size
180
+ end
181
+ @slop.longest_flag = size
182
+ end
183
+ end
179
184
  end
180
185
  end
@@ -4,22 +4,21 @@ class Slop
4
4
  # @param [Boolean] symbols true to cast hash keys to symbols
5
5
  # @return [Hash]
6
6
  def to_hash(symbols)
7
- out = {}
8
- each do |option|
7
+ reduce({}) do |hsh, option|
9
8
  key = option.key
10
9
  key = key.to_sym if symbols
11
- out[key] = option.argument_value
10
+ hsh[key] = option.argument_value
11
+ hsh
12
12
  end
13
- out
14
13
  end
15
14
 
16
15
  # @param [Object] flag The short/long flag representing the option
17
16
  # @return [Option] the option assoiated with this flag
18
17
  def [](flag)
19
- item = flag.to_s
20
18
  if flag.is_a?(Integer)
21
19
  slice flag
22
20
  else
21
+ item = flag.to_s
23
22
  find do |option|
24
23
  option.short_flag == item || option.long_flag == item
25
24
  end
@@ -29,9 +28,9 @@ class Slop
29
28
  # @see Slop#help
30
29
  # @return [String] All options in a pretty help string
31
30
  def to_help
32
- heads = reject {|x| x.tail }
33
- tails = select {|x| x.tail }
34
- all = (heads + tails).reject {|x| !x.help }
31
+ heads = reject(&:tail)
32
+ tails = select(&:tail)
33
+ all = (heads + tails).select(&:help)
35
34
  all.map(&:to_s).join("\n")
36
35
  end
37
36
  end
@@ -4,14 +4,11 @@ require 'slop'
4
4
  Gem::Specification.new do |s|
5
5
  s.name = 'slop'
6
6
  s.version = Slop::VERSION
7
- s.platform = Gem::Platform::RUBY
8
7
  s.summary = 'Option gathering made easy'
9
8
  s.description = 'A simple DSL for gathering options and parsing the command line'
10
9
  s.author = 'Lee Jarvis'
11
10
  s.email = 'lee@jarvis.co'
12
11
  s.homepage = 'http://github.com/injekt/slop'
13
-
14
- s.files = `git ls-files`.split("\n")
15
- s.test_files = `git ls-files -- test/*`.split("\n")
16
- s.require_paths = ["lib"]
12
+ s.files = `git ls-files`.split("\n")
13
+ s.test_files = `git ls-files -- test/*`.split("\n")
17
14
  end
@@ -1,4 +1,4 @@
1
- require File.dirname(__FILE__) + '/helper'
1
+ require 'helper'
2
2
 
3
3
  class CommandsTest < TestCase
4
4
  test 'creating commands' do
@@ -1,3 +1,15 @@
1
+ unless Object.const_defined? 'Slop'
2
+ $:.unshift File.expand_path('../../lib', __FILE__)
3
+ require 'slop'
4
+ end
5
+
6
+ require 'minitest/autorun'
7
+
8
+ begin
9
+ require 'turn'
10
+ rescue LoadError
11
+ end
12
+
1
13
  class TestCase < MiniTest::Unit::TestCase
2
14
  def self.test(name, &block)
3
15
  test_name = "test_#{name.gsub(/\s+/, '_')}".to_sym
@@ -1,4 +1,4 @@
1
- require File.dirname(__FILE__) + '/helper'
1
+ require 'helper'
2
2
 
3
3
  class OptionTest < TestCase
4
4
  def option(*args, &block)
@@ -63,6 +63,7 @@ class OptionTest < TestCase
63
63
  test 'casting' do
64
64
  assert_equal :foo, option_value(%w/--name foo/, :name, true, :as => Symbol)
65
65
  assert_equal :foo, option_value(%w/--name foo/, :name, true, :as => :symbol)
66
+ assert_equal :foo, option_value(%w/--name foo/, :name, true, :as => :sym)
66
67
  assert_equal 30, option_value(%w/--age 30/, :age, true, :as => Integer)
67
68
  assert_equal "1.0", option_value(%w/--id 1/, :id, true, :as => Float).to_s
68
69
  end
@@ -75,7 +76,7 @@ class OptionTest < TestCase
75
76
 
76
77
  # default back to the string unless a regex is successful
77
78
  # return value.to_i if the value is /\A\d+\z/
78
- # maybe this should raise is Slop#strict?
79
+ # maybe this should raise if Slop#strict?
79
80
  assert_equal "1abc10", option_value(%w/-r 1abc10/, :r, true, :as => Range)
80
81
  assert_equal 1, option_value(%w/-r 1/, :r, true, :as => Range)
81
82
  end
@@ -137,4 +138,11 @@ class OptionTest < TestCase
137
138
  assert_equal nil, slop[:foo]
138
139
  refute_equal "", slop[:foo]
139
140
  end
141
+
142
+ test 'counting options' do
143
+ slop = Slop.new { on :v; on :x }
144
+ slop.parse %w/-v -v -v -x/
145
+ assert_equal 1, slop.options[:x].count
146
+ assert_equal 3, slop.options[:v].count
147
+ end
140
148
  end
@@ -1,3 +1,5 @@
1
+ require 'helper'
2
+
1
3
  class SlopTest < TestCase
2
4
  def clean_options(*args)
3
5
  Slop.new.send(:clean_options, args)
@@ -32,7 +34,7 @@ class SlopTest < TestCase
32
34
  slop.opt(:f, :foo, 'foo')
33
35
  slop.opt(:b, :bar, 'bar')
34
36
 
35
- slop.each { |option| assert option }
37
+ slop.each { |option| assert_kind_of Slop::Option, option }
36
38
  end
37
39
 
38
40
  test 'defaulting to ARGV' do
@@ -42,13 +44,12 @@ class SlopTest < TestCase
42
44
  end
43
45
 
44
46
  test 'callback when option array is empty' do
45
- item1 = item2 = nil
47
+ item1 = nil
46
48
  temp_argv([]) do
47
49
  Slop.new { on_empty { item1 = 'foo' } }.parse
48
50
  end
49
51
 
50
52
  assert_equal 'foo', item1
51
- assert_nil item2
52
53
  end
53
54
 
54
55
  test 'multiple switches with the :multiple_switches flag' do
@@ -144,6 +145,12 @@ class SlopTest < TestCase
144
145
  assert_empty items
145
146
  end
146
147
 
148
+ test '#parse! does not remove unparsed items with same value as a parsed item' do
149
+ items = %w/bar --foo bar/
150
+ Slop.new { |opt| opt.on :foo, 'foo', true }.parse!(items)
151
+ assert_equal %w/bar/, items
152
+ end
153
+
147
154
  test '#parse! removes parsed items prefixed with --no-' do
148
155
  items = %w/--no-foo/
149
156
  Slop.new { |opt| opt.on :foo }.parse!(items)
@@ -210,6 +217,14 @@ class SlopTest < TestCase
210
217
  refute slop.debug?
211
218
  end
212
219
 
220
+ test 'options are present' do
221
+ opts = Slop.new { on :f, 'foo-bar'; on :b, 'bar-baz' }
222
+ opts.parse %w/--foo-bar/
223
+
224
+ assert opts.present?('foo-bar')
225
+ refute opts.present?('bar-baz')
226
+ end
227
+
213
228
  test 'raises if an option expects an argument and none is given' do
214
229
  slop = Slop.new
215
230
  slop.opt :name, true
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: slop
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 1.5.3
5
+ version: 1.5.4
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-23 00:00:00 +01:00
13
+ date: 2011-05-01 00:00:00 +01:00
14
14
  default_executable:
15
15
  dependencies: []
16
16