slop 2.1.0 → 2.2.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/CHANGES.md CHANGED
@@ -1,3 +1,13 @@
1
+ 2.2.0 (2011-11-02)
2
+ ------------------
3
+
4
+ * Support `bup.options` style optspec parsing
5
+ * http://apenwarr.ca/log/?m=201111
6
+
7
+ * Allow `:as` to accept a `count` value (Conrad Irwin):
8
+
9
+ `on :v, :verbose, :as => :count # -vv; opts[:verbose] #=> 2`
10
+
1
11
  2.1.0 (2011-08-03)
2
12
  ------------------
3
13
 
@@ -1,6 +1,9 @@
1
1
  class Slop
2
2
  include Enumerable
3
3
 
4
+ # @return [String] The current version string
5
+ VERSION = '2.2.0'
6
+
4
7
  # Slops standard Error class. All exception classes should
5
8
  # inherit from this class
6
9
  class Error < StandardError; end
@@ -20,8 +23,7 @@ class Slop
20
23
  class InvalidOptionError < Error; end
21
24
 
22
25
  # Each option specified in `Slop#opt` creates an instance of this class
23
- class Option < Struct.new(:short_flag, :long_flag, :description,
24
- :tail, :match, :help, :required, :forced, :count)
26
+ class Option < Struct.new(:short_flag, :long_flag, :description, :tail, :match, :help, :required, :forced, :count)
25
27
 
26
28
  # @param [Slop] slop The Slop object this Option belongs to
27
29
  #
@@ -143,6 +145,9 @@ class Slop
143
145
  # according to the `:as` option
144
146
  def argument_value
145
147
  return @argument_value if forced
148
+ # Check for count first to prefer 0 over nil
149
+ return count if @argument_type == 'count'
150
+
146
151
  value = @argument_value || @options[:default]
147
152
  return if value.nil?
148
153
 
@@ -219,10 +224,8 @@ class Slop
219
224
 
220
225
  def value_to_range(value)
221
226
  case value.to_s
222
- when /\A(-?\d+?)(?:\.\.|-|,)(-?\d+)\z/
223
- $1.to_i .. $2.to_i
224
- when /\A(-?\d+?)\.\.\.(-?\d+)\z/
225
- $1.to_i ... $2.to_i
227
+ when /\A(-?\d+?)(\.\.\.?|-|,)(-?\d+)\z/
228
+ Range.new($1.to_i, $3.to_i, $2 == '...')
226
229
  when /\A-?\d+\z/
227
230
  value.to_i
228
231
  else
@@ -262,9 +265,6 @@ class Slop
262
265
  end
263
266
  end
264
267
 
265
- # @return [String] The current version string
266
- VERSION = '2.1.0'
267
-
268
268
  # Parses the items from a CLI format into a friendly object
269
269
  #
270
270
  # @param [Array] items Items to parse into options.
@@ -287,6 +287,30 @@ class Slop
287
287
  initialize_and_parse items, true, options, &block
288
288
  end
289
289
 
290
+ # Build options from an optspec string
291
+ #
292
+ # @param [String] optspec The option spec string
293
+ # @param [Array] options A list of options to forward to Slop.new
294
+ # @return [Slop] A new instance of Slop
295
+ def self.optspec(optspec, *options)
296
+ if optspec[/^--+$/]
297
+ banner, optspec = optspec.split(/^--+$/, 2)
298
+ end
299
+
300
+ lines = optspec.split("\n").reject(&:empty?)
301
+ opts = Slop.new(banner, *options)
302
+
303
+ lines.each do |line|
304
+ opt, description = line.split(' ', 2)
305
+ short, long = opt.split(',').map { |s| s.sub(/\A--?/, '') }
306
+ argument = long && long[/\=$/]
307
+ long.sub!(/\=$/, '') if argument
308
+ opts.on short, long, description, argument
309
+ end
310
+
311
+ opts
312
+ end
313
+
290
314
  # @return [Options]
291
315
  attr_reader :options
292
316
 
@@ -522,7 +546,7 @@ class Slop
522
546
  # @raise [ArgumentError] When this command already exists
523
547
  # @return [Slop] a new instance of Slop namespaced to +label+
524
548
  def command(label, options={}, &block)
525
- if @commands[label]
549
+ if @commands.key?(label)
526
550
  raise ArgumentError, "command `#{label}` already exists"
527
551
  end
528
552
 
@@ -866,25 +890,22 @@ class Slop
866
890
  end
867
891
  end
868
892
 
869
- # wrap and indent a string, used to wrap and indent a description string
870
893
  def wrap_and_indent(string, width, indentation)
871
894
  string.lines.map do |paragraph|
872
895
  lines = []
873
896
  line = ''
874
897
 
875
898
  paragraph.split(/\s/).each do |word|
876
- # Begin new line if it's too long
877
899
  if (line + ' ' + word).length >= width
878
900
  lines << line
879
901
  line = ''
880
902
  end
881
903
 
882
- # Add word to line
883
904
  line << (line == '' ? '' : ' ' ) + word
884
905
  end
885
906
  lines << line
886
907
 
887
- lines.map { |l| ' '*indentation + l }.join("\n")
908
+ lines.map { |l| ' ' * indentation + l }.join("\n")
888
909
  end.join("\n")
