benry-cmdopt 2.0.0 → 2.0.1
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 +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
|