opt-simple 1.0.0 → 1.1.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.
- checksums.yaml +4 -4
- data/README.md +39 -21
- data/lib/opt_simple.rb +52 -38
- data/test/test_regressions.rb +148 -0
- metadata +7 -8
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 57cca5d40e69cf2f9a914290d54ca098293e06a122cfecbe0170045de81a3c2a
|
|
4
|
+
data.tar.gz: b069da5060d12936a2d2022053d414c3ecf84708ac62d530aae91d675a72f593
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 61a13e28947dc8ecf33690b7b6013692849fc6075136814fb831facb6cb82bdc0ae0fe90247f525e35b6ff8644cd3cdb98bd6f37d4cdbf8a715ea8e7335bd4b4
|
|
7
|
+
data.tar.gz: 4694df6658044f29a6c0dd2ad616bb2f0cc3ed636db884fe521f601139e4bdb2a0a4ca98a8a50063881d43b30048852a93f991d809169796ccf7152d0c4bca34
|
data/README.md
CHANGED
|
@@ -34,7 +34,7 @@ See OptSimple for the API specification
|
|
|
34
34
|
It is recommended to install OptSimple using RubyGems:
|
|
35
35
|
|
|
36
36
|
```
|
|
37
|
-
$
|
|
37
|
+
$ gem install opt-simple
|
|
38
38
|
```
|
|
39
39
|
|
|
40
40
|
## Examples
|
|
@@ -49,7 +49,7 @@ It is recommended to install OptSimple using RubyGems:
|
|
|
49
49
|
:range => [5,10]
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
opts = OptSimple.new(defaults).parse_opts! do
|
|
52
|
+
opts = OptSimple.new(defaults: defaults).parse_opts! do
|
|
53
53
|
argument %w[-i --infile], "Infile, multiple allowed", "FILE" do | arg |
|
|
54
54
|
accumulate_opt arg
|
|
55
55
|
end
|
|
@@ -108,27 +108,27 @@ It is recommended to install OptSimple using RubyGems:
|
|
|
108
108
|
puts "Things: #{opts.things.inspect}"
|
|
109
109
|
```
|
|
110
110
|
|
|
111
|
-
```
|
|
112
111
|
Which prints out an automatic usage statement:
|
|
112
|
+
```
|
|
113
113
|
Usage: opt_ex.rb [options]
|
|
114
|
-
|
|
114
|
+
|
|
115
115
|
MANDATORY ARGS:
|
|
116
|
-
-i, --infile FILE
|
|
117
|
-
|
|
116
|
+
-i, --infile FILE Infile, multiple allowed
|
|
117
|
+
|
|
118
118
|
OPTIONS:
|
|
119
|
-
-d, --debug
|
|
120
|
-
|
|
121
|
-
-m, --cowbell, --morecowbell I've got a fever, and this is the only prescription.
|
|
122
|
-
|
|
123
|
-
-n, -num, --num-values VAL The answer to everything
|
|
124
|
-
|
|
125
|
-
-p, --pattern, --glob-pattern PATTERN glob pattern (default is '*')
|
|
126
|
-
|
|
127
|
-
--range ARG range: min,max (both >0) (default is '[5, 10]')
|
|
119
|
+
-d, --debug debug mode
|
|
128
120
|
|
|
129
|
-
|
|
121
|
+
-m, --cowbell, --morecowbell I've got a fever, and this is the only prescription.
|
|
130
122
|
|
|
131
|
-
-
|
|
123
|
+
-n, -num, --num-values VAL The answer to everything (default is '42')
|
|
124
|
+
|
|
125
|
+
-p, --pattern, --glob-pattern PATTERN glob pattern (default is '*')
|
|
126
|
+
|
|
127
|
+
--range ARG range: min,max (both >0) (default is '5,10')
|
|
128
|
+
|
|
129
|
+
-t, --things THINGS Some things - variable number allowed
|
|
130
|
+
|
|
131
|
+
-h, --help (for this help message)
|
|
132
132
|
```
|
|
133
133
|
### A very simple example with no error checking. Use at your own risk!
|
|
134
134
|
``` ruby
|
|
@@ -138,7 +138,7 @@ Which prints out an automatic usage statement:
|
|
|
138
138
|
'max' => 40
|
|
139
139
|
}
|
|
140
140
|
|
|
141
|
-
options = OptSimple.new(defaults).parse_opts!
|
|
141
|
+
options = OptSimple.new(defaults: defaults).parse_opts!
|
|
142
142
|
|
|
143
143
|
puts "Options"
|
|
144
144
|
puts options
|
|
@@ -165,7 +165,7 @@ Which prints out an automatic usage statement:
|
|
|
165
165
|
"max" => 10
|
|
166
166
|
}
|
|
167
167
|
|
|
168
|
-
options = OptSimple.new(defaults).parse_opts! do
|
|
168
|
+
options = OptSimple.new(defaults: defaults).parse_opts! do
|
|
169
169
|
banner "USAGE: #{$0}"
|
|
170
170
|
summary "Show how to set a banner and summary."
|
|
171
171
|
|
|
@@ -246,7 +246,7 @@ Which prints out an automatic usage statement:
|
|
|
246
246
|
option %w[-p --pattern --glob-pattern], "glob pattern","PATTERN"
|
|
247
247
|
end
|
|
248
248
|
|
|
249
|
-
os.register_opts({num: 7}) do
|
|
249
|
+
os.register_opts(defaults: {num: 7}) do
|
|
250
250
|
option %w[-n -num --num-values],"Number of val","VAL" do |arg|
|
|
251
251
|
set_opt arg.to_i
|
|
252
252
|
end
|
|
@@ -283,7 +283,7 @@ Which prints out an automatic usage statement:
|
|
|
283
283
|
|
|
284
284
|
# Note that b/c we define option [--odd] and [--evens] _after_ the max-out flag,
|
|
285
285
|
# they will override the max-out setting.
|
|
286
|
-
opts = OptSimple.new(defaults).parse_opts! do | opt_obj |
|
|
286
|
+
opts = OptSimple.new(defaults: defaults).parse_opts! do | opt_obj |
|
|
287
287
|
flag %w[-m --max-out], "Maximize evens and odds." do
|
|
288
288
|
opt_obj.odd_val = allowed_odds.last
|
|
289
289
|
opt_obj.even_val = allowed_evens.last
|
|
@@ -305,6 +305,24 @@ Which prints out an automatic usage statement:
|
|
|
305
305
|
puts "Options"
|
|
306
306
|
puts opts
|
|
307
307
|
```
|
|
308
|
+
## Errors
|
|
309
|
+
|
|
310
|
+
Parsing problems raise a subclass of `OptSimple::Error` (a `StandardError`):
|
|
311
|
+
`MissingArgument`, `InvalidOption` or `ParameterUsageError`, and `error` inside a
|
|
312
|
+
parameter block raises `OptSimple::Error`. The `message` is the reason followed by
|
|
313
|
+
the usage statement; `reason` and `usage` are also available on their own.
|
|
314
|
+
|
|
315
|
+
```ruby
|
|
316
|
+
begin
|
|
317
|
+
opts = OptSimple.new.parse_opts! { argument '--model', 'Model name', 'MODEL' }
|
|
318
|
+
rescue OptSimple::Error => e
|
|
319
|
+
abort e.message # or: abort "error: #{e.reason}"
|
|
320
|
+
end
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
A registered switch is never taken as a value, so `--model --num 4` is reported
|
|
324
|
+
as a missing value for `--model` (negative numbers like `--num -1` still work).
|
|
325
|
+
|
|
308
326
|
## Questions and/or Comments
|
|
309
327
|
|
|
310
328
|
email [Ethan Stryker](mailto:e.stryker@gmail.com])
|
data/lib/opt_simple.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
=begin rdoc
|
|
2
4
|
|
|
3
5
|
= OptSimple provides a very simple interface to command line parsing.
|
|
@@ -91,12 +93,6 @@ class OptSimple
|
|
|
91
93
|
# go through the registered parameters, and pull out
|
|
92
94
|
# the specified parms from @arg
|
|
93
95
|
|
|
94
|
-
# first look for a call for help
|
|
95
|
-
unless (help_strings & @args).empty?
|
|
96
|
-
$stdout.puts self.to_s
|
|
97
|
-
exit(0)
|
|
98
|
-
end
|
|
99
|
-
|
|
100
96
|
mandatory_check = mandatory_opts.map {|m| m.switches}
|
|
101
97
|
|
|
102
98
|
positional_args = []
|
|
@@ -104,15 +100,28 @@ class OptSimple
|
|
|
104
100
|
#remove the '--', but don't include it w/ positional arguments
|
|
105
101
|
positional_args = @args.slice!(loc..-1)[1..-1]
|
|
106
102
|
end
|
|
103
|
+
|
|
104
|
+
# look for a call for help, but not in the positional args after '--'
|
|
105
|
+
unless (help_strings & @args).empty?
|
|
106
|
+
$stdout.puts self.to_s
|
|
107
|
+
exit(0)
|
|
108
|
+
end
|
|
107
109
|
|
|
108
|
-
# Handle the case where a user specifies --foo=bar, or --foo=bar,baz
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
110
|
+
# Handle the case where a user specifies --foo=bar, or --foo=bar,baz.
|
|
111
|
+
# Only switch-looking args are split, and they are expanded in place so
|
|
112
|
+
# values like 'a=b' and the order of positional args are left alone.
|
|
113
|
+
# replace (rather than reassign) keeps parse_opts! destructive on ARGV.
|
|
114
|
+
expanded = @args.flat_map do | arg |
|
|
115
|
+
if (m = arg.match(/\A(-[^=]+)=(.*)\z/m))
|
|
116
|
+
[m[1], *m[2].split(',')]
|
|
117
|
+
else
|
|
118
|
+
arg
|
|
119
|
+
end
|
|
115
120
|
end
|
|
121
|
+
@args.replace(expanded)
|
|
122
|
+
|
|
123
|
+
# a value that is itself a registered switch means the real value is missing
|
|
124
|
+
all_switches = @parameters.flat_map(&:switches)
|
|
116
125
|
|
|
117
126
|
# now actually parse the args, and call all the stored up blocks from the options
|
|
118
127
|
@parameters.each do | parm |
|
|
@@ -152,11 +161,16 @@ class OptSimple
|
|
|
152
161
|
if parm.block.arity > 0 and (pieces.length < parm.block.arity) # or # pieces.any? {|p| p.start_with?('-')})
|
|
153
162
|
raise OptSimple::ParameterUsageError.new "Not enough args following #{intersection}",self
|
|
154
163
|
end
|
|
164
|
+
|
|
165
|
+
# but a registered switch is never a value: '--model --num 4' is a missing value
|
|
166
|
+
if (clash = pieces.find {|p| all_switches.include?(p) })
|
|
167
|
+
raise OptSimple::ParameterUsageError.new "Missing value for #{intersection.join(' OR ')} (found switch #{clash})",self
|
|
168
|
+
end
|
|
155
169
|
|
|
156
170
|
begin
|
|
157
171
|
parm.instance_exec(*pieces,&parm.block)
|
|
158
172
|
rescue OptSimple::Error => e
|
|
159
|
-
raise
|
|
173
|
+
raise e.class.new(e.reason,self)
|
|
160
174
|
end
|
|
161
175
|
end
|
|
162
176
|
@results.merge! parm.param_options
|
|
@@ -246,7 +260,7 @@ class OptSimple
|
|
|
246
260
|
parm.set_opt @defaults[intersection.first]
|
|
247
261
|
@results.merge! parm.param_options
|
|
248
262
|
elsif intersection.length > 1
|
|
249
|
-
raise OptSimple::Error
|
|
263
|
+
raise OptSimple::Error.new("Clashes in the defaults for #{parm.switches}",self)
|
|
250
264
|
end
|
|
251
265
|
|
|
252
266
|
add_parameter(parm)
|
|
@@ -272,7 +286,7 @@ class OptSimple
|
|
|
272
286
|
# returns the automatic usage statement
|
|
273
287
|
def to_s
|
|
274
288
|
if @help.empty?
|
|
275
|
-
help_str = ""
|
|
289
|
+
help_str = +""
|
|
276
290
|
|
|
277
291
|
help_str << " MANDATORY ARGS:\n" unless mandatory_opts.empty?
|
|
278
292
|
mandatory_opts.each do | parm |
|
|
@@ -293,7 +307,9 @@ class OptSimple
|
|
|
293
307
|
elsif @defaults[intersection.first].nil?
|
|
294
308
|
help_str << " (default is 'nil')\n\n"
|
|
295
309
|
else
|
|
296
|
-
|
|
310
|
+
default = @defaults[intersection.first]
|
|
311
|
+
default = default.join(',') if default.is_a?(Array)
|
|
312
|
+
help_str << " (default is '#{default}')\n\n"
|
|
297
313
|
end
|
|
298
314
|
end
|
|
299
315
|
help_str << " SUMMARY:\n\n #{@summary}\n\n" unless @summary.empty?
|
|
@@ -359,24 +375,23 @@ class OptSimple
|
|
|
359
375
|
end
|
|
360
376
|
|
|
361
377
|
def switch_len #:nodoc:
|
|
362
|
-
|
|
378
|
+
switch_str.length
|
|
363
379
|
end
|
|
364
380
|
|
|
381
|
+
# Short switches first, then the rest in the order given. Without a short
|
|
382
|
+
# switch, indent so long switches line up under '-x, --long'.
|
|
383
|
+
# (Build a new string: the switches may be frozen literals.)
|
|
365
384
|
def switch_str #:nodoc:
|
|
366
385
|
short_parms = @switches.find_all {|st| st.start_with?('-') and st.length == 2 and st[1] != '-'}
|
|
367
|
-
|
|
368
|
-
other_parms = @switches.find_all {|st| not st.start_with?('-')}
|
|
386
|
+
other_parms = @switches - short_parms
|
|
369
387
|
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
sh_str << ', ' unless sh_str =~/^\s+$/ or long_str.empty?
|
|
373
|
-
|
|
374
|
-
sh_str + long_str
|
|
388
|
+
indent = short_parms.empty? ? " " * 4 : ""
|
|
389
|
+
indent + (short_parms + other_parms).join(', ')
|
|
375
390
|
end
|
|
376
391
|
|
|
377
392
|
# a single line that will be put in the overall usage string
|
|
378
393
|
def help_str(switch_len)
|
|
379
|
-
" %-#{switch_len}s"
|
|
394
|
+
" %-#{switch_len}s" % self.switch_str + " #{@help}"
|
|
380
395
|
end
|
|
381
396
|
|
|
382
397
|
# A shortcut for raising an OptSimple::Error exception
|
|
@@ -436,7 +451,6 @@ class OptSimple
|
|
|
436
451
|
# leading '-'s removed) will be used as keys in the Result
|
|
437
452
|
# and the values set to the arg following the switch on the CL.
|
|
438
453
|
class Option < Parameter
|
|
439
|
-
attr_reader = :metavar
|
|
440
454
|
def initialize(switches,help="",metavar="ARG",&block)
|
|
441
455
|
super(switches,help,&block)
|
|
442
456
|
@metavar = metavar
|
|
@@ -447,13 +461,8 @@ class OptSimple
|
|
|
447
461
|
@first_call = true # use this so we can accumulate non-defaults
|
|
448
462
|
end
|
|
449
463
|
|
|
450
|
-
def switch_len #:nodoc:
|
|
451
|
-
metavar_space = @metavar.empty? ? 0 : @metavar.length + 1
|
|
452
|
-
super + metavar_space
|
|
453
|
-
end
|
|
454
|
-
|
|
455
464
|
def switch_str #:nodoc:
|
|
456
|
-
super + " #{@metavar}"
|
|
465
|
+
@metavar.empty? ? super : super + " #{@metavar}"
|
|
457
466
|
end
|
|
458
467
|
|
|
459
468
|
# append val to the parameter list
|
|
@@ -481,10 +490,15 @@ class OptSimple
|
|
|
481
490
|
def mandatory?; true; end
|
|
482
491
|
end
|
|
483
492
|
|
|
484
|
-
# A general error in the options
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
493
|
+
# A general error in the options. The message is the reason followed by the
|
|
494
|
+
# usage statement; both are also available separately.
|
|
495
|
+
class Error < StandardError
|
|
496
|
+
attr_reader :reason, :usage
|
|
497
|
+
|
|
498
|
+
def initialize(string=nil,option_obj=nil)
|
|
499
|
+
@reason = string.to_s
|
|
500
|
+
@usage = option_obj.to_s
|
|
501
|
+
super("#{@reason}\n#{@usage}")
|
|
488
502
|
set_backtrace []
|
|
489
503
|
end
|
|
490
504
|
end
|
|
@@ -583,7 +597,7 @@ class OptSimple
|
|
|
583
597
|
|
|
584
598
|
# a hash looking return string.
|
|
585
599
|
def to_s
|
|
586
|
-
ret = ""
|
|
600
|
+
ret = +""
|
|
587
601
|
aliases.each do | a |
|
|
588
602
|
ret << "#{a}=>#{@inside_hash[a]},"
|
|
589
603
|
end
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Regression tests for bugs found in 1.0.0. The magic comment above matters:
|
|
4
|
+
# switch strings below are frozen, as they are in most modern Ruby files.
|
|
5
|
+
require 'stringio'
|
|
6
|
+
require 'opt_simple'
|
|
7
|
+
require 'test/unit'
|
|
8
|
+
require 'test_unit_extensions'
|
|
9
|
+
|
|
10
|
+
class TestRegressions < Test::Unit::TestCase
|
|
11
|
+
|
|
12
|
+
def parse(args, defaults: {}, &block)
|
|
13
|
+
OptSimple.new(defaults: defaults, args: args).parse_opts!(&block)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# --- frozen switch strings -------------------------------------------------
|
|
17
|
+
|
|
18
|
+
must "build the usage statement when switches are frozen strings" do
|
|
19
|
+
os = OptSimple.new(args: [])
|
|
20
|
+
os.register_opts { option %w[-n --num], "a number", "N"; flag %w[-v --verbose] }
|
|
21
|
+
assert_nothing_raised { os.to_s }
|
|
22
|
+
assert_match(/-n, --num N/, os.to_s)
|
|
23
|
+
assert_match(/-v, --verbose/, os.to_s)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
must "report a missing argument, not a FrozenError, when switches are frozen" do
|
|
27
|
+
assert_raise(OptSimple::MissingArgument) { parse([]) { argument %w[-i --infile] } }
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
must "leave the caller's switch strings unchanged after building usage" do
|
|
31
|
+
switches = %w[-n --num]
|
|
32
|
+
os = OptSimple.new(args: [])
|
|
33
|
+
os.register_opts { option switches }
|
|
34
|
+
os.to_s
|
|
35
|
+
assert_equal %w[-n --num], switches
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
must "show every short switch in the usage statement" do
|
|
39
|
+
os = OptSimple.new(args: [])
|
|
40
|
+
os.register_opts { flag %w[-v -V --verbose] }
|
|
41
|
+
assert_match(/-v, -V, --verbose/, os.to_s)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# --- '=' handling --------------------------------------------------------------
|
|
45
|
+
|
|
46
|
+
must "not treat a value containing '=' as a switch" do
|
|
47
|
+
o = parse(%w[--model a=b]) { option '--model' }
|
|
48
|
+
assert_equal 'a=b', o['model']
|
|
49
|
+
assert_equal [], o.positional_args
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
must "keep everything after the first '=' in --switch=value" do
|
|
53
|
+
o = parse(%w[--filter=key=val]) { option '--filter' }
|
|
54
|
+
assert_equal 'key=val', o['filter']
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
must "let the last repeated option win whether or not it uses '='" do
|
|
58
|
+
# 1.0.0 moved '=' args to the end, so '--a=1' was applied last
|
|
59
|
+
o = parse(%w[--a=1 --a 2]) { option '--a' }
|
|
60
|
+
assert_equal '2', o['a']
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# --- switches used as values ---------------------------------------------------
|
|
64
|
+
|
|
65
|
+
must "raise a usage error when a switch is followed by another switch instead of a value" do
|
|
66
|
+
e = assert_raise(OptSimple::ParameterUsageError) do
|
|
67
|
+
parse(%w[--model --num 4]) { option '--model'; option '--num' }
|
|
68
|
+
end
|
|
69
|
+
assert_match(/--model.*--num/, e.reason)
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# guard: the check above must not reject negative numbers
|
|
73
|
+
must "still allow negative numbers as values" do
|
|
74
|
+
o = parse(%w[--num -1]) { option('--num') { |v| set_opt v.to_i } }
|
|
75
|
+
assert_equal(-1, o['num'])
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# --- error class ---------------------------------------------------------------
|
|
79
|
+
|
|
80
|
+
must "raise errors a plain rescue can catch" do
|
|
81
|
+
caught = begin
|
|
82
|
+
parse([]) { argument '--model' }
|
|
83
|
+
rescue => e
|
|
84
|
+
e
|
|
85
|
+
end
|
|
86
|
+
assert_kind_of OptSimple::MissingArgument, caught
|
|
87
|
+
assert_kind_of StandardError, caught
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
must "expose the reason and the usage statement separately" do
|
|
91
|
+
e = assert_raise(OptSimple::MissingArgument) { parse([]) { argument '--model' } }
|
|
92
|
+
assert_equal 'Must set the following parameters: --model', e.reason
|
|
93
|
+
assert_match(/\AUsage:/, e.usage)
|
|
94
|
+
assert_equal "#{e.reason}\n#{e.usage}", e.message
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
must "keep the error subclass and add usage when a block calls error" do
|
|
98
|
+
e = assert_raise(OptSimple::Error) do
|
|
99
|
+
parse(%w[--num x]) { option('--num') { |v| error "--num must be a number" } }
|
|
100
|
+
end
|
|
101
|
+
assert_equal '--num must be a number', e.reason
|
|
102
|
+
assert_match(/--num/, e.usage)
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
must "raise OptSimple::Error when two defaults name the same option" do
|
|
106
|
+
assert_raise(OptSimple::Error) do
|
|
107
|
+
parse([], defaults: { 'num-val' => 1, num_val: 2 }) { option '--num-val' }
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
# --- help ----------------------------------------------------------------------
|
|
112
|
+
|
|
113
|
+
must "not show help for --help after '--'" do
|
|
114
|
+
o = parse(%w[-- --help]) { option '--model' }
|
|
115
|
+
assert_equal %w[--help], o.positional_args
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
# guard: moving the help check after the '--' split must not break help
|
|
119
|
+
must "show help and exit for --help before '--'" do
|
|
120
|
+
out = StringIO.new
|
|
121
|
+
begin
|
|
122
|
+
$stdout = out
|
|
123
|
+
assert_raise(SystemExit) { parse(%w[--help --]) { option '--model' } }
|
|
124
|
+
ensure
|
|
125
|
+
$stdout = STDOUT
|
|
126
|
+
end
|
|
127
|
+
assert_match(/--model/, out.string)
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
must "line up the help descriptions in one column" do
|
|
131
|
+
os = OptSimple.new(args: [])
|
|
132
|
+
os.register_opts do
|
|
133
|
+
argument %w[-i --infile], "infile", "FILE"
|
|
134
|
+
option '--a-much-longer-option-name', "long one", "VAL"
|
|
135
|
+
flag '-v', "verbose"
|
|
136
|
+
end
|
|
137
|
+
lines = os.to_s.lines.grep(/infile$|long one$|verbose$/)
|
|
138
|
+
assert_equal 3, lines.size
|
|
139
|
+
columns = lines.map { |l| l.index(/infile$|long one$|verbose$/) }
|
|
140
|
+
assert_equal 1, columns.uniq.size, os.to_s
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
must "show array defaults the way they are typed on the command line" do
|
|
144
|
+
os = OptSimple.new(defaults: { tasks: %w[a b] }, args: [])
|
|
145
|
+
os.register_opts { option('--tasks') { |*t| set_opt t } }
|
|
146
|
+
assert_match(/default is 'a,b'/, os.to_s)
|
|
147
|
+
end
|
|
148
|
+
end
|
metadata
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: opt-simple
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.1.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ethan Stryker
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: bin
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies: []
|
|
13
12
|
description: " Parameter specification, validity checking and argument transformations
|
|
14
13
|
\n can be put in one place, default parameters are easily set, and an \n automatic
|
|
@@ -25,12 +24,13 @@ files:
|
|
|
25
24
|
- lib/test_unit_extensions.rb
|
|
26
25
|
- test/test_arglist.rb
|
|
27
26
|
- test/test_help.rb
|
|
27
|
+
- test/test_regressions.rb
|
|
28
28
|
- test/test_return.rb
|
|
29
29
|
- test/test_usage.rb
|
|
30
|
-
homepage:
|
|
31
|
-
licenses:
|
|
30
|
+
homepage: https://github.com/estryker/opt-simple
|
|
31
|
+
licenses:
|
|
32
|
+
- MIT
|
|
32
33
|
metadata: {}
|
|
33
|
-
post_install_message:
|
|
34
34
|
rdoc_options: []
|
|
35
35
|
require_paths:
|
|
36
36
|
- lib
|
|
@@ -45,8 +45,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
45
45
|
- !ruby/object:Gem::Version
|
|
46
46
|
version: '0'
|
|
47
47
|
requirements: []
|
|
48
|
-
rubygems_version:
|
|
49
|
-
signing_key:
|
|
48
|
+
rubygems_version: 4.0.10
|
|
50
49
|
specification_version: 4
|
|
51
50
|
summary: A simple and elegant command line option parser.
|
|
52
51
|
test_files: []
|