benry-cmdopt 2.0.0 → 2.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGES.md +6 -0
- data/MIT-LICENSE +1 -1
- data/README.md +15 -17
- data/Rakefile.rb +1 -1
- data/benry-cmdopt.gemspec +1 -1
- data/doc/benry-cmdopt.html +152 -154
- data/doc/css/style.css +8 -0
- data/lib/benry/cmdopt.rb +2 -2
- data/task/common-task.rb +1 -0
- 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: fa5cc6fe56fade46613abc3f6d3c7430ec0585a9c21535e478debe20500829c0
|
4
|
+
data.tar.gz: eeb5e6c9d78008b92a68662d55c6c45f9fbb4cacb983f66667db32fa537855f8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 84af5c4bc66e2066213dcc907c3fd2e1cb380278552a4e5e900c256e95fc10f6a1f2d2127a995fd5f1496f0bb239f1e1c68afe06536300d180c530a5196a0b89
|
7
|
+
data.tar.gz: dd51bc08bd53742b5556f47887bd9a80ffac505608b5d79a55aa53d4a5023d5472f9b7015bf3f6144456695edbe793e5fb80878432b25a59ed0b4dfa2885c782
|
data/CHANGES.md
CHANGED
data/MIT-LICENSE
CHANGED
data/README.md
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
# Benry-CmdOpt
|
2
2
|
|
3
|
-
($Release: 2.0.
|
3
|
+
($Release: 2.0.1 $)
|
4
4
|
|
5
5
|
|
6
6
|
|
7
|
-
##
|
7
|
+
## What's This?
|
8
8
|
|
9
9
|
Benry-CmdOpt is a command option parser library, like `optparse.rb`
|
10
10
|
(Ruby standard library).
|
@@ -20,11 +20,11 @@ Benry-CmdOpt requires Ruby >= 2.3.
|
|
20
20
|
|
21
21
|
|
22
22
|
|
23
|
-
|
23
|
+
### Table of Contents
|
24
24
|
|
25
25
|
<!-- TOC -->
|
26
26
|
|
27
|
-
* [
|
27
|
+
* [What's This?](#whats-this)
|
28
28
|
* [Why not `optparse.rb`?](#why-not-optparserb)
|
29
29
|
* [Install](#install)
|
30
30
|
* [Usage](#usage)
|
@@ -236,8 +236,7 @@ opts = {}
|
|
236
236
|
begin
|
237
237
|
parser.parse!(ARGV, into: opts)
|
238
238
|
rescue OptionParser::ParseError => err # specify error class
|
239
|
-
|
240
|
-
exit 1
|
239
|
+
abort "ERROR: #{err.message}"
|
241
240
|
end
|
242
241
|
|
243
242
|
### benry/cmdopt.rb
|
@@ -245,21 +244,22 @@ require 'benry/cmdopt'
|
|
245
244
|
cmdopt = Benry::CmdOpt.new
|
246
245
|
cmdopt.add(:file, '-f, --file=<FILE>', "filename")
|
247
246
|
opts = cmdopt.parse(ARGV) do |err| # error handling wihtout error class name
|
248
|
-
|
249
|
-
exit 1
|
247
|
+
abort "ERROR: #{err.message}"
|
250
248
|
end
|
251
249
|
```
|
252
250
|
|
253
|
-
*
|
254
|
-
|
255
|
-
|
251
|
+
* The source code of "optparse.rb" is quite large and complex for a command
|
252
|
+
option parser library. The reason is that one large `OptParse` class
|
253
|
+
does everything related to parsing command options. Bad class design.
|
254
|
+
Therefore it is hard to customize or extend `OptionParser` class.
|
256
255
|
|
257
256
|
In contract, `benry/cmdopt.rb` consists of several classes
|
258
257
|
(schema class, parser class, and facade class).
|
259
258
|
Therefore it is easy to understand and extend these classes.
|
260
259
|
|
261
|
-
|
262
|
-
|
260
|
+
In fact, file `optparse.rb` and `optparse/*.rb` (in Ruby 3.2)
|
261
|
+
contains total 1298 lines (except comments and blanks), while
|
262
|
+
`benry/cmdopt.rb` (v2.0.0) contains only 429 lines (except both, too).
|
263
263
|
|
264
264
|
|
265
265
|
|
@@ -286,8 +286,7 @@ cmdopt.add(:version, ' --version', "print version")
|
|
286
286
|
|
287
287
|
## parse with error handling
|
288
288
|
options = cmdopt.parse(ARGV) do |err|
|
289
|
-
|
290
|
-
exit(1)
|
289
|
+
abort "ERROR: #{err.message}"
|
291
290
|
end
|
292
291
|
p options # ex: {:help => true, :version => true}
|
293
292
|
p ARGV # options are removed from ARGV
|
@@ -642,8 +641,7 @@ schema.add(:indent, '-i, --indent[=<WIDTH>]', "enable indent", type: Integer)
|
|
642
641
|
parser = Benry::CmdOpt::Parser.new(schema)
|
643
642
|
argv = ['-hi2', '--file=blabla.txt', 'aaa', 'bbb']
|
644
643
|
opts = parser.parse(argv) do |err|
|
645
|
-
|
646
|
-
exit 1
|
644
|
+
abort "ERROR: #{err.message}"
|
647
645
|
end
|
648
646
|
p opts #=> {:help=>true, :indent=>2, :file=>"blabla.txt"}
|
649
647
|
p argv #=> ["aaa", "bbb"]
|
data/Rakefile.rb
CHANGED
data/benry-cmdopt.gemspec
CHANGED
data/doc/benry-cmdopt.html
CHANGED
@@ -21,9 +21,9 @@
|
|
21
21
|
<ul class="nav">
|
22
22
|
</ul>
|
23
23
|
</nav>
|
24
|
-
<p>($Release: 2.0.
|
25
|
-
<section class="section" id="
|
26
|
-
<h2>
|
24
|
+
<p>($Release: 2.0.1 $)</p>
|
25
|
+
<section class="section" id="whats-this">
|
26
|
+
<h2>What's This?</h2>
|
27
27
|
<p>Benry-CmdOpt is a command option parser library, like <code>optparse.rb</code>
|
28
28
|
(Ruby standard library).</p>
|
29
29
|
<p>Compared to <code>optparse.rb</code>, Benry-CmdOpt is easy to use, easy to extend,
|
@@ -34,12 +34,11 @@ and easy to understahnd.</p>
|
|
34
34
|
<li>Changes: <a href="https://github.com/kwatch/benry-ruby/tree/main/benry-cmdopt/CHANGES.md">https://github.com/kwatch/benry-ruby/tree/main/benry-cmdopt/CHANGES.md</a></li>
|
35
35
|
</ul>
|
36
36
|
<p>Benry-CmdOpt requires Ruby >= 2.3.</p>
|
37
|
-
|
38
|
-
<
|
39
|
-
<h2>Table of Contents</h2>
|
37
|
+
<section class="subsection" id="table-of-contents">
|
38
|
+
<h3>Table of Contents</h3>
|
40
39
|
<div class="toc">
|
41
40
|
<ul>
|
42
|
-
<li><a href="#
|
41
|
+
<li><a href="#whats-this">What's This?</a></li>
|
43
42
|
<li><a href="#why-not-optparserb">Why not <code>optparse.rb</code>?</a></li>
|
44
43
|
<li><a href="#install">Install</a></li>
|
45
44
|
<li><a href="#usage">Usage</a>
|
@@ -61,6 +60,7 @@ and easy to understahnd.</p>
|
|
61
60
|
</ul>
|
62
61
|
</div>
|
63
62
|
</section>
|
63
|
+
</section>
|
64
64
|
<section class="section" id="why-not-optparserb">
|
65
65
|
<h2>Why not <code>optparse.rb</code>?</h2>
|
66
66
|
<ul>
|
@@ -80,45 +80,45 @@ and easy to understahnd.</p>
|
|
80
80
|
This feature is hard-coded in <code>OptionParser#parse_in_order()</code>
|
81
81
|
and hard to be disabled.
|
82
82
|
<p></p>
|
83
|
-
In contact, <code>benry/cmdopt.rb</code> doesn
|
83
|
+
In contact, <code>benry/cmdopt.rb</code> doesn't behave this way.
|
84
84
|
<code>-x</code> option is available only when <code>-x</code> is defined.
|
85
85
|
<code>benry/cmdopt.rb</code> does nothing superfluous.</li>
|
86
86
|
<p></p>
|
87
87
|
<li><code>optparse.rb</code> uses long option name as hash key automatically, but
|
88
|
-
it doesn
|
88
|
+
it doesn't provide the way to specify hash key for short-only option.
|
89
89
|
<p></p>
|
90
90
|
<code>benry/cmdopt.rb</code> can specify hash key for short-only option.</li>
|
91
91
|
</ul>
|
92
92
|
<pre class="language-ruby">
|
93
93
|
### optparse.rb
|
94
|
-
require
|
94
|
+
require 'optparse'
|
95
95
|
parser = OptionParser.new
|
96
|
-
parser.on(
|
97
|
-
parser.on(<strong
|
96
|
+
parser.on('-v', '--verbose', "verbose mode") # short and long option
|
97
|
+
parser.on(<strong>'-q'</strong>, "quiet mode") # short-only option
|
98
98
|
#
|
99
99
|
opts = {}
|
100
|
-
parser.parse!([
|
100
|
+
parser.parse!(['-v'], into: opts) # short option
|
101
101
|
p opts #=> {:verbose=>true} # hash key is long option name
|
102
102
|
#
|
103
103
|
opts = {}
|
104
|
-
parser.parse!([
|
104
|
+
parser.parse!(['-q'], into: opts) # short option
|
105
105
|
p opts #=> <strong>{:q=>true}</strong> # hash key is short option name
|
106
106
|
|
107
107
|
### benry/cmdopt.rb
|
108
|
-
require
|
108
|
+
require 'benry/cmdopt'
|
109
109
|
cmdopt = Benry::CmdOpt.new
|
110
|
-
cmdopt.add(:verbose,
|
111
|
-
cmdopt.add(<strong>:quiet</strong> , <strong
|
110
|
+
cmdopt.add(:verbose, '-v, --verbose', "verbose mode") # short and long
|
111
|
+
cmdopt.add(<strong>:quiet</strong> , <strong>'-q'</strong> , "quiet mode") # short-only
|
112
112
|
#
|
113
|
-
opts = cmdopt.parse([
|
113
|
+
opts = cmdopt.parse(['-v']) # short option
|
114
114
|
p opts #=> {:verbose=>true} # independent hash key of option name
|
115
115
|
#
|
116
|
-
opts = cmdopt.parse([
|
116
|
+
opts = cmdopt.parse(['-q']) # short option
|
117
117
|
p opts #=> <strong>{:quiet=>true}</strong> # independent hash key of option name
|
118
118
|
</pre>
|
119
119
|
<ul>
|
120
120
|
<li><code>optparse.rb</code> provides severay ways to validate option values, such as
|
121
|
-
type class, Regexp as pattern, or Array/Set as enum. But it doesn
|
121
|
+
type class, Regexp as pattern, or Array/Set as enum. But it doesn't
|
122
122
|
accept Range object. This means that, for examle, it is not simple to
|
123
123
|
validate whether integer or float value is positive or not.
|
124
124
|
<p></p>
|
@@ -128,12 +128,12 @@ p opts #=> <strong>{:quiet=>true}</strong> # independent hash key of o
|
|
128
128
|
<pre class="language-ruby">
|
129
129
|
### optparse.rb
|
130
130
|
parser = OptionParser.new
|
131
|
-
parser.on(
|
131
|
+
parser.on('-n <N>', "number", Integer, <strong>(1..)</strong>) #=> NoMethodError
|
132
132
|
|
133
133
|
### benry/cmdopt.rb
|
134
|
-
require
|
134
|
+
require 'benry/cmdopt'
|
135
135
|
cmdopt = Benry::CmdOpt.new
|
136
|
-
cmdopt.add(:number,
|
136
|
+
cmdopt.add(:number, "-n <N>", "number", type: Integer, <strong>range: (1..)</strong>) #=> ok
|
137
137
|
</pre>
|
138
138
|
<ul>
|
139
139
|
<li><code>optparse.rb</code> accepts Array or Set object as enum values. But values
|
@@ -145,13 +145,13 @@ cmdopt.add(:number, "-n <N>", "number", type: Integer,
|
|
145
145
|
<pre class="language-ruby">
|
146
146
|
### optparse.rb
|
147
147
|
parser = OptionParser.new
|
148
|
-
parser.on(
|
149
|
-
parser.on(
|
148
|
+
parser.on('-n <N>', "number", Integer, <strong>[1, 2, 3]</strong>) # wrong
|
149
|
+
parser.on('-n <N>', "number", Integer, <strong>['1','2','3']</strong>) # ok (but not intuitive)
|
150
150
|
|
151
151
|
### benry/cmdopt.rb
|
152
|
-
require
|
152
|
+
require 'benry/cmdopt'
|
153
153
|
cmdopt = Benry::CmdOpt.new
|
154
|
-
cmdopt.add(:number,
|
154
|
+
cmdopt.add(:number, "-n <N>", "number", type: Integer, <strong>enum: [1, 2, 3]</strong>) # very intuitive
|
155
155
|
</pre>
|
156
156
|
<ul>
|
157
157
|
<li><code>optparse.rb</code> adds <code>-h</code> and <code>--help</code> options automatically, and
|
@@ -162,14 +162,14 @@ cmdopt.add(:number, "-n <N>", "number", type: Integer,
|
|
162
162
|
<code>benry/cmdopt.rb</code> does nothing superfluous.</li>
|
163
163
|
</ul>
|
164
164
|
<pre class="language-ruby">
|
165
|
-
require
|
165
|
+
require 'optparse'
|
166
166
|
parser = OptionParser.new
|
167
|
-
## it is able to overwrite
|
167
|
+
## it is able to overwrite '-h' and/or '--help',
|
168
168
|
## but how to remove or disable these options?
|
169
169
|
opts = {}
|
170
|
-
parser.on(<strong
|
171
|
-
parser.parse([<strong
|
172
|
-
puts
|
170
|
+
parser.on(<strong>'-h <host>'</strong>, "hostname") {|v| opts[:host] = v }
|
171
|
+
parser.parse([<strong>'--help'</strong>]) # <== terminates current process!!
|
172
|
+
puts 'xxx' #<== not printed because current process alreay terminated
|
173
173
|
</pre>
|
174
174
|
<ul>
|
175
175
|
<li><code>optparse.rb</code> adds <code>-v</code> and <code>--version</code> options automatically, and
|
@@ -182,42 +182,42 @@ puts 'xxx' #<== not printed because current process alreay termina
|
|
182
182
|
<code>benry/cmdopt.rb</code> does nothing superfluous.</li>
|
183
183
|
</ul>
|
184
184
|
<pre class="language-ruby">
|
185
|
-
require
|
185
|
+
require 'optparse'
|
186
186
|
parser = OptionParser.new
|
187
|
-
## it is able to overwrite
|
187
|
+
## it is able to overwrite '-v' and/or '--version',
|
188
188
|
## but how to remove or disable these options?
|
189
189
|
opts = {}
|
190
|
-
parser.on(<strong
|
191
|
-
parser.parse([<strong
|
192
|
-
puts
|
190
|
+
parser.on(<strong>'-v'</strong>, "verbose mode") { opts[:verbose] = true }
|
191
|
+
parser.parse([<strong>'--version'</strong>]) # <== terminates current process!!
|
192
|
+
puts 'xxx' #<== not printed because current process alreay terminated
|
193
193
|
</pre>
|
194
194
|
<ul>
|
195
|
-
<li><code>optparse.rb</code> generates help message automatically, but it doesn
|
195
|
+
<li><code>optparse.rb</code> generates help message automatically, but it doesn't
|
196
196
|
contain <code>-h</code>, <code>--help</code>, <code>-v</code>, nor <code>--version</code>.
|
197
197
|
These options are available but not shown in help message. Strange.</li>
|
198
198
|
<p></p>
|
199
199
|
<li><code>optparse.rb</code> generate help message which contains command usage string
|
200
200
|
such as <code>Usage: <command> [options]</code>. <code>optparse.rb</code> should NOT include
|
201
201
|
it in help message because it is just a library, not framework.
|
202
|
-
If you want to change
|
202
|
+
If you want to change '[options]' to '[<options>]', you must manipulate
|
203
203
|
help message string by yourself.
|
204
204
|
<p></p>
|
205
|
-
<code>benry/cmdopt.rb</code> doesn
|
205
|
+
<code>benry/cmdopt.rb</code> doesn't include extra text (such as usage text) into
|
206
206
|
help message. <code>benry/cmdopt.rb</code> does nothing superfluous.</li>
|
207
207
|
<p></p>
|
208
208
|
<li><code>optparse.rb</code> generates help message with too wide option name
|
209
209
|
by default. You must specify proper width.
|
210
210
|
<p></p>
|
211
211
|
<code>benry/cmdopt.rb</code> calculates proper width automatically.
|
212
|
-
You don
|
212
|
+
You don't need to specify proper width in many case.</li>
|
213
213
|
</ul>
|
214
214
|
<pre class="language-ruby">
|
215
215
|
### optparse.rb
|
216
|
-
require
|
217
|
-
banner =
|
216
|
+
require 'optparse'
|
217
|
+
banner = "Usage: blabla <options>"
|
218
218
|
parser = OptionParser.new(banner) # or: OptionParser.new(banner, 25)
|
219
|
-
parser.on(
|
220
|
-
parser.on(
|
219
|
+
parser.on('-f', '--file=<FILE>', "filename")
|
220
|
+
parser.on('-m <MODE>' , "verbose/quiet")
|
221
221
|
puts parser.help
|
222
222
|
### output
|
223
223
|
# Usage: blabla <options>
|
@@ -225,11 +225,11 @@ puts parser.help
|
|
225
225
|
# <strong>-m <MODE> verbose/quiet</strong>
|
226
226
|
|
227
227
|
### benry/cmdopt.rb
|
228
|
-
require
|
228
|
+
require 'benry/cmdopt'
|
229
229
|
cmdopt = Benry::CmdOpt.new()
|
230
|
-
cmdopt.add(:file,
|
231
|
-
cmdopt.add(:mode,
|
232
|
-
puts
|
230
|
+
cmdopt.add(:file, '-f, --file=<FILE>', "filename")
|
231
|
+
cmdopt.add(:mode, '-m <MODE>' , "verbose/quiet")
|
232
|
+
puts "Usage: blabla [<options>]"
|
233
233
|
puts cmdopt.to_s()
|
234
234
|
### output (calculated proper width)
|
235
235
|
# Usage: blabla [<options>]
|
@@ -241,41 +241,41 @@ puts cmdopt.to_s()
|
|
241
241
|
That is, you must know the error class name.
|
242
242
|
<p></p>
|
243
243
|
<code>benry/cmdopt.rb</code> provides error handler without exception class name.
|
244
|
-
You don
|
244
|
+
You don't need to know the error class name on error handling.</li>
|
245
245
|
</ul>
|
246
246
|
<pre class="language-ruby">
|
247
247
|
### optparse.rb
|
248
|
-
require
|
248
|
+
require 'optparse'
|
249
249
|
parser = OptionParser.new
|
250
|
-
parser.on(
|
250
|
+
parser.on('-f', '--file=<FILE>', "filename")
|
251
251
|
opts = {}
|
252
252
|
begin
|
253
253
|
parser.parse!(ARGV, into: opts)
|
254
254
|
<strong>rescue OptionParser::ParseError => err</strong> # specify error class
|
255
|
-
|
256
|
-
exit 1
|
255
|
+
abort "ERROR: #{err.message}"
|
257
256
|
end
|
258
257
|
|
259
258
|
### benry/cmdopt.rb
|
260
|
-
require
|
259
|
+
require 'benry/cmdopt'
|
261
260
|
cmdopt = Benry::CmdOpt.new
|
262
|
-
cmdopt.add(:file,
|
261
|
+
cmdopt.add(:file, '-f, --file=<FILE>', "filename")
|
263
262
|
opts = cmdopt.parse(ARGV) <strong>do |err|</strong> # error handling wihtout error class name
|
264
|
-
|
265
|
-
exit 1
|
263
|
+
abort "ERROR: #{err.message}"
|
266
264
|
end
|
267
265
|
</pre>
|
268
266
|
<ul>
|
269
|
-
<li>
|
270
|
-
<code>OptParse</code> class
|
271
|
-
|
267
|
+
<li>The source code of "optparse.rb" is quite large and complex for a command
|
268
|
+
option parser library. The reason is that one large <code>OptParse</code> class
|
269
|
+
does everything related to parsing command options. Bad class design.
|
270
|
+
Therefore it is hard to customize or extend <code>OptionParser</code> class.
|
272
271
|
<p></p>
|
273
272
|
In contract, <code>benry/cmdopt.rb</code> consists of several classes
|
274
273
|
(schema class, parser class, and facade class).
|
275
274
|
Therefore it is easy to understand and extend these classes.
|
276
275
|
<p></p>
|
277
|
-
|
278
|
-
|
276
|
+
In fact, file <code>optparse.rb</code> and <code>optparse/*.rb</code> (in Ruby 3.2)
|
277
|
+
contains total 1298 lines (except comments and blanks), while
|
278
|
+
<code>benry/cmdopt.rb</code> (v2.0.0) contains only 429 lines (except both, too).</li>
|
279
279
|
</ul>
|
280
280
|
</section>
|
281
281
|
<section class="section" id="install">
|
@@ -289,75 +289,74 @@ $ gem install benry-cmdopt
|
|
289
289
|
<section class="subsection" id="define-parse-and-print-help">
|
290
290
|
<h3>Define, Parse, and Print Help</h3>
|
291
291
|
<pre class="language-ruby">
|
292
|
-
<strong>require
|
292
|
+
<strong>require 'benry/cmdopt'</strong>
|
293
293
|
|
294
294
|
## define
|
295
295
|
<strong>cmdopt = Benry::CmdOpt.new</strong>
|
296
|
-
cmdopt.add(:help ,
|
297
|
-
cmdopt.add(:version,
|
296
|
+
cmdopt.add(:help , '-h, --help' , "print help message")
|
297
|
+
cmdopt.add(:version, ' --version', "print version")
|
298
298
|
|
299
299
|
## parse with error handling
|
300
300
|
<strong>options = cmdopt.parse(ARGV)</strong> do |err|
|
301
|
-
|
302
|
-
exit(1)
|
301
|
+
abort "ERROR: #{err.message}"
|
303
302
|
end
|
304
303
|
p options # ex: {:help => true, :version => true}
|
305
304
|
p ARGV # options are removed from ARGV
|
306
305
|
|
307
306
|
## help
|
308
307
|
if options[:help]
|
309
|
-
puts
|
310
|
-
puts
|
311
|
-
puts
|
308
|
+
puts "Usage: foobar [<options>] [<args>...]"
|
309
|
+
puts ""
|
310
|
+
puts "Options:"
|
312
311
|
<strong>puts cmdopt.to_s()</strong>
|
313
312
|
## or: puts cmdopt.to_s(20) # width
|
314
|
-
## or: puts cmdopt.to_s(
|
313
|
+
## or: puts cmdopt.to_s(" %-20s : %s") # format
|
315
314
|
## or:
|
316
|
-
#format =
|
315
|
+
#format = " %-20s : %s"
|
317
316
|
#cmdopt.each_option_and_desc {|opt, help| puts format % [opt, help] }
|
318
317
|
end
|
319
318
|
</pre>
|
320
319
|
<p>You can set <code>nil</code> to option name only if long option specified.</p>
|
321
320
|
<pre class="language-ruby">
|
322
321
|
## both are same
|
323
|
-
cmdopt.add(:help,
|
324
|
-
cmdopt.add(<strong>nil</strong> ,
|
322
|
+
cmdopt.add(:help, "-h, --help", "print help message")
|
323
|
+
cmdopt.add(<strong>nil</strong> , "-h, --help", "print help message")
|
325
324
|
</pre>
|
326
325
|
</section>
|
327
326
|
<section class="subsection" id="command-option-parameter">
|
328
327
|
<h3>Command Option Parameter</h3>
|
329
328
|
<pre class="language-ruby">
|
330
329
|
## required parameter
|
331
|
-
cmdopt.add(:file,
|
332
|
-
cmdopt.add(:file,
|
333
|
-
cmdopt.add(:file,
|
330
|
+
cmdopt.add(:file, '-f, --file<strong>=<FILE></strong>', "filename") # short & long
|
331
|
+
cmdopt.add(:file, ' --file<strong>=<FILE></strong>', "filename") # long only
|
332
|
+
cmdopt.add(:file, '-f <strong><FILE></strong>' , "filename") # short only
|
334
333
|
|
335
334
|
## optional parameter
|
336
|
-
cmdopt.add(:indent,
|
337
|
-
cmdopt.add(:indent,
|
338
|
-
cmdopt.add(:indent,
|
335
|
+
cmdopt.add(:indent, '-i, --indent<strong>[=<N>]</strong>', "indent width") # short & long
|
336
|
+
cmdopt.add(:indent, ' --indent<strong>[=<N>]</strong>', "indent width") # long only
|
337
|
+
cmdopt.add(:indent, '-i<strong>[<N>]</strong>' , "indent width") # short only
|
339
338
|
</pre>
|
340
|
-
<p>Notice that <code
|
341
|
-
Use <code
|
339
|
+
<p>Notice that <code>"--file <FILE>"</code> style is <strong>not supported for usability reason</strong>.
|
340
|
+
Use <code>"--file=<FILE>"</code> style instead.</p>
|
342
341
|
<p>(From a usability perspective, the former style should not be supported.
|
343
342
|
<code>optparse.rb</code> is wrong because it supports both styles
|
344
|
-
and doesn
|
343
|
+
and doesn't provide the way to disable the former style.)</p>
|
345
344
|
</section>
|
346
345
|
<section class="subsection" id="argument-validation">
|
347
346
|
<h3>Argument Validation</h3>
|
348
347
|
<pre class="language-ruby">
|
349
348
|
## type (class)
|
350
|
-
cmdopt.add(:indent ,
|
349
|
+
cmdopt.add(:indent , '-i <N>', "indent width", <strong>type: Integer</strong>)
|
351
350
|
## pattern (regular expression)
|
352
|
-
cmdopt.add(:indent ,
|
351
|
+
cmdopt.add(:indent , '-i <N>', "indent width", <strong>rexp: /\A\d+\z/</strong>)
|
353
352
|
## enum (Array or Set)
|
354
|
-
cmdopt.add(:indent ,
|
353
|
+
cmdopt.add(:indent , '-i <N>', "indent width", <strong>enum: ["2", "4", "8"]</strong>)
|
355
354
|
## range (endless range such as ``1..`` available)
|
356
|
-
cmdopt.add(:indent ,
|
355
|
+
cmdopt.add(:indent , '-i <N>', "indent width", <strong>range: (0..8)</strong>)
|
357
356
|
## callback
|
358
|
-
cmdopt.add(:indent ,
|
357
|
+
cmdopt.add(:indent , '-i <N>', "indent width") <strong>{|val|</strong>
|
359
358
|
val =~ /\A\d+\z/ or
|
360
|
-
<strong>raise
|
359
|
+
<strong>raise "Integer expected."</strong> # raise without exception class.
|
361
360
|
<strong>val.to_i</strong> # convert argument value.
|
362
361
|
}
|
363
362
|
</pre>
|
@@ -370,7 +369,7 @@ cmdopt.add(:indent , '-i <N>', "indent width") <strong>
|
|
370
369
|
<li>TrueClass (<code>/\A(true|on|yes|false|off|no)\z/</code>)</li>
|
371
370
|
<li>Date (<code>/\A\d\d\d\d-\d\d?-\d\d?\z/</code>)</li>
|
372
371
|
</ul>
|
373
|
-
<p>Notice that Ruby doesn
|
372
|
+
<p>Notice that Ruby doesn't have Boolean class.
|
374
373
|
Benry-CmdOpt uses TrueClass instead.</p>
|
375
374
|
<p>In addition:</p>
|
376
375
|
<ul>
|
@@ -379,29 +378,29 @@ Benry-CmdOpt uses TrueClass instead.</p>
|
|
379
378
|
</ul>
|
380
379
|
<pre class="language-ruby">
|
381
380
|
## ok
|
382
|
-
cmdopt.add(:lang,
|
381
|
+
cmdopt.add(:lang, '-l <lang>', "language", <strong>enum: ["en", "fr", "it"]</strong>)
|
383
382
|
|
384
383
|
## error: enum values are not Integer
|
385
|
-
cmdopt.add(:lang,
|
384
|
+
cmdopt.add(:lang, '-l <lang>', "language", <strong>enum: ["en", "fr", "it"], type: Integer</strong>)
|
386
385
|
|
387
386
|
## ok
|
388
|
-
cmdopt.add(:indent,
|
387
|
+
cmdopt.add(:indent, '-i <N>', "indent", <strong>range: (0..), type: Integer</strong>)
|
389
388
|
|
390
389
|
## error: beginning value of range is not a String
|
391
|
-
cmdopt.add(:indent,
|
390
|
+
cmdopt.add(:indent, '-i <N>', "indent", <strong>range: (0..)</strong>)
|
392
391
|
</pre>
|
393
392
|
</section>
|
394
393
|
<section class="subsection" id="boolean-onoff-option">
|
395
394
|
<h3>Boolean (on/off) Option</h3>
|
396
|
-
<p>Benry-CmdOpt doens
|
395
|
+
<p>Benry-CmdOpt doens't support <code>--no-xxx</code> style option for usability reason.
|
397
396
|
Use boolean option instead.</p>
|
398
397
|
<p>ex3.rb:</p>
|
399
398
|
<pre class="language-ruby">
|
400
|
-
require
|
399
|
+
require 'benry/cmdopt'
|
401
400
|
cmdopt = Benry::CmdOpt.new()
|
402
|
-
cmdopt.add(:foo, <strong
|
401
|
+
cmdopt.add(:foo, <strong>"--foo[=on|off]"</strong>, "foo feature", <strong>type: TrueClass</strong>) # !!!!
|
403
402
|
## or:
|
404
|
-
#cmdopt.add(:foo, <strong
|
403
|
+
#cmdopt.add(:foo, <strong>"--foo=<on|off>"</strong>, "foo feature", <strong>type: TrueClass</strong>)
|
405
404
|
options = cmdopt.parse(ARGV)
|
406
405
|
p options
|
407
406
|
</pre>
|
@@ -419,24 +418,24 @@ $ ruby ex3.rb <strong>--foo=off</strong> # disable
|
|
419
418
|
<h3>Alternative Value</h3>
|
420
419
|
<p>Benry-CmdOpt supports alternative value.</p>
|
421
420
|
<pre class="language-ruby">
|
422
|
-
require
|
421
|
+
require 'benry/cmdopt'
|
423
422
|
cmdopt = Benry::CmdOpt.new
|
424
|
-
cmdopt.add(:help1,
|
425
|
-
cmdopt.add(:help2,
|
423
|
+
cmdopt.add(:help1, "-h", "help")
|
424
|
+
cmdopt.add(:help2, "-H", "help", <strong>value: "HELP"</strong>) # !!!!!
|
426
425
|
|
427
|
-
options = cmdopt.parse([
|
426
|
+
options = cmdopt.parse(["-h", "-H"])
|
428
427
|
p options[:help1] #=> true # normal
|
429
|
-
p options[:help2] #=> <strong
|
428
|
+
p options[:help2] #=> <strong>"HELP"</strong> # alternative value
|
430
429
|
</pre>
|
431
430
|
<p>This is useful for boolean option.</p>
|
432
431
|
<pre class="language-ruby">
|
433
|
-
require
|
432
|
+
require 'benry/cmdopt'
|
434
433
|
cmdopt = Benry::CmdOpt.new
|
435
|
-
cmdopt.add(:flag1,
|
436
|
-
cmdopt.add(:flag2,
|
434
|
+
cmdopt.add(:flag1, "--flag1[=<on|off>]", "f1", type: TrueClass)
|
435
|
+
cmdopt.add(:flag2, "--flag2[=<on|off>]", "f2", type: TrueClass, <strong>value: false</strong>) # !!!!
|
437
436
|
|
438
437
|
## when `--flag2` specified, got `false` value.
|
439
|
-
options = cmdopt.parse([
|
438
|
+
options = cmdopt.parse(["--flag1", "--flag2"])
|
440
439
|
p options[:flag1] #=> true
|
441
440
|
p options[:flag2] #=> <strong>false</strong> (!!!!!)
|
442
441
|
</pre>
|
@@ -444,10 +443,10 @@ p options[:flag2] #=> <strong>false</strong> (!!!!!)
|
|
444
443
|
<section class="subsection" id="multiple-value-option">
|
445
444
|
<h3>Multiple Value Option</h3>
|
446
445
|
<pre class="language-ruby">
|
447
|
-
require
|
446
|
+
require 'benry/cmdopt'
|
448
447
|
cmdopt = Benry::CmdOpt.new
|
449
448
|
|
450
|
-
cmdopt.add(:lib ,
|
449
|
+
cmdopt.add(:lib , '-I <NAME>', "library name") <strong>{|options, key, val|</strong>
|
451
450
|
<strong>arr = options[key] || []</strong>
|
452
451
|
<strong>arr << val</strong>
|
453
452
|
<strong>arr</strong>
|
@@ -455,8 +454,8 @@ cmdopt.add(:lib , '-I <NAME>', "library name") <strong>
|
|
455
454
|
#(options[key] || []) << val
|
456
455
|
<strong>}</strong>
|
457
456
|
|
458
|
-
options = cmdopt.parse([
|
459
|
-
p options #=> <strong>{:lib=>[
|
457
|
+
options = cmdopt.parse(["-I", "foo", "-I", "bar", "-Ibaz"])
|
458
|
+
p options #=> <strong>{:lib=>["foo", "bar", "baz"]}</strong>
|
460
459
|
</pre>
|
461
460
|
</section>
|
462
461
|
<section class="subsection" id="hidden-option">
|
@@ -469,14 +468,14 @@ p options #=> <strong>{:lib=>["foo", "bar", "ba
|
|
469
468
|
<p>The former is better than the latter, because even hidden option should have its own description.</p>
|
470
469
|
<p>These hidden options are not included in help message.</p>
|
471
470
|
<pre class="language-ruby">
|
472
|
-
require
|
471
|
+
require 'benry/cmdopt'
|
473
472
|
cmdopt = Benry::CmdOpt.new
|
474
|
-
cmdopt.add(:help ,
|
475
|
-
cmdopt.add(:debug,
|
476
|
-
cmdopt.add(<strong>:_log</strong> ,
|
473
|
+
cmdopt.add(:help , '-h', "help message")
|
474
|
+
cmdopt.add(:debug, '-D', <strong>nil</strong>) # hidden (because description is nil)
|
475
|
+
cmdopt.add(<strong>:_log</strong> , '-L', "logging") # hidden (because key starts with '_')
|
477
476
|
puts cmdopt.to_s()
|
478
477
|
|
479
|
-
### output (neither
|
478
|
+
### output (neither '-D' nor '-L' is shown because hidden options)
|
480
479
|
# -h : help message
|
481
480
|
</pre>
|
482
481
|
<p>To show all options including hidden ones, add <code>all: true</code> to <code>cmdopt.to_s()</code>.</p>
|
@@ -498,62 +497,62 @@ puts cmdopt.to_s(<strong>all: true</strong>) # or: cmdopt.to_s(nil, all: true)
|
|
498
497
|
<li><code>parse(argv, all: false)</code> only parses options placed before arguments.</li>
|
499
498
|
</ul>
|
500
499
|
<pre class="language-ruby">
|
501
|
-
require
|
500
|
+
require 'benry/cmdopt'
|
502
501
|
cmdopt = Benry::CmdOpt.new()
|
503
|
-
cmdopt.add(:help ,
|
504
|
-
cmdopt.add(:version,
|
502
|
+
cmdopt.add(:help , '--help' , "print help message")
|
503
|
+
cmdopt.add(:version, '--version', "print version")
|
505
504
|
|
506
505
|
## `parse(argv, all: true)` (default)
|
507
|
-
argv = [
|
506
|
+
argv = ["--help", "arg1", "--version", "arg2"]
|
508
507
|
options = cmdopt.parse(argv, <strong>all: true</strong>) # !!!
|
509
508
|
p options #=> {:help=>true, <strong>:version=>true</strong>}
|
510
|
-
p argv #=> [
|
509
|
+
p argv #=> ["arg1", "arg2"]
|
511
510
|
|
512
511
|
## `parse(argv, all: false)`
|
513
|
-
argv = [
|
512
|
+
argv = ["--help", "arg1", "--version", "arg2"]
|
514
513
|
options = cmdopt.parse(argv, <strong>all: false</strong>) # !!!
|
515
514
|
p options #=> {:help=>true}
|
516
|
-
p argv #=> [
|
515
|
+
p argv #=> ["arg1", <strong>"--version"</strong>, "arg2"]
|
517
516
|
</pre>
|
518
517
|
<p>This is useful when parsing global options of sub-commands, like Git command.</p>
|
519
518
|
<pre class="language-ruby">
|
520
|
-
require
|
519
|
+
require 'benry/cmdopt'
|
521
520
|
|
522
|
-
argv = [
|
521
|
+
argv = ["-h", "commit", "xxx", "-m", "yyy"]
|
523
522
|
|
524
523
|
## parse global options
|
525
524
|
cmdopt = Benry::CmdOpt.new()
|
526
|
-
cmdopt.add(:help,
|
525
|
+
cmdopt.add(:help, '-h', "print help message")
|
527
526
|
global_opts = cmdopt.parse(argv, <strong>all: false</strong>) # !!!false!!!
|
528
527
|
p global_opts #=> {:help=>true}
|
529
|
-
p argv #=> [
|
528
|
+
p argv #=> ["commit", "xxx", "-m", "yyy"]
|
530
529
|
|
531
530
|
## get sub-command
|
532
531
|
sub_command = argv.shift()
|
533
|
-
p sub_command #=>
|
534
|
-
p argv #=> [
|
532
|
+
p sub_command #=> "commit"
|
533
|
+
p argv #=> ["xxx", <strong>"-m"</strong>, "yyy"]
|
535
534
|
|
536
535
|
## parse sub-command options
|
537
536
|
cmdopt = Benry::CmdOpt.new()
|
538
537
|
case sub_command
|
539
|
-
when
|
540
|
-
cmdopt.add(:message,
|
538
|
+
when "commit"
|
539
|
+
cmdopt.add(:message, '-m <message>', "commit message")
|
541
540
|
else
|
542
541
|
# ...
|
543
542
|
end
|
544
543
|
sub_opts = cmdopt.parse(argv, <strong>all: true</strong>) # !!!true!!!
|
545
|
-
p sub_opts #=> {:message =>
|
546
|
-
p argv #=> [
|
544
|
+
p sub_opts #=> {:message => "yyy"}
|
545
|
+
p argv #=> ["xxx"]
|
547
546
|
</pre>
|
548
547
|
</section>
|
549
548
|
<section class="subsection" id="detailed-description-of-option">
|
550
549
|
<h3>Detailed Description of Option</h3>
|
551
550
|
<p><code>#add()</code> method in <code>Benry::CmdOpt</code> or <code>Benry::CmdOpt::Schema</code> supports <code>detail:</code> keyword argument which takes detailed description of option.</p>
|
552
551
|
<pre class="language-ruby">
|
553
|
-
require
|
552
|
+
require 'benry/cmdopt'
|
554
553
|
|
555
554
|
cmdopt = Benry::CmdOpt.new()
|
556
|
-
cmdopt.add(:mode,
|
555
|
+
cmdopt.add(:mode, "-m, --mode=<MODE>", "output mode", <strong>detail: <<"END"</strong>)
|
557
556
|
v, verbose: print many output
|
558
557
|
q, quiet: print litte output
|
559
558
|
c, compact: print summary output
|
@@ -561,8 +560,8 @@ cmdopt.add(:mode, "-m, --mode=<MODE>", "output mode", <
|
|
561
560
|
puts cmdopt.to_s()
|
562
561
|
## or:
|
563
562
|
#cmdopt.each_option_and_desc do |optstr, desc, detail|
|
564
|
-
# puts
|
565
|
-
# puts detail.gsub(/^/,
|
563
|
+
# puts " %-20s : %s\n" % [optstr, desc]
|
564
|
+
# puts detail.gsub(/^/, ' ' * 25) if detail
|
566
565
|
#end
|
567
566
|
</pre>
|
568
567
|
<p>Output:</p>
|
@@ -578,17 +577,17 @@ puts cmdopt.to_s()
|
|
578
577
|
<p><code>#add()</code> method in <code>Benry::CmdOpt</code> or <code>Benry::CmdOpt::Schema</code> supports <code>tag:</code> keyword argument.
|
579
578
|
You can use it for any purpose.</p>
|
580
579
|
<pre class="language-ruby">
|
581
|
-
require
|
580
|
+
require 'benry/cmdopt'
|
582
581
|
|
583
582
|
cmdopt = Benry::CmdOpt.new()
|
584
|
-
cmdopt.add(:help,
|
585
|
-
cmdopt.add(:version,
|
583
|
+
cmdopt.add(:help, "-h, --help", "help message", <strong>tag: "important"</strong>) # !!!
|
584
|
+
cmdopt.add(:version, "--version", "print version", <strong>tag: nil</strong>)
|
586
585
|
cmdopt.schema.each do |item|
|
587
|
-
puts
|
586
|
+
puts "#{item.key}: tag=#{item.tag.inspect}"
|
588
587
|
end
|
589
588
|
|
590
589
|
## output:
|
591
|
-
#help: <strong>tag
|
590
|
+
#help: <strong>tag="important"</strong>
|
592
591
|
#version: <strong>tag=nil</strong>
|
593
592
|
</pre>
|
594
593
|
</section>
|
@@ -610,30 +609,29 @@ end
|
|
610
609
|
<li><code>Benry::CmdOpt::Facade</code> ... facade object including schema and parser.</li>
|
611
610
|
</ul>
|
612
611
|
<pre class="language-ruby">
|
613
|
-
require
|
612
|
+
require 'benry/cmdopt'
|
614
613
|
|
615
614
|
## define schema
|
616
615
|
<strong>schema = Benry::CmdOpt::Schema.new</strong>
|
617
|
-
schema.add(:help ,
|
618
|
-
schema.add(:file ,
|
619
|
-
schema.add(:indent,
|
616
|
+
schema.add(:help , '-h, --help' , "show help message")
|
617
|
+
schema.add(:file , '-f, --file=<FILE>' , "filename")
|
618
|
+
schema.add(:indent, '-i, --indent[=<WIDTH>]', "enable indent", type: Integer)
|
620
619
|
|
621
620
|
## parse options
|
622
621
|
<strong>parser = Benry::CmdOpt::Parser.new(schema)</strong>
|
623
|
-
argv = [
|
622
|
+
argv = ['-hi2', '--file=blabla.txt', 'aaa', 'bbb']
|
624
623
|
opts = parser.parse(argv) do |err|
|
625
|
-
|
626
|
-
exit 1
|
624
|
+
abort "ERROR: #{err.message}"
|
627
625
|
end
|
628
|
-
p opts #=> {:help=>true, :indent=>2, :file=>
|
629
|
-
p argv #=> [
|
626
|
+
p opts #=> {:help=>true, :indent=>2, :file=>"blabla.txt"}
|
627
|
+
p argv #=> ["aaa", "bbb"]
|
630
628
|
</pre>
|
631
629
|
<p>Notice that <code>Benry::CmdOpt.new()</code> returns a facade object.</p>
|
632
630
|
<pre class="language-ruby">
|
633
|
-
require
|
631
|
+
require 'benry/cmdopt'
|
634
632
|
|
635
633
|
<strong>cmdopt = Benry::CmdOpt.new() # new facade object</strong>
|
636
|
-
<strong>cmdopt.add</strong>(:help,
|
634
|
+
<strong>cmdopt.add</strong>(:help, '-h', "help message") # same as <strong>schema.add</strong>(...)
|
637
635
|
opts = <strong>cmdopt.parse</strong>(ARGV) # same as <strong>parser.parse</strong>(...)
|
638
636
|
</pre>
|
639
637
|
<p>Notice that <code>cmdopt.is_a?(Benry::CmdOpt)</code> results in false.
|
data/doc/css/style.css
CHANGED
@@ -40,6 +40,10 @@ h3 {
|
|
40
40
|
font-size: 180%;
|
41
41
|
font-weight: normal;
|
42
42
|
}
|
43
|
+
h2 > code, h3 > code {
|
44
|
+
color: #39c;
|
45
|
+
font-weight: bold;
|
46
|
+
}
|
43
47
|
|
44
48
|
|
45
49
|
section.section {
|
@@ -85,6 +89,10 @@ code {
|
|
85
89
|
padding: 1px 3px;
|
86
90
|
color: #444;
|
87
91
|
}
|
92
|
+
h2 > code, h3 > code {
|
93
|
+
border: none;
|
94
|
+
background-color: transparent;
|
95
|
+
}
|
88
96
|
|
89
97
|
|
90
98
|
dt.bold {
|
data/lib/benry/cmdopt.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
###
|
5
|
-
### $Release: 2.0.
|
5
|
+
### $Release: 2.0.1 $
|
6
6
|
### $Copyright: copyright(c) 2021 kwatch@gmail.com $
|
7
7
|
### $License: MIT License $
|
8
8
|
###
|
@@ -23,7 +23,7 @@ end
|
|
23
23
|
module Benry::CmdOpt
|
24
24
|
|
25
25
|
|
26
|
-
VERSION = '$Release: 2.0.
|
26
|
+
VERSION = '$Release: 2.0.1 $'.split()[1]
|
27
27
|
|
28
28
|
|
29
29
|
def self.new()
|
data/task/common-task.rb
CHANGED
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: 2.0.
|
4
|
+
version: 2.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- kwatch
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-10-
|
11
|
+
date: 2023-10-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: oktest
|