benry-cmdapp 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CHANGES.md +8 -0
- data/MIT-LICENSE +21 -0
- data/README.md +2475 -0
- data/benry-cmdapp.gemspec +38 -0
- data/doc/benry-cmdapp.html +2314 -0
- data/doc/css/style.css +168 -0
- data/lib/benry/cmdapp.rb +1376 -0
- data/test/action_test.rb +1038 -0
- data/test/app_test.rb +1371 -0
- data/test/func_test.rb +137 -0
- data/test/help_test.rb +755 -0
- data/test/index_test.rb +185 -0
- data/test/run_all.rb +7 -0
- data/test/shared.rb +75 -0
- data/test/util_test.rb +189 -0
- metadata +98 -0
@@ -0,0 +1,2314 @@
|
|
1
|
+
<!doctype html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<meta charset="utf-8"/>
|
5
|
+
<meta name="viewport" content="width=device-width,initial-scale=1"/>
|
6
|
+
<meta name="description" content="">
|
7
|
+
<meta name="theme-color" content="#fafafa">
|
8
|
+
<meta property="og:title" content="">
|
9
|
+
<meta property="og:type" content="">
|
10
|
+
<meta property="og:url" content="">
|
11
|
+
<meta property="og:image" content="">
|
12
|
+
<title></title>
|
13
|
+
<link rel="stylesheet" href="lib/sanitize.css/2.0.0/sanitize.min.css">
|
14
|
+
<link rel="stylesheet" href="css/style.css">
|
15
|
+
</head>
|
16
|
+
<body>
|
17
|
+
<main>
|
18
|
+
<section class="chapter" id="benry-cmdapp">
|
19
|
+
<h1>Benry-CmdApp</h1>
|
20
|
+
<nav class="nav">
|
21
|
+
<ul class="nav">
|
22
|
+
</ul>
|
23
|
+
</nav>
|
24
|
+
<p>($Release: 0.1.0 $)</p>
|
25
|
+
<section class="section" id="whats-this">
|
26
|
+
<h2>What's This?</h2>
|
27
|
+
<p>Benry-CmdApp is a framework to create command-line application.
|
28
|
+
If you want create command-line application which takes sub-commands
|
29
|
+
like <code>git</code>, <code>docker</code>, or <code>npm</code>, Benry-CmdApp is the solution.</p>
|
30
|
+
<p>Base idea:</p>
|
31
|
+
<ul>
|
32
|
+
<li>Sub-command (= action) is defined as a method in Ruby.</li>
|
33
|
+
<li>Commnad-line arguments are passed to action method as positional arguments.</li>
|
34
|
+
<li>Command-line options are passed to action method as keyword arguments.</li>
|
35
|
+
</ul>
|
36
|
+
<p>For example:</p>
|
37
|
+
<ul>
|
38
|
+
<li><code><command> foo</code> in command-line invokes action method <code>foo()</code> in Ruby.</li>
|
39
|
+
<li><code><command> foo arg1 arg2</code> invokes <code>foo("arg1", "arg2")</code>.</li>
|
40
|
+
<li><code><command> foo arg --opt=val</code> invokes <code>foo("arg", opt: "val")</code>.</li>
|
41
|
+
</ul>
|
42
|
+
<p>Links:</p>
|
43
|
+
<ul>
|
44
|
+
<li>Document: <a href="https://kwatch.github.io/benry-ruby/benry-cmdapp.html">https://kwatch.github.io/benry-ruby/benry-cmdapp.html</a></li>
|
45
|
+
<li>GitHub: <a href="https://github.com/kwatch/benry-ruby/tree/main/benry-cmdapp">https://github.com/kwatch/benry-ruby/tree/main/benry-cmdapp</a></li>
|
46
|
+
<li>Changes: <a href="https://github.com/kwatch/benry-ruby/tree/main/benry-cmdapp/CHANGES.md">https://github.com/kwatch/benry-ruby/tree/main/benry-cmdapp/CHANGES.md</a></li>
|
47
|
+
</ul>
|
48
|
+
<p>Benry-CmdApp requires Ruby >= 2.3.</p>
|
49
|
+
<section class="subsection" id="table-of-contents">
|
50
|
+
<h3>Table of Contents</h3>
|
51
|
+
<div class="toc">
|
52
|
+
<ul>
|
53
|
+
<li><a href="#whats-this">What's This?</a></li>
|
54
|
+
<li><a href="#install">Install</a></li>
|
55
|
+
<li><a href="#usage">Usage</a>
|
56
|
+
<ul>
|
57
|
+
<li><a href="#action">Action</a></li>
|
58
|
+
<li><a href="#method-name-and-action-name">Method Name and Action Name</a></li>
|
59
|
+
<li><a href="#parameter-name-in-help-message-of-action">Parameter Name in Help Message of Action</a></li>
|
60
|
+
<li><a href="#options">Options</a></li>
|
61
|
+
<li><a href="#option-definition-format">Option Definition Format</a></li>
|
62
|
+
<li><a href="#option-value-validation">Option Value Validation</a></li>
|
63
|
+
<li><a href="#callback-for-option-value">Callback for Option Value</a></li>
|
64
|
+
<li><a href="#boolean-onoff-option">Boolean (On/Off) Option</a></li>
|
65
|
+
<li><a href="#prefix-of-action-name">Prefix of Action Name</a></li>
|
66
|
+
<li><a href="#invoke-other-action">Invoke Other Action</a></li>
|
67
|
+
<li><a href="#action-alias">Action Alias</a></li>
|
68
|
+
<li><a href="#default-action">Default Action</a></li>
|
69
|
+
<li><a href="#default-help">Default Help</a></li>
|
70
|
+
<li><a href="#private-hidden-action">Private (Hidden) Action</a></li>
|
71
|
+
<li><a href="#private-hidden-option">Private (Hidden) Option</a></li>
|
72
|
+
</ul></li>
|
73
|
+
<li><a href="#configuratoin-and-customization">Configuratoin and Customization</a>
|
74
|
+
<ul>
|
75
|
+
<li><a href="#application-configuration">Application Configuration</a></li>
|
76
|
+
<li><a href="#customization-of-global-options">Customization of Global Options</a></li>
|
77
|
+
<li><a href="#customization-of-global-option-behaviour">Customization of Global Option Behaviour</a></li>
|
78
|
+
<li><a href="#custom-hook-of-application">Custom Hook of Application</a></li>
|
79
|
+
<li><a href="#customization-of-command-help-message">Customization of Command Help Message</a></li>
|
80
|
+
<li><a href="#customization-of-action-help-message">Customization of Action Help Message</a></li>
|
81
|
+
</ul></li>
|
82
|
+
<li><a href="#q--a">Q & A</a>
|
83
|
+
<ul>
|
84
|
+
<li><a href="#q-how-to-append-some-tasks-to-existing-action">Q: How to Append Some Tasks to Existing Action?</a></li>
|
85
|
+
<li><a href="#q-how-to-re-define-existing-action">Q: How to Re-define Existing Action?</a></li>
|
86
|
+
<li><a href="#q-how-to-delete-existing-actionalias">Q: How to Delete Existing Action/Alias?</a></li>
|
87
|
+
<li><a href="#q-how-to-show-entering-into-or-exitting-from-action">Q: How to Show Entering Into or Exitting From Action?</a></li>
|
88
|
+
<li><a href="#q-how-to-enabledisable-color-mode">Q: How to Enable/Disable Color Mode?</a></li>
|
89
|
+
<li><a href="#q-how-to-define-multiple-option-like--i-option-of-ruby">Q: How to Define Multiple Option, like <code>-I</code> Option of Ruby?</a></li>
|
90
|
+
<li><a href="#q-how-to-specify-detailed-description-of-option">Q: How to Specify Detailed Description of Option?</a></li>
|
91
|
+
<li><a href="#q-how-to-copy-all-options-from-other-action">Q: How to Copy All Options from Other Action?</a></li>
|
92
|
+
<li><a href="#q-what-is-the-difference-between-prefixalias_of-and-prefixaction">Q: What is the Difference Between <code>prefix(alias_of:)</code> and <code>prefix(action:)</code>?</a></li>
|
93
|
+
<li><a href="#q-how-to-change-order-of-options-in-help-message">Q: How to Change Order of Options in Help Message?</a></li>
|
94
|
+
<li><a href="#q-is-it-possible-to-make-action-names-emphasised-or-weaken">Q: Is It Possible to Make Action Names Emphasised or Weaken?</a></li>
|
95
|
+
<li><a href="#q-is-it-possible-to-add-metadata-to-action-or-option">Q: Is It Possible to Add Metadata to Action or Option?</a></li>
|
96
|
+
<li><a href="#q-how-to-make-error-messages-i18ned">Q: How to Make Error Messages I18Ned?</a></li>
|
97
|
+
</ul></li>
|
98
|
+
<li><a href="#license-and-copyright">License and Copyright</a></li>
|
99
|
+
</ul>
|
100
|
+
</div>
|
101
|
+
</section>
|
102
|
+
</section>
|
103
|
+
<section class="section" id="install">
|
104
|
+
<h2>Install</h2>
|
105
|
+
<pre class="language-console">
|
106
|
+
$ gem install benry-cmdapp
|
107
|
+
</pre>
|
108
|
+
</section>
|
109
|
+
<section class="section" id="usage">
|
110
|
+
<h2>Usage</h2>
|
111
|
+
<section class="subsection" id="action">
|
112
|
+
<h3>Action</h3>
|
113
|
+
<ul>
|
114
|
+
<li>Inherit action class and define action methods in it.</li>
|
115
|
+
<li>An action class can have several action methods.</li>
|
116
|
+
<li>It is ok to define multiple action classes.</li>
|
117
|
+
<li>Command-line arguments are passed to action method as positional arguments.</li>
|
118
|
+
</ul>
|
119
|
+
<p>File: ex01.rb</p>
|
120
|
+
<pre class="language-ruby">
|
121
|
+
#!/usr/bin/env ruby
|
122
|
+
<strong>require 'benry/cmdapp'</strong>
|
123
|
+
|
124
|
+
## action
|
125
|
+
class MyAction < <strong>Benry::CmdApp::Action</strong> # !!!!
|
126
|
+
|
127
|
+
<strong>@action.("print greeting message")</strong> # !!!!
|
128
|
+
<strong>def hello(user="world")</strong> # !!!!
|
129
|
+
puts "Hello, #{user}!"
|
130
|
+
end
|
131
|
+
|
132
|
+
end
|
133
|
+
|
134
|
+
## configuration
|
135
|
+
config = <strong>Benry::CmdApp::Config.new("sample app", "1.0.0")</strong>
|
136
|
+
config.default_help = true
|
137
|
+
|
138
|
+
## run application
|
139
|
+
app = <strong>Benry::CmdApp::Application.new(config)</strong>
|
140
|
+
status_code = app.main()
|
141
|
+
exit status_code
|
142
|
+
</pre>
|
143
|
+
<p>Output:</p>
|
144
|
+
<pre class="language-console">
|
145
|
+
[bash]$ ruby ex01.rb <strong>hello</strong> # action
|
146
|
+
Hello, world!
|
147
|
+
|
148
|
+
[bash]$ ruby ex01.rb <strong>hello Alice</strong> # action + argument
|
149
|
+
Hello, <strong>Alice</strong>!
|
150
|
+
</pre>
|
151
|
+
<p>Help message of command:</p>
|
152
|
+
<pre class="language-console">
|
153
|
+
[bash]$ ruby ex01.rb <strong>-h</strong> # or `<strong>--help</strong>`
|
154
|
+
ex01.rb (1.0.0) -- sample app
|
155
|
+
|
156
|
+
Usage:
|
157
|
+
$ ex01.rb [<options>] [<action> [<arguments>...]]
|
158
|
+
|
159
|
+
Options:
|
160
|
+
-h, --help : print help message (of action if action specified)
|
161
|
+
-V, --version : print version
|
162
|
+
|
163
|
+
Actions:
|
164
|
+
hello : print greeting message
|
165
|
+
</pre>
|
166
|
+
<p>Help message of action:</p>
|
167
|
+
<pre class="language-console">
|
168
|
+
[bash]$ ruby ex01.rb <strong>-h hello</strong>
|
169
|
+
ex01.rb hello -- print greeting message
|
170
|
+
|
171
|
+
Usage:
|
172
|
+
$ ex01.rb hello [<user>]
|
173
|
+
</pre>
|
174
|
+
</section>
|
175
|
+
<section class="subsection" id="method-name-and-action-name">
|
176
|
+
<h3>Method Name and Action Name</h3>
|
177
|
+
<ul>
|
178
|
+
<li>Method name <code>print_</code> results in action name <code>print</code>.
|
179
|
+
This is useful to define actions which name is same as Ruby keyword or popular functions.</li>
|
180
|
+
<li>Method name <code>foo_bar_baz</code> results in action name <code>foo-bar-baz</code>.</li>
|
181
|
+
<li>Method name <code>foo__bar__baz</code> results in action name <code>foo:bar:baz</code>.</li>
|
182
|
+
</ul>
|
183
|
+
<p>File: ex02.rb</p>
|
184
|
+
<pre class="language-ruby">
|
185
|
+
#!/usr/bin/env ruby
|
186
|
+
require 'benry/cmdapp'
|
187
|
+
|
188
|
+
class SampleAction < Benry::CmdApp::Action
|
189
|
+
|
190
|
+
## 'print_' => 'print'
|
191
|
+
@action.("sample #1")
|
192
|
+
def print<strong>_</strong>() # !!!!
|
193
|
+
puts __method__
|
194
|
+
end
|
195
|
+
|
196
|
+
## 'foo_bar_baz' => 'foo-bar-baz'
|
197
|
+
@action.("sample #2")
|
198
|
+
def foo<strong>_</strong>bar<strong>_</strong>baz() # !!!!
|
199
|
+
puts __method__
|
200
|
+
end
|
201
|
+
|
202
|
+
## 'foo__bar__baz' => 'foo:bar:baz'
|
203
|
+
@action.("sample #3")
|
204
|
+
def foo<strong>__</strong>ba<strong>r__</strong>baz() # !!!!
|
205
|
+
puts __method__
|
206
|
+
end
|
207
|
+
|
208
|
+
end
|
209
|
+
|
210
|
+
config = Benry::CmdApp::Config.new("test app")
|
211
|
+
app = Benry::CmdApp::Application.new(config)
|
212
|
+
exit app.main()
|
213
|
+
</pre>
|
214
|
+
<p>Help message:</p>
|
215
|
+
<pre class="language-console">
|
216
|
+
[bash]$ ruby ex02.rb --help
|
217
|
+
ex02.rb -- test app
|
218
|
+
|
219
|
+
Usage:
|
220
|
+
$ ex02.rb [<options>] [<action> [<arguments>...]]
|
221
|
+
|
222
|
+
Options:
|
223
|
+
-h, --help : print help message (of action if action specified)
|
224
|
+
|
225
|
+
Actions:
|
226
|
+
<strong>foo-bar-baz</strong> : sample #2
|
227
|
+
<strong>foo:bar:baz</strong> : sample #3
|
228
|
+
<strong>print</strong> : sample #1
|
229
|
+
</pre>
|
230
|
+
<p>Output:</p>
|
231
|
+
<pre class="language-console">
|
232
|
+
[bash]$ ruby ex02.rb <strong>print</strong> # `print_` method
|
233
|
+
print_
|
234
|
+
|
235
|
+
[bash]$ ruby ex02.rb <strong>foo-bar-baz</strong> # `foo_bar_baz` method
|
236
|
+
foo_bar_baz
|
237
|
+
|
238
|
+
[bash]$ ruby ex02.rb <strong>foo:bar:baz</strong> # `foo__bar__baz` method
|
239
|
+
foo__bar__baz
|
240
|
+
</pre>
|
241
|
+
</section>
|
242
|
+
<section class="subsection" id="parameter-name-in-help-message-of-action">
|
243
|
+
<h3>Parameter Name in Help Message of Action</h3>
|
244
|
+
<p>In help message of action, positional parameters of action methods are printed under the name conversion rule.</p>
|
245
|
+
<ul>
|
246
|
+
<li>Parameter <code>foo</code> is printed as <code><foo></code>.</li>
|
247
|
+
<li>Parameter <code>foo_bar_baz</code> is printed as <code><foo-bar-baz></code>.</li>
|
248
|
+
<li>Parameter <code>foo_or_bar_or_baz</code> is printed as <code><foo|bar|baz></code>.</li>
|
249
|
+
</ul>
|
250
|
+
<p>In addition, positional parameters are printed in different way according to its kind.</p>
|
251
|
+
<ul>
|
252
|
+
<li>If parameter <code>foo</code> is required (= doesn't have default value), it will be printed as <code><foo></code>.</li>
|
253
|
+
<li>If parameter <code>foo</code> is optional (= has default value), it will be printed as <code>[<foo>]</code>.</li>
|
254
|
+
<li>If parameter <code>foo</code> is variable length (= <code>*foo</code> style), it will be printed as <code>[<foo>...]</code>.</li>
|
255
|
+
</ul>
|
256
|
+
<p>File: ex03.rb</p>
|
257
|
+
<pre class="language-ruby">
|
258
|
+
#!/usr/bin/env ruby
|
259
|
+
require 'benry/cmdapp'
|
260
|
+
|
261
|
+
class SampleAction < Benry::CmdApp::Action
|
262
|
+
|
263
|
+
@action.("parameter names test")
|
264
|
+
def test1(<strong>aaa, bbb_or_ccc, ddd=nil, eee=nil, *fff</strong>) # !!!!
|
265
|
+
# ...
|
266
|
+
end
|
267
|
+
|
268
|
+
end
|
269
|
+
|
270
|
+
config = Benry::CmdApp::Config.new("sample app")
|
271
|
+
app = Benry::CmdApp::Application.new(config)
|
272
|
+
exit app.main()
|
273
|
+
</pre>
|
274
|
+
<p>Help message:</p>
|
275
|
+
<pre class="language-console">
|
276
|
+
[bash]$ ruby ex03.rb -h test1
|
277
|
+
hoge.rb test1 -- parameter names test
|
278
|
+
|
279
|
+
Usage:
|
280
|
+
$ ex03.rb test1 <strong><aaa> <bbb|ccc> [<ddd> [<eee> [<fff>...]]]</strong> # !!!!
|
281
|
+
</pre>
|
282
|
+
</section>
|
283
|
+
<section class="subsection" id="options">
|
284
|
+
<h3>Options</h3>
|
285
|
+
<ul>
|
286
|
+
<li>Action can take command-line options.</li>
|
287
|
+
<li>Option values specified in command-line are passed to actio method as keyword arguments.</li>
|
288
|
+
</ul>
|
289
|
+
<p>File: ex04.rb</p>
|
290
|
+
<pre class="language-ruby">
|
291
|
+
#!/usr/bin/env ruby
|
292
|
+
require 'benry/cmdapp'
|
293
|
+
|
294
|
+
## action
|
295
|
+
class MyAction < Benry::CmdApp::Action
|
296
|
+
|
297
|
+
@action.("print greeting message")
|
298
|
+
<strong>@option.(:lang, "-l, --lang=<en|fr|it>", "language")</strong> # !!!!
|
299
|
+
def hello(user="world", <strong>lang: "en"</strong>) # !!!!
|
300
|
+
case lang
|
301
|
+
when "en" ; puts "Hello, #{user}!"
|
302
|
+
when "fr" ; puts "Bonjour, #{user}!"
|
303
|
+
when "it" ; puts "Ciao, #{user}!"
|
304
|
+
else
|
305
|
+
raise "#{lang}: unknown language."
|
306
|
+
end
|
307
|
+
end
|
308
|
+
|
309
|
+
end
|
310
|
+
|
311
|
+
## configuration
|
312
|
+
config = Benry::CmdApp::Config.new("sample app", "1.0.0")
|
313
|
+
config.default_help = true
|
314
|
+
|
315
|
+
## run application
|
316
|
+
app = Benry::CmdApp::Application.new(config)
|
317
|
+
status_code = app.main()
|
318
|
+
exit status_code
|
319
|
+
</pre>
|
320
|
+
<p>Output:</p>
|
321
|
+
<pre class="language-console">
|
322
|
+
[bash]$ ruby ex04.rb hello
|
323
|
+
<strong>Hello</strong>, world!
|
324
|
+
|
325
|
+
[bash]$ ruby ex04.rb hello <strong>-l fr</strong> # !!!!
|
326
|
+
<strong>Bonjour</strong>, world!
|
327
|
+
|
328
|
+
[bash]$ ruby ex04.rb hello <strong>--lang=it</strong> # !!!!
|
329
|
+
<strong>Ciao</strong>, world!
|
330
|
+
</pre>
|
331
|
+
<ul>
|
332
|
+
<li>An action can have multiple options.</li>
|
333
|
+
<li>Option format can have indentation spaces, for example <code>' --help'</code>.</li>
|
334
|
+
</ul>
|
335
|
+
<p>File: ex05.rb</p>
|
336
|
+
<pre class="language-ruby">
|
337
|
+
#!/usr/bin/env ruby
|
338
|
+
require 'benry/cmdapp'
|
339
|
+
|
340
|
+
## action
|
341
|
+
class MyAction < Benry::CmdApp::Action
|
342
|
+
|
343
|
+
@action.("print greeting message")
|
344
|
+
@option.(:lang , "-l, --lang=<en|fr|it>", "language")
|
345
|
+
<strong>@option.(:repeat, " --repeat=<N>", "repeat <N> times")</strong> # !!!!
|
346
|
+
def hello(user="world", lang: "en", <strong>repeat: "1"</strong>)
|
347
|
+
#p repeat.class #=> String # !!!!
|
348
|
+
repeat.to_i.times do # !!!!
|
349
|
+
case lang
|
350
|
+
when "en" ; puts "Hello, #{user}!"
|
351
|
+
when "fr" ; puts "Bonjour, #{user}!"
|
352
|
+
when "it" ; puts "Ciao, #{user}!"
|
353
|
+
else
|
354
|
+
raise "#{lang}: unknown language."
|
355
|
+
end
|
356
|
+
end
|
357
|
+
end
|
358
|
+
|
359
|
+
end
|
360
|
+
|
361
|
+
## configuration
|
362
|
+
config = Benry::CmdApp::Config.new("sample app", "1.0.0")
|
363
|
+
config.default_help = true
|
364
|
+
|
365
|
+
## run application
|
366
|
+
app = Benry::CmdApp::Application.new(config)
|
367
|
+
status_code = app.main()
|
368
|
+
exit status_code
|
369
|
+
</pre>
|
370
|
+
<p>Output:</p>
|
371
|
+
<pre class="language-console">
|
372
|
+
[bash]$ ruby ex05.rb hello Alice -l fr <strong>--repeat=3</strong>
|
373
|
+
Bonjour, Alice!
|
374
|
+
Bonjour, Alice!
|
375
|
+
Bonjour, Alice!
|
376
|
+
`````
|
377
|
+
|
378
|
+
Help message:
|
379
|
+
|
380
|
+
```console
|
381
|
+
[bash]$ ruby ex05.rb -h hello
|
382
|
+
ex05.rb hello -- print greeting message
|
383
|
+
|
384
|
+
Usage:
|
385
|
+
$ ex05.rb hello [<options>] [<user>]
|
386
|
+
|
387
|
+
Options:
|
388
|
+
-l, --lang=<en|fr|it> : language # !!!!
|
389
|
+
<strong> --repeat=<N> : repeat <N> times</strong> # !!!!
|
390
|
+
</pre>
|
391
|
+
<p>For usability reason, Benry::CmdApp supports <code>--lang=<val></code> style long option
|
392
|
+
and doesn't support <code>--lang <val></code> style option.
|
393
|
+
Benry::CmdApp regards <code>--lang <val></code> as 'long option without argument'
|
394
|
+
and 'argument for command'.</p>
|
395
|
+
<pre class="language-console">
|
396
|
+
[bash]$ ruby ex05.rb hello <strong>--lang fr</strong> # ``--lang fr`` != ``--lang=fr``
|
397
|
+
<strong>[ERROR] --lang: argument required.</strong>
|
398
|
+
</pre>
|
399
|
+
</section>
|
400
|
+
<section class="subsection" id="option-definition-format">
|
401
|
+
<h3>Option Definition Format</h3>
|
402
|
+
<p>Option definition format should be one of:</p>
|
403
|
+
<ul>
|
404
|
+
<li>(short option) <code>-q</code> : no values.</li>
|
405
|
+
<li>(short option) <code>-f <file></code> : value required.</li>
|
406
|
+
<li>(short option) <code>-i[<width>]</code> : value is optional.</li>
|
407
|
+
<li>(long option) <code>--quiet</code> : no values.</li>
|
408
|
+
<li>(long option) <code>--file=<file></code> : value required.</li>
|
409
|
+
<li>(long option) <code>--indent[=<width>]</code> : value is optional.</li>
|
410
|
+
<li>(short & long) <code>-q, --quiet</code> : no values.</li>
|
411
|
+
<li>(short & long) <code>-f, --file=<file></code> : value required.</li>
|
412
|
+
<li>(short & long) <code>-i, --indent[=<width>]</code> : value is optional.</li>
|
413
|
+
</ul>
|
414
|
+
<p>File: ex06.rb</p>
|
415
|
+
<pre class="language-ruby">
|
416
|
+
#!/usr/bin/env ruby
|
417
|
+
require 'benry/cmdapp'
|
418
|
+
|
419
|
+
class SampleAction < Benry::CmdApp::Action
|
420
|
+
|
421
|
+
## short options
|
422
|
+
@action.("short options")
|
423
|
+
@option.(:quiet , <strong>"-q"</strong> , "quiet mode") # none
|
424
|
+
@option.(:file , <strong>"-f <file>"</strong> , "filename") # required
|
425
|
+
@option.(:indent , <strong>"-i[<N>]"</strong> , "indent width") # optional
|
426
|
+
def test1(quiet: false, file: nil, indent: nil)
|
427
|
+
puts "quiet=#{quiet.inspect}, file=#{file.inspect}, indent=#{indent.inspect}"
|
428
|
+
end
|
429
|
+
|
430
|
+
## long options
|
431
|
+
@action.("long options")
|
432
|
+
@option.(:quiet , <strong>"--quiet"</strong> , "quiet mode") # none
|
433
|
+
@option.(:file , <strong>"--file=<file>"</strong> , "filename") # required
|
434
|
+
@option.(:indent , <strong>"--indent[=<N>]"</strong> , "indent width") # optional
|
435
|
+
def test2(quiet: false, file: nil, indent: nil)
|
436
|
+
puts "quiet=#{quiet.inspect}, file=#{file.inspect}, indent=#{indent.inspect}"
|
437
|
+
end
|
438
|
+
|
439
|
+
## short and long options
|
440
|
+
@action.("short and long options")
|
441
|
+
@option.(:quiet , <strong>"-q, --quiet"</strong> , "quiet mode") # none
|
442
|
+
@option.(:file , <strong>"-f, --file=<file>"</strong> , "filename") # required
|
443
|
+
@option.(:indent , <strong>"-i, --indent[=<N>]"</strong> , "indent width") # optional
|
444
|
+
def test3(quiet: false, file: nil, indent: nil)
|
445
|
+
puts "quiet=#{quiet.inspect}, file=#{file.inspect}, indent=#{indent.inspect}"
|
446
|
+
end
|
447
|
+
|
448
|
+
end
|
449
|
+
|
450
|
+
config = Benry::CmdApp::Config.new("test app")
|
451
|
+
app = Benry::CmdApp::Application.new(config)
|
452
|
+
exit app.main()
|
453
|
+
</pre>
|
454
|
+
<p>Output:</p>
|
455
|
+
<pre class="language-console">
|
456
|
+
[bash]$ ruby ex06.rb test1 <strong>-q -f readme.txt -i4</strong>
|
457
|
+
quiet=true, file="readme.txt", indent="4"
|
458
|
+
|
459
|
+
[bash]$ ruby ex06.rb test2 <strong>--quiet --file=readme.txt --indent=4</strong>
|
460
|
+
quiet=true, file="readme.txt", indent="4"
|
461
|
+
|
462
|
+
[bash]$ ruby ex06.rb test3 <strong>-q -f readme.txt -i4</strong>
|
463
|
+
quiet=true, file="readme.txt", indent="4"
|
464
|
+
[bash]$ ruby ex06.rb test3 <strong>--quiet --file=readme.txt --indent=4</strong>
|
465
|
+
quiet=true, file="readme.txt", indent="4"
|
466
|
+
</pre>
|
467
|
+
<p>Optional argument example:</p>
|
468
|
+
<pre class="language-console">
|
469
|
+
[bash]$ ruby ex06.rb test1 <strong>-i</strong> # ``-i`` results in ``true``
|
470
|
+
quiet=false, file=nil, <strong>indent=true</strong>
|
471
|
+
[bash]$ ruby ex06.rb test1 <strong>-i4</strong> # ``-i4`` results in ``4``
|
472
|
+
quiet=false, file=nil, <strong>indent="4"</strong>
|
473
|
+
|
474
|
+
[bash]$ ruby ex06.rb test2 <strong>--indent</strong> # ``--indent`` results in ``true``
|
475
|
+
quiet=false, file=nil, <strong>indent=true</strong>
|
476
|
+
[bash]$ ruby ex06.rb test2 <strong>--indent=4</strong> # ``--indent=4`` results in ``4``
|
477
|
+
quiet=false, file=nil, <strong>indent="4"</strong>
|
478
|
+
</pre>
|
479
|
+
<p>Help message:</p>
|
480
|
+
<pre class="language-ruby">
|
481
|
+
[bash]$ ruby ex06.rb -h test1
|
482
|
+
ex06.rb test1 -- short options
|
483
|
+
|
484
|
+
Usage:
|
485
|
+
$ ex06.rb test1 [<options>]
|
486
|
+
|
487
|
+
Options:
|
488
|
+
<strong>-q</strong> : quiet mode
|
489
|
+
<strong>-f <file></strong> : filename
|
490
|
+
<strong>-i[<N>]</strong> : indent width
|
491
|
+
|
492
|
+
[bash]$ ruby ex06.rb -h test2
|
493
|
+
ex06.rb test2 -- long options
|
494
|
+
|
495
|
+
Usage:
|
496
|
+
$ ex06.rb test2 [<options>]
|
497
|
+
|
498
|
+
Options:
|
499
|
+
<strong>--quiet</strong> : quiet mode
|
500
|
+
<strong>--file=<file></strong> : filename
|
501
|
+
<strong>--indent[=<N>]</strong> : indent width
|
502
|
+
|
503
|
+
[bash]$ ruby ex06.rb -h test3
|
504
|
+
ex06.rb test3 -- short and long options
|
505
|
+
|
506
|
+
Usage:
|
507
|
+
$ ex06.rb test3 [<options>]
|
508
|
+
|
509
|
+
Options:
|
510
|
+
<strong>-q, --quiet</strong> : quiet mode
|
511
|
+
<strong>-f, --file=<file></strong> : filename
|
512
|
+
<strong>-i, --indent[=<N>]</strong> : indent width
|
513
|
+
</pre>
|
514
|
+
</section>
|
515
|
+
<section class="subsection" id="option-value-validation">
|
516
|
+
<h3>Option Value Validation</h3>
|
517
|
+
<p><code>@option.()</code> can validate option value via keyword argument.</p>
|
518
|
+
<ul>
|
519
|
+
<li><code>type: <class></code> specifies option value class.
|
520
|
+
Currently supports <code>Integer</code>, <code>Float</code>, <code>TrueClass</code>, and <code>Date</code>.</li>
|
521
|
+
<li><code>rexp: <rexp></code> specifies regular expression of option value.</li>
|
522
|
+
<li><code>enum: <array></code> specifies available values as option value.</li>
|
523
|
+
<li><code>range: <range></code> specifies range of option value.</li>
|
524
|
+
</ul>
|
525
|
+
<p>File: ex07.rb</p>
|
526
|
+
<pre class="language-ruby">
|
527
|
+
#!/usr/bin/env ruby
|
528
|
+
require 'benry/cmdapp'
|
529
|
+
|
530
|
+
## action
|
531
|
+
class MyAction < Benry::CmdApp::Action
|
532
|
+
|
533
|
+
@action.("print greeting message")
|
534
|
+
@option.(:lang , "-l, --lang=<en|fr|it>", "language",
|
535
|
+
<strong>enum: ["en", "fr", "it"]</strong>, # !!!!
|
536
|
+
<strong>rexp: /\A\w\w\z/</strong>) # !!!!
|
537
|
+
@option.(:repeat, " --repeat=<N>", "repeat <N> times",
|
538
|
+
<strong>type: Integer, range: 1..10</strong>) # !!!!
|
539
|
+
def hello(user="world", lang: "en", repeat: 1)
|
540
|
+
#p repeat.class #=> Integer
|
541
|
+
repeat.times do
|
542
|
+
case lang
|
543
|
+
when "en" ; puts "Hello, #{user}!"
|
544
|
+
when "fr" ; puts "Bonjour, #{user}!"
|
545
|
+
when "it" ; puts "Ciao, #{user}!"
|
546
|
+
else
|
547
|
+
raise "#{lang}: unknown language."
|
548
|
+
end
|
549
|
+
end
|
550
|
+
end
|
551
|
+
|
552
|
+
end
|
553
|
+
|
554
|
+
## configuration
|
555
|
+
config = Benry::CmdApp::Config.new("sample app", "1.0.0")
|
556
|
+
config.default_help = true
|
557
|
+
|
558
|
+
## run application
|
559
|
+
app = Benry::CmdApp::Application.new(config)
|
560
|
+
status_code = app.main()
|
561
|
+
exit status_code
|
562
|
+
</pre>
|
563
|
+
<p>Output:</p>
|
564
|
+
<pre class="language-console">
|
565
|
+
[bash]$ ruby ex07.rb hello <strong>-l japan</strong>
|
566
|
+
<strong>[ERROR] -l japan: pattern unmatched.</strong>
|
567
|
+
|
568
|
+
[bash]$ ruby ex07.rb hello <strong>-l ja</strong>
|
569
|
+
<strong>[ERROR] -l ja: expected one of en/fr/it.</strong>
|
570
|
+
|
571
|
+
[bash]$ ruby ex07.rb hello <strong>--repeat=abc</strong>
|
572
|
+
<strong>[ERROR] --repeat=abc: integer expected.</strong>
|
573
|
+
|
574
|
+
[bash]$ ruby ex07.rb hello <strong>--repeat=100</strong>
|
575
|
+
<strong>[ERROR] --repeat=100: Too large (max: 10).</strong>
|
576
|
+
</pre>
|
577
|
+
</section>
|
578
|
+
<section class="subsection" id="callback-for-option-value">
|
579
|
+
<h3>Callback for Option Value</h3>
|
580
|
+
<p><code>@option.()</code> can take a block argument which is a callback for option value.
|
581
|
+
Callback can:</p>
|
582
|
+
<ul>
|
583
|
+
<li>Do custom validation of option value.</li>
|
584
|
+
<li>Convert option value into other value.</li>
|
585
|
+
</ul>
|
586
|
+
<p>File: ex08.rb</p>
|
587
|
+
<pre class="language-ruby">
|
588
|
+
#!/usr/bin/env ruby
|
589
|
+
require 'benry/cmdapp'
|
590
|
+
|
591
|
+
## action
|
592
|
+
class MyAction < Benry::CmdApp::Action
|
593
|
+
|
594
|
+
@action.("print greeting message")
|
595
|
+
@option.(:lang , "-l, --lang=<en|fr|it>", "language",
|
596
|
+
enum: ["en", "fr", "it", "EN", "FR", "IT"],
|
597
|
+
rexp: /\A\w\w\z/) <strong>{|v| v.downcase }</strong> # !!!!
|
598
|
+
@option.(:repeat, " --repeat=<N>", "repeat <N> times",
|
599
|
+
type: Integer) <strong>{|v|</strong> # !!!!
|
600
|
+
<strong>v > 0 or raise "not positive value."</strong> # !!!!
|
601
|
+
<strong>v</strong> # !!!!
|
602
|
+
<strong>}</strong> # !!!!
|
603
|
+
def hello(user="world", lang: "en", repeat: 1)
|
604
|
+
repeat.times do
|
605
|
+
case lang
|
606
|
+
when "en" ; puts "Hello, #{user}!"
|
607
|
+
when "fr" ; puts "Bonjour, #{user}!"
|
608
|
+
when "it" ; puts "Ciao, #{user}!"
|
609
|
+
else
|
610
|
+
raise "#{lang}: unknown language."
|
611
|
+
end
|
612
|
+
end
|
613
|
+
end
|
614
|
+
|
615
|
+
end
|
616
|
+
|
617
|
+
## configuration
|
618
|
+
config = Benry::CmdApp::Config.new("sample app", "1.0.0")
|
619
|
+
config.default_help = true
|
620
|
+
|
621
|
+
## run application
|
622
|
+
app = Benry::CmdApp::Application.new(config)
|
623
|
+
status_code = app.main()
|
624
|
+
exit status_code
|
625
|
+
</pre>
|
626
|
+
<p>Output:</p>
|
627
|
+
<pre class="language-console">
|
628
|
+
[bash]$ ruby ex08.rb hello <strong>-l FR</strong> # converted into lowercase
|
629
|
+
Bonjour, world!
|
630
|
+
|
631
|
+
[bash]$ ruby ex08.rb hello <strong>--repeat=0</strong>
|
632
|
+
<strong>[ERROR] --repeat=0: not positive value.</strong>
|
633
|
+
</pre>
|
634
|
+
</section>
|
635
|
+
<section class="subsection" id="boolean-onoff-option">
|
636
|
+
<h3>Boolean (On/Off) Option</h3>
|
637
|
+
<p>Benry::CmdApp doesn't support <code>--[no-]foobar</code> style option.
|
638
|
+
Instead, define boolean (on/off) option.</p>
|
639
|
+
<ul>
|
640
|
+
<li>Specify <code>type: TrueClass</code> to <code>@option.()</code>.</li>
|
641
|
+
<li>Option value <code>true</code>, <code>yes</code>, and <code>on</code> are converted into true.</li>
|
642
|
+
<li>Option value <code>false</code>, <code>no</code>, and <code>off</code> are converted into false.</li>
|
643
|
+
</ul>
|
644
|
+
<p>File: ex09.rb</p>
|
645
|
+
<pre class="language-ruby">
|
646
|
+
#!/usr/bin/env ruby
|
647
|
+
require 'benry/cmdapp'
|
648
|
+
|
649
|
+
class SampleAction < Benry::CmdApp::Action
|
650
|
+
|
651
|
+
@action.("flag test")
|
652
|
+
@option.(:verbose, <strong>"--verbose[=<on|off>]"</strong>, # !!!!
|
653
|
+
"verbose mode",
|
654
|
+
<strong>type: TrueClass</strong>) # !!!!
|
655
|
+
def flagtest(<strong>verbose: false</strong>) # !!!!
|
656
|
+
puts "verbose=#{verbose}"
|
657
|
+
end
|
658
|
+
|
659
|
+
end
|
660
|
+
|
661
|
+
config = Benry::CmdApp::Config.new("sample app", "1.0.0")
|
662
|
+
app = Benry::CmdApp::Application.new(config)
|
663
|
+
exit app.main()
|
664
|
+
</pre>
|
665
|
+
<p>Output:</p>
|
666
|
+
<pre class="language-console">
|
667
|
+
[bash]$ ruby ex09.rb flagtest --verbose=<strong>on</strong> # on
|
668
|
+
verbose=<strong>true</strong>
|
669
|
+
|
670
|
+
[bash]$ ruby ex09.rb flagtest --verbose=<strong>off</strong> # off
|
671
|
+
verbose=<strong>false</strong>
|
672
|
+
|
673
|
+
[bash]$ ruby ex09.rb flagtest --verbose=<strong>true</strong> # on
|
674
|
+
verbose=<strong>true</strong>
|
675
|
+
|
676
|
+
[bash]$ ruby ex09.rb flagtest --verbose=<strong>false</strong> # off
|
677
|
+
verbose=<strong>false</strong>
|
678
|
+
|
679
|
+
[bash]$ ruby ex09.rb flagtest --verbose=<strong>yes</strong> # on
|
680
|
+
verbose=<strong>true</strong>
|
681
|
+
|
682
|
+
[bash]$ ruby ex09.rb flagtest --verbose=<strong>no</strong> # off
|
683
|
+
verbose=<strong>false</strong>
|
684
|
+
|
685
|
+
[bash]$ ruby ex09.rb flagtest --verbose=<strong>abc</strong> # error
|
686
|
+
<strong>[ERROR] --verbose=abc: boolean expected.</strong>
|
687
|
+
</pre>
|
688
|
+
<p>If you want default value of flag to <code>true</code>, use <code>value:</code> keyword argument.</p>
|
689
|
+
<ul>
|
690
|
+
<li><code>value:</code> keyword argument in <code>@option.()</code> specifies the substitute value
|
691
|
+
instead of <code>true</code> when no option value specified in command-line.</li>
|
692
|
+
</ul>
|
693
|
+
<p>File: ex10.rb</p>
|
694
|
+
<pre class="language-ruby">
|
695
|
+
#!/usr/bin/env ruby
|
696
|
+
require 'benry/cmdapp'
|
697
|
+
|
698
|
+
class SampleAction < Benry::CmdApp::Action
|
699
|
+
|
700
|
+
@action.("flag test")
|
701
|
+
@option.(:verbose, "-q, --quiet", "quiet mode",
|
702
|
+
<strong>value: false</strong>) # !!!!
|
703
|
+
def flagtest2(<strong>verbose: true</strong>) # !!!!
|
704
|
+
puts "verbose=#{verbose.inspect}"
|
705
|
+
end
|
706
|
+
|
707
|
+
end
|
708
|
+
|
709
|
+
config = Benry::CmdApp::Config.new("git helper")
|
710
|
+
app = Benry::CmdApp::Application.new(config)
|
711
|
+
exit app.main()
|
712
|
+
</pre>
|
713
|
+
<p>Output:</p>
|
714
|
+
<pre class="language-console">
|
715
|
+
[bash]$ ruby ex10.rb flagtest2 # true if '--quiet' NOT specified
|
716
|
+
verbose=<strong>true</strong>
|
717
|
+
|
718
|
+
[bash]$ ruby ex10.rb flagtest2 <strong>--quiet</strong> # false if '--quiet' specified
|
719
|
+
verbose=<strong>false</strong>
|
720
|
+
|
721
|
+
[bash]$ ruby ex10.rb flagtest2 <strong>--quiet=on</strong> # error
|
722
|
+
<strong>[ERROR] --quiet=on: unexpected argument.</strong>
|
723
|
+
</pre>
|
724
|
+
<p>In above example, <code>--quiet=on</code> will be error because option is defined as
|
725
|
+
<code>@option.(:verbose, "-q, --quiet", ...)</code> which means that this option takes no arguments.
|
726
|
+
If you want to allow <code>--quiet=on</code>, specify option argument and <code>type: TrueClass</code>.</p>
|
727
|
+
<pre class="language-ruby">
|
728
|
+
...(snip)...
|
729
|
+
|
730
|
+
@action.("flag test")
|
731
|
+
@option.(:verbose, "-q, --quiet<strong>[=<on|off]</strong>", "quiet mode", # !!!!
|
732
|
+
<strong>type: TrueClass</strong>, value: false) # !!!!
|
733
|
+
def flagtest2(verbose: true)
|
734
|
+
puts "verbose=#{verbose.inspect}"
|
735
|
+
end
|
736
|
+
|
737
|
+
...(snip)...
|
738
|
+
</pre>
|
739
|
+
</section>
|
740
|
+
<section class="subsection" id="prefix-of-action-name">
|
741
|
+
<h3>Prefix of Action Name</h3>
|
742
|
+
<ul>
|
743
|
+
<li><code>prefix: "foo:bar"</code> in action class adds prefix <code>foo:bar:</code> to each action name.</li>
|
744
|
+
<li>Method name <code>def baz__test()</code> with <code>prefix: "foo:bar"</code> results in action name <code>foo:bar:baz:test</code>.</li>
|
745
|
+
</ul>
|
746
|
+
<p>File: ex11.rb</p>
|
747
|
+
<pre class="language-ruby">
|
748
|
+
#!/usr/bin/env ruby
|
749
|
+
require 'benry/cmdapp'
|
750
|
+
|
751
|
+
class SampleAction < Benry::CmdApp::Action
|
752
|
+
<strong>prefix "foo:bar"</strong> # !!!!
|
753
|
+
|
754
|
+
@action.("test action #1")
|
755
|
+
def <strong>test1</strong>() # action name: 'foo:bar:test1'
|
756
|
+
puts __method__
|
757
|
+
end
|
758
|
+
|
759
|
+
@action.("test action #2")
|
760
|
+
def <strong>baz__test2</strong>() # action name: 'foo:bar:baz:test2'
|
761
|
+
puts __method__
|
762
|
+
end
|
763
|
+
|
764
|
+
end
|
765
|
+
|
766
|
+
config = Benry::CmdApp::Config.new("sample app")
|
767
|
+
app = Benry::CmdApp::Application.new(config)
|
768
|
+
exit app.main()
|
769
|
+
</pre>
|
770
|
+
<p>Output:</p>
|
771
|
+
<pre class="language-console">
|
772
|
+
[bash]$ ruby ex11.rb <strong>foo:bar:test1</strong>
|
773
|
+
test1
|
774
|
+
|
775
|
+
[bash]$ ruby ex11.rb <strong>foo:bar:baz:test2</strong>
|
776
|
+
baz__test2
|
777
|
+
</pre>
|
778
|
+
<p>Help message:</p>
|
779
|
+
<pre class="language-console">
|
780
|
+
[bash]$ ruby ex11.rb -h
|
781
|
+
ex11.rb -- sample app
|
782
|
+
|
783
|
+
Usage:
|
784
|
+
$ ex11.rb [<options>] [<action> [<arguments>...]]
|
785
|
+
|
786
|
+
Options:
|
787
|
+
-h, --help : print help message (of action if action specified)
|
788
|
+
|
789
|
+
Actions:
|
790
|
+
<strong>foo:bar:baz:test2</strong> : test action #2
|
791
|
+
<strong>foo:bar:test1</strong> : test action #1
|
792
|
+
</pre>
|
793
|
+
<ul>
|
794
|
+
<li><code>prefix: "foo:bar", action: :test</code> defines <code>foo:bar</code> action (intead of <code>foo:bar:test</code>) with <code>test()</code> method.</li>
|
795
|
+
</ul>
|
796
|
+
<p>File: ex12.rb</p>
|
797
|
+
<pre class="language-ruby">
|
798
|
+
#!/usr/bin/env ruby
|
799
|
+
require 'benry/cmdapp'
|
800
|
+
|
801
|
+
class SampleAction < Benry::CmdApp::Action
|
802
|
+
prefix "foo:bar", <strong>action: :test3_</strong> # !!!!
|
803
|
+
## or:
|
804
|
+
#prefix "foo:bar", <strong>action: "test3"</strong> # !!!!
|
805
|
+
|
806
|
+
@action.("test action #1")
|
807
|
+
def test1() # action name: 'foo:bar:test1'
|
808
|
+
puts __method__
|
809
|
+
end
|
810
|
+
|
811
|
+
@action.("test action #3")
|
812
|
+
def <strong>test3_</strong>() # action name: 'foo:bar'
|
813
|
+
puts __method__
|
814
|
+
end
|
815
|
+
|
816
|
+
end
|
817
|
+
|
818
|
+
config = Benry::CmdApp::Config.new("sample app")
|
819
|
+
app = Benry::CmdApp::Application.new(config)
|
820
|
+
exit app.main()
|
821
|
+
</pre>
|
822
|
+
<p>Output:</p>
|
823
|
+
<pre class="language-console">
|
824
|
+
[bash]$ ruby ex12.rb foo:bar:test1
|
825
|
+
test1
|
826
|
+
|
827
|
+
[bash]$ ruby ex12.rb <strong>foo:bar:test3</strong>
|
828
|
+
[ERROR] foo:bar:test2: unknown action.
|
829
|
+
|
830
|
+
[bash]$ ruby ex12.rb <strong>foo:bar</strong>
|
831
|
+
test3_
|
832
|
+
</pre>
|
833
|
+
<p>Help message:</p>
|
834
|
+
<pre class="language-console">
|
835
|
+
[bash]$ ruby ex12.rb -h
|
836
|
+
ex12.rb -- sample app
|
837
|
+
|
838
|
+
Usage:
|
839
|
+
$ ex12.rb [<options>] [<action> [<arguments>...]]
|
840
|
+
|
841
|
+
Options:
|
842
|
+
-h, --help : print help message (of action if action specified)
|
843
|
+
|
844
|
+
Actions:
|
845
|
+
<strong>foo:bar</strong> : test action #3
|
846
|
+
foo:bar:test1 : test action #1
|
847
|
+
</pre>
|
848
|
+
</section>
|
849
|
+
<section class="subsection" id="invoke-other-action">
|
850
|
+
<h3>Invoke Other Action</h3>
|
851
|
+
<ul>
|
852
|
+
<li><code>run_action!()</code> invokes other action.</li>
|
853
|
+
<li><code>run_action_once()</code> invokes other action only once.
|
854
|
+
This is equivarent to 'prerequisite task' feature in task runner application.</li>
|
855
|
+
</ul>
|
856
|
+
<p>File: ex13.rb</p>
|
857
|
+
<pre class="language-ruby">
|
858
|
+
#!/usr/bin/env ruby
|
859
|
+
require 'benry/cmdapp'
|
860
|
+
|
861
|
+
class SampleAction < Benry::CmdApp::Action
|
862
|
+
|
863
|
+
@action.("create build dir")
|
864
|
+
def <strong>prepare</strong>()
|
865
|
+
puts <strong>"rm -rf build"</strong>
|
866
|
+
puts <strong>"mkdir build"</strong>
|
867
|
+
end
|
868
|
+
|
869
|
+
@action.("build something")
|
870
|
+
def build()
|
871
|
+
<strong>run_action_once("prepare")</strong> # !!!!
|
872
|
+
<strong>run_action_once("prepare")</strong> # skipped because already invoked
|
873
|
+
puts "echo 'README' > build/README.txt"
|
874
|
+
puts "zip -r build.zip build"
|
875
|
+
end
|
876
|
+
|
877
|
+
end
|
878
|
+
|
879
|
+
config = Benry::CmdApp::Config.new("sample app")
|
880
|
+
app = Benry::CmdApp::Application.new(config)
|
881
|
+
exit app.main()
|
882
|
+
</pre>
|
883
|
+
<p>Output:</p>
|
884
|
+
<pre class="language-console">
|
885
|
+
[bash]$ ruby ex13.rb build
|
886
|
+
<strong>rm -rf build</strong> # invoked only once!!!!
|
887
|
+
<strong>mkdir build</strong> # invoked only once!!!!
|
888
|
+
echo 'README' > build/README.txt
|
889
|
+
zip -r build.zip build
|
890
|
+
</pre>
|
891
|
+
<ul>
|
892
|
+
<li>When looped action is detected, Benry::CmdApp aborts action.</li>
|
893
|
+
</ul>
|
894
|
+
<p>File: ex14.rb</p>
|
895
|
+
<pre class="language-ruby">
|
896
|
+
#!/usr/bin/env ruby
|
897
|
+
require 'benry/cmdapp'
|
898
|
+
|
899
|
+
class LoopedAction < Benry::CmdApp::Action
|
900
|
+
|
901
|
+
@action.("test #1")
|
902
|
+
def test1()
|
903
|
+
run_action_once("test2")
|
904
|
+
end
|
905
|
+
|
906
|
+
@action.("test #2")
|
907
|
+
def test2()
|
908
|
+
run_action_once("test3")
|
909
|
+
end
|
910
|
+
|
911
|
+
@action.("test #3")
|
912
|
+
def test3()
|
913
|
+
<strong>run_action_once("test1")</strong> # !!!!
|
914
|
+
end
|
915
|
+
|
916
|
+
end
|
917
|
+
|
918
|
+
config = Benry::CmdApp::Config.new("sample app")
|
919
|
+
app = Benry::CmdApp::Application.new(config)
|
920
|
+
exit app.main()
|
921
|
+
</pre>
|
922
|
+
<p>Output:</p>
|
923
|
+
<pre class="language-console">
|
924
|
+
[bash]$ ruby ex14.rb test1
|
925
|
+
<strong>[ERROR] test1: looped action detected.</strong>
|
926
|
+
|
927
|
+
[bash]$ ruby ex14.rb test3
|
928
|
+
<strong>[ERROR] test3: looped action detected.</strong>
|
929
|
+
</pre>
|
930
|
+
</section>
|
931
|
+
<section class="subsection" id="action-alias">
|
932
|
+
<h3>Action Alias</h3>
|
933
|
+
<ul>
|
934
|
+
<li>Alias of action provides alternative short name of action.</li>
|
935
|
+
</ul>
|
936
|
+
<p>File: ex15.rb</p>
|
937
|
+
<pre class="language-ruby">
|
938
|
+
#!/usr/bin/env ruby
|
939
|
+
require 'benry/cmdapp'
|
940
|
+
|
941
|
+
class SampleAction < Benry::CmdApp::Action
|
942
|
+
<strong>prefix "foo:bar"</strong>
|
943
|
+
|
944
|
+
@action.("test action #1")
|
945
|
+
def <strong>test1</strong>() # action name: 'foo:bar:test1'
|
946
|
+
puts __method__
|
947
|
+
end
|
948
|
+
|
949
|
+
end
|
950
|
+
|
951
|
+
<strong>Benry::CmdApp.action_alias "test", "foo:bar:test1"</strong> # !!!!
|
952
|
+
|
953
|
+
config = Benry::CmdApp::Config.new("sample app")
|
954
|
+
app = Benry::CmdApp::Application.new(config)
|
955
|
+
exit app.main()
|
956
|
+
</pre>
|
957
|
+
<p>Output:</p>
|
958
|
+
<pre class="language-console">
|
959
|
+
[bash]$ ruby ex15.rb <strong>test</strong> # alias name
|
960
|
+
test1
|
961
|
+
|
962
|
+
[bash]$ ruby ex15.rb <strong>foo:bar:test1</strong> # original action name
|
963
|
+
test1
|
964
|
+
</pre>
|
965
|
+
<p>Help message:</p>
|
966
|
+
<pre class="language-console">
|
967
|
+
[bash]$ ruby ex15.rb -h
|
968
|
+
ex15.rb -- sample app
|
969
|
+
|
970
|
+
Usage:
|
971
|
+
$ ex15.rb [<options>] [<action> [<arguments>...]]
|
972
|
+
|
973
|
+
Options:
|
974
|
+
-h, --help : print help message (of action if action specified)
|
975
|
+
|
976
|
+
Actions:
|
977
|
+
foo:bar:test1 : test action #1
|
978
|
+
<strong>test : alias to 'foo:bar:test1' action</strong>
|
979
|
+
</pre>
|
980
|
+
<ul>
|
981
|
+
<li>Alias can include positional and keyword arguments in definition.</li>
|
982
|
+
</ul>
|
983
|
+
<p>File: ex16.rb</p>
|
984
|
+
<pre class="language-ruby">
|
985
|
+
#!/usr/bin/env ruby
|
986
|
+
require 'benry/cmdapp'
|
987
|
+
|
988
|
+
class MyAction < Benry::CmdApp::Action
|
989
|
+
|
990
|
+
@action.("print greeting message")
|
991
|
+
@option.(:lang, "-l, --lang=<lang>", "language", enum: ["en", "fr", "it"])
|
992
|
+
def hello(user="world", lang: "en")
|
993
|
+
case lang
|
994
|
+
when "en" ; puts "Hello, #{user}!"
|
995
|
+
when "fr" ; puts "Bonjour, #{user}!"
|
996
|
+
when "it" ; puts "Ciao, #{user}!"
|
997
|
+
else
|
998
|
+
raise "#{lang}: unknown language."
|
999
|
+
end
|
1000
|
+
end
|
1001
|
+
|
1002
|
+
end
|
1003
|
+
|
1004
|
+
Benry::CmdApp.action_alias("bonjour", "hello", <strong>"--lang=fr"</strong>) # !!!!
|
1005
|
+
Benry::CmdApp.action_alias("ciao" , "hello", <strong>"Bob", "-l", "it"</strong>) # !!!!
|
1006
|
+
|
1007
|
+
config = Benry::CmdApp::Config.new("sample app")
|
1008
|
+
app = Benry::CmdApp::Application.new(config)
|
1009
|
+
exit app.main()
|
1010
|
+
</pre>
|
1011
|
+
<p>Output:</p>
|
1012
|
+
<pre class="language-console">
|
1013
|
+
[bash]$ ruby ex16.rb hello
|
1014
|
+
Hello, world!
|
1015
|
+
|
1016
|
+
[bash]$ ruby ex16.rb <strong>bonjour</strong> # !!!!
|
1017
|
+
Bonjour, world!
|
1018
|
+
|
1019
|
+
[bash]$ ruby ex16.rb <strong>bonjour Alice</strong> # !!!!
|
1020
|
+
Bonjour, Alice!
|
1021
|
+
|
1022
|
+
[bash]$ ruby ex16.rb <strong>ciao</strong> # !!!!
|
1023
|
+
Ciao, Bob!
|
1024
|
+
</pre>
|
1025
|
+
</section>
|
1026
|
+
<section class="subsection" id="default-action">
|
1027
|
+
<h3>Default Action</h3>
|
1028
|
+
<ul>
|
1029
|
+
<li><code>config.default = "test1"</code> defines default action.
|
1030
|
+
In this case, action <code>test1</code> will be invoked if action name not specified in command-line.</li>
|
1031
|
+
<li>Default action name is shown in help message.</li>
|
1032
|
+
</ul>
|
1033
|
+
<p>File: ex17.rb</p>
|
1034
|
+
<pre class="language-ruby">
|
1035
|
+
#!/usr/bin/env ruby
|
1036
|
+
require 'benry/cmdapp'
|
1037
|
+
|
1038
|
+
class SampleAction < Benry::CmdApp::Action
|
1039
|
+
|
1040
|
+
@action.("test action #1")
|
1041
|
+
def test1()
|
1042
|
+
puts __method__
|
1043
|
+
end
|
1044
|
+
|
1045
|
+
end
|
1046
|
+
|
1047
|
+
config = Benry::CmdApp::Config.new("sample app")
|
1048
|
+
<strong>config.default_action = "test1"</strong> # !!!!
|
1049
|
+
app = Benry::CmdApp::Application.new(config)
|
1050
|
+
exit app.main()
|
1051
|
+
</pre>
|
1052
|
+
<p>Output:</p>
|
1053
|
+
<pre class="language-console">
|
1054
|
+
[bash]$ ruby ex17.rb test1
|
1055
|
+
test1
|
1056
|
+
|
1057
|
+
[bash]$ <strong>ruby ex17.rb</strong> # no action name!!!!
|
1058
|
+
test1
|
1059
|
+
</pre>
|
1060
|
+
<p>Help message:</p>
|
1061
|
+
<pre class="language-console">
|
1062
|
+
[bash]$ ruby ex17.rb -h
|
1063
|
+
ex17.rb -- sample app
|
1064
|
+
|
1065
|
+
Usage:
|
1066
|
+
$ ex17.rb [<options>] [<action> [<arguments>...]]
|
1067
|
+
|
1068
|
+
Options:
|
1069
|
+
-h, --help : print help message (of action if action specified)
|
1070
|
+
|
1071
|
+
Actions: <strong>(default: test1)</strong> # !!!!
|
1072
|
+
test1 : test action #1
|
1073
|
+
</pre>
|
1074
|
+
</section>
|
1075
|
+
<section class="subsection" id="default-help">
|
1076
|
+
<h3>Default Help</h3>
|
1077
|
+
<ul>
|
1078
|
+
<li><code>config.default_help = true</code> prints help message if action not specified in command-line.</li>
|
1079
|
+
<li>This is very useful when you don't have proper default action. It's recommended.</li>
|
1080
|
+
<li><code>config.default_action</code> is prior than <code>config.default_help</code>.</li>
|
1081
|
+
</ul>
|
1082
|
+
<p>File: ex18.rb</p>
|
1083
|
+
<pre class="language-ruby">
|
1084
|
+
#!/usr/bin/env ruby
|
1085
|
+
require 'benry/cmdapp'
|
1086
|
+
|
1087
|
+
class SampleAction < Benry::CmdApp::Action
|
1088
|
+
|
1089
|
+
@action.("test action #1")
|
1090
|
+
def test1()
|
1091
|
+
puts __method__
|
1092
|
+
end
|
1093
|
+
|
1094
|
+
end
|
1095
|
+
|
1096
|
+
config = Benry::CmdApp::Config.new("sample app")
|
1097
|
+
<strong>config.default_help = true</strong> # !!!!
|
1098
|
+
app = Benry::CmdApp::Application.new(config)
|
1099
|
+
exit app.main()
|
1100
|
+
</pre>
|
1101
|
+
<p>Output:</p>
|
1102
|
+
<pre class="language-console">
|
1103
|
+
[bash]$ <strong>ruby ex18.rb</strong> # no action name!!!!
|
1104
|
+
ex18.rb -- sample app
|
1105
|
+
|
1106
|
+
Usage:
|
1107
|
+
$ ex18.rb [<options>] [<action> [<arguments>...]]
|
1108
|
+
|
1109
|
+
Options:
|
1110
|
+
-h, --help : print help message (of action if action specified)
|
1111
|
+
|
1112
|
+
Actions:
|
1113
|
+
test1 : test action #1
|
1114
|
+
</pre>
|
1115
|
+
</section>
|
1116
|
+
<section class="subsection" id="private-hidden-action">
|
1117
|
+
<h3>Private (Hidden) Action</h3>
|
1118
|
+
<ul>
|
1119
|
+
<li>If action method is private, Benry::CmdApp regards that action as private.</li>
|
1120
|
+
<li>Private actions are hidden in help message.</li>
|
1121
|
+
<li>Private actions are shown when <code>-a</code> or <code>--all</code> option enabled and specified.</li>
|
1122
|
+
</ul>
|
1123
|
+
<p>File: ex20.rb</p>
|
1124
|
+
<pre class="language-ruby">
|
1125
|
+
#!/usr/bin/env ruby
|
1126
|
+
require 'benry/cmdapp'
|
1127
|
+
|
1128
|
+
class SampleAction < Benry::CmdApp::Action
|
1129
|
+
|
1130
|
+
@action.("test action #1")
|
1131
|
+
def test1()
|
1132
|
+
puts __method__
|
1133
|
+
end
|
1134
|
+
|
1135
|
+
@action.("test action #2")
|
1136
|
+
def test2()
|
1137
|
+
puts __method__
|
1138
|
+
end
|
1139
|
+
<strong>private :test2</strong> # !!!! private method !!!!
|
1140
|
+
|
1141
|
+
<strong>private</strong> # !!!! private method !!!!
|
1142
|
+
|
1143
|
+
@action.("test action #3")
|
1144
|
+
def test3()
|
1145
|
+
puts __method__
|
1146
|
+
end
|
1147
|
+
|
1148
|
+
end
|
1149
|
+
|
1150
|
+
config = Benry::CmdApp::Config.new("sample app")
|
1151
|
+
<strong>config.option_all = true</strong> # !!!! enable '-a, --all' option !!!!
|
1152
|
+
app = Benry::CmdApp::Application.new(config)
|
1153
|
+
exit app.main()
|
1154
|
+
</pre>
|
1155
|
+
<p>Help message (without <code>-a</code> nor <code>--all</code>):</p>
|
1156
|
+
<pre class="language-console">
|
1157
|
+
[bash]$ ruby ex20.rb <strong>-h</strong>
|
1158
|
+
ex20.rb -- sample app
|
1159
|
+
|
1160
|
+
Usage:
|
1161
|
+
$ ex20.rb [<options>] [<action> [<arguments>...]]
|
1162
|
+
|
1163
|
+
Options:
|
1164
|
+
-h, --help : print help message (of action if action specified)
|
1165
|
+
-a, --all : list all actions/options including private (hidden) ones
|
1166
|
+
|
1167
|
+
Actions:
|
1168
|
+
test1 : test action #1
|
1169
|
+
</pre>
|
1170
|
+
<p>Help message (with <code>-a</code> or <code>--all</code>):</p>
|
1171
|
+
<pre class="language-console">
|
1172
|
+
[bash]$ ruby ex20.rb <strong>-h --all</strong> # !!!!
|
1173
|
+
ex20.rb -- sample app
|
1174
|
+
|
1175
|
+
Usage:
|
1176
|
+
$ ex20.rb [<options>] [<action> [<arguments>...]]
|
1177
|
+
|
1178
|
+
Options:
|
1179
|
+
-h, --help : print help message (of action if action specified)
|
1180
|
+
-a, --all : list all actions/options including private (hidden) ones
|
1181
|
+
|
1182
|
+
Actions:
|
1183
|
+
test1 : test action #1
|
1184
|
+
<strong>test2 : test action #2</strong> # !!!!
|
1185
|
+
<strong>test3 : test action #3</strong> # !!!!
|
1186
|
+
</pre>
|
1187
|
+
</section>
|
1188
|
+
<section class="subsection" id="private-hidden-option">
|
1189
|
+
<h3>Private (Hidden) Option</h3>
|
1190
|
+
<ul>
|
1191
|
+
<li>Options which name stars with <code>_</code> are treated as private option.</li>
|
1192
|
+
<li>Private options are hidden in help message of action.</li>
|
1193
|
+
<li>Private options are shown when <code>-a</code> or <code>--all</code> option enabled and specified.</li>
|
1194
|
+
</ul>
|
1195
|
+
<p>File: ex21.rb</p>
|
1196
|
+
<pre class="language-ruby">
|
1197
|
+
#!/usr/bin/env ruby
|
1198
|
+
require 'benry/cmdapp'
|
1199
|
+
|
1200
|
+
class SampleAction < Benry::CmdApp::Action
|
1201
|
+
|
1202
|
+
@action.("test action")
|
1203
|
+
@option.(:verbose, "-v", "verbose mode")
|
1204
|
+
@option.(<strong>:_debug</strong> , "-D", "debug mode") # !!!!
|
1205
|
+
def test1(verbose: false, _debug: false)
|
1206
|
+
puts "verbose=#{verbose}, _debug=#{_debug}"
|
1207
|
+
end
|
1208
|
+
|
1209
|
+
end
|
1210
|
+
|
1211
|
+
config = Benry::CmdApp::Config.new("sample app")
|
1212
|
+
<strong>config.option_all = true</strong> # !!!! enable '-a, --all' option !!!!
|
1213
|
+
app = Benry::CmdApp::Application.new(config)
|
1214
|
+
exit app.main()
|
1215
|
+
</pre>
|
1216
|
+
<p>Help message (without <code>-a</code> nor <code>--all</code>):</p>
|
1217
|
+
<pre class="language-console">
|
1218
|
+
[bash]$ ruby ex21.rb -h test1
|
1219
|
+
ex21.rb test1 -- test action
|
1220
|
+
|
1221
|
+
Usage:
|
1222
|
+
$ ex21.rb test1 [<options>]
|
1223
|
+
|
1224
|
+
Options:
|
1225
|
+
-v : verbose mode
|
1226
|
+
</pre>
|
1227
|
+
<p>Help message (with <code>-a</code> or <code>--all</code>)</p>
|
1228
|
+
<pre class="language-console">
|
1229
|
+
[bash]$ ruby ex21.rb -h <strong>--all</strong> test1 # !!!!
|
1230
|
+
ex21.rb test1 -- test action
|
1231
|
+
|
1232
|
+
Usage:
|
1233
|
+
$ ex21.rb test1 [<options>]
|
1234
|
+
|
1235
|
+
Options:
|
1236
|
+
-v : verbose mode
|
1237
|
+
-D : debug mode # !!!!
|
1238
|
+
</pre>
|
1239
|
+
</section>
|
1240
|
+
</section>
|
1241
|
+
<section class="section" id="configuratoin-and-customization">
|
1242
|
+
<h2>Configuratoin and Customization</h2>
|
1243
|
+
<section class="subsection" id="application-configuration">
|
1244
|
+
<h3>Application Configuration</h3>
|
1245
|
+
<p><code>Benry::CmdApp::Config</code> class configures application behaviour.</p>
|
1246
|
+
<ul>
|
1247
|
+
<li><code>config.app_desc = "..."</code> sets command description which is shown in help message. (required)</li>
|
1248
|
+
<li><code>config.app_version = "1.0.0"</code> enables <code>-V</code> and <code>--version</code> option, and prints version number if <code>-V</code> or <code>--version</code> option specified. (default: <code>nil</code>)</li>
|
1249
|
+
<li><code>config.app_command = "<command>"</code> sets command name which is shown in help message. (default: <code>File.basname($0)</code>)</li>
|
1250
|
+
<li><code>config.app_detail = "<text>"</code> sets detailed description of command which is showin in help message. (default: <code>nil</code>)</li>
|
1251
|
+
<li><code>config.default_action = "<action>"</code> sets default action name. (default: <code>nil</code>)</li>
|
1252
|
+
<li><code>config.default_help = true</code> prints help message if no action names specified in command-line. (default: <code>false</code>)</li>
|
1253
|
+
<li><code>config.option_help = true</code> enables <code>-h</code> and <code>--help</code> options. (default: <code>true</code>)</li>
|
1254
|
+
<li><code>config.option_all = true</code> enables <code>-a</code> and <code>--all</code> options which shows private (hidden) actions and options into help message. (default: <code>false</code>)</li>
|
1255
|
+
<li><code>config.option_verbose = true</code> enables <code>-v</code> and <code>--verbose</code> options which sets <code>$QUIET_MODE = false</code>. (default: <code>false</code>)</li>
|
1256
|
+
<li><code>config.option_quiet = true</code> enables <code>-q</code> and <code>--quiet</code> options which sets <code>$QUIET_MODE = true</code>. (default: <code>false</code>)</li>
|
1257
|
+
<li><code>config.option_color = true</code> enables <code>--color[=<on|off>]</code> option which sets <code>$COLOR_MODE = true/false</code>. This affects to help message colorized or not. (default: <code>false</code>)</li>
|
1258
|
+
<li><code>config.option_debug = true</code> enables <code>-D</code> and <code>--debug</code> options which sets <code>$DEBUG_MODE = true</code>. (default: <code>false</code>)</li>
|
1259
|
+
<li><code>config.option_trace = true</code> enables <code>-T</code> and <code>--trace</code> options which sets <code>$TRACE_MODE = true</code>. Entering into and exitting from action are reported when trace mode is on. (default: <code>false</code>)</li>
|
1260
|
+
<li><code>config.help_aliases = true</code> adds <code>Aliases:</code> section in help message. (default: <code>false</code>)</li>
|
1261
|
+
<li><code>config.help_sections = [["<title>", "<text>"], ...]</code> adds section title and text into help message. (default: <code>[]</code>)</li>
|
1262
|
+
<li><code>config.help_postamble = "<text>"</code> sets postamble text in help message, such as 'Examples:' or 'Tips:'. (default: <code>nil</code>)</li>
|
1263
|
+
<li><code>config.feat_candidate = true</code> enables feature to list action names starting with 'foo:' when action name specified in command-line is <code>foo:</code>. (default: <code>true</code>)</li>
|
1264
|
+
<li><code>config.format_help = " %-18s : %s"</code> sets format of options and actions in help message. (default: <code>" \e[1m%-18s\e[0m : %s"</code>)</li>
|
1265
|
+
<li><code>config.format_usage = " $ %s %s"</code> sets format of usage in help message. (default: <code>" $ \e[1m%s\e[0m %s"</code>)</li>
|
1266
|
+
<li><code>config.format_heading = "[%s]"</code> sets format of heading in help message. (default: <code>"\e[34m%s\e[0m"</code>)</li>
|
1267
|
+
</ul>
|
1268
|
+
<p>File: ex22.rb</p>
|
1269
|
+
<pre class="language-ruby">
|
1270
|
+
#!/usr/bin/env ruby
|
1271
|
+
require 'benry/cmdapp'
|
1272
|
+
|
1273
|
+
config = Benry::CmdApp::Config.new("sample app", "1.0.0")
|
1274
|
+
#config.default_help = true
|
1275
|
+
|
1276
|
+
config.class.instance_methods(false).each do |name|
|
1277
|
+
next if name =~ /=$/
|
1278
|
+
next if ! config.class.method_defined?("#{name}=")
|
1279
|
+
val = config.__send__(name)
|
1280
|
+
puts "%-25s = %s" % ["config.#{name}", val.inspect]
|
1281
|
+
end
|
1282
|
+
</pre>
|
1283
|
+
<p>Output:</p>
|
1284
|
+
<pre class="language-console">
|
1285
|
+
[bash]$ ruby ex22.rb
|
1286
|
+
config<strong>.app_desc</strong> = "sample app"
|
1287
|
+
config<strong>.app_version</strong> = "1.0.0"
|
1288
|
+
config<strong>.app_name</strong> = "ex22.rb"
|
1289
|
+
config<strong>.app_command</strong> = "ex22.rb"
|
1290
|
+
config<strong>.app_detail</strong> = nil
|
1291
|
+
config<strong>.default_action</strong> = nil
|
1292
|
+
config<strong>.default_help</strong> = false
|
1293
|
+
config<strong>.option_help</strong> = true
|
1294
|
+
config<strong>.option_all</strong> = false
|
1295
|
+
config<strong>.option_verbose</strong> = false
|
1296
|
+
config<strong>.option_quiet</strong> = false
|
1297
|
+
config<strong>.option_color</strong> = false
|
1298
|
+
config<strong>.option_debug</strong> = false
|
1299
|
+
config<strong>.option_trace</strong> = false
|
1300
|
+
config<strong>.help_aliases</strong> = false
|
1301
|
+
config<strong>.help_sections</strong> = []
|
1302
|
+
config<strong>.help_postamble</strong> = nil
|
1303
|
+
config<strong>.feat_candidate</strong> = true
|
1304
|
+
config<strong>.format_help</strong> = " \e[1m%-18s\e[0m : %s"
|
1305
|
+
config<strong>.format_usage</strong> = " $ \e[1m%s\e[0m %s"
|
1306
|
+
config<strong>.format_heading</strong> = "\e[34m%s\e[0m"
|
1307
|
+
config<strong>.format_appname</strong> = "\e[1m%s\e[0m"
|
1308
|
+
</pre>
|
1309
|
+
</section>
|
1310
|
+
<section class="subsection" id="customization-of-global-options">
|
1311
|
+
<h3>Customization of Global Options</h3>
|
1312
|
+
<p>To add custom global options:</p>
|
1313
|
+
<ul>
|
1314
|
+
<li>(1) Create global option schema object.</li>
|
1315
|
+
<li>(2) Add custom options to it.</li>
|
1316
|
+
<li>(3) Pass it to <code>Application.new()</code>.</li>
|
1317
|
+
</ul>
|
1318
|
+
<p>File: ex23.rb</p>
|
1319
|
+
<pre class="language-ruby">
|
1320
|
+
#!/usr/bin/env ruby
|
1321
|
+
require 'benry/cmdapp'
|
1322
|
+
|
1323
|
+
class SampleAction < Benry::CmdApp::Action
|
1324
|
+
|
1325
|
+
@action.("test action")
|
1326
|
+
def test1()
|
1327
|
+
puts __method__
|
1328
|
+
end
|
1329
|
+
|
1330
|
+
end
|
1331
|
+
|
1332
|
+
## (1) create global option shema
|
1333
|
+
config = Benry::CmdApp::Config.new("sample app")
|
1334
|
+
<strong>schema = Benry::CmdApp::AppOptionSchema.new(config)</strong> # !!!!
|
1335
|
+
|
1336
|
+
## (2) add custom options to it
|
1337
|
+
<strong>schema.add(:logging, "--logging", "enable logging")</strong> # !!!!
|
1338
|
+
|
1339
|
+
## (3) pass it to ``Application.new()``
|
1340
|
+
app = Benry::CmdApp::Application.new(config, <strong>schema</strong>) # !!!!
|
1341
|
+
|
1342
|
+
exit app.main()
|
1343
|
+
</pre>
|
1344
|
+
<p>Help message:</p>
|
1345
|
+
<pre class="language-console">
|
1346
|
+
[bash]$ ruby ex23.rb -h
|
1347
|
+
ex23.rb -- sample app
|
1348
|
+
|
1349
|
+
Usage:
|
1350
|
+
$ ex23.rb [<options>] [<action> [<arguments>...]]
|
1351
|
+
|
1352
|
+
Options:
|
1353
|
+
-h, --help : print help message (of action if action specified)
|
1354
|
+
<strong>--logging : enable logging</strong> # !!!!
|
1355
|
+
|
1356
|
+
Actions:
|
1357
|
+
test1 : test action
|
1358
|
+
</pre>
|
1359
|
+
<p>To customize global options entirely:</p>
|
1360
|
+
<ul>
|
1361
|
+
<li>(1) Create empty <code>AppOptionSchema</code> object.</li>
|
1362
|
+
<li>(2) Add global options as you want.</li>
|
1363
|
+
<li>(3) Create and execute Application object with it.</li>
|
1364
|
+
</ul>
|
1365
|
+
<p>File: ex24.rb</p>
|
1366
|
+
<pre class="language-ruby">
|
1367
|
+
#!/usr/bin/env ruby
|
1368
|
+
require 'benry/cmdapp'
|
1369
|
+
|
1370
|
+
## (1) Create empty ``AppOptionSchema`` object.
|
1371
|
+
<strong>schema = Benry::CmdApp::AppOptionSchema.new(nil)</strong> # !!!!
|
1372
|
+
|
1373
|
+
## (2) Add global options as you want.
|
1374
|
+
<strong>schema.add</strong>(:help , "-h, --help" , "print help message")
|
1375
|
+
<strong>schema.add</strong>(:version, "-V, --version", "print version")
|
1376
|
+
<strong>schema.add</strong>(:all , "-a, --all" , "list all actions/options")
|
1377
|
+
<strong>schema.add</strong>(:verbose, "-v, --verbose", "verbose mode")
|
1378
|
+
<strong>schema.add</strong>(:quiet , "-q, --quiet" , "quiet mode")
|
1379
|
+
<strong>schema.add</strong>(:color , "--color[=<on|off>]", "enable/disable color", type: TrueClass)
|
1380
|
+
<strong>schema.add</strong>(:debug , "-D, --debug" , "set $DEBUG_MODE to true")
|
1381
|
+
<strong>schema.add</strong>(:trace , "-T, --trace" , "report enter into and exit from action")
|
1382
|
+
|
1383
|
+
## (3) Create and execute Application object with it.
|
1384
|
+
config = Benry::CmdApp::Config.new("sample app")
|
1385
|
+
app = Benry::CmdApp::Application.new(config, <strong>schema</strong>) # !!!!
|
1386
|
+
exit app.main()
|
1387
|
+
</pre>
|
1388
|
+
</section>
|
1389
|
+
<section class="subsection" id="customization-of-global-option-behaviour">
|
1390
|
+
<h3>Customization of Global Option Behaviour</h3>
|
1391
|
+
<ul>
|
1392
|
+
<li>(1) Define subclass of <code>Application</code> class.</li>
|
1393
|
+
<li>(2) Override <code>#do_toggle_global_switches()</code> method.</li>
|
1394
|
+
<li>(3) Create and execute subclass object of <code>Application</code>.</li>
|
1395
|
+
</ul>
|
1396
|
+
<p>File: ex25.rb</p>
|
1397
|
+
<pre class="language-ruby">
|
1398
|
+
#!/usr/bin/env ruby
|
1399
|
+
require 'benry/cmdapp'
|
1400
|
+
|
1401
|
+
## (1) Define subclass of ``Application`` class.
|
1402
|
+
<strong>class MyApplication < Benry::CmdApp::Application</strong>
|
1403
|
+
|
1404
|
+
## (2) Override ``#do_toggle_global_switches()`` method.
|
1405
|
+
<strong>def do_toggle_global_switches(_args, global_opts)</strong>
|
1406
|
+
<strong>super</strong>
|
1407
|
+
## here is original behaviour
|
1408
|
+
#global_opts.each do |key, val|
|
1409
|
+
# case key
|
1410
|
+
# when :verbose ; $QUIET_MODE = ! val
|
1411
|
+
# when :quiet ; $QUIET_MODE = val
|
1412
|
+
# when :color ; $COLOR_MODE = val
|
1413
|
+
# when :debug ; $DEBUG_MODE = val
|
1414
|
+
# when :trace ; $TRACE_MODE = val
|
1415
|
+
# else ; # do nothing
|
1416
|
+
# end
|
1417
|
+
#end
|
1418
|
+
end
|
1419
|
+
|
1420
|
+
end
|
1421
|
+
|
1422
|
+
## (3) Create and execute subclass object of ``Application``.
|
1423
|
+
config = Benry::CmdApp::Config.new("sample app")
|
1424
|
+
app = <strong>MyApplication.new(config)</strong> # !!!!
|
1425
|
+
exit app.main()
|
1426
|
+
</pre>
|
1427
|
+
<p>Of course, prepending custom module to Application class is also effective way.</p>
|
1428
|
+
<p>File: ex26.rb</p>
|
1429
|
+
<pre class="language-ruby">
|
1430
|
+
#!/usr/bin/env ruby
|
1431
|
+
require 'benry/cmdapp'
|
1432
|
+
|
1433
|
+
<strong>module MyApplicationMod</strong>
|
1434
|
+
|
1435
|
+
<strong>def do_toggle_global_switches(_args, global_opts)</strong>
|
1436
|
+
# ....
|
1437
|
+
end
|
1438
|
+
|
1439
|
+
end
|
1440
|
+
|
1441
|
+
Benry::CmdApp::Application<strong>.prepend(MyApplicationMod)</strong> # !!!!
|
1442
|
+
|
1443
|
+
config = Benry::CmdApp::Config.new("sample app")
|
1444
|
+
app = Benry::CmdApp::Application.new(config)
|
1445
|
+
exit app.main()
|
1446
|
+
</pre>
|
1447
|
+
</section>
|
1448
|
+
<section class="subsection" id="custom-hook-of-application">
|
1449
|
+
<h3>Custom Hook of Application</h3>
|
1450
|
+
<ul>
|
1451
|
+
<li>(1) Define subclass of Application class.</li>
|
1452
|
+
<li>(2) Override callback method.</li>
|
1453
|
+
<li>(3) Create and execute custom application object.</li>
|
1454
|
+
</ul>
|
1455
|
+
<p>File: ex27.rb</p>
|
1456
|
+
<pre class="language-ruby">
|
1457
|
+
#!/usr/bin/env ruby
|
1458
|
+
require 'benry/cmdapp'
|
1459
|
+
|
1460
|
+
class SampleAction < Benry::CmdApp::Action
|
1461
|
+
|
1462
|
+
@action.("test action")
|
1463
|
+
def test1()
|
1464
|
+
$logger.info("logging message") if $logger
|
1465
|
+
end
|
1466
|
+
|
1467
|
+
end
|
1468
|
+
|
1469
|
+
## (1) Define subclass of Application class
|
1470
|
+
<strong>class MyApplication < Benry::CmdApp::Application</strong> # !!!!
|
1471
|
+
|
1472
|
+
## (2) Override callback method
|
1473
|
+
<strong>def do_callback(args, global_opts)</strong> # !!!!
|
1474
|
+
#p @config
|
1475
|
+
#p @schema
|
1476
|
+
if global_opts[:logging]
|
1477
|
+
require 'logger'
|
1478
|
+
$logger = Logger.new(STDOUT)
|
1479
|
+
end
|
1480
|
+
## if return :SKIP, action skipped (not invoked).
|
1481
|
+
#return :SKIP
|
1482
|
+
end
|
1483
|
+
|
1484
|
+
## or:
|
1485
|
+
#def do_handle_global_options(args, global_opts)
|
1486
|
+
# if global_opts[:logging]
|
1487
|
+
# require 'logger'
|
1488
|
+
# $logger = Logger.new(STDOUT)
|
1489
|
+
# end
|
1490
|
+
# super
|
1491
|
+
#end
|
1492
|
+
|
1493
|
+
end
|
1494
|
+
|
1495
|
+
## (3) create and execute custom application object
|
1496
|
+
config = Benry::CmdApp::Config.new("sample app")
|
1497
|
+
schema = Benry::CmdApp::AppOptionSchema.new(config)
|
1498
|
+
schema.add(:logging, "--logging", "enable logging")
|
1499
|
+
app = <strong>MyApplication</strong>.new(config, schema) # !!!!
|
1500
|
+
exit app.main()
|
1501
|
+
</pre>
|
1502
|
+
<ul>
|
1503
|
+
<li>[EXPERIMENTAL] Instead of defining subclass of Application, you can pass callback block to Application object.</li>
|
1504
|
+
</ul>
|
1505
|
+
<p>File: ex28.rb</p>
|
1506
|
+
<pre class="language-ruby">
|
1507
|
+
#!/usr/bin/env ruby
|
1508
|
+
require 'benry/cmdapp'
|
1509
|
+
|
1510
|
+
class SampleAction < Benry::CmdApp::Action
|
1511
|
+
|
1512
|
+
@action.("test action")
|
1513
|
+
def test1()
|
1514
|
+
$logger.info("logging message") if $logger
|
1515
|
+
end
|
1516
|
+
|
1517
|
+
end
|
1518
|
+
|
1519
|
+
config = Benry::CmdApp::Config.new("sample app")
|
1520
|
+
schema = Benry::CmdApp::AppOptionSchema.new(config)
|
1521
|
+
schema.add(:logging, "--logging", "enable logging")
|
1522
|
+
app = Benry::CmdApp::Application.new(config, schema) <strong>do</strong> # !!!!
|
1523
|
+
<strong>|args, global_opts, config|</strong> # !!!!
|
1524
|
+
if global_opts[:logging] # !!!!
|
1525
|
+
require 'logger' # !!!!
|
1526
|
+
$logger = Logger.new(STDOUT) # !!!!
|
1527
|
+
end # !!!!
|
1528
|
+
#:SKIP # !!!!
|
1529
|
+
end # !!!!
|
1530
|
+
exit app.main()
|
1531
|
+
</pre>
|
1532
|
+
</section>
|
1533
|
+
<section class="subsection" id="customization-of-command-help-message">
|
1534
|
+
<h3>Customization of Command Help Message</h3>
|
1535
|
+
<p>If you want to just add more text into command help message,
|
1536
|
+
set <code>config.app_detail</code>, <code>config.help_sections</code>, and/or <code>config.help_postamble</code>.</p>
|
1537
|
+
<p>File: ex29.rb</p>
|
1538
|
+
<pre class="language-ruby">
|
1539
|
+
#!/usr/bin/env ruby
|
1540
|
+
require 'benry/cmdapp'
|
1541
|
+
|
1542
|
+
class SampleAction < Benry::CmdApp::Action
|
1543
|
+
|
1544
|
+
@action.("test action #1")
|
1545
|
+
def hello(user="world")
|
1546
|
+
puts "Hello, #{user}!"
|
1547
|
+
end
|
1548
|
+
|
1549
|
+
end
|
1550
|
+
|
1551
|
+
config = Benry::CmdApp::Config.new("sample app")
|
1552
|
+
<strong>config.app_detail</strong> = "Document: https://...." # !!!!
|
1553
|
+
config.help_sections</strong> = [ # !!!!
|
1554
|
+
["Example:", " $ <command> hello Alice"], # !!!!
|
1555
|
+
] # !!!!
|
1556
|
+
<strong>config.help_postamble</strong> = "(Tips: ....)" # !!!!
|
1557
|
+
app = Benry::CmdApp::Application.new(config)
|
1558
|
+
exit app.main()
|
1559
|
+
</pre>
|
1560
|
+
<p>Help message:</p>
|
1561
|
+
<pre class="language-console">
|
1562
|
+
[bash]$ ruby ex29.rb -h
|
1563
|
+
ex29.rb -- sample app
|
1564
|
+
|
1565
|
+
<strong>Document: https://....</strong> # !!!! app.detail !!!!
|
1566
|
+
|
1567
|
+
Usage:
|
1568
|
+
$ ex29.rb [<options>] [<action> [<arguments>...]]
|
1569
|
+
|
1570
|
+
Options:
|
1571
|
+
-h, --help : print help message (of action if action specified)
|
1572
|
+
|
1573
|
+
Actions:
|
1574
|
+
hello : test action #1
|
1575
|
+
|
1576
|
+
<strong>Example:</strong> # !!!! help_sections !!!!
|
1577
|
+
<strong>$ <command> hello Alice</strong> # !!!! help_sections !!!!
|
1578
|
+
|
1579
|
+
<strong>(Tips: ....)</strong> # !!!! help_postamble !!!!
|
1580
|
+
</pre>
|
1581
|
+
<p>If you want to change behaviour of building command help message:</p>
|
1582
|
+
<ul>
|
1583
|
+
<li>(1) Define subclass of <code>Benry::CmdApp::AppHelpBuilder</code> class.</li>
|
1584
|
+
<li>(2) Override methods.</li>
|
1585
|
+
<li>(3) Create an instance object of the class.</li>
|
1586
|
+
<li>(4) Pass it to Application object.</li>
|
1587
|
+
</ul>
|
1588
|
+
<p>File: ex30.rb</p>
|
1589
|
+
<pre class="language-ruby">
|
1590
|
+
#!/usr/bin/env ruby
|
1591
|
+
require 'benry/cmdapp'
|
1592
|
+
|
1593
|
+
class SampleAction < Benry::CmdApp::Action
|
1594
|
+
|
1595
|
+
@action.("greeting message")
|
1596
|
+
def hello(user="world")
|
1597
|
+
puts "Hello, #{user}!"
|
1598
|
+
end
|
1599
|
+
|
1600
|
+
end
|
1601
|
+
|
1602
|
+
## (1) Define subclass of ``Benry::CmdApp::AppHelpBuilder`` class.
|
1603
|
+
<strong>class MyAppHelpBuilder < Benry::CmdApp::AppHelpBuilder</strong>
|
1604
|
+
|
1605
|
+
## (2) Override methods.
|
1606
|
+
def <strong>build_help_message</strong>(all=false, format=nil)
|
1607
|
+
super
|
1608
|
+
end
|
1609
|
+
def <strong>build_preamble</strong>(all=false)
|
1610
|
+
super
|
1611
|
+
end
|
1612
|
+
def <strong>build_usage</strong>(all=false)
|
1613
|
+
super
|
1614
|
+
end
|
1615
|
+
def <strong>build_options</strong>(all=false, format=nil)
|
1616
|
+
super
|
1617
|
+
end
|
1618
|
+
def <strong>build_actions</strong>(all=false, format=nil)
|
1619
|
+
super
|
1620
|
+
end
|
1621
|
+
def <strong>build_postamble</strong>(all=false)
|
1622
|
+
super
|
1623
|
+
end
|
1624
|
+
def <strong>heading</strong>(str)
|
1625
|
+
super
|
1626
|
+
end
|
1627
|
+
end
|
1628
|
+
|
1629
|
+
## (3) Create an instance object of the class.
|
1630
|
+
config = Benry::CmdApp::Config.new("sample app")
|
1631
|
+
schema = Benry::CmdApp::AppOptionSchema.new(config)
|
1632
|
+
schema.add(:logging, "--logging", "enable logging")
|
1633
|
+
help_builder = <strong>MyAppHelpBuilder</strong>.new(config, schema) # !!!!
|
1634
|
+
|
1635
|
+
## (4) Pass it to Application object.
|
1636
|
+
app = Benry::CmdApp::Application.new(config, schema, <strong>help_builder</strong>) # !!!!
|
1637
|
+
exit app.main()
|
1638
|
+
</pre>
|
1639
|
+
<p>More simple way:</p>
|
1640
|
+
<ul>
|
1641
|
+
<li>(1) Create a module and override methods of <code>Benry::CmdApp::AppHelpBuilder</code> class.</li>
|
1642
|
+
<li>(2) Prepend it to <code>Benry::CmdApp::AppHelpBuilder</code> class.</li>
|
1643
|
+
<li>(3) Create and execute Application object.</li>
|
1644
|
+
</ul>
|
1645
|
+
<p>File: ex31.rb</p>
|
1646
|
+
<pre class="language-ruby">
|
1647
|
+
#!/usr/bin/env ruby
|
1648
|
+
require 'benry/cmdapp'
|
1649
|
+
|
1650
|
+
class SampleAction < Benry::CmdApp::Action
|
1651
|
+
|
1652
|
+
@action.("greeting message")
|
1653
|
+
def hello(user="world")
|
1654
|
+
puts "Hello, #{user}!"
|
1655
|
+
end
|
1656
|
+
|
1657
|
+
end
|
1658
|
+
|
1659
|
+
## (1) Create a module and override methods of ``AppHelpBuilder`` class.
|
1660
|
+
<strong>module MyHelpBuilderMod</strong>
|
1661
|
+
def build_help_message(all=false, format=nil)
|
1662
|
+
super
|
1663
|
+
end
|
1664
|
+
def build_preamble(all=false)
|
1665
|
+
super
|
1666
|
+
end
|
1667
|
+
def build_usage(all=false)
|
1668
|
+
super
|
1669
|
+
end
|
1670
|
+
def build_options(all=false, format=nil)
|
1671
|
+
super
|
1672
|
+
end
|
1673
|
+
def build_actions(all=false, format=nil)
|
1674
|
+
super
|
1675
|
+
end
|
1676
|
+
def build_postamble(all=false)
|
1677
|
+
super
|
1678
|
+
end
|
1679
|
+
def heading(str)
|
1680
|
+
super
|
1681
|
+
end
|
1682
|
+
end
|
1683
|
+
|
1684
|
+
## (2) Prepend it to ``Benry::CmdApp::AppHelpBuilder`` class.
|
1685
|
+
<strong>Benry::CmdApp::AppHelpBuilder.prepend(MyHelpBuilderMod)</strong>
|
1686
|
+
|
1687
|
+
## (3) Create and execute Application object.
|
1688
|
+
config = Benry::CmdApp::Config.new("sample app")
|
1689
|
+
app = Benry::CmdApp::Application.new(config)
|
1690
|
+
exit app.main()
|
1691
|
+
</pre>
|
1692
|
+
</section>
|
1693
|
+
<section class="subsection" id="customization-of-action-help-message">
|
1694
|
+
<h3>Customization of Action Help Message</h3>
|
1695
|
+
<p>If you want to just add more text into action help message,
|
1696
|
+
pass <code>detail:</code> and/or <code>postamble:</code> keyword arguments to <code>@action.()</code>.</p>
|
1697
|
+
<p>File: ex32.rb</p>
|
1698
|
+
<pre class="language-ruby">
|
1699
|
+
#!/usr/bin/env ruby
|
1700
|
+
require 'benry/cmdapp'
|
1701
|
+
|
1702
|
+
class SampleAction < Benry::CmdApp::Action
|
1703
|
+
|
1704
|
+
@action.("test action #1",
|
1705
|
+
<strong>detail:</strong> "Document: https://....", # !!!!
|
1706
|
+
<strong>postamble:</strong> "(Tips: ....)") # !!!!
|
1707
|
+
def hello(user="world")
|
1708
|
+
puts "Hello, #{user}!"
|
1709
|
+
end
|
1710
|
+
|
1711
|
+
end
|
1712
|
+
|
1713
|
+
config = Benry::CmdApp::Config.new("sample app")
|
1714
|
+
app = Benry::CmdApp::Application.new(config)
|
1715
|
+
exit app.main()
|
1716
|
+
</pre>
|
1717
|
+
<p>Help message:</p>
|
1718
|
+
<pre class="language-console">
|
1719
|
+
[bash]$ ruby ex32.rb -h
|
1720
|
+
ex32.rb hello -- test action #1
|
1721
|
+
|
1722
|
+
<strong>Document: https://....</strong> # !!!!
|
1723
|
+
|
1724
|
+
Usage:
|
1725
|
+
$ ex32.rb hello [<user>]
|
1726
|
+
|
1727
|
+
<strong>(Tips: ....)</strong> # !!!!
|
1728
|
+
</pre>
|
1729
|
+
<p>If you want to change behaviour of building action help message:</p>
|
1730
|
+
<ul>
|
1731
|
+
<li>(1) Create a module and override methods of <code>Benry::CmdApp::ActionHelpBuilder</code> class.</li>
|
1732
|
+
<li>(2) Prepend it to <code>Benry::CmdApp::ActionHelpBuilder</code> class.</li>
|
1733
|
+
<li>(3) Create and execute Application object.</li>
|
1734
|
+
</ul>
|
1735
|
+
<p>File: ex33.rb</p>
|
1736
|
+
<pre class="language-ruby">
|
1737
|
+
#!/usr/bin/env ruby
|
1738
|
+
require 'benry/cmdapp'
|
1739
|
+
|
1740
|
+
class SampleAction < Benry::CmdApp::Action
|
1741
|
+
|
1742
|
+
@action.("greeting message")
|
1743
|
+
def hello(user="world")
|
1744
|
+
puts "Hello, #{user}!"
|
1745
|
+
end
|
1746
|
+
|
1747
|
+
end
|
1748
|
+
|
1749
|
+
## (1) Create a module and override methods of ``ActionHelpBuilder`` class.
|
1750
|
+
<strong>module MyActionHelpBuilderMod</strong>
|
1751
|
+
def <strong>build_help_message</strong>(command, all=false)
|
1752
|
+
super
|
1753
|
+
end
|
1754
|
+
def <strong>build_preamble</strong>(command, all=false)
|
1755
|
+
super
|
1756
|
+
end
|
1757
|
+
def <strong>build_usage</strong>(command, all=false)
|
1758
|
+
super
|
1759
|
+
end
|
1760
|
+
def <strong>build_options</strong>(command, all=false)
|
1761
|
+
super
|
1762
|
+
end
|
1763
|
+
def <strong>build_postamble</strong>(command, all=false)
|
1764
|
+
super
|
1765
|
+
end
|
1766
|
+
def <strong>heading</strong>(str)
|
1767
|
+
super
|
1768
|
+
end
|
1769
|
+
end
|
1770
|
+
|
1771
|
+
## (2) Prepend it to ``Benry::CmdApp::ActionHelpBuilder`` class.
|
1772
|
+
Benry::CmdApp::ActionHelpBuilder<strong>.prepend(MyActionHelpBuilderMod)</strong> # !!!!
|
1773
|
+
|
1774
|
+
## (3) Create and execute Application object.
|
1775
|
+
config = Benry::CmdApp::Config.new("sample app")
|
1776
|
+
app = Benry::CmdApp::Application.new(config)
|
1777
|
+
exit app.main()
|
1778
|
+
</pre>
|
1779
|
+
<p>Another way:</p>
|
1780
|
+
<ul>
|
1781
|
+
<li>(1) Define subclass of <code>ActionHelpBuilder</code> class.</li>
|
1782
|
+
<li>(2) Set it to <code>ACTION_HELP_BUILDER_CLASS</code> constant value.</li>
|
1783
|
+
<li>(3) Create and execute Application object.</li>
|
1784
|
+
</ul>
|
1785
|
+
<p>File: ex34.rb</p>
|
1786
|
+
<pre class="language-ruby">
|
1787
|
+
#!/usr/bin/env ruby
|
1788
|
+
require 'benry/cmdapp'
|
1789
|
+
|
1790
|
+
class SampleAction < Benry::CmdApp::Action
|
1791
|
+
|
1792
|
+
@action.("greeting message")
|
1793
|
+
def hello(user="world")
|
1794
|
+
puts "Hello, #{user}!"
|
1795
|
+
end
|
1796
|
+
|
1797
|
+
end
|
1798
|
+
|
1799
|
+
## (1) Define subclass of ``ActionHelpBuilder`` class.
|
1800
|
+
<strong>class MyActionHelpBuilder < Benry::CmdApp::ActionHelpBuilder</strong>
|
1801
|
+
def build_help_message(command, all=false)
|
1802
|
+
super
|
1803
|
+
end
|
1804
|
+
def build_preamble(command, all=false)
|
1805
|
+
super
|
1806
|
+
end
|
1807
|
+
def build_usage(command, all=false)
|
1808
|
+
super
|
1809
|
+
end
|
1810
|
+
def build_options(command, all=false)
|
1811
|
+
super
|
1812
|
+
end
|
1813
|
+
def build_postamble(command, all=false)
|
1814
|
+
super
|
1815
|
+
end
|
1816
|
+
def heading(str)
|
1817
|
+
super
|
1818
|
+
end
|
1819
|
+
end
|
1820
|
+
|
1821
|
+
## (2) Set it to ``ACTION_HELP_BUILDER_CLASS`` constant value.
|
1822
|
+
Benry::CmdApp.module_eval do
|
1823
|
+
<strong>remove_const :ACTION_HELP_BUILDER_CLASS</strong>
|
1824
|
+
<strong>const_set :ACTION_HELP_BUILDER_CLASS, MyActionHelpBuilder</strong>
|
1825
|
+
end
|
1826
|
+
|
1827
|
+
## (3) Create and execute Application object.
|
1828
|
+
config = Benry::CmdApp::Config.new("sample app")
|
1829
|
+
app = Benry::CmdApp::Application.new(config)
|
1830
|
+
exit app.main()
|
1831
|
+
</pre>
|
1832
|
+
</section>
|
1833
|
+
</section>
|
1834
|
+
<section class="section" id="q--a">
|
1835
|
+
<h2>Q & A</h2>
|
1836
|
+
<section class="subsection" id="q-how-to-append-some-tasks-to-existing-action">
|
1837
|
+
<h3>Q: How to Append Some Tasks to Existing Action?</h3>
|
1838
|
+
<p>A: (a) Use method alias, or (b) use prepend.</p>
|
1839
|
+
<p>File: ex41.rb</p>
|
1840
|
+
<pre class="language-ruby">
|
1841
|
+
require 'benry/cmdapp'
|
1842
|
+
|
1843
|
+
class SampleAction < Benry::CmdApp::Action
|
1844
|
+
|
1845
|
+
@action.("test action #1")
|
1846
|
+
def hello(user="world")
|
1847
|
+
puts "Hello, #{user}!"
|
1848
|
+
end
|
1849
|
+
|
1850
|
+
@action.("test action #2")
|
1851
|
+
def hi(user="world")
|
1852
|
+
puts "Hi, #{user}!"
|
1853
|
+
end
|
1854
|
+
|
1855
|
+
end
|
1856
|
+
|
1857
|
+
## (a) use method alias
|
1858
|
+
class SampleAction # open existing class
|
1859
|
+
<strong>alias __old_hello hello</strong> # alias of existing method
|
1860
|
+
def <strong>hello</strong>(user="world") # override existing method
|
1861
|
+
puts "---- >8 ---- >8 ----"
|
1862
|
+
<strong>__old_hello(user)</strong> # call original method
|
1863
|
+
puts "---- 8< ---- 8< ----"
|
1864
|
+
end
|
1865
|
+
end
|
1866
|
+
|
1867
|
+
## (b) use prepend
|
1868
|
+
<strong>module SampleMod</strong> # define new module
|
1869
|
+
def <strong>hi</strong>(user="world") # override existing method
|
1870
|
+
puts "~~~~ >8 ~~~~ >8 ~~~~"
|
1871
|
+
<strong>super</strong> # call original method
|
1872
|
+
puts "~~~~ 8< ~~~~ 8< ~~~~"
|
1873
|
+
end
|
1874
|
+
end
|
1875
|
+
SampleAction<strong>.prepend(SampleMod)</strong> # prepend it to existing class
|
1876
|
+
|
1877
|
+
config = Benry::CmdApp::Config.new("sample app")
|
1878
|
+
app = Benry::CmdApp::Application.new(config)
|
1879
|
+
exit app.main()
|
1880
|
+
</pre>
|
1881
|
+
<p>Output:</p>
|
1882
|
+
<pre class="language-console">
|
1883
|
+
[bash]$ ruby ex41.rb hello
|
1884
|
+
---- >8 ---- >8 ----
|
1885
|
+
Hello, world!
|
1886
|
+
---- 8< ---- 8< ----
|
1887
|
+
|
1888
|
+
[bash]$ ruby ex41.rb hi Alice
|
1889
|
+
~~~~ >8 ~~~~ >8 ~~~~
|
1890
|
+
Hi, Alice!
|
1891
|
+
~~~~ 8< ~~~~ 8< ~~~~
|
1892
|
+
</pre>
|
1893
|
+
</section>
|
1894
|
+
<section class="subsection" id="q-how-to-re-define-existing-action">
|
1895
|
+
<h3>Q: How to Re-define Existing Action?</h3>
|
1896
|
+
<p>A: Remove existing action at first, and re-define action.</p>
|
1897
|
+
<p>File: ex42.rb</p>
|
1898
|
+
<pre class="language-ruby">
|
1899
|
+
require 'benry/cmdapp'
|
1900
|
+
|
1901
|
+
class <strong>SampleAction</strong> < Benry::CmdApp::Action
|
1902
|
+
|
1903
|
+
@action.("sample action")
|
1904
|
+
def <strong>hello</strong>() # !!!!
|
1905
|
+
puts "Hello, world!"
|
1906
|
+
end
|
1907
|
+
|
1908
|
+
end
|
1909
|
+
|
1910
|
+
Benry::CmdApp<strong>.delete_action("hello")</strong> # !!!!
|
1911
|
+
|
1912
|
+
class <strong>OtherAction</strong> < Benry::CmdApp::Action
|
1913
|
+
|
1914
|
+
@action.("other action") # !!!!
|
1915
|
+
def <strong>hello</strong>() # !!!!
|
1916
|
+
puts "Ciao, world!"
|
1917
|
+
end
|
1918
|
+
|
1919
|
+
end
|
1920
|
+
|
1921
|
+
config = Benry::CmdApp::Config.new("sample app")
|
1922
|
+
app = Benry::CmdApp::Application.new(config)
|
1923
|
+
exit app.main()
|
1924
|
+
</pre>
|
1925
|
+
<p>Help message:</p>
|
1926
|
+
<pre class="language-console">
|
1927
|
+
[bash]$ ruby ex42.rb -h
|
1928
|
+
ex42.rb -- sample app
|
1929
|
+
|
1930
|
+
Usage:
|
1931
|
+
$ ex42.rb [<options>] [<action> [<arguments>...]]
|
1932
|
+
|
1933
|
+
Options:
|
1934
|
+
-h, --help : print help message (of action if action specified)
|
1935
|
+
|
1936
|
+
Actions:
|
1937
|
+
<strong>hello : other action</strong> # !!!!
|
1938
|
+
</pre>
|
1939
|
+
</section>
|
1940
|
+
<section class="subsection" id="q-how-to-delete-existing-actionalias">
|
1941
|
+
<h3>Q: How to Delete Existing Action/Alias?</h3>
|
1942
|
+
<p>A: Call <code>Benry::CmdApp.delete_action("<action>")</code> or <code>Benry::CmdApp.delete_alias("<alias>")</code>.</p>
|
1943
|
+
</section>
|
1944
|
+
<section class="subsection" id="q-how-to-show-entering-into-or-exitting-from-action">
|
1945
|
+
<h3>Q: How to Show Entering Into or Exitting From Action?</h3>
|
1946
|
+
<p>A: Set <code>config.option_trace = true</code> and pass <code>-T</code> (or <code>--trace</code>) option.</p>
|
1947
|
+
<p>File: ex43.rb</p>
|
1948
|
+
<pre class="language-ruby">
|
1949
|
+
require 'benry/cmdapp'
|
1950
|
+
|
1951
|
+
class SampleAction < Benry::CmdApp::Action
|
1952
|
+
|
1953
|
+
@action.("preparation")
|
1954
|
+
def prepare()
|
1955
|
+
puts "... prepare something ..."
|
1956
|
+
end
|
1957
|
+
|
1958
|
+
@action.("build")
|
1959
|
+
def build()
|
1960
|
+
run_action_once("prepare")
|
1961
|
+
puts "... build something ..."
|
1962
|
+
end
|
1963
|
+
|
1964
|
+
end
|
1965
|
+
|
1966
|
+
config = Benry::CmdApp::Config.new("sample app")
|
1967
|
+
<strong>config.option_trace = true</strong> # !!!!
|
1968
|
+
app = Benry::CmdApp::Application.new(config)
|
1969
|
+
exit app.main()
|
1970
|
+
</pre>
|
1971
|
+
<p>Output:</p>
|
1972
|
+
<pre class="language-console">
|
1973
|
+
[bash]$ ruby ex43.rb -T build # !!!!
|
1974
|
+
<strong>## enter: build</strong>
|
1975
|
+
<strong>## enter: prepare</strong>
|
1976
|
+
... prepare something ...
|
1977
|
+
<strong>## exit: prepare</strong>
|
1978
|
+
... build something ...
|
1979
|
+
<strong>## exit: build</strong>
|
1980
|
+
</pre>
|
1981
|
+
</section>
|
1982
|
+
<section class="subsection" id="q-how-to-enabledisable-color-mode">
|
1983
|
+
<h3>Q: How to Enable/Disable Color Mode?</h3>
|
1984
|
+
<p>A: Set <code>config.option_color = true</code> and pass <code>--color=on</code> or <code>--color=off</code> option.</p>
|
1985
|
+
<p>File: ex44.rb</p>
|
1986
|
+
<pre class="language-ruby">
|
1987
|
+
require 'benry/cmdapp'
|
1988
|
+
|
1989
|
+
class SampleAction < Benry::CmdApp::Action
|
1990
|
+
|
1991
|
+
@action.("greeting message")
|
1992
|
+
def hello(user="world")
|
1993
|
+
puts "Hello, #{user}!"
|
1994
|
+
end
|
1995
|
+
|
1996
|
+
end
|
1997
|
+
|
1998
|
+
config = Benry::CmdApp::Config.new("sample app")
|
1999
|
+
<strong>config.option_color = true</strong> # !!!!
|
2000
|
+
app = Benry::CmdApp::Application.new(config)
|
2001
|
+
exit app.main()
|
2002
|
+
</pre>
|
2003
|
+
<p>Help message:</p>
|
2004
|
+
<pre class="language-console">
|
2005
|
+
[bash]$ ruby ex44.rb -h
|
2006
|
+
ex44.rb -- sample app
|
2007
|
+
|
2008
|
+
Usage:
|
2009
|
+
$ ex44.rb [<options>] [<action> [<arguments>...]]
|
2010
|
+
|
2011
|
+
Options:
|
2012
|
+
-h, --help : print help message (of action if action specified)
|
2013
|
+
<strong>--color[=<on|off>] : enable/disable color</strong> # !!!!
|
2014
|
+
|
2015
|
+
Actions:
|
2016
|
+
hello : greeting message
|
2017
|
+
|
2018
|
+
[bash]$ ruby ex44.rb -h <strong>--color=off</strong> # !!!!
|
2019
|
+
|
2020
|
+
[bash]$ ruby ex44.rb -h <strong>--color=on</strong> # !!!!
|
2021
|
+
</pre>
|
2022
|
+
</section>
|
2023
|
+
<section class="subsection" id="q-how-to-define-multiple-option-like--i-option-of-ruby">
|
2024
|
+
<h3>Q: How to Define Multiple Option, like <code>-I</code> Option of Ruby?</h3>
|
2025
|
+
<p>A: Provide block parameter on <code>@option.()</code>.</p>
|
2026
|
+
<p>File: ex45.rb</p>
|
2027
|
+
<pre class="language-ruby">
|
2028
|
+
require 'benry/cmdapp'
|
2029
|
+
|
2030
|
+
class TestAction < Benry::CmdApp::Action
|
2031
|
+
|
2032
|
+
@action.("multiple option test")
|
2033
|
+
@option.(:path, "-I <path>", "path") <strong>{|options, key, val|</strong> # !!!!
|
2034
|
+
<strong>arr = options[key] || []</strong> # !!!!
|
2035
|
+
<strong>arr << val</strong> # !!!!
|
2036
|
+
<strong>arr</strong> # !!!!
|
2037
|
+
## or: # !!!!
|
2038
|
+
#<strong>(options[key] || []) << val</strong> # !!!!
|
2039
|
+
<strong>}</strong> # !!!!
|
2040
|
+
def test(path: [])
|
2041
|
+
puts "path=#{path.inspect}" #=> path=["/tmp", "/var/tmp"]
|
2042
|
+
end
|
2043
|
+
|
2044
|
+
end
|
2045
|
+
|
2046
|
+
config = Benry::CmdApp::Config.new("test app")
|
2047
|
+
app = Benry::CmdApp::Application.new(config)
|
2048
|
+
exit app.main()
|
2049
|
+
</pre>
|
2050
|
+
<p>Output:</p>
|
2051
|
+
<pre class="language-console">
|
2052
|
+
[bash]$ ruby ex45.rb test <strong>-I /tmp -I /var/tmp</strong> # !!!!
|
2053
|
+
path=["/tmp", "/var/tmp"] # !!!!
|
2054
|
+
</pre>
|
2055
|
+
</section>
|
2056
|
+
<section class="subsection" id="q-how-to-specify-detailed-description-of-option">
|
2057
|
+
<h3>Q: How to Specify Detailed Description of Option?</h3>
|
2058
|
+
<p>A: Add <code>detail:</code> keyword argument to <code>@option.()</code>.</p>
|
2059
|
+
<p>File: ex46.rb</p>
|
2060
|
+
<pre class="language-ruby">
|
2061
|
+
require 'benry/cmdapp'
|
2062
|
+
|
2063
|
+
class TestAction < Benry::CmdApp::Action
|
2064
|
+
|
2065
|
+
@action.("detailed description test")
|
2066
|
+
@option.(:mode, "-m <mode>", "output mode", <strong>detail:</strong> <<"END")
|
2067
|
+
v, verbose: print many output
|
2068
|
+
q, quiet: print litte output
|
2069
|
+
c, compact: print summary output
|
2070
|
+
END
|
2071
|
+
def test(mode: nil)
|
2072
|
+
puts "mode=#{mode.inspect}"
|
2073
|
+
end
|
2074
|
+
|
2075
|
+
end
|
2076
|
+
|
2077
|
+
config = Benry::CmdApp::Config.new("test app")
|
2078
|
+
app = Benry::CmdApp::Application.new(config)
|
2079
|
+
exit app.main()
|
2080
|
+
</pre>
|
2081
|
+
<p>Help message:</p>
|
2082
|
+
<pre class="language-console">
|
2083
|
+
[bash]$ ruby ex46.rb -h test
|
2084
|
+
ex46.rb test -- detailed description test
|
2085
|
+
|
2086
|
+
Usage:
|
2087
|
+
$ ex46.rb test [<options>]
|
2088
|
+
|
2089
|
+
Options:
|
2090
|
+
-m <mode> : output mode
|
2091
|
+
<strong>v, verbose: print many output</strong>
|
2092
|
+
<strong>q, quiet: print litte output</strong>
|
2093
|
+
<strong>c, compact: print summary output</strong>
|
2094
|
+
</pre>
|
2095
|
+
</section>
|
2096
|
+
<section class="subsection" id="q-how-to-copy-all-options-from-other-action">
|
2097
|
+
<h3>Q: How to Copy All Options from Other Action?</h3>
|
2098
|
+
<p>A: Use <code>@copy_options.()</code>.</p>
|
2099
|
+
<p>File: ex47.rb</p>
|
2100
|
+
<pre class="language-ruby">
|
2101
|
+
require 'benry/cmdapp'
|
2102
|
+
|
2103
|
+
class SampleAction < Benry::CmdApp::Action
|
2104
|
+
|
2105
|
+
@action.("test action #1")
|
2106
|
+
@option.(:verbose, "-v, --verbose", "verbose mode")
|
2107
|
+
@option.(:file, "-f, --file=<file>", "filename")
|
2108
|
+
@option.(:indent, "-i, --indent[=<N>]", "indent")
|
2109
|
+
def test1(verbose: false, file: nil, indent: nil)
|
2110
|
+
puts "verbose=#{verbose}, file=#{file}, indent=#{indent}"
|
2111
|
+
end
|
2112
|
+
|
2113
|
+
@action.("test action #2")
|
2114
|
+
<strong>@copy_options.("test1")</strong> # !!!! copy options from test1 !!!!
|
2115
|
+
@option.(:debug, "-D, --debug", "debug mode")
|
2116
|
+
def test2(verbose: false, file: nil, indent: nil, debug: false)
|
2117
|
+
puts "verbose=#{verbose}, file=#{file}, indent=#{indent}, debug=#{debug}"
|
2118
|
+
end
|
2119
|
+
|
2120
|
+
end
|
2121
|
+
|
2122
|
+
config = Benry::CmdApp::Config.new("sample app")
|
2123
|
+
app = Benry::CmdApp::Application.new(config)
|
2124
|
+
exit app.main()
|
2125
|
+
</pre>
|
2126
|
+
<p>Help message of <code>test2</code> action:</p>
|
2127
|
+
<pre class="language-console">
|
2128
|
+
[bash]$ ruby ex47.rb -h test2
|
2129
|
+
ex47.rb test2 -- test action #2
|
2130
|
+
|
2131
|
+
Usage:
|
2132
|
+
$ ex47.rb test2 [<options>]
|
2133
|
+
|
2134
|
+
Options:
|
2135
|
+
-v, --verbose : verbose mode # copied!!
|
2136
|
+
-f, --file=<file> : filename # copied!!
|
2137
|
+
-i, --indent[=<N>] : indent # copied!!
|
2138
|
+
-D, --debug : debug mode
|
2139
|
+
</pre>
|
2140
|
+
</section>
|
2141
|
+
<section class="subsection" id="q-what-is-the-difference-between-prefixalias_of-and-prefixaction">
|
2142
|
+
<h3>Q: What is the Difference Between <code>prefix(alias_of:)</code> and <code>prefix(action:)</code>?</h3>
|
2143
|
+
<p>A: The former defines an alias, and the latter doesn't.</p>
|
2144
|
+
<p>File: ex48.rb</p>
|
2145
|
+
<pre class="language-ruby">
|
2146
|
+
require 'benry/cmdapp'
|
2147
|
+
|
2148
|
+
class AaaAction < Benry::CmdApp::Action
|
2149
|
+
prefix "aaa", <strong>alias_of:</strong> :print_ # (or) alias_of: "print"
|
2150
|
+
|
2151
|
+
@action.("test #1")
|
2152
|
+
def print_()
|
2153
|
+
puts "test"
|
2154
|
+
end
|
2155
|
+
|
2156
|
+
end
|
2157
|
+
|
2158
|
+
class BbbAction < Benry::CmdApp::Action
|
2159
|
+
prefix "bbb", <strong>action:</strong> :print_ # (or) action: "print"
|
2160
|
+
|
2161
|
+
@action.("test #2")
|
2162
|
+
def print_()
|
2163
|
+
puts "test"
|
2164
|
+
end
|
2165
|
+
|
2166
|
+
end
|
2167
|
+
|
2168
|
+
config = Benry::CmdApp::Config.new("sample app")
|
2169
|
+
app = Benry::CmdApp::Application.new(config)
|
2170
|
+
exit app.main()
|
2171
|
+
</pre>
|
2172
|
+
<p>Help message:</p>
|
2173
|
+
<pre class="language-console">
|
2174
|
+
[bash]$ ruby ex48.rb
|
2175
|
+
ex48.rb -- sample app
|
2176
|
+
|
2177
|
+
Usage:
|
2178
|
+
$ ex48.rb [<options>] [<action> [<arguments>...]]
|
2179
|
+
|
2180
|
+
Options:
|
2181
|
+
-h, --help : print help message (of action if action specified)
|
2182
|
+
|
2183
|
+
Actions:
|
2184
|
+
<strong>aaa : alias of 'aaa:print' action</strong> # !!!!
|
2185
|
+
aaa:print : test #1
|
2186
|
+
<strong>bbb : test #2</strong> # !!!!
|
2187
|
+
</pre>
|
2188
|
+
<p>In the above example, alias <code>aaa</code> is defined due to <code>prefix(alias_of:)</code>,
|
2189
|
+
and action <code>bbb</code> is not an alias due to <code>prefix(action:)</code>.</p>
|
2190
|
+
</section>
|
2191
|
+
<section class="subsection" id="q-how-to-change-order-of-options-in-help-message">
|
2192
|
+
<h3>Q: How to Change Order of Options in Help Message?</h3>
|
2193
|
+
<p>A: Call <code>AppOptionSchema#sort_options_in_this_order()</code>.</p>
|
2194
|
+
<p>File: ex49.rb</p>
|
2195
|
+
<pre class="language-ruby">
|
2196
|
+
require 'benry/cmdapp'
|
2197
|
+
|
2198
|
+
config = Benry::CmdApp::Config.new("sample app", "1.0.0",
|
2199
|
+
option_all: true,
|
2200
|
+
option_quiet: true,
|
2201
|
+
option_color: true,
|
2202
|
+
)
|
2203
|
+
schema = Benry::CmdApp::AppOptionSchema.new(config)
|
2204
|
+
<strong>keys = [:all, :quiet, :color, :help, :version]</strong> # !!!!
|
2205
|
+
<strong>schema.sort_options_in_this_order(*keys)</strong> # !!!!
|
2206
|
+
app = Benry::CmdApp::Application.new(config, schema)
|
2207
|
+
## or:
|
2208
|
+
#app = Benry::CmdApp::Application.new(config)
|
2209
|
+
#<strong>app.schema.sort_options_in_this_order(*keys)</strong> # !!!!
|
2210
|
+
exit app.main()
|
2211
|
+
</pre>
|
2212
|
+
<p>Help message:</p>
|
2213
|
+
<pre class="language-console">
|
2214
|
+
[bash]$ ruby ex49.rb -h
|
2215
|
+
ex49.rb (1.0.0) -- sample app
|
2216
|
+
|
2217
|
+
Usage:
|
2218
|
+
$ ex49.rb [<options>] [<action> [<arguments>...]]
|
2219
|
+
|
2220
|
+
Options:
|
2221
|
+
-a, --all : list all actions/options including private (hidden) ones
|
2222
|
+
-q, --quiet : quiet mode
|
2223
|
+
--color[=<on|off>] : enable/disable color
|
2224
|
+
-h, --help : print help message (of action if action specified)
|
2225
|
+
-V, --version : print version
|
2226
|
+
|
2227
|
+
Actions:
|
2228
|
+
|
2229
|
+
</pre>
|
2230
|
+
</section>
|
2231
|
+
<section class="subsection" id="q-is-it-possible-to-make-action-names-emphasised-or-weaken">
|
2232
|
+
<h3>Q: Is It Possible to Make Action Names Emphasised or Weaken?</h3>
|
2233
|
+
<p>A: Yes. When you pass <code>important: true</code> to <code>@action.()</code>, that action will be printed with unerline in help message. When you pass <code>important: false</code>, that action will be printed in gray color.</p>
|
2234
|
+
<p>File: ex50.rb</p>
|
2235
|
+
<pre class="language-ruby">
|
2236
|
+
require 'benry/cmdapp'
|
2237
|
+
|
2238
|
+
class SampleAction < Benry::CmdApp::Action
|
2239
|
+
|
2240
|
+
@action.("empasized", <strong>important: true</strong>) # !!!!
|
2241
|
+
def test1()
|
2242
|
+
end
|
2243
|
+
|
2244
|
+
@action.("weaken", <strong>important: false</strong>) # !!!!
|
2245
|
+
def test2()
|
2246
|
+
end
|
2247
|
+
|
2248
|
+
end
|
2249
|
+
|
2250
|
+
config = Benry::CmdApp::Config.new("sample app")
|
2251
|
+
app = Benry::CmdApp::Application.new(config)
|
2252
|
+
exit app.main()
|
2253
|
+
</pre>
|
2254
|
+
<p>Help message:</p>
|
2255
|
+
<pre class="language-console">
|
2256
|
+
[bash]$ ruby ex50.rb -h
|
2257
|
+
ex50.rb -- sample app
|
2258
|
+
|
2259
|
+
Usage:
|
2260
|
+
$ ex50.rb [<options>] [<action> [<arguments>...]]
|
2261
|
+
|
2262
|
+
Options:
|
2263
|
+
-h, --help : print help message (of action if action specified)
|
2264
|
+
|
2265
|
+
Actions:
|
2266
|
+
<strong>test1 : empasized</strong> # !!!! printed with underline !!!!
|
2267
|
+
<strong>test2 : weaken</strong> # !!!! printed in gray color !!!!
|
2268
|
+
</pre>
|
2269
|
+
</section>
|
2270
|
+
<section class="subsection" id="q-is-it-possible-to-add-metadata-to-action-or-option">
|
2271
|
+
<h3>Q: Is It Possible to Add Metadata to Action or Option?</h3>
|
2272
|
+
<p>A: Yes. Pass <code>tag:</code> keyword argument to <code>@action.()</code> or <code>@option.()</code>.</p>
|
2273
|
+
<ul>
|
2274
|
+
<li><code>tag:</code> keyword argument accept any type of value such as symbol, string, array, and so on.</li>
|
2275
|
+
<li>Currenty, Benry::CmdApp doesn't provide the good way to use it effectively.
|
2276
|
+
This feature may be used by command-line application or framework based on Benry::CmdApp.</li>
|
2277
|
+
</ul>
|
2278
|
+
<p>File: ex51.rb</p>
|
2279
|
+
<pre class="language-ruby">
|
2280
|
+
require 'benry/cmdapp'
|
2281
|
+
|
2282
|
+
class SampleAction < Benry::CmdApp::Action
|
2283
|
+
|
2284
|
+
@action.("print greeting message", <strong>tag: :important</strong>) # !!!!
|
2285
|
+
@option.(:repeat, "-r <N>", "repeat N times", <strong>tag: :important</strong>) # !!!!
|
2286
|
+
def hello(user="world", repeat: nil)
|
2287
|
+
(repeat || 1).times do
|
2288
|
+
puts "Hello, #{user}!"
|
2289
|
+
end
|
2290
|
+
end
|
2291
|
+
|
2292
|
+
end
|
2293
|
+
|
2294
|
+
config = Benry::CmdApp::Config.new("sample app")
|
2295
|
+
app = Benry::CmdApp::Application.new(config)
|
2296
|
+
exit app.main()
|
2297
|
+
</pre>
|
2298
|
+
</section>
|
2299
|
+
<section class="subsection" id="q-how-to-make-error-messages-i18ned">
|
2300
|
+
<h3>Q: How to Make Error Messages I18Ned?</h3>
|
2301
|
+
<p>A: Currently not supported. May be supported in the future release.</p>
|
2302
|
+
</section>
|
2303
|
+
</section>
|
2304
|
+
<section class="section" id="license-and-copyright">
|
2305
|
+
<h2>License and Copyright</h2>
|
2306
|
+
<ul>
|
2307
|
+
<li>$License: MIT License $</li>
|
2308
|
+
<li>$Copyright: copyright(c) 2023 kwatch@gmail.com $</li>
|
2309
|
+
</ul>
|
2310
|
+
</section>
|
2311
|
+
</section>
|
2312
|
+
</main>
|
2313
|
+
</body>
|
2314
|
+
</html>
|