benry-cmdopt 1.0.0 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|