benry-cmdopt 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/CHANGES.md +7 -0
- data/README.md +209 -27
- data/benry-cmdopt.gemspec +1 -1
- data/lib/benry/cmdopt.rb +70 -48
- data/test/cmdopt_test.rb +66 -14
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e22704458cfcb32a806de14c4b4df853673de1309b964d4362e2cc9605f64fca
|
4
|
+
data.tar.gz: 78a52a4a0d1b5d261bea63c58b454b0b68810f10fb3795e347644f269715580f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b79a27875901ee9aaa5ef6f8bee208e2b5d76ff69511a9b47d741df9350c724f1b3c9530a48c80cc2e1bd69ce5283f447c104da0c2587ec96628750ce141031f
|
7
|
+
data.tar.gz: e063f8ab5ab3d1054d96e1410b6b85d4517086d0c64772b1957951e6faada16e2e71d7333eb3388f981d545b1011db37a002fc7eb70cb7e637f5828165f1aef0
|
data/CHANGES.md
CHANGED
@@ -3,6 +3,13 @@ CHANGES
|
|
3
3
|
=======
|
4
4
|
|
5
5
|
|
6
|
+
Release 1.0.0 (2021-01-18)
|
7
|
+
--------------------------
|
8
|
+
|
9
|
+
* [change] rename 'build_option_help()' to 'option_help()'.
|
10
|
+
* [change] shorten option help width when no long options defined.
|
11
|
+
|
12
|
+
|
6
13
|
Release 1.0.0 (2021-01-17)
|
7
14
|
--------------------------
|
8
15
|
|
data/README.md
CHANGED
@@ -1,23 +1,184 @@
|
|
1
1
|
Benry::Cmdopt README
|
2
2
|
====================
|
3
3
|
|
4
|
-
($Release: 1.
|
4
|
+
($Release: 1.1.0 $)
|
5
5
|
|
6
6
|
Benry::Cmdopt is a command option parser library, like `optparse.rb`.
|
7
7
|
|
8
|
-
Compared to `optparse.rb
|
9
|
-
|
10
|
-
* Easy to use, easy to extend, easy to understand.
|
11
|
-
* Not add `-h` nor `--help` automatically.
|
12
|
-
* Not add `-v` nor `--version` automatically.
|
13
|
-
* Not regard `-x` as short cut of `--xxx`.
|
14
|
-
(`optparser.rb` regards `-x` as short cut of `--xxx` automatically.)
|
15
|
-
* Provides very simple feature to build custom help message.
|
16
|
-
* Separates command option schema class from parser class.
|
8
|
+
Compared to `optparse.rb`, Benry::Cmdopt is easy to use, easy to extend,
|
9
|
+
and easy to understahnd.
|
17
10
|
|
18
11
|
(Benry::Cmdopt requires Ruby >= 2.3)
|
19
12
|
|
20
13
|
|
14
|
+
Why not `optparse.rb`?
|
15
|
+
======================
|
16
|
+
|
17
|
+
* Source code of `optparse.rb` is very large and complicated, because
|
18
|
+
`OptParse` class does everything about command option parsing.
|
19
|
+
It is hard to customize or extend `OptionParser` class.
|
20
|
+
|
21
|
+
On the other hand, `benry/cmdopt.rb` consists of several classes
|
22
|
+
(schema class, parser class, and facade class).
|
23
|
+
Therefore it is easy to understand and extend these classes.
|
24
|
+
|
25
|
+
File `optparse.rb` contains 1234 lines (without comments), while
|
26
|
+
`benry/cmdopt.rb` (v1.1.0) contains only 361 lines (without comments).
|
27
|
+
|
28
|
+
* `optparse.rb` regards `-x` as a short cut of `--xxx` automatically
|
29
|
+
even if you have not defined `-x` option.
|
30
|
+
That is, short options which are not defined can be available unexpectedly.
|
31
|
+
This feature is hard-coded in `OptionParser#parse_in_order()`
|
32
|
+
and hard to be disabled.
|
33
|
+
|
34
|
+
On the other hand, `benry/cmdopt.rb` doesn't behave this way.
|
35
|
+
`-x` option is available only when `-x` is defined.
|
36
|
+
|
37
|
+
* `optparse.rb` can handle both `--name=val` and `--name val` styles.
|
38
|
+
The later style is ambiguous; you may wonder whether `--name` takes
|
39
|
+
`val` as argument or `--name` takes no argument (and `val` is command
|
40
|
+
argument).
|
41
|
+
|
42
|
+
Therefore the `--name=val` style is better than the `--name val` style.
|
43
|
+
|
44
|
+
`optparse.rb` cannot disable `--name val` style.
|
45
|
+
`benry/cmdopt.rb` supports only `--name=val` style.
|
46
|
+
|
47
|
+
* `optparse.rb` enforces you to catch `OptionParser::ParseError` exception.
|
48
|
+
That is, you must know error class name.
|
49
|
+
|
50
|
+
`benry/cmdopt.rb` provides error handler without exception class name.
|
51
|
+
You don't need to know error class name on error handling.
|
52
|
+
|
53
|
+
```ruby
|
54
|
+
### optparse.rb
|
55
|
+
require 'optparse'
|
56
|
+
parser = OptionParser.new
|
57
|
+
parser.on('-f', '--file=<FILE>', "filename")
|
58
|
+
opts = {}
|
59
|
+
begin
|
60
|
+
parser.parse!(ARGV, into: opts)
|
61
|
+
rescue OptionParser::ParseError => ex # specify error class
|
62
|
+
$stderr.puts "ERROR: #{ex.message}"
|
63
|
+
exit 1
|
64
|
+
end
|
65
|
+
|
66
|
+
### benry/cmdopt.rb
|
67
|
+
require 'benry/cmdopt'
|
68
|
+
cmdopt = Benry::Cmdopt.new
|
69
|
+
cmdopt.add(:file, '-f, --file=<FILE>', "filename")
|
70
|
+
opts = cmdopt.parse(ARGV) do |err| # error handling wihtout error class name
|
71
|
+
$stderr.puts "ERROR: #{err.message}"
|
72
|
+
exit 1
|
73
|
+
end
|
74
|
+
```
|
75
|
+
|
76
|
+
* `optparse.rb` uses long option name as hash key automatically, but
|
77
|
+
it doesn't provide the way to specify hash key of short-only option.
|
78
|
+
|
79
|
+
`benry/cmdopt.rb` can specify hash key of short-only option.
|
80
|
+
|
81
|
+
```ruby
|
82
|
+
### optparse.rb
|
83
|
+
require 'optparse'
|
84
|
+
parser = OptionParser.new
|
85
|
+
parser.on('-v', '--verbose', "verbose mode") # short and long option
|
86
|
+
parser.on('-q', "quiet mode") # short-only option
|
87
|
+
#
|
88
|
+
opts = {}
|
89
|
+
parser.parse!(['-v'], into: opts) # short option
|
90
|
+
p opts #=> {:verbose=>true} # hash key is long option name
|
91
|
+
#
|
92
|
+
opts = {}
|
93
|
+
parser.parse!(['-q'], into: opts) # short option
|
94
|
+
p opts #=> {:q=>true} # hash key is short option name
|
95
|
+
|
96
|
+
### benry/cmdopt.rb
|
97
|
+
require 'benry/cmdopt'
|
98
|
+
cmdopt = Benry::Cmdopt.new
|
99
|
+
cmdopt.add(:verbose, '-v, --verbose', "verbose mode") # short and long
|
100
|
+
cmdopt.add(:quiet , '-q' , "quiet mode") # short-only
|
101
|
+
#
|
102
|
+
opts = cmdopt.parse(['-v']) # short option
|
103
|
+
p opts #=> {:verbose=>true} # independent hash key of option name
|
104
|
+
#
|
105
|
+
opts = cmdopt.parse(['-q']) # short option
|
106
|
+
p opts #=> {:quiet=>true} # independent hash key of option name
|
107
|
+
```
|
108
|
+
|
109
|
+
* `optparse.rb` adds `-h` and `--help` options automatically, and
|
110
|
+
terminates current process when `-v` or `--version` specified in terminal.
|
111
|
+
It is hard to remove these options.
|
112
|
+
|
113
|
+
On the other hand, `benry/cmdopt.rb` does not add these options.
|
114
|
+
benry/cmdopt.rb` does nothing extra.
|
115
|
+
|
116
|
+
```ruby
|
117
|
+
require 'optparse'
|
118
|
+
parser = OptionParser.new
|
119
|
+
## it is able to overwrite '-h' and/or '--help',
|
120
|
+
## but how to remove or disable these options?
|
121
|
+
opts = {}
|
122
|
+
parser.on('-h <host>', "hostname") {|v| opts[:host] = v }
|
123
|
+
parser.parse(['--help']) # <== terminates current process!!
|
124
|
+
puts 'xxx' #<== not printed because current process alreay terminated
|
125
|
+
```
|
126
|
+
|
127
|
+
* `optparse.rb` adds `-v` and `--version` options automatically, and
|
128
|
+
terminates current process when `-v` or `--version` specified in terminal.
|
129
|
+
It is hard to remove these options.
|
130
|
+
|
131
|
+
On the other hand, `benry/cmdopt.rb` does not add these options.
|
132
|
+
benry/cmdopt.rb` does nothing extra.
|
133
|
+
|
134
|
+
```ruby
|
135
|
+
require 'optparse'
|
136
|
+
parser = OptionParser.new
|
137
|
+
## it is able to overwrite '-v' and/or '--version',
|
138
|
+
## but how to remove or disable these options?
|
139
|
+
opts = {}
|
140
|
+
parser.on('-v', "verbose mode") { opts[:verbose] = true }
|
141
|
+
parser.parse(['--version']) # <== terminates current process!!
|
142
|
+
puts 'xxx' #<== not printed because current process alreay terminated
|
143
|
+
```
|
144
|
+
|
145
|
+
* `optparse.rb` generates help message automatically, but it doesn't
|
146
|
+
contain `-h`, `--help`, `-v`, nor `--version`.
|
147
|
+
These options are available but not shown in help message. Strange.
|
148
|
+
|
149
|
+
* `optparse.rb` generates help message with too wide option name
|
150
|
+
by default. You must specify proper width.
|
151
|
+
|
152
|
+
`benry/cmdopt.rb` calculates proper width automatically.
|
153
|
+
You don't need to specify proper width in many case.
|
154
|
+
|
155
|
+
```ruby
|
156
|
+
### optparse.rb
|
157
|
+
require 'optparse'
|
158
|
+
banner = "Usage: blabla <options>"
|
159
|
+
parser = OptionParser.new(banner) # or OptionParser.new(banner, 25)
|
160
|
+
parser.on('-f', '--file=<FILE>', "filename")
|
161
|
+
parser.on('-m <MODE>' , "verbose/quiet")
|
162
|
+
puts parser.help
|
163
|
+
### output
|
164
|
+
# Usage: blabla <options>
|
165
|
+
# -f, --file=<FILE> filename
|
166
|
+
# -m <MODE> verbose/quiet
|
167
|
+
|
168
|
+
### benry/cmdopt.rb
|
169
|
+
require 'benry/cmdopt'
|
170
|
+
cmdopt = Benry::Cmdopt.new()
|
171
|
+
cmdopt.add(:file, '-f, --file=<FILE>', "filename")
|
172
|
+
cmdopt.add(:mode, '-m <MODE>' , "verbose/quiet")
|
173
|
+
puts "Usage: blabla <options>"
|
174
|
+
puts cmdopt.option_help()
|
175
|
+
### output (calculated proper width)
|
176
|
+
# Usage: blabla <options>
|
177
|
+
# -f, --file=<FILE> : filename
|
178
|
+
# -m <MODE> : verbose/quiet
|
179
|
+
```
|
180
|
+
|
181
|
+
|
21
182
|
Usage
|
22
183
|
=====
|
23
184
|
|
@@ -30,8 +191,8 @@ require 'benry/cmdopt'
|
|
30
191
|
|
31
192
|
## define
|
32
193
|
cmdopt = Benry::Cmdopt.new
|
33
|
-
cmdopt.add(:help ,
|
34
|
-
cmdopt.add(:version,
|
194
|
+
cmdopt.add(:help , '-h, --help' , "print help message")
|
195
|
+
cmdopt.add(:version, ' --version', "print version")
|
35
196
|
|
36
197
|
## parse with error handling
|
37
198
|
options = cmdopt.parse(ARGV) do |err|
|
@@ -46,7 +207,7 @@ if options[:help]
|
|
46
207
|
puts "Usage: foobar [<options>] [<args>...]"
|
47
208
|
puts ""
|
48
209
|
puts "Options:"
|
49
|
-
puts cmdopt.
|
210
|
+
puts cmdopt.option_help()
|
50
211
|
## or
|
51
212
|
#format = " %-20s : %s"
|
52
213
|
#cmdopt.each_option_help {|opt, help| puts format % [opt, help] }
|
@@ -59,29 +220,32 @@ Command option parameter
|
|
59
220
|
|
60
221
|
```ruby
|
61
222
|
## required parameter
|
62
|
-
cmdopt.add(:file,
|
63
|
-
cmdopt.add(:file,
|
64
|
-
cmdopt.add(:file,
|
223
|
+
cmdopt.add(:file, '-f, --file=<FILE>', "filename")
|
224
|
+
cmdopt.add(:file, ' --file=<FILE>', "filename")
|
225
|
+
cmdopt.add(:file, '-f <FILE>' , "filename")
|
65
226
|
|
66
227
|
## optional parameter
|
67
|
-
cmdopt.add(:file,
|
68
|
-
cmdopt.add(:file,
|
69
|
-
cmdopt.add(:file,
|
228
|
+
cmdopt.add(:file, '-f, --file[=<FILE>]', "filename")
|
229
|
+
cmdopt.add(:file, ' --file[=<FILE>]', "filename")
|
230
|
+
cmdopt.add(:file, '-f[<FILE>]' , "filename")
|
70
231
|
```
|
71
232
|
|
233
|
+
Notice that `"--file <FILE>"` style is not supported.
|
234
|
+
Please use `"--file=<FILE>"` style.
|
235
|
+
|
72
236
|
|
73
237
|
Argument varidation
|
74
238
|
-------------------
|
75
239
|
|
76
240
|
```ruby
|
77
241
|
## type
|
78
|
-
cmdopt.add(:indent ,
|
242
|
+
cmdopt.add(:indent , '-i <N>', "indent width", type: Integer)
|
79
243
|
## pattern
|
80
|
-
cmdopt.add(:indent ,
|
244
|
+
cmdopt.add(:indent , '-i <N>', "indent width", pattern: /\A\d+\z/)
|
81
245
|
## enum
|
82
|
-
cmdopt.add(:indent ,
|
246
|
+
cmdopt.add(:indent , '-i <N>', "indent width", enum: [2, 4, 8])
|
83
247
|
## callback
|
84
|
-
cmdopt.add(:indent ,
|
248
|
+
cmdopt.add(:indent , '-i <N>', "indent width") {|val|
|
85
249
|
val =~ /\A\d+\z/ or
|
86
250
|
raise "integer expected." # raise without exception class.
|
87
251
|
val.to_i # convert argument value.
|
@@ -102,7 +266,7 @@ Multiple parameters
|
|
102
266
|
-------------------
|
103
267
|
|
104
268
|
```ruby
|
105
|
-
cmdopt.add(:lib ,
|
269
|
+
cmdopt.add(:lib , '-I <NAME>', "library name") {|optdict, key, val|
|
106
270
|
arr = optdict[key] || []
|
107
271
|
arr << val
|
108
272
|
arr
|
@@ -110,11 +274,29 @@ cmdopt.add(:lib , "-I <NAME>", "library names") {|optdict, key, val|
|
|
110
274
|
```
|
111
275
|
|
112
276
|
|
113
|
-
|
114
|
-
|
277
|
+
Hidden option
|
278
|
+
-------------
|
279
|
+
|
280
|
+
If help string of command otpion is nil, it will not included
|
281
|
+
in help message.
|
282
|
+
|
283
|
+
```ruby
|
284
|
+
require 'benry/cmdopt'
|
285
|
+
cmdopt = Benry::Cmdopt.new
|
286
|
+
cmdopt.add(:verbose, '-v, --verbose', "verbose mode")
|
287
|
+
cmdopt.add(:debug , '-d[<LEVEL>]' , nil, type: Integer) # hidden
|
288
|
+
puts cmdopt.option_help()
|
289
|
+
### output ('-d' is not included)
|
290
|
+
# -v, --verbose : verbose mode
|
291
|
+
```
|
292
|
+
|
293
|
+
|
294
|
+
Not supported
|
295
|
+
-------------
|
115
296
|
|
116
297
|
* default value
|
117
298
|
* `--no-xxx` style option
|
299
|
+
* bash/zsh completion
|
118
300
|
|
119
301
|
|
120
302
|
Internal classes
|
@@ -140,7 +322,7 @@ opts = parser.parse(argv) do |err|
|
|
140
322
|
$stderr.puts "ERROR: #{err.message}"
|
141
323
|
exit 1
|
142
324
|
end
|
143
|
-
p opts #=>
|
325
|
+
p opts #=> {:help=>true, :indent=>2, :file=>"blabla.txt"}
|
144
326
|
p argv #=> ["aaa", "bbb"]
|
145
327
|
```
|
146
328
|
|
data/benry-cmdopt.gemspec
CHANGED
data/lib/benry/cmdopt.rb
CHANGED
@@ -19,8 +19,8 @@ module Benry
|
|
19
19
|
## Usage:
|
20
20
|
## ## define
|
21
21
|
## cmdopt = Benry::Cmdopt.new
|
22
|
-
## cmdopt.add(:help ,
|
23
|
-
## cmdopt.add(:version,
|
22
|
+
## cmdopt.add(:help , '-h, --help' , "print help message")
|
23
|
+
## cmdopt.add(:version, ' --version', "print version")
|
24
24
|
## ## parse
|
25
25
|
## options = cmdopt.parse(ARGV) do |err|
|
26
26
|
## $stderr.puts "ERROR: #{err.message}"
|
@@ -33,7 +33,7 @@ module Benry
|
|
33
33
|
## puts "Usage: foobar [<options>] [<args>...]"
|
34
34
|
## puts ""
|
35
35
|
## puts "Options:"
|
36
|
-
## puts cmdopt.
|
36
|
+
## puts cmdopt.option_help()
|
37
37
|
## ## or
|
38
38
|
## #format = " %-20s : %s"
|
39
39
|
## #cmdopt.each_option_help {|opt, help| puts format % [opt, help] }
|
@@ -41,23 +41,23 @@ module Benry
|
|
41
41
|
##
|
42
42
|
## Command option parameter:
|
43
43
|
## ## required
|
44
|
-
## cmdopt.add(:file,
|
45
|
-
## cmdopt.add(:file,
|
46
|
-
## cmdopt.add(:file,
|
44
|
+
## cmdopt.add(:file, '-f, --file=<FILE>', "filename")
|
45
|
+
## cmdopt.add(:file, ' --file=<FILE>', "filename")
|
46
|
+
## cmdopt.add(:file, '-f <FILE>' , "filename")
|
47
47
|
## ## optional
|
48
|
-
## cmdopt.add(:file,
|
49
|
-
## cmdopt.add(:file,
|
50
|
-
## cmdopt.add(:file,
|
48
|
+
## cmdopt.add(:file, '-f, --file[=<FILE>]', "filename")
|
49
|
+
## cmdopt.add(:file, ' --file[=<FILE>]', "filename")
|
50
|
+
## cmdopt.add(:file, '-f[<FILE>]' , "filename")
|
51
51
|
##
|
52
52
|
## Validation:
|
53
53
|
## ## type
|
54
|
-
## cmdopt.add(:indent ,
|
54
|
+
## cmdopt.add(:indent , '-i <N>', "indent width", type: Integer)
|
55
55
|
## ## pattern
|
56
|
-
## cmdopt.add(:indent ,
|
56
|
+
## cmdopt.add(:indent , '-i <N>', "indent width", pattern: /\A\d+\z/)
|
57
57
|
## ## enum
|
58
|
-
## cmdopt.add(:indent ,
|
58
|
+
## cmdopt.add(:indent , '-i <N>', "indent width", enum: [2, 4, 8])
|
59
59
|
## ## callback
|
60
|
-
## cmdopt.add(:indent ,
|
60
|
+
## cmdopt.add(:indent , '-i <N>', "indent width") {|val|
|
61
61
|
## val =~ /\A\d+\z/ or
|
62
62
|
## raise "integer expected." # raise without exception class.
|
63
63
|
## val.to_i # convert argument value.
|
@@ -70,20 +70,31 @@ module Benry
|
|
70
70
|
## * Date (`/\A\d\d\d\d-\d\d?-\d\d?\z/`)
|
71
71
|
##
|
72
72
|
## Multiple parameters:
|
73
|
-
## cmdopt.add(:lib ,
|
73
|
+
## cmdopt.add(:lib , '-I <NAME>', "library name") {|optdict, key, val|
|
74
74
|
## arr = optdict[key] || []
|
75
75
|
## arr << val
|
76
76
|
## arr
|
77
77
|
## }
|
78
78
|
##
|
79
|
-
##
|
79
|
+
## Hidden option:
|
80
|
+
## ### if help string is nil, that option is removed from help message.
|
81
|
+
## require 'benry/cmdopt'
|
82
|
+
## cmdopt = Benry::Cmdopt.new
|
83
|
+
## cmdopt.add(:verbose, '-v, --verbose', "verbose mode")
|
84
|
+
## cmdopt.add(:debug , '-d[<LEVEL>]' , nil, type: Integer) # hidden
|
85
|
+
## puts cmdopt.option_help()
|
86
|
+
## ### output ('-d' doesn't appear because help string is nil)
|
87
|
+
## # -v, --verbose : verbose mode
|
88
|
+
##
|
89
|
+
## Not supported:
|
80
90
|
## * default value
|
81
91
|
## * `--no-xxx` style option
|
92
|
+
## * bash/zsh completion
|
82
93
|
##
|
83
94
|
module Cmdopt
|
84
95
|
|
85
96
|
|
86
|
-
VERSION = '$Release: 1.
|
97
|
+
VERSION = '$Release: 1.1.0 $'.split()[1]
|
87
98
|
|
88
99
|
|
89
100
|
def self.new
|
@@ -105,9 +116,9 @@ module Benry
|
|
105
116
|
self
|
106
117
|
end
|
107
118
|
|
108
|
-
def
|
119
|
+
def option_help(width_or_format=nil, all: false)
|
109
120
|
#; [!dm4p8] returns option help message.
|
110
|
-
return @schema.
|
121
|
+
return @schema.option_help(width_or_format, all: all)
|
111
122
|
end
|
112
123
|
|
113
124
|
def each_option_help(&block)
|
@@ -148,6 +159,10 @@ module Benry
|
|
148
159
|
key || long or
|
149
160
|
raise error("add(#{key.inspect}, #{optdef.inspect}): long option required when option key (1st arg) not specified.")
|
150
161
|
key ||= long.gsub(/-/, '_').intern
|
162
|
+
#; [!97sn0] raises SchemaError when ',' is missing between short and long options.
|
163
|
+
if long.nil? && param =~ /\A--/
|
164
|
+
raise error("add(#{key.inspect}, #{optdef.inspect}): missing ',' between short option and long options.")
|
165
|
+
end
|
151
166
|
#; [!7xmr5] raises SchemaError when type is not registered.
|
152
167
|
#; [!s2aaj] raises SchemaError when option has no params but type specified.
|
153
168
|
if type
|
@@ -179,13 +194,13 @@ module Benry
|
|
179
194
|
item
|
180
195
|
end
|
181
196
|
|
182
|
-
def
|
197
|
+
def option_help(width_or_format=nil, all: false)
|
183
198
|
#; [!0aq0i] can take integer as width.
|
184
199
|
#; [!pcsah] can take format string.
|
185
200
|
#; [!dndpd] detects option width automatically when nothing specified.
|
186
201
|
case width_or_format
|
187
202
|
when nil ; format = _default_format()
|
188
|
-
when Integer; format = " %-#{width_or_format}s: %s"
|
203
|
+
when Integer; format = " %-#{width_or_format}s : %s"
|
189
204
|
when String ; format = width_or_format
|
190
205
|
else
|
191
206
|
raise ArgumentError.new("#{width_or_format.inspect}: width (integer) or format (string) expected.")
|
@@ -214,19 +229,6 @@ module Benry
|
|
214
229
|
return buf.join()
|
215
230
|
end
|
216
231
|
|
217
|
-
def _default_format(min_width=20, max_width=35)
|
218
|
-
#; [!hr45y] detects preffered option width.
|
219
|
-
w = 0
|
220
|
-
each_option_help do |opt, help|
|
221
|
-
w = opt.length if w < opt.length
|
222
|
-
end
|
223
|
-
w = min_width if w < min_width
|
224
|
-
w = max_width if w > max_width
|
225
|
-
#; [!kkh9t] returns format string.
|
226
|
-
return " %-#{w}s : %s"
|
227
|
-
end
|
228
|
-
private :_default_format
|
229
|
-
|
230
232
|
def each_option_help(&block)
|
231
233
|
#; [!4b911] yields each optin definition str and help message.
|
232
234
|
@items.each do |item|
|
@@ -274,30 +276,50 @@ module Benry
|
|
274
276
|
return short, long, param1 || param2, !!param2
|
275
277
|
end
|
276
278
|
|
279
|
+
def _default_format(min_width=nil, max_width=35)
|
280
|
+
#; [!bmr7d] changes min_with according to options.
|
281
|
+
min_width ||= _preferred_option_width()
|
282
|
+
#; [!hr45y] detects preffered option width.
|
283
|
+
w = 0
|
284
|
+
each_option_help do |opt, help|
|
285
|
+
w = opt.length if w < opt.length
|
286
|
+
end
|
287
|
+
w = min_width if w < min_width
|
288
|
+
w = max_width if w > max_width
|
289
|
+
#; [!kkh9t] returns format string.
|
290
|
+
return " %-#{w}s : %s"
|
291
|
+
end
|
292
|
+
|
293
|
+
def _preferred_option_width()
|
294
|
+
#; [!kl91t] shorten option help min width when only single options which take no arg.
|
295
|
+
#; [!0koqb] widen option help min width when any option takes an arg.
|
296
|
+
#; [!kl91t] widen option help min width when long option exists.
|
297
|
+
long_p = @items.any? {|x| x.help && x.long && x.param }
|
298
|
+
short_p = @items.all? {|x| x.help && !x.long && !x.param }
|
299
|
+
return short_p ? 8 : long_p ? 20 : 14
|
300
|
+
end
|
301
|
+
|
277
302
|
end
|
278
303
|
|
279
304
|
|
280
305
|
class SchemaItem # avoid Struct
|
281
306
|
|
282
307
|
def initialize(key, optdef, short, long, param, help, optional: nil, type: nil, pattern: nil, enum: nil, &callback)
|
283
|
-
@key = key
|
284
|
-
@optdef = optdef
|
285
|
-
@short = short
|
286
|
-
@long = long
|
287
|
-
@param = param
|
288
|
-
@help = help
|
289
|
-
@optional = optional
|
290
|
-
@type = type
|
291
|
-
@pattern = pattern
|
292
|
-
@enum = enum
|
293
|
-
@callback = callback
|
308
|
+
@key = key unless key.nil?
|
309
|
+
@optdef = optdef unless optdef.nil?
|
310
|
+
@short = short unless short.nil?
|
311
|
+
@long = long unless long.nil?
|
312
|
+
@param = param unless param.nil?
|
313
|
+
@help = help unless help.nil?
|
314
|
+
@optional = optional unless optional.nil?
|
315
|
+
@type = type unless type.nil?
|
316
|
+
@pattern = pattern unless pattern.nil?
|
317
|
+
@enum = enum unless enum.nil?
|
318
|
+
@callback = callback unless callback.nil?
|
294
319
|
end
|
295
320
|
|
296
321
|
attr_reader :key, :optdef, :short, :long, :param, :help, :optional, :type, :pattern, :enum, :callback
|
297
|
-
|
298
|
-
def optional_param?
|
299
|
-
@optional
|
300
|
-
end
|
322
|
+
alias optional_param? optional
|
301
323
|
|
302
324
|
def validate_and_convert(val, optdict)
|
303
325
|
#; [!h0s0o] raises RuntimeError when value not matched to pattern.
|
data/test/cmdopt_test.rb
CHANGED
@@ -113,6 +113,13 @@ class Benry::Cmdopt::Schema::Test < MiniTest::Test
|
|
113
113
|
ok {pr}.raise?(Benry::Cmdopt::SchemaError, msg)
|
114
114
|
end
|
115
115
|
|
116
|
+
it "[!97sn0] raises SchemaError when ',' is missing between short and long options." do
|
117
|
+
sc = @schema
|
118
|
+
pr = proc { sc.add(:exec, '-x --exec=ARG', "exec") }
|
119
|
+
msg = "add(:exec, \"-x --exec=ARG\"): missing ',' between short option and long options."
|
120
|
+
ok {pr}.raise?(Benry::Cmdopt::SchemaError, msg)
|
121
|
+
end
|
122
|
+
|
116
123
|
it "[!yht0v] keeps command option definitions." do
|
117
124
|
sc = @schema
|
118
125
|
sc.add(:indent, "-i, --indent[=<WIDTH>]", "indent width",
|
@@ -213,7 +220,7 @@ class Benry::Cmdopt::Schema::Test < MiniTest::Test
|
|
213
220
|
end
|
214
221
|
|
215
222
|
|
216
|
-
describe '#
|
223
|
+
describe '#option_help()' do
|
217
224
|
|
218
225
|
before do
|
219
226
|
sc = Benry::Cmdopt::Schema.new
|
@@ -226,19 +233,19 @@ class Benry::Cmdopt::Schema::Test < MiniTest::Test
|
|
226
233
|
end
|
227
234
|
|
228
235
|
it "[!0aq0i] can take integer as width." do
|
229
|
-
help = @schema.
|
236
|
+
help = @schema.option_help(41)
|
230
237
|
ok {help} == <<END
|
231
|
-
-h, --help
|
232
|
-
--version
|
233
|
-
-f, --file=<FILE>
|
234
|
-
-i, --indent[=<WIDTH>]
|
238
|
+
-h, --help : show help message.
|
239
|
+
--version : print version
|
240
|
+
-f, --file=<FILE> : filename
|
241
|
+
-i, --indent[=<WIDTH>] : enable indent
|
235
242
|
END
|
236
243
|
s = help.each_line.first.split(':')[0]
|
237
|
-
ok {s.length} == 41+
|
244
|
+
ok {s.length} == 41+3
|
238
245
|
end
|
239
246
|
|
240
247
|
it "[!pcsah] can take format string." do
|
241
|
-
help = @schema.
|
248
|
+
help = @schema.option_help("%-42s: %s")
|
242
249
|
ok {help} == <<END
|
243
250
|
-h, --help : show help message.
|
244
251
|
--version : print version
|
@@ -250,7 +257,7 @@ END
|
|
250
257
|
end
|
251
258
|
|
252
259
|
it "[!dndpd] detects option width automatically when nothing specified." do
|
253
|
-
help = @schema.
|
260
|
+
help = @schema.option_help()
|
254
261
|
ok {help} == <<END
|
255
262
|
-h, --help : show help message.
|
256
263
|
--version : print version
|
@@ -262,12 +269,12 @@ END
|
|
262
269
|
end
|
263
270
|
|
264
271
|
it "[!v7z4x] skips option help if help message is not specified." do
|
265
|
-
help = @schema.
|
272
|
+
help = @schema.option_help()
|
266
273
|
ok {help} !~ /debug/
|
267
274
|
end
|
268
275
|
|
269
276
|
it "[!to1th] includes all option help when `all` is true." do
|
270
|
-
help = @schema.
|
277
|
+
help = @schema.option_help(nil, all: true)
|
271
278
|
ok {help} =~ /debug/
|
272
279
|
ok {help} == <<END
|
273
280
|
-h, --help : show help message.
|
@@ -286,7 +293,7 @@ output mode
|
|
286
293
|
q, quiet: print litte output
|
287
294
|
c, compact: print summary output
|
288
295
|
END
|
289
|
-
actual = sc.
|
296
|
+
actual = sc.option_help()
|
290
297
|
expected = <<END
|
291
298
|
-m, --mode=<MODE> : output mode
|
292
299
|
v, verbose: print many output
|
@@ -325,6 +332,51 @@ END
|
|
325
332
|
ok {ret} == " %-22s : %s"
|
326
333
|
end
|
327
334
|
|
335
|
+
it "[!bmr7d] changes min_with according to options." do
|
336
|
+
sc = Benry::Cmdopt::Schema.new
|
337
|
+
sc.add(:help , '-h', "help")
|
338
|
+
sc.add(:version, '-v', "version")
|
339
|
+
ok {sc.__send__(:_default_format, nil, 40)} == " %-8s : %s"
|
340
|
+
#
|
341
|
+
sc.add(:file , '-f <FILE>', "filename")
|
342
|
+
ok {sc.__send__(:_default_format, nil, 40)} == " %-14s : %s"
|
343
|
+
#
|
344
|
+
sc.add(:force , '--force', "forcedly")
|
345
|
+
ok {sc.__send__(:_default_format, nil, 40)} == " %-14s : %s"
|
346
|
+
#
|
347
|
+
sc.add(:mode , '-m, --mode=<MODE>', "verbose/quiet")
|
348
|
+
ok {sc.__send__(:_default_format, nil, 40)} == " %-20s : %s"
|
349
|
+
end
|
350
|
+
|
351
|
+
end
|
352
|
+
|
353
|
+
|
354
|
+
describe '#_preferred_option_width()' do
|
355
|
+
|
356
|
+
it "[!kl91t] shorten option help min width when only single options which take no arg." do
|
357
|
+
sc = Benry::Cmdopt::Schema.new
|
358
|
+
sc.add(:help , '-h', "help")
|
359
|
+
sc.add(:version, '-v', "version")
|
360
|
+
ok {sc.__send__(:_preferred_option_width)} == 8
|
361
|
+
end
|
362
|
+
|
363
|
+
it "[!0koqb] widen option help min width when any option takes an arg." do
|
364
|
+
sc = Benry::Cmdopt::Schema.new
|
365
|
+
sc.add(:help , '-h', "help")
|
366
|
+
sc.add(:indent , '-i[<N>]', "indent")
|
367
|
+
ok {sc.__send__(:_preferred_option_width)} == 14
|
368
|
+
end
|
369
|
+
|
370
|
+
it "[!kl91t] widen option help min width when long option exists." do
|
371
|
+
sc = Benry::Cmdopt::Schema.new
|
372
|
+
sc.add(:help , '-h', "help")
|
373
|
+
sc.add(:version, '-v, --version', "version")
|
374
|
+
ok {sc.__send__(:_preferred_option_width)} == 14
|
375
|
+
#
|
376
|
+
sc.add(:file, '--file=<FILE>', "filename")
|
377
|
+
ok {sc.__send__(:_preferred_option_width)} == 20
|
378
|
+
end
|
379
|
+
|
328
380
|
end
|
329
381
|
|
330
382
|
|
@@ -839,7 +891,7 @@ class Benry::Cmdopt::Facade::Test < MiniTest::Test
|
|
839
891
|
end
|
840
892
|
|
841
893
|
|
842
|
-
describe '#
|
894
|
+
describe '#option_help()' do
|
843
895
|
|
844
896
|
before do
|
845
897
|
@cmdopt = Benry::Cmdopt.new
|
@@ -849,7 +901,7 @@ class Benry::Cmdopt::Facade::Test < MiniTest::Test
|
|
849
901
|
end
|
850
902
|
|
851
903
|
it "[!dm4p8] returns option help message." do
|
852
|
-
help = @cmdopt.
|
904
|
+
help = @cmdopt.option_help()
|
853
905
|
ok {help} == <<END
|
854
906
|
-h, --help : show help message
|
855
907
|
--version : print version
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: benry-cmdopt
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- kwatch
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-01-
|
11
|
+
date: 2021-01-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: minitest
|