slop 1.5.3 → 1.5.4

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