889
910
  end
890
911
 
@@ -927,7 +948,7 @@ class Slop
927
948
  if str
928
949
  command = @commands.keys.find { |c| c.to_s == str.to_s }
929
950
 
930
- if !command && @completion
951
+ if @completion and not command
931
952
  cmds = @commands.keys.select { |c| c.to_s[0, str.length] == str }
932
953
 
933
954
  if cmds.size > 1
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'slop'
3
- s.version = '2.1.0'
3
+ s.version = '2.2.0'
4
4
  s.summary = 'Option gathering made easy'
5
5
  s.description = 'A simple DSL for gathering options and parsing the command line'
6
6
  s.author = 'Lee Jarvis'
@@ -75,6 +75,11 @@ class OptionTest < TestCase
75
75
  assert_equal -1, option_value(%w/-i -1.1/, :i, true, :as => Integer)
76
76
  assert_equal "-1.1", option_value(%w/-i -1.1/, :i, true, :as => Float).to_s
77
77
  assert_equal "foo", option_value(%w/--foo1 foo/, :foo1, true)
78
+
79
+ assert_equal 0, option_value(%w//, :v, :verbose, :as => :count)
80
+ assert_equal 1, option_value(%w/--verbose/, :v, :verbose, :as => :count)
81
+ assert_equal 2, option_value(%w/--verbose -v/, :v, :verbose, :as => :count)
82
+ assert_equal 3, option_value(%w/-vvv/, :v, :verbose, :as => :count)
78
83
  end
79
84
 
80
85
  test 'ranges' do
@@ -552,4 +552,23 @@ class SlopTest < TestCase
552
552
 
553
553
  assert_equal %w[ bar c ], slop.missing
554
554
  end
555
+
556
+ test 'parsing an optspec and building options' do
557
+ optspec = <<-SPEC
558
+ ruby foo.rb [options]
559
+ --
560
+ v,verbose enable verbose mode
561
+ q,quiet enable quiet mode
562
+ debug enable debug mode
563
+ H enable hax mode (srsly)
564
+ n,name= set your name
565
+ -a,--age= set your age
566
+ SPEC
567
+ opts = Slop.optspec(optspec.gsub(/^\s+/, ''))
568
+ opts.parse %w[ --verbose --name Lee ]
569
+
570
+ assert_equal 'Lee', opts[:name]
571
+ assert opts.verbose?
572
+ assert_equal 'enable quiet mode', opts.options[:quiet].description
573
+ end
555
574
  end
metadata CHANGED
@@ -1,23 +1,32 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: slop
3
- version: !ruby/object:Gem::Version
4
- version: 2.1.0
3
+ version: !ruby/object:Gem::Version
4
+ hash: 7
5
5
  prerelease:
6
+ segments:
7
+ - 2
8
+ - 2
9
+ - 0
10
+ version: 2.2.0
6
11
  platform: ruby
7
- authors:
12
+ authors:
8
13
  - Lee Jarvis
9
14
  autorequire:
10
15
  bindir: bin
11
16
  cert_chain: []
12
- date: 2011-08-03 00:00:00.000000000 +01:00
13
- default_executable:
17
+
18
+ date: 2011-11-02 00:00:00 Z
14
19
  dependencies: []
20
+
15
21
  description: A simple DSL for gathering options and parsing the command line
16
22
  email: lee@jarvis.co
17
23
  executables: []
24
+
18
25
  extensions: []
26
+
19
27
  extra_rdoc_files: []
20
- files:
28
+
29
+ files:
21
30
  - .gemtest
22
31
  - .gitignore
23
32
  - .yardopts
@@ -31,32 +40,40 @@ files:
31
40
  - test/helper.rb
32
41
  - test/option_test.rb
33
42
  - test/slop_test.rb
34
- has_rdoc: true
35
43
  homepage: http://github.com/injekt/slop
36
44
  licenses: []
45
+
37
46
  post_install_message:
38
47
  rdoc_options: []
39
- require_paths:
48
+
49
+ require_paths:
40
50
  - lib
41
- required_ruby_version: !ruby/object:Gem::Requirement
51
+ required_ruby_version: !ruby/object:Gem::Requirement
42
52
  none: false
43
- requirements:
44
- - - ! '>='
45
- - !ruby/object:Gem::Version
46
- version: '0'
47
- required_rubygems_version: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ hash: 3
57
+ segments:
58
+ - 0
59
+ version: "0"
60
+ required_rubygems_version: !ruby/object:Gem::Requirement
48
61
  none: false
49
- requirements:
50
- - - ! '>='
51
- - !ruby/object:Gem::Version
52
- version: '0'
62
+ requirements:
63
+ - - ">="
64
+ - !ruby/object:Gem::Version
65
+ hash: 3
66
+ segments:
67
+ - 0
68
+ version: "0"
53
69
  requirements: []
70
+
54
71
  rubyforge_project:
55
- rubygems_version: 1.6.2
72
+ rubygems_version: 1.8.6
56
73
  signing_key:
57
74
  specification_version: 3
58
75
  summary: Option gathering made easy
59
- test_files:
76
+ test_files:
60
77
  - test/commands_test.rb
61
78
  - test/helper.rb
62
79
  - test/option_test.rb