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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 51be94488014a32dabfc2f524a850fa657a11c4c1d9d9b92761d00e57e24969e
4
- data.tar.gz: d2078058fec806f194f0bfd1d5d6705a78430c7989d7eb9ddccadea2daa3311b
3
+ metadata.gz: e22704458cfcb32a806de14c4b4df853673de1309b964d4362e2cc9605f64fca
4
+ data.tar.gz: 78a52a4a0d1b5d261bea63c58b454b0b68810f10fb3795e347644f269715580f
5
5
  SHA512:
6
- metadata.gz: 41e0e1a914cb6022f31244d6770067bd38636f27c0ce9e30dbcd37a731bc8d3f485329e0c0b49ff3aa322250f6d475ee0c28032a1053132e0f8c2bf061b2aa7c
7
- data.tar.gz: e5e3922ccf2d06e9b56997cc07e7616dfa905fedb1974953f7bc9138d7b888cab6d5b5c8025000cd574b8b608ead71ef772571fa71486c5467294d20376bdb9e
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.0.0 $)
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 , "-h, --help" , "print help message")
34
- cmdopt.add(:version, " --version", "print 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.build_option_help()
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, "-f, --file=<FILE>", "filename")
63
- cmdopt.add(:file, " --file=<FILE>", "filename")
64
- cmdopt.add(:file, "-f <FILE>" , "filename")
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, "-f, --file[=<FILE>]", "filename")
68
- cmdopt.add(:file, " --file[=<FILE>]", "filename")
69
- cmdopt.add(:file, "-f[<FILE>]" , "filename")
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 , "-i <N>", "indent width", type: Integer)
242
+ cmdopt.add(:indent , '-i <N>', "indent width", type: Integer)
79
243
  ## pattern
80
- cmdopt.add(:indent , "-i <N>", "indent width", pattern: /\A\d+\z/)
244
+ cmdopt.add(:indent , '-i <N>', "indent width", pattern: /\A\d+\z/)
81
245
  ## enum
82
- cmdopt.add(:indent , "-i <N>", "indent width", enum: [2, 4, 8])
246
+ cmdopt.add(:indent , '-i <N>', "indent width", enum: [2, 4, 8])
83
247
  ## callback
84
- cmdopt.add(:indent , "-i <N>", "indent width") {|val|
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 , "-I <NAME>", "library names") {|optdict, key, val|
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
- Not support
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 #=> [:help=>true, :indent=>2, :file=>"blabla.txt"]
325
+ p opts #=> {:help=>true, :indent=>2, :file=>"blabla.txt"}
144
326
  p argv #=> ["aaa", "bbb"]
145
327
  ```
146
328
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |spec|
4
4
  spec.name = 'benry-cmdopt'
5
- spec.version = '$Release: 1.0.0 $'.split()[1]
5
+ spec.version = '$Release: 1.1.0 $'.split()[1]
6
6
  spec.author = 'kwatch'
7
7
  spec.email = 'kwatch@gmail.com'
8
8
  spec.platform = Gem::Platform::RUBY
@@ -19,8 +19,8 @@ module Benry
19
19
  ## Usage:
20
20
  ## ## define
21
21
  ## cmdopt = Benry::Cmdopt.new
22
- ## cmdopt.add(:help , "-h, --help" , "print help message")
23
- ## cmdopt.add(:version, " --version", "print 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.build_option_help()
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, "-f, --file=<FILE>", "filename")
45
- ## cmdopt.add(:file, " --file=<FILE>", "filename")
46
- ## cmdopt.add(:file, "-f <FILE>" , "filename")
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, "-f, --file[=<FILE>]", "filename")
49
- ## cmdopt.add(:file, " --file[=<FILE>]", "filename")
50
- ## cmdopt.add(:file, "-f[<FILE>]" , "filename")
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 , "-i <N>", "indent width", type: Integer)
54
+ ## cmdopt.add(:indent , '-i <N>', "indent width", type: Integer)
55
55
  ## ## pattern
56
- ## cmdopt.add(:indent , "-i <N>", "indent width", pattern: /\A\d+\z/)
56
+ ## cmdopt.add(:indent , '-i <N>', "indent width", pattern: /\A\d+\z/)
57
57
  ## ## enum
58
- ## cmdopt.add(:indent , "-i <N>", "indent width", enum: [2, 4, 8])
58
+ ## cmdopt.add(:indent , '-i <N>', "indent width", enum: [2, 4, 8])
59
59
  ## ## callback
60
- ## cmdopt.add(:indent , "-i <N>", "indent width") {|val|
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 , "-I <NAME>", "library names") {|optdict, key, val|
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
- ## Not support:
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.0.0 $'.split()[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 build_option_help(width_or_format=nil, all: false)
119
+ def option_help(width_or_format=nil, all: false)
109
120
  #; [!dm4p8] returns option help message.
110
- return @schema.build_option_help(width_or_format, all: all)
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 build_option_help(width_or_format=nil, all: false)
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.
@@ -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 '#build_option_help()' do
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.build_option_help(41)
236
+ help = @schema.option_help(41)
230
237
  ok {help} == <<END
231
- -h, --help : show help message.
232
- --version : print version
233
- -f, --file=<FILE> : filename
234
- -i, --indent[=<WIDTH>] : enable indent
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+2
244
+ ok {s.length} == 41+3
238
245
  end
239
246
 
240
247
  it "[!pcsah] can take format string." do
241
- help = @schema.build_option_help("%-42s: %s")
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.build_option_help()
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.build_option_help()
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.build_option_help(nil, all: true)
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.build_option_help()
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 '#build_option_help()' do
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.build_option_help()
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.0.0
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-17 00:00:00.000000000 Z
11
+ date: 2021-01-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: minitest