benry-cmdapp 0.2.0 → 1.0.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 +4 -4
- data/CHANGES.md +6 -0
- data/README.md +1693 -852
- data/benry-cmdapp.gemspec +3 -3
- data/doc/benry-cmdapp.html +1582 -906
- data/lib/benry/cmdapp.rb +1894 -1060
- data/test/app_test.rb +882 -1078
- data/test/config_test.rb +71 -0
- data/test/context_test.rb +382 -0
- data/test/func_test.rb +302 -82
- data/test/help_test.rb +1054 -553
- data/test/metadata_test.rb +191 -0
- data/test/misc_test.rb +175 -0
- data/test/registry_test.rb +402 -0
- data/test/run_all.rb +4 -3
- data/test/scope_test.rb +1210 -0
- data/test/shared.rb +112 -49
- data/test/util_test.rb +154 -99
- metadata +17 -9
- data/test/action_test.rb +0 -1038
- data/test/index_test.rb +0 -185
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Benry-CmdApp
|
2
2
|
|
3
|
-
($Release: 0.
|
3
|
+
($Release: 1.0.0 $)
|
4
4
|
|
5
5
|
|
6
6
|
## What's This?
|
@@ -9,17 +9,17 @@ Benry-CmdApp is a framework to create command-line application.
|
|
9
9
|
If you want create command-line application which takes sub-commands
|
10
10
|
like `git`, `docker`, or `npm`, Benry-CmdApp is the solution.
|
11
11
|
|
12
|
-
|
12
|
+
Basic idea:
|
13
13
|
|
14
|
-
*
|
14
|
+
* Action (= sub-command) is defined as a method in Ruby.
|
15
15
|
* Commnad-line arguments are passed to action method as positional arguments.
|
16
16
|
* Command-line options are passed to action method as keyword arguments.
|
17
17
|
|
18
18
|
For example:
|
19
19
|
|
20
|
-
* `<command>
|
21
|
-
* `<command>
|
22
|
-
* `<command>
|
20
|
+
* `<command> hello` in command-line invokes action method `hello()` in Ruby.
|
21
|
+
* `<command> hello arg1 arg2` invokes `hello("arg1", "arg2")`.
|
22
|
+
* `<command> hello arg --opt=val` invokes `hello("arg", opt: "val")`.
|
23
23
|
|
24
24
|
Links:
|
25
25
|
|
@@ -36,7 +36,7 @@ Benry-CmdApp requires Ruby >= 2.3.
|
|
36
36
|
|
37
37
|
* [What's This?](#whats-this)
|
38
38
|
* [Install](#install)
|
39
|
-
* [Usage](#usage)
|
39
|
+
* [Basic Usage](#basic-usage)
|
40
40
|
* [Action](#action)
|
41
41
|
* [Method Name and Action Name](#method-name-and-action-name)
|
42
42
|
* [Parameter Name in Help Message of Action](#parameter-name-in-help-message-of-action)
|
@@ -45,34 +45,47 @@ Benry-CmdApp requires Ruby >= 2.3.
|
|
45
45
|
* [Option Value Validation](#option-value-validation)
|
46
46
|
* [Callback for Option Value](#callback-for-option-value)
|
47
47
|
* [Boolean (On/Off) Option](#boolean-onoff-option)
|
48
|
-
* [
|
48
|
+
* [Option Set](#option-set)
|
49
|
+
* [Copy Options](#copy-options)
|
50
|
+
* [Option Error and Action Error](#option-error-and-action-error)
|
51
|
+
* [Advanced Feature](#advanced-feature)
|
52
|
+
* [Category of Action](#category-of-action)
|
53
|
+
* [Nested Category](#nested-category)
|
54
|
+
* [Category Action or Alias](#category-action-or-alias)
|
49
55
|
* [Invoke Other Action](#invoke-other-action)
|
50
|
-
* [
|
56
|
+
* [Cleaning Up Block](#cleaning-up-block)
|
57
|
+
* [Alias for Action](#alias-for-action)
|
58
|
+
* [Abbreviation of Category](#abbreviation-of-category)
|
51
59
|
* [Default Action](#default-action)
|
52
|
-
* [
|
53
|
-
* [
|
54
|
-
* [
|
60
|
+
* [Action List and Category List](#action-list-and-category-list)
|
61
|
+
* [Hidden Action](#hidden-action)
|
62
|
+
* [Hidden Option](#hidden-option)
|
63
|
+
* [Important Actions or Options](#important-actions-or-options)
|
55
64
|
* [Configuratoin and Customization](#configuratoin-and-customization)
|
56
65
|
* [Application Configuration](#application-configuration)
|
57
66
|
* [Customization of Global Options](#customization-of-global-options)
|
58
67
|
* [Customization of Global Option Behaviour](#customization-of-global-option-behaviour)
|
59
68
|
* [Custom Hook of Application](#custom-hook-of-application)
|
60
|
-
* [Customization of
|
69
|
+
* [Customization of Application Help Message](#customization-of-application-help-message)
|
61
70
|
* [Customization of Action Help Message](#customization-of-action-help-message)
|
71
|
+
* [Customization of Section Title in Help Message](#customization-of-section-title-in-help-message)
|
62
72
|
* [Q & A](#q--a)
|
63
|
-
* [Q: How to
|
64
|
-
* [Q: How to
|
65
|
-
* [Q: How to
|
66
|
-
* [Q: How to
|
67
|
-
* [Q: How to
|
68
|
-
* [Q: How to
|
69
|
-
* [Q: How to
|
70
|
-
* [Q: How to
|
71
|
-
* [Q:
|
72
|
-
* [Q: How to
|
73
|
-
* [Q:
|
74
|
-
* [Q:
|
75
|
-
* [Q: How to
|
73
|
+
* [Q: How to show all backtraces of exception?](#q-how-to-show-all-backtraces-of-exception)
|
74
|
+
* [Q: How to specify description to arguments of actions?](#q-how-to-specify-description-to-arguments-of-actions)
|
75
|
+
* [Q: How to append some tasks to an existing action?](#q-how-to-append-some-tasks-to-an-existing-action)
|
76
|
+
* [Q: How to delete an existing action/alias?](#q-how-to-delete-an-existing-actionalias)
|
77
|
+
* [Q: How to re-define an existing action?](#q-how-to-re-define-an-existing-action)
|
78
|
+
* [Q: How to show entering into or exitting from actions?](#q-how-to-show-entering-into-or-exitting-from-actions)
|
79
|
+
* [Q: How to enable/disable color mode?](#q-how-to-enabledisable-color-mode)
|
80
|
+
* [Q: How to define a multiple option, like `-I` option of Ruby?](#q-how-to-define-a-multiple-option-like--i-option-of-ruby)
|
81
|
+
* [Q: How to show global option `-L <topic>` in help message?](#q-how-to-show-global-option--l-topic-in-help-message)
|
82
|
+
* [Q: How to specify detailed description of options?](#q-how-to-specify-detailed-description-of-options)
|
83
|
+
* [Q: How to list only aliases (or actions) excluding actions (or aliases) ?](#q-how-to-list-only-aliases-or-actions-excluding-actions-or-aliases-)
|
84
|
+
* [Q: How to change the order of options in help message?](#q-how-to-change-the-order-of-options-in-help-message)
|
85
|
+
* [Q: How to add metadata to actions or options?](#q-how-to-add-metadata-to-actions-or-options)
|
86
|
+
* [Q: How to remove common help option from all actions?](#q-how-to-remove-common-help-option-from-all-actions)
|
87
|
+
* [Q: Is it possible to show details of actions and aliases?](#q-is-it-possible-to-show-details-of-actions-and-aliases)
|
88
|
+
* [Q: How to make error messages I18Ned?](#q-how-to-make-error-messages-i18ned)
|
76
89
|
* [License and Copyright](#license-and-copyright)
|
77
90
|
|
78
91
|
<!-- /TOC -->
|
@@ -87,40 +100,49 @@ $ gem install benry-cmdapp
|
|
87
100
|
|
88
101
|
|
89
102
|
|
90
|
-
## Usage
|
103
|
+
## Basic Usage
|
91
104
|
|
92
105
|
|
93
106
|
### Action
|
94
107
|
|
95
|
-
|
108
|
+
How to define actions:
|
109
|
+
|
110
|
+
* (1) Inherit action class.
|
111
|
+
* (2) Define action methods with `@action.()`.
|
112
|
+
* (3) Create an application object and run it.
|
113
|
+
|
114
|
+
Note:
|
115
|
+
|
116
|
+
* Use `@action.()`, not `@action()`.
|
117
|
+
* Command-line arguments are passed to action method as positional arguments.
|
96
118
|
* An action class can have several action methods.
|
97
119
|
* It is ok to define multiple action classes.
|
98
|
-
* Command-line arguments are passed to action method as positional arguments.
|
99
120
|
|
100
121
|
File: ex01.rb
|
101
122
|
|
102
123
|
```ruby
|
103
|
-
|
124
|
+
# coding: utf-8
|
104
125
|
require 'benry/cmdapp'
|
105
126
|
|
106
|
-
## action
|
127
|
+
## (1) Inherit action class.
|
107
128
|
class MyAction < Benry::CmdApp::Action # !!!!
|
108
129
|
|
130
|
+
## (2) Define action methods with `@action.()`.
|
109
131
|
@action.("print greeting message") # !!!!
|
110
|
-
def hello(
|
111
|
-
puts "Hello, #{
|
132
|
+
def hello(name="world") # !!!!
|
133
|
+
puts "Hello, #{name}!"
|
112
134
|
end
|
113
135
|
|
114
136
|
end
|
115
137
|
|
116
|
-
##
|
117
|
-
|
118
|
-
config.default_help = true
|
119
|
-
|
120
|
-
## run application
|
121
|
-
app = Benry::CmdApp::Application.new(config)
|
122
|
-
status_code = app.main()
|
138
|
+
## (3) Create an application object and run it.
|
139
|
+
status_code = Benry::CmdApp.main("sample app", "1.0.0")
|
123
140
|
exit status_code
|
141
|
+
## or:
|
142
|
+
#config = Benry::CmdApp::Config.new("sample app", "1.0.0")
|
143
|
+
#app = Benry::CmdApp::Application.new(config)
|
144
|
+
#status_code = app.main()
|
145
|
+
#exit status_code
|
124
146
|
```
|
125
147
|
|
126
148
|
Output:
|
@@ -137,32 +159,48 @@ Help message of command:
|
|
137
159
|
|
138
160
|
```console
|
139
161
|
[bash]$ ruby ex01.rb -h # or `--help`
|
140
|
-
ex01.rb (1.0.0)
|
162
|
+
ex01.rb (1.0.0) --- sample app
|
141
163
|
|
142
164
|
Usage:
|
143
|
-
$ ex01.rb [<options>]
|
165
|
+
$ ex01.rb [<options>] <action> [<arguments>...]
|
144
166
|
|
145
167
|
Options:
|
146
|
-
-h, --help : print help message (of action if
|
168
|
+
-h, --help : print help message (of action if specified)
|
147
169
|
-V, --version : print version
|
170
|
+
-l, --list : list actions and aliases
|
171
|
+
-a, --all : list hidden actions/options, too
|
148
172
|
|
149
173
|
Actions:
|
150
174
|
hello : print greeting message
|
175
|
+
help : print help message (of action if specified)
|
151
176
|
```
|
152
177
|
|
153
178
|
Help message of action:
|
154
179
|
|
155
180
|
```console
|
156
|
-
[bash]$ ruby ex01.rb -h hello
|
157
|
-
ex01.rb hello
|
181
|
+
[bash]$ ruby ex01.rb -h hello # or: ruby ex01.rb --help hello
|
182
|
+
ex01.rb hello --- print greeting message
|
183
|
+
|
184
|
+
Usage:
|
185
|
+
$ ex01.rb hello [<name>]
|
186
|
+
```
|
187
|
+
|
188
|
+
* Benry-CmdApp adds `-h` and `--help` options to each action automatically.
|
189
|
+
Output of `ruby ex01.rb hello -h` and `ruby ex01.rb -h hello` will be the same.
|
190
|
+
|
191
|
+
```console
|
192
|
+
[bash]$ ruby ex01.rb hello -h # or: ruby ex01.rb helo --help
|
193
|
+
ex01.rb hello --- print greeting message
|
158
194
|
|
159
195
|
Usage:
|
160
|
-
$ ex01.rb hello [<
|
196
|
+
$ ex01.rb hello [<name>]
|
161
197
|
```
|
162
198
|
|
163
199
|
|
164
200
|
### Method Name and Action Name
|
165
201
|
|
202
|
+
Rules between method name and action name:
|
203
|
+
|
166
204
|
* Method name `print_` results in action name `print`.
|
167
205
|
This is useful to define actions which name is same as Ruby keyword or popular functions.
|
168
206
|
* Method name `foo_bar_baz` results in action name `foo-bar-baz`.
|
@@ -171,7 +209,7 @@ Usage:
|
|
171
209
|
File: ex02.rb
|
172
210
|
|
173
211
|
```ruby
|
174
|
-
|
212
|
+
# coding: utf-8
|
175
213
|
require 'benry/cmdapp'
|
176
214
|
|
177
215
|
class SampleAction < Benry::CmdApp::Action
|
@@ -196,26 +234,33 @@ class SampleAction < Benry::CmdApp::Action
|
|
196
234
|
|
197
235
|
end
|
198
236
|
|
199
|
-
|
200
|
-
|
201
|
-
|
237
|
+
status_code = Benry::CmdApp.main("test app")
|
238
|
+
exit status_code
|
239
|
+
## or:
|
240
|
+
#config = Benry::CmdApp::Config.new("test app")
|
241
|
+
#app = Benry::CmdApp::Application.new(config)
|
242
|
+
#status_code = app.main()
|
243
|
+
#exit status_code
|
202
244
|
```
|
203
245
|
|
204
246
|
Help message:
|
205
247
|
|
206
248
|
```console
|
207
249
|
[bash]$ ruby ex02.rb --help
|
208
|
-
ex02.rb
|
250
|
+
ex02.rb --- test app
|
209
251
|
|
210
252
|
Usage:
|
211
|
-
$ ex02.rb [<options>]
|
253
|
+
$ ex02.rb [<options>] <action> [<arguments>...]
|
212
254
|
|
213
255
|
Options:
|
214
|
-
-h, --help : print help message (of action if
|
256
|
+
-h, --help : print help message (of action if specified)
|
257
|
+
-l, --list : list actions and aliases
|
258
|
+
-a, --all : list hidden actions/options, too
|
215
259
|
|
216
260
|
Actions:
|
217
261
|
foo-bar-baz : sample #2
|
218
262
|
foo:bar:baz : sample #3
|
263
|
+
help : print help message (of action if specified)
|
219
264
|
print : sample #1
|
220
265
|
```
|
221
266
|
|
@@ -235,62 +280,85 @@ foo__bar__baz
|
|
235
280
|
|
236
281
|
### Parameter Name in Help Message of Action
|
237
282
|
|
238
|
-
In help message of action, positional parameters of action methods are printed under the name conversion rule.
|
283
|
+
In help message of an action, positional parameters of action methods are printed under the name conversion rule.
|
239
284
|
|
240
285
|
* Parameter `foo` is printed as `<foo>`.
|
241
286
|
* Parameter `foo_bar_baz` is printed as `<foo-bar-baz>`.
|
242
287
|
* Parameter `foo_or_bar_or_baz` is printed as `<foo|bar|baz>`.
|
288
|
+
* Parameter `foobar__xxx` is printed as `<foobar.xxx>`.
|
243
289
|
|
244
290
|
In addition, positional parameters are printed in different way according to its kind.
|
245
291
|
|
246
292
|
* If parameter `foo` is required (= doesn't have default value), it will be printed as `<foo>`.
|
247
293
|
* If parameter `foo` is optional (= has default value), it will be printed as `[<foo>]`.
|
248
294
|
* If parameter `foo` is variable length (= `*foo` style), it will be printed as `[<foo>...]`.
|
295
|
+
* If parameter `foo` is required or optional and `foo_` is variable length, it will be printed as `<foo>...`.
|
249
296
|
|
250
297
|
|
251
298
|
File: ex03.rb
|
252
299
|
|
253
300
|
```ruby
|
254
|
-
|
301
|
+
# coding: utf-8
|
255
302
|
require 'benry/cmdapp'
|
256
303
|
|
257
304
|
class SampleAction < Benry::CmdApp::Action
|
258
305
|
|
259
|
-
@action.("
|
260
|
-
def test1(
|
306
|
+
@action.("name conversion test")
|
307
|
+
def test1(file_name, file_or_dir, file__html) # !!!!
|
308
|
+
# ...
|
309
|
+
end
|
310
|
+
|
311
|
+
@action.("parameter kind test")
|
312
|
+
def test2(aaa, bbb, ccc=nil, ddd=nil, *eee) # !!!!
|
313
|
+
# ...
|
314
|
+
end
|
315
|
+
|
316
|
+
@action.("parameter combination test")
|
317
|
+
def test3(file, *file_) # !!!!
|
318
|
+
files = [file] + file_
|
261
319
|
# ...
|
262
320
|
end
|
263
321
|
|
264
322
|
end
|
265
323
|
|
266
|
-
|
267
|
-
|
268
|
-
exit app.main()
|
324
|
+
status_code = Benry::CmdApp.main("sample app", "1.0.0")
|
325
|
+
exit status_code
|
269
326
|
```
|
270
327
|
|
271
328
|
Help message:
|
272
329
|
|
273
330
|
```console
|
274
331
|
[bash]$ ruby ex03.rb -h test1
|
275
|
-
|
332
|
+
ex03.rb test1 --- name conversion test
|
333
|
+
|
334
|
+
Usage:
|
335
|
+
$ ex03.rb test1 <file-name> <file|dir> <file.html> # !!!!
|
336
|
+
|
337
|
+
[bash]$ ruby ex03.rb -h test2
|
338
|
+
ex03.rb test2 --- parameter kind test
|
276
339
|
|
277
340
|
Usage:
|
278
|
-
$ ex03.rb
|
341
|
+
$ ex03.rb test2 <aaa> <bbb> [<ccc> [<ddd> [<eee>...]]] # !!!!
|
342
|
+
|
343
|
+
[bash]$ ruby ex03.rb -h test3
|
344
|
+
ex03.rb test3 --- parameter combination test
|
345
|
+
|
346
|
+
Usage:
|
347
|
+
$ ex03.rb test3 <file>... # !!!!
|
279
348
|
```
|
280
349
|
|
281
350
|
|
282
351
|
### Options
|
283
352
|
|
284
353
|
* Action can take command-line options.
|
285
|
-
* Option values specified in command-line are passed to
|
354
|
+
* Option values specified in command-line are passed to action method as keyword arguments.
|
286
355
|
|
287
356
|
File: ex04.rb
|
288
357
|
|
289
358
|
```ruby
|
290
|
-
|
359
|
+
# coding: utf-8
|
291
360
|
require 'benry/cmdapp'
|
292
361
|
|
293
|
-
## action
|
294
362
|
class MyAction < Benry::CmdApp::Action
|
295
363
|
|
296
364
|
@action.("print greeting message")
|
@@ -301,20 +369,13 @@ class MyAction < Benry::CmdApp::Action
|
|
301
369
|
when "fr" ; puts "Bonjour, #{user}!"
|
302
370
|
when "it" ; puts "Ciao, #{user}!"
|
303
371
|
else
|
304
|
-
raise "#{lang}:
|
372
|
+
raise "#{lang}: Unknown language."
|
305
373
|
end
|
306
374
|
end
|
307
375
|
|
308
376
|
end
|
309
377
|
|
310
|
-
|
311
|
-
config = Benry::CmdApp::Config.new("sample app", "1.0.0")
|
312
|
-
config.default_help = true
|
313
|
-
|
314
|
-
## run application
|
315
|
-
app = Benry::CmdApp::Application.new(config)
|
316
|
-
status_code = app.main()
|
317
|
-
exit status_code
|
378
|
+
exit Benry::CmdApp.main("sample app", "1.0.0")
|
318
379
|
```
|
319
380
|
|
320
381
|
Output:
|
@@ -336,10 +397,9 @@ Ciao, world!
|
|
336
397
|
File: ex05.rb
|
337
398
|
|
338
399
|
```ruby
|
339
|
-
|
400
|
+
# coding: utf-8
|
340
401
|
require 'benry/cmdapp'
|
341
402
|
|
342
|
-
## action
|
343
403
|
class MyAction < Benry::CmdApp::Action
|
344
404
|
|
345
405
|
@action.("print greeting message")
|
@@ -353,21 +413,14 @@ class MyAction < Benry::CmdApp::Action
|
|
353
413
|
when "fr" ; puts "Bonjour, #{user}!"
|
354
414
|
when "it" ; puts "Ciao, #{user}!"
|
355
415
|
else
|
356
|
-
raise "#{lang}:
|
416
|
+
raise "#{lang}: Unknown language."
|
357
417
|
end
|
358
418
|
end
|
359
419
|
end
|
360
420
|
|
361
421
|
end
|
362
422
|
|
363
|
-
|
364
|
-
config = Benry::CmdApp::Config.new("sample app", "1.0.0")
|
365
|
-
config.default_help = true
|
366
|
-
|
367
|
-
## run application
|
368
|
-
app = Benry::CmdApp::Application.new(config)
|
369
|
-
status_code = app.main()
|
370
|
-
exit status_code
|
423
|
+
exit Benry::CmdApp.main("sample app", "1.0.0")
|
371
424
|
```
|
372
425
|
|
373
426
|
Output:
|
@@ -377,51 +430,75 @@ Output:
|
|
377
430
|
Bonjour, Alice!
|
378
431
|
Bonjour, Alice!
|
379
432
|
Bonjour, Alice!
|
380
|
-
|
433
|
+
```
|
381
434
|
|
382
435
|
Help message:
|
383
436
|
|
384
437
|
```console
|
385
438
|
[bash]$ ruby ex05.rb -h hello
|
386
|
-
ex05.rb hello
|
439
|
+
ex05.rb hello --- print greeting message
|
387
440
|
|
388
441
|
Usage:
|
389
442
|
$ ex05.rb hello [<options>] [<user>]
|
390
443
|
|
391
444
|
Options:
|
392
|
-
-l, --lang=<en|fr|it> : language
|
445
|
+
-l, --lang=<en|fr|it> : language
|
393
446
|
--repeat=<N> : repeat <N> times # !!!!
|
394
447
|
```
|
395
448
|
|
396
|
-
|
397
|
-
|
398
|
-
|
449
|
+
* If an option defined but the corresponding keyword argument is missing, error will be raised.
|
450
|
+
* If an action method accepts any keyword arguments (such as `**kwargs`), nothing will be raised.
|
451
|
+
|
452
|
+
```ruby
|
453
|
+
### ERROR: option `:repeat` is defined but keyword arg `repeat:` is missing.
|
454
|
+
@action.("greeting message")
|
455
|
+
@option.(:lang , "-l <lang>", "language")
|
456
|
+
@option.(:repeat, "-n <N>" , "repeat N times")
|
457
|
+
def hello(user="world", lang: "en")
|
458
|
+
....
|
459
|
+
end
|
460
|
+
|
461
|
+
### NO ERROR: `**kwargs` accepts any keyword arguments.
|
462
|
+
@action.("greeting message")
|
463
|
+
@option.(:lang , "-l <lang>", "language")
|
464
|
+
@option.(:repeat, "-n <N>" , "repeat N times")
|
465
|
+
def hello(user="world", lang: "en", **kwargs)
|
466
|
+
....
|
467
|
+
end
|
468
|
+
```
|
469
|
+
|
470
|
+
For usability reason, Benry-CmdApp supports `--lang=<val>` style of long option
|
471
|
+
but doesn't support `--lang <val>` style.
|
472
|
+
Benry-CmdApp regards `--lang <val>` as 'long option without argument'
|
399
473
|
and 'argument for command'.
|
400
474
|
|
401
475
|
```console
|
402
476
|
[bash]$ ruby ex05.rb hello --lang fr # ``--lang fr`` != ``--lang=fr``
|
403
|
-
[ERROR] --lang:
|
477
|
+
[ERROR] --lang: Argument required.
|
404
478
|
```
|
405
479
|
|
406
480
|
|
407
481
|
### Option Definition Format
|
408
482
|
|
409
|
-
|
410
|
-
|
411
|
-
*
|
412
|
-
*
|
413
|
-
*
|
414
|
-
*
|
415
|
-
*
|
416
|
-
*
|
417
|
-
*
|
418
|
-
*
|
419
|
-
*
|
483
|
+
There are 9 option definition formats.
|
484
|
+
|
485
|
+
* When the option takes no value:
|
486
|
+
* `-q` --- Short style.
|
487
|
+
* `--quiet` --- Long style.
|
488
|
+
* `-q, --quiet` --- Short and long style.
|
489
|
+
* When the option takes a required value:
|
490
|
+
* `-f <path>` --- Short style.
|
491
|
+
* `--file=<path>` --- Long style.
|
492
|
+
* `-f, --file=<path>` --- Short and long style.
|
493
|
+
* When the option takes an optional value:
|
494
|
+
* `-i[<N>]` --- Short style.
|
495
|
+
* `--indent[=<N>]` --- Long style.
|
496
|
+
* `-i, --indent[=<N>]` --- Short and long style.
|
420
497
|
|
421
498
|
File: ex06.rb
|
422
499
|
|
423
500
|
```ruby
|
424
|
-
|
501
|
+
# coding: utf-8
|
425
502
|
require 'benry/cmdapp'
|
426
503
|
|
427
504
|
class SampleAction < Benry::CmdApp::Action
|
@@ -455,9 +532,7 @@ class SampleAction < Benry::CmdApp::Action
|
|
455
532
|
|
456
533
|
end
|
457
534
|
|
458
|
-
|
459
|
-
app = Benry::CmdApp::Application.new(config)
|
460
|
-
exit app.main()
|
535
|
+
exit Benry::CmdApp.main("test app")
|
461
536
|
```
|
462
537
|
|
463
538
|
Output:
|
@@ -493,7 +568,7 @@ Help message:
|
|
493
568
|
|
494
569
|
```ruby
|
495
570
|
[bash]$ ruby ex06.rb -h test1
|
496
|
-
ex06.rb test1
|
571
|
+
ex06.rb test1 --- short options
|
497
572
|
|
498
573
|
Usage:
|
499
574
|
$ ex06.rb test1 [<options>]
|
@@ -504,7 +579,7 @@ Options:
|
|
504
579
|
-i[<N>] : indent width
|
505
580
|
|
506
581
|
[bash]$ ruby ex06.rb -h test2
|
507
|
-
ex06.rb test2
|
582
|
+
ex06.rb test2 --- long options
|
508
583
|
|
509
584
|
Usage:
|
510
585
|
$ ex06.rb test2 [<options>]
|
@@ -515,7 +590,7 @@ Options:
|
|
515
590
|
--indent[=<N>] : indent width
|
516
591
|
|
517
592
|
[bash]$ ruby ex06.rb -h test3
|
518
|
-
ex06.rb test3
|
593
|
+
ex06.rb test3 --- short and long options
|
519
594
|
|
520
595
|
Usage:
|
521
596
|
$ ex06.rb test3 [<options>]
|
@@ -540,10 +615,9 @@ Options:
|
|
540
615
|
File: ex07.rb
|
541
616
|
|
542
617
|
```ruby
|
543
|
-
|
618
|
+
# coding: utf-8
|
544
619
|
require 'benry/cmdapp'
|
545
620
|
|
546
|
-
## action
|
547
621
|
class MyAction < Benry::CmdApp::Action
|
548
622
|
|
549
623
|
@action.("print greeting message")
|
@@ -560,34 +634,27 @@ class MyAction < Benry::CmdApp::Action
|
|
560
634
|
when "fr" ; puts "Bonjour, #{user}!"
|
561
635
|
when "it" ; puts "Ciao, #{user}!"
|
562
636
|
else
|
563
|
-
raise "#{lang}:
|
637
|
+
raise "#{lang}: Unknown language."
|
564
638
|
end
|
565
639
|
end
|
566
640
|
end
|
567
641
|
|
568
642
|
end
|
569
643
|
|
570
|
-
|
571
|
-
config = Benry::CmdApp::Config.new("sample app", "1.0.0")
|
572
|
-
config.default_help = true
|
573
|
-
|
574
|
-
## run application
|
575
|
-
app = Benry::CmdApp::Application.new(config)
|
576
|
-
status_code = app.main()
|
577
|
-
exit status_code
|
644
|
+
exit Benry::CmdApp.main("sample app", "1.0.0")
|
578
645
|
```
|
579
646
|
|
580
647
|
Output:
|
581
648
|
|
582
649
|
```console
|
583
650
|
[bash]$ ruby ex07.rb hello -l japan
|
584
|
-
[ERROR] -l japan:
|
651
|
+
[ERROR] -l japan: Pattern unmatched.
|
585
652
|
|
586
653
|
[bash]$ ruby ex07.rb hello -l ja
|
587
|
-
[ERROR] -l ja:
|
654
|
+
[ERROR] -l ja: Expected one of en/fr/it.
|
588
655
|
|
589
656
|
[bash]$ ruby ex07.rb hello --repeat=abc
|
590
|
-
[ERROR] --repeat=abc:
|
657
|
+
[ERROR] --repeat=abc: Integer expected.
|
591
658
|
|
592
659
|
[bash]$ ruby ex07.rb hello --repeat=100
|
593
660
|
[ERROR] --repeat=100: Too large (max: 10).
|
@@ -605,10 +672,9 @@ Callback can:
|
|
605
672
|
File: ex08.rb
|
606
673
|
|
607
674
|
```ruby
|
608
|
-
|
675
|
+
# coding: utf-8
|
609
676
|
require 'benry/cmdapp'
|
610
677
|
|
611
|
-
## action
|
612
678
|
class MyAction < Benry::CmdApp::Action
|
613
679
|
|
614
680
|
@action.("print greeting message")
|
@@ -617,7 +683,7 @@ class MyAction < Benry::CmdApp::Action
|
|
617
683
|
rexp: /\A\w\w\z/) {|v| v.downcase } # !!!!
|
618
684
|
@option.(:repeat, " --repeat=<N>", "repeat <N> times",
|
619
685
|
type: Integer) {|v| # !!!!
|
620
|
-
v > 0 or raise "
|
686
|
+
v > 0 or raise "Not positive value." # !!!!
|
621
687
|
v # !!!!
|
622
688
|
} # !!!!
|
623
689
|
def hello(user="world", lang: "en", repeat: 1)
|
@@ -627,21 +693,14 @@ class MyAction < Benry::CmdApp::Action
|
|
627
693
|
when "fr" ; puts "Bonjour, #{user}!"
|
628
694
|
when "it" ; puts "Ciao, #{user}!"
|
629
695
|
else
|
630
|
-
raise "#{lang}:
|
696
|
+
raise "#{lang}: Unknown language."
|
631
697
|
end
|
632
698
|
end
|
633
699
|
end
|
634
700
|
|
635
701
|
end
|
636
702
|
|
637
|
-
|
638
|
-
config = Benry::CmdApp::Config.new("sample app", "1.0.0")
|
639
|
-
config.default_help = true
|
640
|
-
|
641
|
-
## run application
|
642
|
-
app = Benry::CmdApp::Application.new(config)
|
643
|
-
status_code = app.main()
|
644
|
-
exit status_code
|
703
|
+
exit Benry::CmdApp.main("sample app", "1.0.0")
|
645
704
|
```
|
646
705
|
|
647
706
|
Output:
|
@@ -651,13 +710,13 @@ Output:
|
|
651
710
|
Bonjour, world!
|
652
711
|
|
653
712
|
[bash]$ ruby ex08.rb hello --repeat=0
|
654
|
-
[ERROR] --repeat=0:
|
713
|
+
[ERROR] --repeat=0: Not positive value.
|
655
714
|
```
|
656
715
|
|
657
716
|
|
658
717
|
### Boolean (On/Off) Option
|
659
718
|
|
660
|
-
Benry
|
719
|
+
Benry-CmdApp doesn't support `--[no-]foobar` style option.
|
661
720
|
Instead, define boolean (on/off) option.
|
662
721
|
|
663
722
|
* Specify `type: TrueClass` to `@option.()`.
|
@@ -667,7 +726,7 @@ Instead, define boolean (on/off) option.
|
|
667
726
|
File: ex09.rb
|
668
727
|
|
669
728
|
```ruby
|
670
|
-
|
729
|
+
# coding: utf-8
|
671
730
|
require 'benry/cmdapp'
|
672
731
|
|
673
732
|
class SampleAction < Benry::CmdApp::Action
|
@@ -682,9 +741,7 @@ class SampleAction < Benry::CmdApp::Action
|
|
682
741
|
|
683
742
|
end
|
684
743
|
|
685
|
-
|
686
|
-
app = Benry::CmdApp::Application.new(config)
|
687
|
-
exit app.main()
|
744
|
+
exit Benry::CmdApp.main("sample app", "1.0.0")
|
688
745
|
```
|
689
746
|
|
690
747
|
Output:
|
@@ -720,7 +777,7 @@ If you want default value of flag to `true`, use `value:` keyword argument.
|
|
720
777
|
File: ex10.rb
|
721
778
|
|
722
779
|
```ruby
|
723
|
-
|
780
|
+
# coding: utf-8
|
724
781
|
require 'benry/cmdapp'
|
725
782
|
|
726
783
|
class SampleAction < Benry::CmdApp::Action
|
@@ -734,9 +791,7 @@ class SampleAction < Benry::CmdApp::Action
|
|
734
791
|
|
735
792
|
end
|
736
793
|
|
737
|
-
|
738
|
-
app = Benry::CmdApp::Application.new(config)
|
739
|
-
exit app.main()
|
794
|
+
exit Benry::CmdApp.main("git helper")
|
740
795
|
```
|
741
796
|
|
742
797
|
Output:
|
@@ -749,7 +804,7 @@ verbose=true
|
|
749
804
|
verbose=false
|
750
805
|
|
751
806
|
[bash]$ ruby ex10.rb flagtest2 --quiet=on # error
|
752
|
-
[ERROR] --quiet=on:
|
807
|
+
[ERROR] --quiet=on: Unexpected argument.
|
753
808
|
```
|
754
809
|
|
755
810
|
In above example, `--quiet=on` will be error because option is defined as
|
@@ -761,8 +816,8 @@ If you want to allow `--quiet=on`, specify option argument and `type: TrueClass`
|
|
761
816
|
...(snip)...
|
762
817
|
|
763
818
|
@action.("flag test")
|
764
|
-
@option.(:verbose, "-q, --quiet[=<on|off]", "quiet mode", # !!!!
|
765
|
-
type: TrueClass, value: false)
|
819
|
+
@option.(:verbose, "-q, --quiet[=<on|off>]", "quiet mode", # !!!!
|
820
|
+
type: TrueClass, value: false) # !!!!
|
766
821
|
def flagtest2(verbose: true)
|
767
822
|
puts "verbose=#{verbose.inspect}"
|
768
823
|
end
|
@@ -771,380 +826,850 @@ If you want to allow `--quiet=on`, specify option argument and `type: TrueClass`
|
|
771
826
|
```
|
772
827
|
|
773
828
|
|
774
|
-
###
|
829
|
+
### Option Set
|
775
830
|
|
776
|
-
|
777
|
-
|
831
|
+
Option set handles multiple options as a object.
|
832
|
+
Option set will help you to define same options into multiple actions.
|
778
833
|
|
779
834
|
File: ex11.rb
|
780
835
|
|
781
836
|
```ruby
|
782
|
-
|
837
|
+
# coding: utf-8
|
783
838
|
require 'benry/cmdapp'
|
784
839
|
|
785
840
|
class SampleAction < Benry::CmdApp::Action
|
786
|
-
prefix "foo:bar" # !!!!
|
787
841
|
|
788
|
-
|
789
|
-
|
790
|
-
|
842
|
+
optset1 = optionset() { # !!!!
|
843
|
+
@option.(:host , "-H, --host=<host>" , "host name")
|
844
|
+
@option.(:port , "-p, --port=<port>" , "port number", type: Integer)
|
845
|
+
}
|
846
|
+
optset2 = optionset() { # !!!!
|
847
|
+
@option.(:user , "-u, --user=<user>" , "user name")
|
848
|
+
}
|
849
|
+
|
850
|
+
@action.("connect to postgresql server")
|
851
|
+
@optionset.(optset1, optset2) # !!!!
|
852
|
+
def postgresql(host: nil, port: nil, user: nil)
|
853
|
+
puts "psql ...."
|
791
854
|
end
|
792
855
|
|
793
|
-
@action.("
|
794
|
-
|
795
|
-
|
856
|
+
@action.("connect to mysql server")
|
857
|
+
@optionset.(optset1, optset2) # !!!!
|
858
|
+
def mysql(host: nil, port: nil, user: nil)
|
859
|
+
puts "mysql ...."
|
796
860
|
end
|
797
861
|
|
798
862
|
end
|
799
863
|
|
800
|
-
|
801
|
-
app = Benry::CmdApp::Application.new(config)
|
802
|
-
exit app.main()
|
864
|
+
exit Benry::CmdApp.main("Sample App")
|
803
865
|
```
|
804
866
|
|
805
|
-
|
867
|
+
Help message:
|
806
868
|
|
807
869
|
```console
|
808
|
-
[bash]$ ruby ex11.rb
|
809
|
-
|
870
|
+
[bash]$ ruby ex11.rb -h postgresql # !!!!
|
871
|
+
ex11.rb postgresql --- connect to postgresql
|
810
872
|
|
811
|
-
|
812
|
-
|
813
|
-
```
|
873
|
+
Usage:
|
874
|
+
$ ex11.rb postgresql [<options>]
|
814
875
|
|
815
|
-
|
876
|
+
Options:
|
877
|
+
-H, --host=<host> : host name # !!!!
|
878
|
+
-p, --port=<port> : port number # !!!!
|
879
|
+
-u, --user=<user> : user name # !!!!
|
816
880
|
|
817
|
-
|
818
|
-
|
819
|
-
ex11.rb -- sample app
|
881
|
+
[bash]$ ruby ex11.rb -h mysql # !!!!
|
882
|
+
ex11.rb mysql --- connect to mysql
|
820
883
|
|
821
884
|
Usage:
|
822
|
-
$ ex11.rb [<options>]
|
885
|
+
$ ex11.rb mysql [<options>]
|
823
886
|
|
824
887
|
Options:
|
825
|
-
-
|
888
|
+
-H, --host=<host> : host name # !!!!
|
889
|
+
-p, --port=<port> : port number # !!!!
|
890
|
+
-u, --user=<user> : user name # !!!!
|
891
|
+
```
|
826
892
|
|
827
|
-
|
828
|
-
|
829
|
-
|
893
|
+
Option set object has the following methods.
|
894
|
+
|
895
|
+
* `OptionSet#select(:key1, :key2, ...)` ---
|
896
|
+
Creates new OptionSet object with copying options which are filtered by the keys specified.
|
897
|
+
* `OptionSet#exclude(:key1, :key2, ...)` ---
|
898
|
+
Creates new OptionSet object with copying options which are filtered by dropping the options that key is included in specified keys.
|
899
|
+
|
900
|
+
```ruby
|
901
|
+
@action.("connect to postgresql server")
|
902
|
+
@optionset.(optset1.select(:host, :port)) # !!!!
|
903
|
+
def postgresql(host: nil, port: nil)
|
904
|
+
....
|
905
|
+
end
|
906
|
+
|
907
|
+
@action.("connect to mysql server")
|
908
|
+
@optionset.(optset1.exclude(:port)) # !!!!
|
909
|
+
def mysql(host: nil)
|
910
|
+
....
|
911
|
+
end
|
830
912
|
```
|
831
913
|
|
832
|
-
|
914
|
+
|
915
|
+
### Copy Options
|
916
|
+
|
917
|
+
`@copy_options.()` copies options from other action.
|
833
918
|
|
834
919
|
File: ex12.rb
|
835
920
|
|
836
921
|
```ruby
|
837
|
-
|
922
|
+
# coding: utf-8
|
838
923
|
require 'benry/cmdapp'
|
839
924
|
|
840
925
|
class SampleAction < Benry::CmdApp::Action
|
841
|
-
prefix "foo:bar", action: :test3_ # !!!!
|
842
|
-
## or:
|
843
|
-
#prefix "foo:bar", action: "test3" # !!!!
|
844
926
|
|
845
|
-
@action.("
|
846
|
-
|
847
|
-
|
927
|
+
@action.("connect to postgresql")
|
928
|
+
@option.(:host , "-H, --host=<host>" , "host name")
|
929
|
+
@option.(:port , "-p, --port=<port>" , "port number", type: Integer)
|
930
|
+
@option.(:user , "-u, --user=<user>" , "user name")
|
931
|
+
def postgresql(host: nil, port: nil, user: nil)
|
932
|
+
puts "psql ...."
|
848
933
|
end
|
849
934
|
|
850
|
-
@action.("
|
851
|
-
|
852
|
-
|
935
|
+
@action.("connect to mysql")
|
936
|
+
@copy_options.("postgresql") # !!!!!
|
937
|
+
def mysql(host: nil, port: nil, user: nil)
|
938
|
+
puts "mysql ...."
|
853
939
|
end
|
854
940
|
|
855
941
|
end
|
856
942
|
|
857
|
-
|
858
|
-
app = Benry::CmdApp::Application.new(config)
|
859
|
-
exit app.main()
|
860
|
-
```
|
861
|
-
|
862
|
-
Output:
|
863
|
-
|
864
|
-
```console
|
865
|
-
[bash]$ ruby ex12.rb foo:bar:test1
|
866
|
-
test1
|
867
|
-
|
868
|
-
[bash]$ ruby ex12.rb foo:bar:test3
|
869
|
-
[ERROR] foo:bar:test2: unknown action.
|
870
|
-
|
871
|
-
[bash]$ ruby ex12.rb foo:bar
|
872
|
-
test3_
|
943
|
+
exit Benry::CmdApp.main("Sample App")
|
873
944
|
```
|
874
945
|
|
875
946
|
Help message:
|
876
947
|
|
877
948
|
```console
|
878
|
-
[bash]$ ruby ex12.rb -h
|
879
|
-
ex12.rb
|
949
|
+
[bash]$ ruby ex12.rb -h mysql # !!!!
|
950
|
+
ex12.rb mysql --- connect to mysql
|
880
951
|
|
881
952
|
Usage:
|
882
|
-
$ ex12.rb [<options>]
|
953
|
+
$ ex12.rb mysql [<options>]
|
883
954
|
|
884
955
|
Options:
|
885
|
-
-
|
886
|
-
|
887
|
-
|
888
|
-
foo:bar : test action #3
|
889
|
-
foo:bar:test1 : test action #1
|
956
|
+
-H, --host=<host> : host name
|
957
|
+
-p, --port=<port> : port number
|
958
|
+
-u, --user=<user> : user name
|
890
959
|
```
|
891
960
|
|
961
|
+
If you want to exclude some options from copying, specify `exlude:` keyword argument.
|
962
|
+
For example, `@copy_options.("hello", exclude: [:help, :lang])` copies all options of `hello` action excluding `:help` and `:lang` options.
|
892
963
|
|
893
|
-
### Invoke Other Action
|
894
964
|
|
895
|
-
|
896
|
-
|
897
|
-
|
965
|
+
### Option Error and Action Error
|
966
|
+
|
967
|
+
* `option_error()` returns (not raise) `Benry::CmdApp::OptionError` object.
|
968
|
+
* `action_error()` returns (not raise) `Benry::CmdApp::ActionError` object.
|
969
|
+
* These are available in action method.
|
898
970
|
|
899
971
|
File: ex13.rb
|
900
972
|
|
901
973
|
```ruby
|
902
|
-
|
974
|
+
# coding: utf-8
|
903
975
|
require 'benry/cmdapp'
|
904
976
|
|
905
977
|
class SampleAction < Benry::CmdApp::Action
|
906
978
|
|
907
|
-
@action.("
|
908
|
-
|
909
|
-
|
910
|
-
|
911
|
-
|
912
|
-
|
913
|
-
|
914
|
-
|
915
|
-
|
916
|
-
|
917
|
-
|
918
|
-
|
979
|
+
@action.("invoke openssl command")
|
980
|
+
@option.(:encrypt, "--encrypt", "encrypt a file")
|
981
|
+
@option.(:decrypt, "--decrypt", "decrypt a file")
|
982
|
+
def openssl(filename, encrypt: false, decrypt: false)
|
983
|
+
if encrypt == false && decrypt == false
|
984
|
+
raise option_error("Required '--encrypt' or '--decrypt' option.") # !!!!
|
985
|
+
end
|
986
|
+
opt = encrypt ? "enc" : "dec"
|
987
|
+
command = "openssl #{opt} ..."
|
988
|
+
result = system command
|
989
|
+
if result == false
|
990
|
+
raise action_error("Command failed: #{command}") # !!!!
|
991
|
+
end
|
919
992
|
end
|
920
993
|
|
921
994
|
end
|
922
995
|
|
923
|
-
|
924
|
-
app = Benry::CmdApp::Application.new(config)
|
925
|
-
exit app.main()
|
996
|
+
exit Benry::CmdApp.main("Sample App")
|
926
997
|
```
|
927
998
|
|
928
999
|
Output:
|
929
1000
|
|
930
1001
|
```console
|
931
|
-
[bash]$ ruby ex13.rb
|
932
|
-
|
933
|
-
|
934
|
-
|
935
|
-
|
1002
|
+
[bash]$ ruby ex13.rb openssl file.txt
|
1003
|
+
[ERROR] Required '--encrypt' or '--decrypt' option. #<== option_error()
|
1004
|
+
|
1005
|
+
[bash]$ ruby ex13.rb openssl --encrypt file.txt
|
1006
|
+
enc: Use -help for summary.
|
1007
|
+
[ERROR] Command failed: openssl enc ... #<== action_error()
|
1008
|
+
From ex13.rb:17:in `openssl'
|
1009
|
+
raise action_error("Command failed: #{command}")
|
1010
|
+
From ex13.rb:25:in `<main>'
|
1011
|
+
exit app.main()
|
1012
|
+
```
|
1013
|
+
|
1014
|
+
If you want to show all stacktrace, add `--debug` global option.
|
1015
|
+
|
1016
|
+
```console
|
1017
|
+
[bash]$ ruby ex13.rb --debug openssl --encrypt file.txt
|
1018
|
+
enc: Use -help for summary.
|
1019
|
+
ex13.rb:17:in `openssl': Command failed: openssl enc ... (Benry::CmdApp::ActionError)
|
1020
|
+
from /home/yourname/cmdapp.rb:988:in `_invoke_action'
|
1021
|
+
from /home/yourname/cmdapp.rb:927:in `start_action'
|
1022
|
+
from /home/yourname/cmdapp.rb:1794:in `start_action'
|
1023
|
+
from /home/yourname/cmdapp.rb:1627:in `handle_action'
|
1024
|
+
from /home/yourname/cmdapp.rb:1599:in `run'
|
1025
|
+
from /home/yourname/cmdapp.rb:1571:in `main'
|
936
1026
|
```
|
937
1027
|
|
938
|
-
* When looped action is detected, Benry::CmdApp aborts action.
|
939
1028
|
|
940
|
-
|
1029
|
+
|
1030
|
+
## Advanced Feature
|
1031
|
+
|
1032
|
+
|
1033
|
+
### Category of Action
|
1034
|
+
|
1035
|
+
* `category "foo:bar:"` in action class adds prefix `foo:bar:` to each action name.
|
1036
|
+
* Category name should be specified as a prefix string ending with `:`. For example, `category "foo:"` is OK but `category "foo"` will be error.
|
1037
|
+
* Symbol is not allowed. For example, `category :foo` will be error.
|
1038
|
+
* Method name `def baz__test()` with `category "foo:bar:"` results in the action name `foo:bar:baz:test`.
|
1039
|
+
|
1040
|
+
File: ex21.rb
|
941
1041
|
|
942
1042
|
```ruby
|
943
|
-
|
1043
|
+
# coding: utf-8
|
944
1044
|
require 'benry/cmdapp'
|
945
1045
|
|
946
|
-
class
|
947
|
-
|
948
|
-
@action.("test #1")
|
949
|
-
def test1()
|
950
|
-
run_action_once("test2")
|
951
|
-
end
|
1046
|
+
class SampleAction < Benry::CmdApp::Action
|
1047
|
+
category "foo:bar:" # !!!!
|
952
1048
|
|
953
|
-
@action.("test #
|
954
|
-
def
|
955
|
-
|
1049
|
+
@action.("test action #1")
|
1050
|
+
def test1() # action name: 'foo:bar:test1'
|
1051
|
+
puts __method__ #=> test1
|
1052
|
+
puts methods().grep(/test1/) #=> foo__bar__test1
|
956
1053
|
end
|
957
1054
|
|
958
|
-
@action.("test #
|
959
|
-
def
|
960
|
-
|
1055
|
+
@action.("test action #2")
|
1056
|
+
def baz__test2() # action name: 'foo:bar:baz:test2'
|
1057
|
+
puts __method__ #=> baz__test2
|
1058
|
+
puts methods().grep(/test2/) #=> foo__bar__baz__test2
|
961
1059
|
end
|
962
1060
|
|
963
1061
|
end
|
964
1062
|
|
965
|
-
|
966
|
-
app = Benry::CmdApp::Application.new(config)
|
967
|
-
exit app.main()
|
1063
|
+
exit Benry::CmdApp.main("sample app")
|
968
1064
|
```
|
969
1065
|
|
970
1066
|
Output:
|
971
1067
|
|
972
1068
|
```console
|
973
|
-
[bash]$ ruby
|
974
|
-
|
1069
|
+
[bash]$ ruby ex21.rb -l
|
1070
|
+
Actions:
|
1071
|
+
foo:bar:baz:test2 : test action #2
|
1072
|
+
foo:bar:test1 : test action #1
|
1073
|
+
help : print help message (of action if specified)
|
975
1074
|
|
976
|
-
[bash]$ ruby
|
977
|
-
|
1075
|
+
[bash]$ ruby ex21.rb foo:bar:test1
|
1076
|
+
test1 # <== puts __method__
|
1077
|
+
foo__bar__test1 # <== puts methods().grep(/test1/)
|
1078
|
+
|
1079
|
+
[bash]$ ruby ex21.rb foo:bar:baz:test2
|
1080
|
+
baz__test2 # <== puts __method__
|
1081
|
+
foo__bar__baz__test2 # <== puts methods().grep(/test1/)
|
978
1082
|
```
|
979
1083
|
|
1084
|
+
(INTERNAL MECHANISM):
|
1085
|
+
As shown in the above output, Benry-CmdApp internally renames `test1()` and `baz__test2()` methods within category `foo:bar:` to `foo__bar__test1()` and `foo__bar__baz__test2()` respectively.
|
1086
|
+
`__method__` seems to keep original method name, but don't be fooled, methods are renamed indeed.
|
1087
|
+
Due to this mechanism, it is possible to define the same name methods in different categories with no confliction.
|
1088
|
+
|
1089
|
+
* `category()` can take a description text of category.
|
1090
|
+
For example, `category "foo:", "Bla bla"` registers `"Bla bla` as a description of category `foo:`.
|
1091
|
+
Description of category is displayed in list of category list.
|
1092
|
+
See [Action List and Prefix List](#action-list-and-prefix-list) section for details.
|
980
1093
|
|
981
|
-
### Action Alias
|
982
1094
|
|
983
|
-
|
1095
|
+
### Nested Category
|
984
1096
|
|
985
|
-
|
1097
|
+
`category()` can take a block which represents sub-category.
|
1098
|
+
|
1099
|
+
File: ex22.rb
|
986
1100
|
|
987
1101
|
```ruby
|
988
|
-
|
1102
|
+
# coding: utf-8
|
989
1103
|
require 'benry/cmdapp'
|
990
1104
|
|
991
|
-
class
|
992
|
-
|
1105
|
+
class GitAction < Benry::CmdApp::Action
|
1106
|
+
category "git:" # top level category
|
993
1107
|
|
994
|
-
@action.("
|
995
|
-
def
|
996
|
-
puts
|
1108
|
+
@action.("show current status in compact format")
|
1109
|
+
def status(path=".")
|
1110
|
+
puts "git status -sb #{path}"
|
997
1111
|
end
|
998
1112
|
|
999
|
-
|
1000
|
-
|
1001
|
-
Benry::CmdApp.action_alias "test", "foo:bar:test1" # !!!!
|
1113
|
+
category "commit:" do # sub level category
|
1002
1114
|
|
1003
|
-
|
1004
|
-
|
1005
|
-
|
1006
|
-
|
1115
|
+
@action.("create a new commit")
|
1116
|
+
def create(message: nil)
|
1117
|
+
puts "git commit"
|
1118
|
+
end
|
1007
1119
|
|
1008
|
-
|
1120
|
+
end
|
1009
1121
|
|
1010
|
-
|
1011
|
-
[bash]$ ruby ex15.rb test # alias name
|
1012
|
-
test1
|
1122
|
+
category "branch:" do # sub level category
|
1013
1123
|
|
1014
|
-
|
1015
|
-
|
1016
|
-
|
1124
|
+
@action.("create a new branch")
|
1125
|
+
def create(branch)
|
1126
|
+
puts "git checkout -b #{branch}"
|
1127
|
+
end
|
1017
1128
|
|
1018
|
-
|
1129
|
+
end
|
1019
1130
|
|
1020
|
-
|
1021
|
-
[bash]$ ruby ex15.rb -h
|
1022
|
-
ex15.rb -- sample app
|
1131
|
+
end
|
1023
1132
|
|
1024
|
-
|
1025
|
-
|
1133
|
+
exit Benry::CmdApp.main("sample app")
|
1134
|
+
```
|
1026
1135
|
|
1027
|
-
|
1028
|
-
-h, --help : print help message (of action if action specified)
|
1136
|
+
Output:
|
1029
1137
|
|
1138
|
+
```console
|
1139
|
+
[bash]$ ruby ex22.rb -l
|
1030
1140
|
Actions:
|
1031
|
-
|
1032
|
-
|
1141
|
+
git:branch:create : create a new branch
|
1142
|
+
git:commit:create : create a new commit
|
1143
|
+
git:status : show current status in compact format
|
1144
|
+
help : print help message (of action if specified)
|
1033
1145
|
```
|
1034
1146
|
|
1035
|
-
|
1147
|
+
Block of `category()` is nestable.
|
1036
1148
|
|
1037
|
-
File:
|
1149
|
+
File: ex23.rb
|
1038
1150
|
|
1039
1151
|
```ruby
|
1040
|
-
|
1152
|
+
# coding: utf-8
|
1041
1153
|
require 'benry/cmdapp'
|
1042
1154
|
|
1043
|
-
class
|
1155
|
+
class GitAction < Benry::CmdApp::Action
|
1156
|
+
|
1157
|
+
category "git:" do # top level category
|
1158
|
+
|
1159
|
+
@action.("show current status in compact format")
|
1160
|
+
def status(path=".")
|
1161
|
+
puts "git status -sb #{path}"
|
1162
|
+
end
|
1163
|
+
|
1164
|
+
category "commit:" do # sub level category
|
1165
|
+
|
1166
|
+
@action.("create a new commit")
|
1167
|
+
def create(message: nil)
|
1168
|
+
puts "git commit"
|
1169
|
+
end
|
1170
|
+
|
1171
|
+
end
|
1172
|
+
|
1173
|
+
category "branch:" do # sub level category
|
1174
|
+
|
1175
|
+
@action.("create a new branch")
|
1176
|
+
def create(branch)
|
1177
|
+
puts "git checkout -b #{branch}"
|
1178
|
+
end
|
1044
1179
|
|
1045
|
-
@action.("print greeting message")
|
1046
|
-
@option.(:lang, "-l, --lang=<lang>", "language", enum: ["en", "fr", "it"])
|
1047
|
-
def hello(user="world", lang: "en")
|
1048
|
-
case lang
|
1049
|
-
when "en" ; puts "Hello, #{user}!"
|
1050
|
-
when "fr" ; puts "Bonjour, #{user}!"
|
1051
|
-
when "it" ; puts "Ciao, #{user}!"
|
1052
|
-
else
|
1053
|
-
raise "#{lang}: unknown language."
|
1054
1180
|
end
|
1181
|
+
|
1055
1182
|
end
|
1056
1183
|
|
1057
1184
|
end
|
1058
1185
|
|
1059
|
-
Benry::CmdApp.
|
1060
|
-
Benry::CmdApp.action_alias("ciao" , "hello", "Bob", "-l", "it") # !!!!
|
1061
|
-
|
1062
|
-
config = Benry::CmdApp::Config.new("sample app")
|
1063
|
-
app = Benry::CmdApp::Application.new(config)
|
1064
|
-
exit app.main()
|
1186
|
+
exit Benry::CmdApp.main("sample app")
|
1065
1187
|
```
|
1066
1188
|
|
1067
1189
|
Output:
|
1068
1190
|
|
1069
1191
|
```console
|
1070
|
-
[bash]$ ruby
|
1071
|
-
|
1072
|
-
|
1073
|
-
|
1074
|
-
|
1075
|
-
|
1076
|
-
[bash]$ ruby ex16.rb bonjour Alice # !!!!
|
1077
|
-
Bonjour, Alice!
|
1078
|
-
|
1079
|
-
[bash]$ ruby ex16.rb ciao # !!!!
|
1080
|
-
Ciao, Bob!
|
1192
|
+
[bash]$ ruby ex23.rb -l
|
1193
|
+
Actions:
|
1194
|
+
git:branch:create : create a new branch
|
1195
|
+
git:commit:create : create a new commit
|
1196
|
+
git:status : show current status in compact format
|
1197
|
+
help : print help message (of action if specified)
|
1081
1198
|
```
|
1082
1199
|
|
1083
1200
|
|
1084
|
-
###
|
1201
|
+
### Category Action or Alias
|
1085
1202
|
|
1086
|
-
* `
|
1087
|
-
In this case, action `test1` will be invoked if action name not specified in command-line.
|
1088
|
-
* Default action name is shown in help message.
|
1203
|
+
* `category "foo:bar:", action: "blabla"` defines `foo:bar` action (instead of `foo:bar:blabla`) with `blabla()` method.
|
1089
1204
|
|
1090
|
-
File:
|
1205
|
+
File: ex24.rb
|
1091
1206
|
|
1092
1207
|
```ruby
|
1093
|
-
|
1208
|
+
# coding: utf-8
|
1094
1209
|
require 'benry/cmdapp'
|
1095
1210
|
|
1096
1211
|
class SampleAction < Benry::CmdApp::Action
|
1212
|
+
category "foo:bar:", action: "test3" # !!!!
|
1097
1213
|
|
1098
1214
|
@action.("test action #1")
|
1099
|
-
def test1()
|
1215
|
+
def test1() # action name: 'foo:bar:test1'
|
1216
|
+
puts __method__
|
1217
|
+
end
|
1218
|
+
|
1219
|
+
@action.("test action #3")
|
1220
|
+
def test3() # action name: 'foo:bar'
|
1100
1221
|
puts __method__
|
1101
1222
|
end
|
1102
1223
|
|
1103
1224
|
end
|
1104
1225
|
|
1105
|
-
|
1106
|
-
config.default_action = "test1" # !!!!
|
1107
|
-
app = Benry::CmdApp::Application.new(config)
|
1108
|
-
exit app.main()
|
1226
|
+
exit Benry::CmdApp.main("sample app")
|
1109
1227
|
```
|
1110
1228
|
|
1111
1229
|
Output:
|
1112
1230
|
|
1113
1231
|
```console
|
1114
|
-
[bash]$ ruby
|
1115
|
-
|
1232
|
+
[bash]$ ruby ex24.rb -l
|
1233
|
+
Actions:
|
1234
|
+
foo:bar : test action #3 # !!!! not 'foo:bar:test3'
|
1235
|
+
foo:bar:test1 : test action #1
|
1236
|
+
help : print help message (of action if specified)
|
1116
1237
|
|
1117
|
-
[bash]$ ruby
|
1238
|
+
[bash]$ ruby ex24.rb foo:bar:test1
|
1118
1239
|
test1
|
1240
|
+
|
1241
|
+
[bash]$ ruby ex24.rb foo:bar:test3 # !!!! not available because renamed
|
1242
|
+
[ERROR] foo:bar:test3: Action not found.
|
1243
|
+
|
1244
|
+
[bash]$ ruby ex24.rb foo:bar # !!!! available because renamed
|
1245
|
+
test3
|
1246
|
+
```
|
1247
|
+
|
1248
|
+
<!--
|
1249
|
+
* `category "foo:", alias_for: "blabla"` defines `foo` as an alias for `foo:blabla` action.
|
1250
|
+
See [Alias for Action](#alias-of-action) section about alias for action.
|
1251
|
+
|
1252
|
+
* Keyword arguments `action:` and `alias_for:` are exclusive.
|
1253
|
+
It is not allowed to specify both of them at the same time.
|
1254
|
+
See [Q: What is the difference between category(alias_for:) and category(action:)?](#q-what-is-the-difference-between-categoryalias_for-and-categoryaction) section for details.
|
1255
|
+
-->
|
1256
|
+
|
1257
|
+
* Action name (and also category name) should be specified as a string. Symbol is not allowed.
|
1258
|
+
|
1259
|
+
```ruby
|
1260
|
+
## Symbol is not allowed
|
1261
|
+
category :foo #=> error
|
1262
|
+
category "foo:", action: :blabla #=> error
|
1263
|
+
```
|
1264
|
+
|
1265
|
+
|
1266
|
+
### Invoke Other Action
|
1267
|
+
|
1268
|
+
* `run_action()` invokes other action.
|
1269
|
+
* `run_once()` invokes other action only once.
|
1270
|
+
This is equivarent to 'prerequisite task' feature in task runner application.
|
1271
|
+
|
1272
|
+
File: ex25.rb
|
1273
|
+
|
1274
|
+
```ruby
|
1275
|
+
# coding: utf-8
|
1276
|
+
require 'benry/cmdapp'
|
1277
|
+
|
1278
|
+
class SampleAction < Benry::CmdApp::Action
|
1279
|
+
|
1280
|
+
@action.("create build dir")
|
1281
|
+
def prepare()
|
1282
|
+
puts "rm -rf build"
|
1283
|
+
puts "mkdir build"
|
1284
|
+
end
|
1285
|
+
|
1286
|
+
@action.("build something")
|
1287
|
+
def build()
|
1288
|
+
run_once("prepare") # !!!!
|
1289
|
+
run_once("prepare") # skipped because already invoked
|
1290
|
+
puts "echo 'README' > build/README.txt"
|
1291
|
+
puts "zip -r build.zip build"
|
1292
|
+
end
|
1293
|
+
|
1294
|
+
end
|
1295
|
+
|
1296
|
+
exit Benry::CmdApp.main("sample app")
|
1297
|
+
```
|
1298
|
+
|
1299
|
+
Output:
|
1300
|
+
|
1301
|
+
```console
|
1302
|
+
[bash]$ ruby ex25.rb build
|
1303
|
+
rm -rf build # invoked only once!!!!
|
1304
|
+
mkdir build # invoked only once!!!!
|
1305
|
+
echo 'README' > build/README.txt
|
1306
|
+
zip -r build.zip build
|
1307
|
+
```
|
1308
|
+
|
1309
|
+
* Action name should be a string. Symbol is not allowed.
|
1310
|
+
|
1311
|
+
```ruby
|
1312
|
+
## Error because action name is not a string.
|
1313
|
+
run_once(:prepare)
|
1314
|
+
```
|
1315
|
+
|
1316
|
+
* When looped action is detected, Benry-CmdApp aborts action.
|
1317
|
+
|
1318
|
+
File: ex26.rb
|
1319
|
+
|
1320
|
+
```ruby
|
1321
|
+
require 'benry/cmdapp'
|
1322
|
+
|
1323
|
+
class LoopedAction < Benry::CmdApp::Action
|
1324
|
+
|
1325
|
+
@action.("test #1")
|
1326
|
+
def test1()
|
1327
|
+
run_once("test2")
|
1328
|
+
end
|
1329
|
+
|
1330
|
+
@action.("test #2")
|
1331
|
+
def test2()
|
1332
|
+
run_once("test3")
|
1333
|
+
end
|
1334
|
+
|
1335
|
+
@action.("test #3")
|
1336
|
+
def test3()
|
1337
|
+
run_once("test1") # !!!!
|
1338
|
+
end
|
1339
|
+
|
1340
|
+
end
|
1341
|
+
|
1342
|
+
exit Benry::CmdApp.main("sample app")
|
1343
|
+
```
|
1344
|
+
|
1345
|
+
Output:
|
1346
|
+
|
1347
|
+
```console
|
1348
|
+
[bash]$ ruby ex26.rb test1
|
1349
|
+
[ERROR] test1: Looped action detected.
|
1350
|
+
|
1351
|
+
[bash]$ ruby ex26.rb test3
|
1352
|
+
[ERROR] test3: Looped action detected.
|
1353
|
+
```
|
1354
|
+
|
1355
|
+
|
1356
|
+
### Cleaning Up Block
|
1357
|
+
|
1358
|
+
* `at_end { ... }` registers a clean-up block that is invoked at end of process (not at end of action).
|
1359
|
+
* This is very useful to register clean-up blocks in preparation action.
|
1360
|
+
* Registered blocks are invoked in reverse order of registration.
|
1361
|
+
For example, `at_end { puts "A" }; at_end { puts "B" }; at_end { puts "C" }` prints "C", "B", and "A" at end of process.
|
1362
|
+
|
1363
|
+
File: ex27.rb
|
1364
|
+
|
1365
|
+
```ruby
|
1366
|
+
# coding: utf-8
|
1367
|
+
require 'benry/cmdapp'
|
1368
|
+
|
1369
|
+
class SampleAction < Benry::CmdApp::Action
|
1370
|
+
|
1371
|
+
@action.("create build dir")
|
1372
|
+
def prepare()
|
1373
|
+
puts "mkdir -p build"
|
1374
|
+
## register cleaning up block in preparation task
|
1375
|
+
at_end { puts "rm -rf build" } # !!!!
|
1376
|
+
end
|
1377
|
+
|
1378
|
+
@action.("build something")
|
1379
|
+
def build()
|
1380
|
+
run_once("prepare")
|
1381
|
+
puts "echo 'README' > build/README.txt"
|
1382
|
+
puts "zip -r build.zip build"
|
1383
|
+
end
|
1384
|
+
|
1385
|
+
end
|
1386
|
+
|
1387
|
+
exit Benry::CmdApp.main("sample app")
|
1388
|
+
```
|
1389
|
+
|
1390
|
+
Output:
|
1391
|
+
|
1392
|
+
```console
|
1393
|
+
[bash]$ ruby ex27.rb build
|
1394
|
+
mkdir -p build
|
1395
|
+
echo 'README' > build/README.txt
|
1396
|
+
zip -r build.zip build
|
1397
|
+
rm -rf build # !!!! clean-up block invoked at the end of process !!!!
|
1398
|
+
```
|
1399
|
+
|
1400
|
+
|
1401
|
+
### Alias for Action
|
1402
|
+
|
1403
|
+
Alias provides alternative short name of action.
|
1404
|
+
|
1405
|
+
* `define_alias()` in action class defines an alias with taking action category into account.
|
1406
|
+
* `Benry::CmdApp.define_alias()` defines an alias, without taking category into account.
|
1407
|
+
|
1408
|
+
File: ex28.rb
|
1409
|
+
|
1410
|
+
```ruby
|
1411
|
+
# coding: utf-8
|
1412
|
+
require 'benry/cmdapp'
|
1413
|
+
|
1414
|
+
class GitAction < Benry::CmdApp::Action
|
1415
|
+
category "git:" # !!!!
|
1416
|
+
|
1417
|
+
@action.("show current status in compact mode")
|
1418
|
+
def status()
|
1419
|
+
puts "git status -sb"
|
1420
|
+
end
|
1421
|
+
|
1422
|
+
define_alias "st", "status" # !!!!
|
1423
|
+
## or:
|
1424
|
+
#Benry::CmdApp.define_alias "st", "git:status" # !!!!
|
1425
|
+
|
1426
|
+
category "staging:" do # !!!!
|
1427
|
+
|
1428
|
+
@action.("show changes in staging area")
|
1429
|
+
def show()
|
1430
|
+
puts "git diff --cached"
|
1431
|
+
end
|
1432
|
+
|
1433
|
+
define_alias "staged" , "show" # !!!!
|
1434
|
+
## or:
|
1435
|
+
#Benry::CmdApp.define_alias "staged", "git:staging:show" # !!!!
|
1436
|
+
|
1437
|
+
end
|
1438
|
+
|
1439
|
+
end
|
1440
|
+
|
1441
|
+
Benry::CmdApp.define_alias "git", "git:status" # !!!!
|
1442
|
+
|
1443
|
+
exit Benry::CmdApp.main("sample app")
|
1119
1444
|
```
|
1120
1445
|
|
1121
1446
|
Help message:
|
1122
1447
|
|
1123
1448
|
```console
|
1124
|
-
[bash]$ ruby
|
1125
|
-
|
1449
|
+
[bash]$ ruby ex28.rb -h
|
1450
|
+
ex28.rb --- sample app
|
1126
1451
|
|
1127
1452
|
Usage:
|
1128
|
-
$
|
1453
|
+
$ ex28.rb [<options>] <action> [<arguments>...]
|
1129
1454
|
|
1130
1455
|
Options:
|
1131
|
-
-h, --help : print help message (of action if
|
1456
|
+
-h, --help : print help message (of action if specified)
|
1457
|
+
-l, --list : list actions and aliases
|
1458
|
+
-a, --all : list hidden actions/options, too
|
1132
1459
|
|
1133
|
-
Actions:
|
1134
|
-
|
1460
|
+
Actions:
|
1461
|
+
git : alias for 'git:status' # !!!!
|
1462
|
+
git:staging:show : show changes in staging area
|
1463
|
+
git:status : show current status in compact mode
|
1464
|
+
help : print help message (of action if specified)
|
1465
|
+
st : alias for 'git:status' # !!!!
|
1466
|
+
staged : alias for 'git:staging:show' # !!!!
|
1467
|
+
```
|
1468
|
+
|
1469
|
+
Output:
|
1470
|
+
|
1471
|
+
```console
|
1472
|
+
[bash]$ ruby ex28.rb st # alias name
|
1473
|
+
git status -sb
|
1474
|
+
|
1475
|
+
[bash]$ ruby ex28.rb git:status # original action name
|
1476
|
+
git status -sb
|
1477
|
+
|
1478
|
+
[bash]$ ruby ex28.rb staged # alias name
|
1479
|
+
git diff --cached
|
1480
|
+
|
1481
|
+
[bash]$ ruby ex28.rb git:staging:show # original action name
|
1482
|
+
git diff --cached
|
1483
|
+
|
1484
|
+
[bash]$ ruby ex28.rb git # alias name
|
1485
|
+
git status -sb
|
1486
|
+
```
|
1487
|
+
|
1488
|
+
* Aliases are printed in the help message of action (if defined).
|
1489
|
+
|
1490
|
+
```console
|
1491
|
+
[bash]$ ruby ex28.rb git:status -h
|
1492
|
+
ex28.rb git:status --- show current status in compact mode
|
1493
|
+
|
1494
|
+
Usage:
|
1495
|
+
$ ex28.rb git:status
|
1496
|
+
|
1497
|
+
Aliases: # !!!!
|
1498
|
+
git : alias for 'git:status' # !!!!
|
1499
|
+
st : alias for 'git:status' # !!!!
|
1500
|
+
```
|
1501
|
+
|
1502
|
+
* Both alias and action names should be string. Symbol is not allowed.
|
1503
|
+
|
1504
|
+
```ruby
|
1505
|
+
## Error because alias name is a Symbol.
|
1506
|
+
Benry::CmdApp.define_alias :test, "hello"
|
1507
|
+
|
1508
|
+
## Error because action name is a Symbol.
|
1509
|
+
Benry::CmdApp.define_alias "test", :hello
|
1510
|
+
```
|
1511
|
+
|
1512
|
+
* Target action (second argument of `define_alias()`) can be an array of string
|
1513
|
+
which contains action name and options.
|
1514
|
+
|
1515
|
+
File: ex29.rb
|
1516
|
+
|
1517
|
+
```ruby
|
1518
|
+
# coding: utf-8
|
1519
|
+
require 'benry/cmdapp'
|
1520
|
+
|
1521
|
+
class MyAction < Benry::CmdApp::Action
|
1522
|
+
|
1523
|
+
@action.("print greeting message")
|
1524
|
+
@option.(:lang, "-l, --lang=<lang>", "language", enum: ["en", "fr", "it"])
|
1525
|
+
def hello(user="world", lang: "en")
|
1526
|
+
case lang
|
1527
|
+
when "en" ; puts "Hello, #{user}!"
|
1528
|
+
when "fr" ; puts "Bonjour, #{user}!"
|
1529
|
+
when "it" ; puts "Ciao, #{user}!"
|
1530
|
+
else
|
1531
|
+
raise "#{lang}: Unknown language."
|
1532
|
+
end
|
1533
|
+
end
|
1534
|
+
|
1535
|
+
end
|
1536
|
+
|
1537
|
+
Benry::CmdApp.define_alias("bonjour", ["hello", "--lang=fr"]) # !!!!
|
1538
|
+
Benry::CmdApp.define_alias("ciao" , ["hello", "-l", "it", "Bob"]) # !!!!
|
1539
|
+
|
1540
|
+
exit Benry::CmdApp.main("sample app")
|
1541
|
+
```
|
1542
|
+
|
1543
|
+
Output:
|
1544
|
+
|
1545
|
+
```console
|
1546
|
+
[bash]$ ruby ex29.rb hello
|
1547
|
+
Hello, world!
|
1548
|
+
|
1549
|
+
[bash]$ ruby ex29.rb bonjour # !!!!
|
1550
|
+
Bonjour, world!
|
1551
|
+
|
1552
|
+
[bash]$ ruby ex29.rb bonjour Alice # !!!!
|
1553
|
+
Bonjour, Alice!
|
1554
|
+
|
1555
|
+
[bash]$ ruby ex29.rb ciao # !!!!
|
1556
|
+
Ciao, Bob!
|
1557
|
+
```
|
1558
|
+
|
1559
|
+
* It is not allowed to define an alias for other alias.
|
1560
|
+
|
1561
|
+
```
|
1562
|
+
## define an alias
|
1563
|
+
Benry::CmdApp.define_alias("hello-it" , ["hello", "-l", "it"])
|
1564
|
+
|
1565
|
+
## ERROR: define an alias for other alias
|
1566
|
+
Benry::CmdApp.define_alias("ciao" , "hello-it") # !!!!
|
1567
|
+
```
|
1568
|
+
|
1569
|
+
<!--
|
1570
|
+
* `category "foo:", alias_for: "bar"` defines new alias `foo` which is an alias for `foo:bar` action.
|
1571
|
+
|
1572
|
+
File: ex30.rb
|
1573
|
+
|
1574
|
+
```ruby
|
1575
|
+
# coding: utf-8
|
1576
|
+
require 'benry/cmdapp'
|
1577
|
+
|
1578
|
+
class GitAction < Benry::CmdApp::Action
|
1579
|
+
category "git:", alias_for: "status"
|
1580
|
+
|
1581
|
+
@action.("show status in compact format")
|
1582
|
+
def status(path=".")
|
1583
|
+
system "git status -sb #{path}"
|
1584
|
+
end
|
1585
|
+
|
1586
|
+
end
|
1587
|
+
|
1588
|
+
exit Benry::CmdApp.main("sample app")
|
1589
|
+
```
|
1590
|
+
|
1591
|
+
Output:
|
1592
|
+
|
1593
|
+
```console
|
1594
|
+
[bash]$ ruby ex30.rb -l
|
1595
|
+
Actions:
|
1596
|
+
git : alias for 'git:status' # !!!!
|
1597
|
+
git:status : show status in compact format
|
1598
|
+
help : print help message (of action if specified)
|
1599
|
+
```
|
1600
|
+
-->
|
1601
|
+
|
1602
|
+
* Global option `-L alias` lists all aliases.
|
1603
|
+
This option is hidden in default, therefore not shown in help message but available in default (for debug purpose).
|
1604
|
+
|
1605
|
+
```console
|
1606
|
+
[bash]$ ruby ex30.rb -L alias
|
1607
|
+
Aliases:
|
1608
|
+
git : alias for 'git:status'
|
1609
|
+
```
|
1610
|
+
|
1611
|
+
|
1612
|
+
### Abbreviation of Category
|
1613
|
+
|
1614
|
+
Abbreviation of category is a shortcut of category prefix.
|
1615
|
+
For example, when `b:` is an abbreviation of a category prefix `git:branch:`, you can invoke `git:branch:create` action by `b:create`.
|
1616
|
+
|
1617
|
+
File: ex31.rb
|
1618
|
+
|
1619
|
+
```ruby
|
1620
|
+
# coding: utf-8
|
1621
|
+
require 'benry/cmdapp'
|
1622
|
+
|
1623
|
+
class GitAction < Benry::CmdApp::Action
|
1624
|
+
|
1625
|
+
category "git:" do
|
1626
|
+
|
1627
|
+
category "branch:" do
|
1628
|
+
|
1629
|
+
@action.("create a new branch")
|
1630
|
+
def create(branch)
|
1631
|
+
puts "git checkout -b #{branch}"
|
1632
|
+
end
|
1633
|
+
|
1634
|
+
end
|
1635
|
+
|
1636
|
+
end
|
1637
|
+
|
1638
|
+
end
|
1639
|
+
|
1640
|
+
## define abbreviation 'b:' of category prefix 'git:branch:'
|
1641
|
+
Benry::CmdApp.define_abbrev("b:", "git:branch:") # !!!!
|
1642
|
+
|
1643
|
+
exit Benry::CmdApp.main("sample app")
|
1644
|
+
```
|
1645
|
+
|
1646
|
+
Output:
|
1647
|
+
|
1648
|
+
```console
|
1649
|
+
[bash]$ ruby ex31.rb b:create topic1 # invokes 'git:branch:create' !!!!
|
1650
|
+
git checkout -b topic1
|
1135
1651
|
```
|
1136
1652
|
|
1653
|
+
Global option `-L abbrev` lists all abbreviations.
|
1654
|
+
This option is hidden in default, therefore not shown in help message but available in default (for debug purpose).
|
1655
|
+
|
1656
|
+
```console
|
1657
|
+
[bash]$ ruby ex31.rb -L abbrev
|
1658
|
+
Abbreviations:
|
1659
|
+
b: => git:branch:
|
1660
|
+
```
|
1137
1661
|
|
1138
|
-
### Default Help
|
1139
1662
|
|
1140
|
-
|
1141
|
-
* This is very useful when you don't have proper default action. It's recommended.
|
1142
|
-
* `config.default_action` is prior than `config.default_help`.
|
1663
|
+
### Default Action
|
1143
1664
|
|
1144
|
-
|
1665
|
+
* `config.default_action = "test1"` defines default action.
|
1666
|
+
In this case, action `test1` will be invoked if action name not specified in command-line.
|
1667
|
+
* Default action name is shown in help message.
|
1668
|
+
|
1669
|
+
File: ex32.rb
|
1145
1670
|
|
1146
1671
|
```ruby
|
1147
|
-
|
1672
|
+
# coding: utf-8
|
1148
1673
|
require 'benry/cmdapp'
|
1149
1674
|
|
1150
1675
|
class SampleAction < Benry::CmdApp::Action
|
@@ -1156,40 +1681,262 @@ class SampleAction < Benry::CmdApp::Action
|
|
1156
1681
|
|
1157
1682
|
end
|
1158
1683
|
|
1159
|
-
|
1160
|
-
|
1161
|
-
|
1162
|
-
|
1684
|
+
exit Benry::CmdApp.main("sample app", "1.0.0",
|
1685
|
+
default_action: "test1") # !!!!
|
1686
|
+
## or:
|
1687
|
+
#config = Benry::CmdApp::Config.new("sample app", "1.0.0")
|
1688
|
+
#config.default_action = "test1" # !!!!
|
1689
|
+
#app = Benry::CmdApp::Application.new(config)
|
1690
|
+
#exit app.main()
|
1163
1691
|
```
|
1164
1692
|
|
1165
1693
|
Output:
|
1166
1694
|
|
1167
1695
|
```console
|
1168
|
-
[bash]$ ruby
|
1169
|
-
|
1696
|
+
[bash]$ ruby ex32.rb test1
|
1697
|
+
test1
|
1698
|
+
|
1699
|
+
[bash]$ ruby ex32.rb # no action name!!!!
|
1700
|
+
test1
|
1701
|
+
```
|
1702
|
+
|
1703
|
+
Help message:
|
1704
|
+
|
1705
|
+
```console
|
1706
|
+
[bash]$ ruby ex32.rb -h
|
1707
|
+
ex32.rb --- sample app
|
1170
1708
|
|
1171
1709
|
Usage:
|
1172
|
-
$
|
1710
|
+
$ ex32.rb [<options>] <action> [<arguments>...]
|
1173
1711
|
|
1174
1712
|
Options:
|
1175
|
-
-h, --help : print help message (of action if
|
1713
|
+
-h, --help : print help message (of action if specified)
|
1714
|
+
-l, --list : list actions and aliases
|
1715
|
+
-a, --all : list hidden actions/options, too
|
1716
|
+
|
1717
|
+
Actions: (default: test1) # !!!!
|
1718
|
+
help : print help message (of action if specified)
|
1719
|
+
test1 : test action #1
|
1720
|
+
```
|
1721
|
+
|
1722
|
+
|
1723
|
+
### Action List and Category List
|
1724
|
+
|
1725
|
+
When `config.default_action` is not specified, Benry-CmdAction lists action names if action name is not specified in command-line.
|
1726
|
+
|
1727
|
+
File: ex33.rb
|
1728
|
+
|
1729
|
+
```ruby
|
1730
|
+
# coding: utf-8
|
1731
|
+
require 'benry/cmdapp'
|
1732
|
+
|
1733
|
+
class SampleAction < Benry::CmdApp::Action
|
1734
|
+
|
1735
|
+
@action.("test action #1")
|
1736
|
+
def test1()
|
1737
|
+
end
|
1738
|
+
|
1739
|
+
category "foo:" do
|
1740
|
+
|
1741
|
+
@action.("test action #2")
|
1742
|
+
def test2()
|
1743
|
+
end
|
1176
1744
|
|
1745
|
+
end
|
1746
|
+
|
1747
|
+
category "bar:" do
|
1748
|
+
|
1749
|
+
@action.("test action #3")
|
1750
|
+
def test3()
|
1751
|
+
end
|
1752
|
+
|
1753
|
+
category "baz:" do
|
1754
|
+
|
1755
|
+
@action.("test action #4")
|
1756
|
+
def test4()
|
1757
|
+
end
|
1758
|
+
|
1759
|
+
end
|
1760
|
+
|
1761
|
+
end
|
1762
|
+
|
1763
|
+
end
|
1764
|
+
|
1765
|
+
exit Benry::CmdApp.main("sample app")
|
1766
|
+
```
|
1767
|
+
|
1768
|
+
Output:
|
1769
|
+
|
1770
|
+
```console
|
1771
|
+
[bash]$ ruby ex33.rb # no action name!!!!
|
1177
1772
|
Actions:
|
1773
|
+
bar:baz:test4 : test action #4
|
1774
|
+
bar:test3 : test action #3
|
1775
|
+
foo:test2 : test action #2
|
1776
|
+
help : print help message (of action if specified)
|
1178
1777
|
test1 : test action #1
|
1179
1778
|
```
|
1180
1779
|
|
1780
|
+
Command-line option `-l, --list` also prints the same result of the above example.
|
1781
|
+
This is useful if you specify default action name wit `config.default_action`.
|
1782
|
+
|
1783
|
+
Action name list contains alias names, too.
|
1784
|
+
If you want to list only action names (or alias names), specify `-L action` or `-L alias` option.
|
1785
|
+
See [Q: How to list only aliases (or actions) excluding actions (or aliases) ?](#q-how-to-list-only-aliases-or-actions-excluding-actions-or-aliases-) for details.
|
1786
|
+
|
1787
|
+
If category prefix (such as `xxx:`) is specified instead of action name,
|
1788
|
+
Benry-CmdApp lists action names which have that category prefix.
|
1789
|
+
|
1790
|
+
Output:
|
1791
|
+
|
1792
|
+
```console
|
1793
|
+
[bash]$ ruby ex33.rb foo: # !!!!
|
1794
|
+
Actions:
|
1795
|
+
foo:test2 : test action #2
|
1796
|
+
|
1797
|
+
[bash]$ ruby ex33.rb bar: # !!!!
|
1798
|
+
Actions:
|
1799
|
+
bar:baz:test4 : test action #4
|
1800
|
+
bar:test3 : test action #3
|
1801
|
+
```
|
1802
|
+
|
1803
|
+
If `:` is specified instead of action name, Benry-CmdApp lists top-level category prefixes of action names and number of actions under the each category prefix.
|
1804
|
+
|
1805
|
+
Outuput:
|
1806
|
+
|
1807
|
+
```console
|
1808
|
+
[bash]$ ruby ex33.rb : # !!!!
|
1809
|
+
Categories: (depth=1)
|
1810
|
+
bar: (2) # !!! two actions ('bar:test3' and 'bar:baz:test4')
|
1811
|
+
foo: (1) # !!! one action ('foo:text2')
|
1812
|
+
```
|
1813
|
+
|
1814
|
+
In the above example, only top-level category prefixes are displayed.
|
1815
|
+
If you specified `::` instead of `:`, second-level category prefixes are displayed,
|
1816
|
+
for example `foo:xxx:` and `foo:yyy:`.
|
1817
|
+
Of course, `:::` displays more level category prefixes.
|
1818
|
+
|
1819
|
+
File: ex34.rb
|
1820
|
+
|
1821
|
+
```ruby
|
1822
|
+
# coding: utf-8
|
1823
|
+
require 'benry/cmdapp'
|
1824
|
+
|
1825
|
+
class GitAction < Benry::CmdApp::Action
|
1826
|
+
category "git:"
|
1827
|
+
|
1828
|
+
category "staging:" do
|
1829
|
+
@action.("..."); def add(); end
|
1830
|
+
@action.("..."); def show(); end
|
1831
|
+
@action.("..."); def delete(); end
|
1832
|
+
end
|
1833
|
+
|
1834
|
+
category "branch:" do
|
1835
|
+
@action.("..."); def list(); end
|
1836
|
+
@action.("..."); def switch(name); end
|
1837
|
+
end
|
1838
|
+
|
1839
|
+
category "repo:" do
|
1840
|
+
@action.("..."); def create(); end
|
1841
|
+
@action.("..."); def init(); end
|
1842
|
+
|
1843
|
+
category "config:" do
|
1844
|
+
@action.("..."); def add(); end
|
1845
|
+
@action.("..."); def delete(); end
|
1846
|
+
@action.("..."); def list(); end
|
1847
|
+
end
|
1848
|
+
|
1849
|
+
category "remote:" do
|
1850
|
+
@action.("..."); def list(); end
|
1851
|
+
@action.("..."); def set(); end
|
1852
|
+
end
|
1853
|
+
|
1854
|
+
end
|
1855
|
+
|
1856
|
+
end
|
1857
|
+
|
1858
|
+
exit Benry::CmdApp.main("sample app")
|
1859
|
+
```
|
1860
|
+
|
1861
|
+
Output:
|
1862
|
+
|
1863
|
+
```console
|
1864
|
+
[bash]$ ruby ex34.rb :
|
1865
|
+
Categories: (depth=1)
|
1866
|
+
git: (12)
|
1867
|
+
|
1868
|
+
[bash]$ ruby ex34.rb :: # !!!!
|
1869
|
+
Categories: (depth=2)
|
1870
|
+
git: (0)
|
1871
|
+
git:branch: (2)
|
1872
|
+
git:repo: (7)
|
1873
|
+
git:staging: (3)
|
1874
|
+
|
1875
|
+
[bash]$ ruby ex34.rb ::: # !!!!
|
1876
|
+
Categories: (depth=3)
|
1877
|
+
git: (0)
|
1878
|
+
git:branch: (2)
|
1879
|
+
git:repo: (2)
|
1880
|
+
git:repo:config: (3)
|
1881
|
+
git:repo:remote: (2)
|
1882
|
+
git:staging: (3)
|
1883
|
+
```
|
1884
|
+
|
1885
|
+
`category()` can take a description of category as second argument.
|
1886
|
+
Descriptions of category are displayed in the category prefix list.
|
1887
|
+
|
1888
|
+
File: ex35.rb
|
1889
|
+
|
1890
|
+
```ruby
|
1891
|
+
# coding: utf-8
|
1892
|
+
require 'benry/cmdapp'
|
1893
|
+
|
1894
|
+
class SampleAction < Benry::CmdApp::Action
|
1895
|
+
|
1896
|
+
category "foo:", "description of Foo" do
|
1897
|
+
@action.("test action #2")
|
1898
|
+
def test2()
|
1899
|
+
end
|
1900
|
+
end
|
1901
|
+
|
1902
|
+
category "bar:", "description of Bar" do
|
1903
|
+
@action.("test action #3")
|
1904
|
+
def test3()
|
1905
|
+
end
|
1906
|
+
|
1907
|
+
category "baz:", "description fo Baz" do
|
1908
|
+
@action.("test action #4")
|
1909
|
+
def test4()
|
1910
|
+
end
|
1911
|
+
end
|
1912
|
+
end
|
1913
|
+
|
1914
|
+
end
|
1915
|
+
|
1916
|
+
exit Benry::CmdApp.main("sample app")
|
1917
|
+
```
|
1918
|
+
|
1919
|
+
Output:
|
1920
|
+
|
1921
|
+
```console
|
1922
|
+
[bash]$ ruby ex35.rb : # !!!!
|
1923
|
+
Categories: (depth=1)
|
1924
|
+
bar: (2) : description of Bar # !!!!
|
1925
|
+
foo: (1) : description of Foo # !!!!
|
1926
|
+
```
|
1181
1927
|
|
1182
|
-
|
1928
|
+
|
1929
|
+
### Hidden Action
|
1183
1930
|
|
1184
1931
|
* If `hidden: true` keyword argument passed to `@action.()`,
|
1185
|
-
or action method is private, then Benry
|
1186
|
-
*
|
1187
|
-
*
|
1932
|
+
or action method is private, then Benry-CmdApp regards that action as hidden.
|
1933
|
+
* Hidden actions are not shown in help message nor action list by default.
|
1934
|
+
* Hidden actions are shown when `-a` or `--all` option is specified in command-line.
|
1188
1935
|
|
1189
|
-
File:
|
1936
|
+
File: ex36.rb
|
1190
1937
|
|
1191
1938
|
```ruby
|
1192
|
-
|
1939
|
+
# coding: utf-8
|
1193
1940
|
require 'benry/cmdapp'
|
1194
1941
|
|
1195
1942
|
class SampleAction < Benry::CmdApp::Action
|
@@ -1213,59 +1960,40 @@ class SampleAction < Benry::CmdApp::Action
|
|
1213
1960
|
|
1214
1961
|
end
|
1215
1962
|
|
1216
|
-
|
1217
|
-
config.option_all = true # !!!! enable '-a, --all' option !!!!
|
1218
|
-
app = Benry::CmdApp::Application.new(config)
|
1219
|
-
exit app.main()
|
1963
|
+
exit Benry::CmdApp.main("sample app")
|
1220
1964
|
```
|
1221
1965
|
|
1222
|
-
|
1966
|
+
Action list (without `-a` nor `--all`):
|
1223
1967
|
|
1224
1968
|
```console
|
1225
|
-
[bash]$ ruby
|
1226
|
-
ex20.rb -- sample app
|
1227
|
-
|
1228
|
-
Usage:
|
1229
|
-
$ ex20.rb [<options>] [<action> [<arguments>...]]
|
1230
|
-
|
1231
|
-
Options:
|
1232
|
-
-h, --help : print help message (of action if action specified)
|
1233
|
-
-a, --all : list all actions/options including private (hidden) ones
|
1234
|
-
|
1969
|
+
[bash]$ ruby ex36.rb
|
1235
1970
|
Actions:
|
1971
|
+
help : print help message (of action if specified)
|
1236
1972
|
test1 : test action #1
|
1237
1973
|
```
|
1238
1974
|
|
1239
|
-
|
1975
|
+
Action list (with `-a` or `--all`):
|
1240
1976
|
|
1241
1977
|
```console
|
1242
|
-
[bash]$ ruby
|
1243
|
-
ex20.rb -- sample app
|
1244
|
-
|
1245
|
-
Usage:
|
1246
|
-
$ ex20.rb [<options>] [<action> [<arguments>...]]
|
1247
|
-
|
1248
|
-
Options:
|
1249
|
-
-h, --help : print help message (of action if action specified)
|
1250
|
-
-a, --all : list all actions/options including private (hidden) ones
|
1251
|
-
|
1978
|
+
[bash]$ ruby ex36.rb --all # !!!!
|
1252
1979
|
Actions:
|
1980
|
+
help : print help message (of action if specified)
|
1253
1981
|
test1 : test action #1
|
1254
1982
|
test2 : test action #2 # !!!!
|
1255
1983
|
test3 : test action #3 # !!!!
|
1256
1984
|
```
|
1257
1985
|
|
1258
1986
|
|
1259
|
-
###
|
1987
|
+
### Hidden Option
|
1260
1988
|
|
1261
|
-
* Options defined with `hidden: true` keyword argument are treated as
|
1262
|
-
*
|
1263
|
-
*
|
1989
|
+
* Options defined with `hidden: true` keyword argument are treated as hidden option.
|
1990
|
+
* Hidden options are not shown in help message of action.
|
1991
|
+
* Hidden options are shown when `-a` or `--all` option is specified in command-line.
|
1264
1992
|
|
1265
|
-
File:
|
1993
|
+
File: ex37.rb
|
1266
1994
|
|
1267
1995
|
```ruby
|
1268
|
-
|
1996
|
+
# coding: utf-8
|
1269
1997
|
require 'benry/cmdapp'
|
1270
1998
|
|
1271
1999
|
class SampleAction < Benry::CmdApp::Action
|
@@ -1274,25 +2002,22 @@ class SampleAction < Benry::CmdApp::Action
|
|
1274
2002
|
@option.(:verbose, "-v", "verbose mode")
|
1275
2003
|
@option.(:debug , "-D", "debug mode", hidden: true) # !!!!
|
1276
2004
|
def test1(verbose: false, debug: false)
|
1277
|
-
puts "verbose=#{verbose}, debug=#{
|
2005
|
+
puts "verbose=#{verbose}, debug=#{debug}"
|
1278
2006
|
end
|
1279
2007
|
|
1280
2008
|
end
|
1281
2009
|
|
1282
|
-
|
1283
|
-
config.option_all = true # !!!! enable '-a, --all' option !!!!
|
1284
|
-
app = Benry::CmdApp::Application.new(config)
|
1285
|
-
exit app.main()
|
2010
|
+
exit Benry::CmdApp.main("sample app")
|
1286
2011
|
```
|
1287
2012
|
|
1288
2013
|
Help message (without `-a` nor `--all`):
|
1289
2014
|
|
1290
2015
|
```console
|
1291
|
-
[bash]$ ruby
|
1292
|
-
|
2016
|
+
[bash]$ ruby ex37.rb -h test1
|
2017
|
+
ex37.rb test1 --- test action
|
1293
2018
|
|
1294
2019
|
Usage:
|
1295
|
-
$
|
2020
|
+
$ ex37.rb test1 [<options>]
|
1296
2021
|
|
1297
2022
|
Options:
|
1298
2023
|
-v : verbose mode
|
@@ -1301,17 +2026,79 @@ Options:
|
|
1301
2026
|
Help message (with `-a` or `--all`)
|
1302
2027
|
|
1303
2028
|
```console
|
1304
|
-
[bash]$ ruby
|
1305
|
-
|
2029
|
+
[bash]$ ruby ex37.rb -h --all test1 # !!!!
|
2030
|
+
ex37.rb test1 --- test action
|
1306
2031
|
|
1307
2032
|
Usage:
|
1308
|
-
$
|
2033
|
+
$ ex37.rb test1 [<options>]
|
1309
2034
|
|
1310
2035
|
Options:
|
2036
|
+
-h, --help : print help message # !!!!
|
1311
2037
|
-v : verbose mode
|
1312
2038
|
-D : debug mode # !!!!
|
1313
2039
|
```
|
1314
2040
|
|
2041
|
+
In the above example, `-h, --help` option as well as `-D` option is shown.
|
2042
|
+
In fact, Benry-CmdApp automatically adds `-h, --help` option to each action in hidden mode.
|
2043
|
+
Therefore all actions accept `-h, --help` option.
|
2044
|
+
|
2045
|
+
For this reason, you should NOT define `-h` or `--help` options for your actions.
|
2046
|
+
|
2047
|
+
|
2048
|
+
### Important Actions or Options
|
2049
|
+
|
2050
|
+
It is possible to mark actions or options as important or not.
|
2051
|
+
|
2052
|
+
* Actions or options marked as important are emphasized in help message.
|
2053
|
+
* Actions or options marked as not important are weaken in help message.
|
2054
|
+
|
2055
|
+
File: ex38.rb
|
2056
|
+
|
2057
|
+
```ruby
|
2058
|
+
require 'benry/cmdapp'
|
2059
|
+
|
2060
|
+
class SampleAction < Benry::CmdApp::Action
|
2061
|
+
|
2062
|
+
@action.("important action", important: true) # !!!!
|
2063
|
+
def test1()
|
2064
|
+
end
|
2065
|
+
|
2066
|
+
@action.("not important action", important: false) # !!!!
|
2067
|
+
def test2()
|
2068
|
+
end
|
2069
|
+
|
2070
|
+
@action.("sample")
|
2071
|
+
@option.(:foo, "--foo", "important option", important: true)
|
2072
|
+
@option.(:bar, "--bar", "not important option", important: false)
|
2073
|
+
def test3(foo: nil, bar: nil)
|
2074
|
+
end
|
2075
|
+
|
2076
|
+
end
|
2077
|
+
|
2078
|
+
exit Benry::CmdApp.main("sample app")
|
2079
|
+
```
|
2080
|
+
|
2081
|
+
Output:
|
2082
|
+
|
2083
|
+
```console
|
2084
|
+
[bash]$ ruby ex38.rb -l
|
2085
|
+
Actions:
|
2086
|
+
help : print help message (of action if specified)
|
2087
|
+
test1 : important action # !!!! bold font !!!!
|
2088
|
+
test2 : not important action # !!!! gray color !!!!
|
2089
|
+
test3 : sample
|
2090
|
+
|
2091
|
+
[bash]$ ruby ex38.rb -h test3
|
2092
|
+
ex38.rb test3 --- sample
|
2093
|
+
|
2094
|
+
Usage:
|
2095
|
+
$ ex38.rb test3 [<options>]
|
2096
|
+
|
2097
|
+
Options:
|
2098
|
+
--foo : important option # !!!! bold font !!!!
|
2099
|
+
--bar : not important option # !!!! gray color !!!!
|
2100
|
+
```
|
2101
|
+
|
1315
2102
|
|
1316
2103
|
|
1317
2104
|
## Configuratoin and Customization
|
@@ -1324,67 +2111,105 @@ Options:
|
|
1324
2111
|
* `config.app_desc = "..."` sets command description which is shown in help message. (required)
|
1325
2112
|
* `config.app_version = "1.0.0"` enables `-V` and `--version` option, and prints version number if `-V` or `--version` option specified. (default: `nil`)
|
1326
2113
|
* `config.app_command = "<command>"` sets command name which is shown in help message. (default: `File.basname($0)`)
|
2114
|
+
* `config.app_name = "<string>"` sets application name which is shown in help message. (default: same as `config.app_command`)
|
2115
|
+
* `config.app_usage = "<text>" (or `["<text1>", "<text2>", ...]`) sets usage string in help message. (default: `" <action> [<arguments>...]"`)
|
1327
2116
|
* `config.app_detail = "<text>"` sets detailed description of command which is showin in help message. (default: `nil`)
|
2117
|
+
* `config.backtrace_ignore_rexp = /.../` sets regular expression to ignore backtrace when error raised. (default: `nil`)
|
2118
|
+
* `config.help_description = "<text>"` sets text of 'Description:' section in help message. (default: `nil`)
|
2119
|
+
* `config.help_postamble = {"<Title>:" => "<text>"}` sets postamble of help message, such as 'Example:' or 'Tips:'. (default: `nil`)
|
1328
2120
|
* `config.default_action = "<action>"` sets default action name. (default: `nil`)
|
1329
|
-
* `config.default_help = true` prints help message if no action names specified in command-line. (default: `false`)
|
1330
2121
|
* `config.option_help = true` enables `-h` and `--help` options. (default: `true`)
|
1331
|
-
* `config.
|
2122
|
+
* `config.option_version = true` enables `-V` and `--version` options. (default: `true` if `app_version` provided, `false` if else)
|
2123
|
+
* `config.option_list = true` enables `-l` and `--list` options. (default: `true`)
|
2124
|
+
* `config.option_topic = true` enables `-L <topic>` option. (default: `:hidden`)
|
2125
|
+
* `config.option_all = true` enables `-a` and `--all` options which shows private (hidden) actions and options into help message. (default: `true`)
|
1332
2126
|
* `config.option_verbose = true` enables `-v` and `--verbose` options which sets `$QUIET_MODE = false`. (default: `false`)
|
1333
2127
|
* `config.option_quiet = true` enables `-q` and `--quiet` options which sets `$QUIET_MODE = true`. (default: `false`)
|
1334
2128
|
* `config.option_color = true` enables `--color[=<on|off>]` option which sets `$COLOR_MODE = true/false`. This affects to help message colorized or not. (default: `false`)
|
1335
|
-
* `config.option_debug = true` enables `-D` and `--debug` options which sets `$DEBUG_MODE = true`. (default: `
|
1336
|
-
* `config.option_trace = true` enables `-T` and `--trace` options
|
1337
|
-
* `config.
|
1338
|
-
* `config.
|
1339
|
-
* `config.
|
1340
|
-
* `config.
|
1341
|
-
* `config.
|
1342
|
-
* `config.format_usage = " $ %s
|
1343
|
-
* `config.
|
2129
|
+
* `config.option_debug = true` enables `-D` and `--debug` options which sets `$DEBUG_MODE = true`. (default: `:hidden`)
|
2130
|
+
* `config.option_trace = true` enables `-T` and `--trace` options. Entering into and exitting from action are reported when trace mode is on. (default: `false`)
|
2131
|
+
* `config.option_dryrun = true` enables `-X` and `--dryrun` options which sets `$DRYRUN_MODE = true`. (default: `false`)
|
2132
|
+
* `config.format_option = " %-18s : %s"` sets format of options in help message. (default: `" %-18s : %s"`)
|
2133
|
+
* `config.format_action = " %-18s : %s"` sets format of actions in help message. (default: `" %-18s : %s"`)
|
2134
|
+
* `config.format_usage = " $ %s"` sets format of usage in help message. (default: `" $ %s"`)
|
2135
|
+
* `config.format_avvrev = " %-10s => %s"` sets format of abbreviations in output of `-L abbrev` option. (default: `" %-10s => %s"`)
|
2136
|
+
* `config.format_usage = " $ %s"` sets format of usage in help message. (default: `" $ %s"`)
|
2137
|
+
* `config.format_category = " $-18s : %s""` sets format of category prefixes in output of `-L category` option. (default: `nil` which means to use value of `config.format_action`)
|
1344
2138
|
|
1345
|
-
File:
|
2139
|
+
File: ex41.rb
|
1346
2140
|
|
1347
2141
|
```ruby
|
1348
|
-
|
2142
|
+
# coding: utf-8
|
1349
2143
|
require 'benry/cmdapp'
|
1350
2144
|
|
1351
|
-
config = Benry::CmdApp::Config.new("sample app", "1.0.0")
|
1352
|
-
|
1353
|
-
|
1354
|
-
config.class.instance_methods(false).each do |name|
|
1355
|
-
next if name =~ /=$/
|
1356
|
-
next if ! config.class.method_defined?("#{name}=")
|
1357
|
-
val = config.__send__(name)
|
1358
|
-
puts "%-25s = %s" % ["config.#{name}", val.inspect]
|
2145
|
+
config = Benry::CmdApp::Config.new("sample app", "1.0.0", app_name: "Sample App")
|
2146
|
+
config.each(sort: false) do |name, val|
|
2147
|
+
puts "config.%-20s = %s" % [name, val.inspect]
|
1359
2148
|
end
|
1360
2149
|
```
|
1361
2150
|
|
1362
2151
|
Output:
|
1363
2152
|
|
1364
2153
|
```console
|
1365
|
-
[bash]$ ruby
|
1366
|
-
config.app_desc
|
1367
|
-
config.app_version
|
1368
|
-
config.app_name
|
1369
|
-
config.app_command
|
1370
|
-
config.
|
1371
|
-
config.
|
1372
|
-
config.
|
1373
|
-
config.
|
1374
|
-
config.
|
1375
|
-
config.
|
1376
|
-
config.
|
1377
|
-
config.
|
1378
|
-
config.
|
1379
|
-
config.
|
1380
|
-
config.
|
1381
|
-
config.
|
1382
|
-
config.
|
1383
|
-
config.
|
1384
|
-
config.
|
1385
|
-
config.
|
1386
|
-
config.
|
1387
|
-
config.
|
2154
|
+
[bash]$ ruby ex41.rb
|
2155
|
+
config.app_desc = "sample app"
|
2156
|
+
config.app_version = "1.0.0"
|
2157
|
+
config.app_name = "Sample App"
|
2158
|
+
config.app_command = "ex41.rb" # == File.basename($0)
|
2159
|
+
config.app_usage = nil
|
2160
|
+
config.app_detail = nil
|
2161
|
+
config.default_action = nil
|
2162
|
+
config.help_description = nil
|
2163
|
+
config.help_postamble = nil
|
2164
|
+
config.format_option = " %-18s : %s"
|
2165
|
+
config.format_action = " %-18s : %s"
|
2166
|
+
config.format_usage = " $ %s"
|
2167
|
+
config.format_category = nil
|
2168
|
+
config.deco_command = "\e[1m%s\e[0m" # bold
|
2169
|
+
config.deco_header = "\e[1;34m%s\e[0m" # bold, blue
|
2170
|
+
config.deco_extra = "\e[2m%s\e[0m" # gray color
|
2171
|
+
config.deco_strong = "\e[1m%s\e[0m" # bold
|
2172
|
+
config.deco_weak = "\e[2m%s\e[0m" # gray color
|
2173
|
+
config.deco_hidden = "\e[2m%s\e[0m" # gray color
|
2174
|
+
config.deco_debug = "\e[2m%s\e[0m" # gray color
|
2175
|
+
config.deco_error = "\e[31m%s\e[0m" # red
|
2176
|
+
config.option_help = true
|
2177
|
+
config.option_version = true
|
2178
|
+
config.option_list = true
|
2179
|
+
config.option_topic = :hidden
|
2180
|
+
config.option_all = true
|
2181
|
+
config.option_verbose = false
|
2182
|
+
config.option_quiet = false
|
2183
|
+
config.option_color = false
|
2184
|
+
config.option_debug = :hidden
|
2185
|
+
config.option_trace = false
|
2186
|
+
config.option_dryrun = false
|
2187
|
+
config.backtrace_ignore_rexp = nil
|
2188
|
+
config.trace_mode = nil
|
2189
|
+
```
|
2190
|
+
|
2191
|
+
You may notice that the value of `config.option_debug` is `:hidden`.
|
2192
|
+
If value of `config.option_xxxx` is `:hidden`, then corresponding global option is enabled as hidden option.
|
2193
|
+
Therefore you can see `--debug` option in help message if you add `-h` and `-a` (or `--all`) option.
|
2194
|
+
|
2195
|
+
Help message:
|
2196
|
+
|
2197
|
+
```console
|
2198
|
+
$ ruby ex37.rb -h -a # !!!!
|
2199
|
+
ex37.rb --- sample app
|
2200
|
+
|
2201
|
+
Usage:
|
2202
|
+
$ ex37.rb [<options>] <action> [<arguments>...]
|
2203
|
+
|
2204
|
+
Options:
|
2205
|
+
-h, --help : print help message (of action if specified)
|
2206
|
+
-l, --list : list actions and aliases
|
2207
|
+
-a, --all : list hidden actions/options, too
|
2208
|
+
--debug : debug mode # !!!!
|
2209
|
+
|
2210
|
+
Actions:
|
2211
|
+
help : print help message (of action if specified)
|
2212
|
+
test1 : test action
|
1388
2213
|
```
|
1389
2214
|
|
1390
2215
|
|
@@ -1392,14 +2217,14 @@ config.format_appname = "\e[1m%s\e[0m"
|
|
1392
2217
|
|
1393
2218
|
To add custom global options:
|
1394
2219
|
|
1395
|
-
* (1) Create global option schema object.
|
2220
|
+
* (1) Create a global option schema object.
|
1396
2221
|
* (2) Add custom options to it.
|
1397
2222
|
* (3) Pass it to `Application.new()`.
|
1398
2223
|
|
1399
|
-
File:
|
2224
|
+
File: ex42.rb
|
1400
2225
|
|
1401
2226
|
```ruby
|
1402
|
-
|
2227
|
+
# coding: utf-8
|
1403
2228
|
require 'benry/cmdapp'
|
1404
2229
|
|
1405
2230
|
class SampleAction < Benry::CmdApp::Action
|
@@ -1413,7 +2238,7 @@ end
|
|
1413
2238
|
|
1414
2239
|
## (1) create global option shema
|
1415
2240
|
config = Benry::CmdApp::Config.new("sample app")
|
1416
|
-
schema = Benry::CmdApp::
|
2241
|
+
schema = Benry::CmdApp::GlobalOptionSchema.new(config) # !!!!
|
1417
2242
|
|
1418
2243
|
## (2) add custom options to it
|
1419
2244
|
schema.add(:logging, "--logging", "enable logging") # !!!!
|
@@ -1427,81 +2252,106 @@ exit app.main()
|
|
1427
2252
|
Help message:
|
1428
2253
|
|
1429
2254
|
```console
|
1430
|
-
[bash]$ ruby
|
1431
|
-
|
2255
|
+
[bash]$ ruby ex42.rb -h
|
2256
|
+
ex42.rb --- sample app
|
1432
2257
|
|
1433
2258
|
Usage:
|
1434
|
-
$
|
2259
|
+
$ ex42.rb [<options>] <action> [<arguments>...]
|
1435
2260
|
|
1436
2261
|
Options:
|
1437
|
-
-h, --help : print help message (of action if
|
2262
|
+
-h, --help : print help message (of action if specified)
|
2263
|
+
-l, --list : list actions and aliases
|
2264
|
+
-a, --all : list hidden actions/options, too
|
1438
2265
|
--logging : enable logging # !!!!
|
1439
2266
|
|
1440
2267
|
Actions:
|
2268
|
+
help : print help message (of action if specified)
|
1441
2269
|
test1 : test action
|
1442
2270
|
```
|
1443
2271
|
|
1444
2272
|
To customize global options entirely:
|
1445
2273
|
|
1446
|
-
* (1) Create empty `
|
2274
|
+
* (1) Create empty `GlobalOptionSchema` object.
|
1447
2275
|
* (2) Add global options as you want.
|
1448
2276
|
* (3) Create and execute Application object with it.
|
1449
2277
|
|
1450
|
-
File:
|
2278
|
+
File: ex43.rb
|
1451
2279
|
|
1452
2280
|
```ruby
|
1453
|
-
|
2281
|
+
# coding: utf-8
|
1454
2282
|
require 'benry/cmdapp'
|
1455
2283
|
|
1456
|
-
## (1) Create empty ``
|
1457
|
-
schema = Benry::CmdApp::
|
2284
|
+
## (1) Create empty ``GlobalOptionSchema`` object.
|
2285
|
+
schema = Benry::CmdApp::GlobalOptionSchema.new(nil) # !!!!
|
1458
2286
|
|
1459
2287
|
## (2) Add global options as you want.
|
1460
2288
|
schema.add(:help , "-h, --help" , "print help message")
|
1461
2289
|
schema.add(:version, "-V, --version", "print version")
|
1462
|
-
schema.add(:
|
2290
|
+
schema.add(:list , "-l, --list" , "list actions and aliases")
|
2291
|
+
schema.add(:all , "-a, --all" , "list hidden actions/options, too")
|
1463
2292
|
schema.add(:verbose, "-v, --verbose", "verbose mode")
|
1464
2293
|
schema.add(:quiet , "-q, --quiet" , "quiet mode")
|
1465
|
-
schema.add(:color , "--color[=<on|off>]", "enable/disable color", type: TrueClass)
|
2294
|
+
schema.add(:color , "--color[=<on|off>]", "enable/disable color mode", type: TrueClass)
|
1466
2295
|
schema.add(:debug , "-D, --debug" , "set $DEBUG_MODE to true")
|
1467
2296
|
schema.add(:trace , "-T, --trace" , "report enter into and exit from action")
|
1468
2297
|
|
1469
2298
|
## (3) Create and execute Application object with it.
|
1470
|
-
config = Benry::CmdApp::Config.new("sample app")
|
2299
|
+
config = Benry::CmdApp::Config.new("sample app", "1.0.0")
|
1471
2300
|
app = Benry::CmdApp::Application.new(config, schema) # !!!!
|
1472
2301
|
exit app.main()
|
1473
2302
|
```
|
1474
2303
|
|
2304
|
+
Help message:
|
2305
|
+
|
2306
|
+
```console
|
2307
|
+
[bash]$ ruby ex43.rb -h
|
2308
|
+
ex43.rb (1.0.0) --- sample app
|
2309
|
+
|
2310
|
+
Usage:
|
2311
|
+
$ ex43.rb [<options>] <action> [<arguments>...]
|
2312
|
+
|
2313
|
+
Options:
|
2314
|
+
-h, --help : print help message
|
2315
|
+
-V, --version : print version
|
2316
|
+
-l, --list : list actions and aliases
|
2317
|
+
-a, --all : list hidden actions/options, too
|
2318
|
+
-v, --verbose : verbose mode
|
2319
|
+
-q, --quiet : quiet mode
|
2320
|
+
--color[=<on|off>] : enable/disable color mode
|
2321
|
+
-D, --debug : set $DEBUG_MODE to true
|
2322
|
+
-T, --trace : report enter into and exit from action
|
2323
|
+
|
2324
|
+
Actions:
|
2325
|
+
help : print help message (of action if specified)
|
2326
|
+
```
|
2327
|
+
|
2328
|
+
|
1475
2329
|
|
1476
2330
|
### Customization of Global Option Behaviour
|
1477
2331
|
|
1478
2332
|
* (1) Define subclass of `Application` class.
|
1479
|
-
* (2) Override `#
|
2333
|
+
* (2) Override `#toggle_global_options()` method.
|
1480
2334
|
* (3) Create and execute subclass object of `Application`.
|
1481
2335
|
|
1482
|
-
File:
|
2336
|
+
File: ex44.rb
|
1483
2337
|
|
1484
2338
|
```ruby
|
1485
|
-
|
2339
|
+
# coding: utf-8
|
1486
2340
|
require 'benry/cmdapp'
|
1487
2341
|
|
1488
2342
|
## (1) Define subclass of ``Application`` class.
|
1489
2343
|
class MyApplication < Benry::CmdApp::Application
|
1490
2344
|
|
1491
|
-
## (2) Override ``#
|
1492
|
-
def
|
1493
|
-
super
|
1494
|
-
|
1495
|
-
|
1496
|
-
|
1497
|
-
|
1498
|
-
|
1499
|
-
|
1500
|
-
#
|
1501
|
-
# when :trace ; $TRACE_MODE = val
|
1502
|
-
# else ; # do nothing
|
1503
|
-
# end
|
1504
|
-
#end
|
2345
|
+
## (2) Override ``#toggle_global_options()`` method.
|
2346
|
+
def toggle_global_options(global_opts)
|
2347
|
+
status_code = super
|
2348
|
+
return status_code if status_code # `return 0` means "stop process successfully",
|
2349
|
+
# `return 1` means "stop process as failed".
|
2350
|
+
if global_opts[:logging]
|
2351
|
+
require 'logger'
|
2352
|
+
$logger = Logger.new(STDOUT)
|
2353
|
+
end
|
2354
|
+
return nil # `return nil` means "continue process".
|
1505
2355
|
end
|
1506
2356
|
|
1507
2357
|
end
|
@@ -1514,15 +2364,15 @@ exit app.main()
|
|
1514
2364
|
|
1515
2365
|
Of course, prepending custom module to Application class is also effective way.
|
1516
2366
|
|
1517
|
-
File:
|
2367
|
+
File: ex45.rb
|
1518
2368
|
|
1519
2369
|
```ruby
|
1520
|
-
|
2370
|
+
# coding: utf-8
|
1521
2371
|
require 'benry/cmdapp'
|
1522
2372
|
|
1523
2373
|
module MyApplicationMod
|
1524
2374
|
|
1525
|
-
def
|
2375
|
+
def toggle_global_options(global_opts)
|
1526
2376
|
# ....
|
1527
2377
|
end
|
1528
2378
|
|
@@ -1539,13 +2389,13 @@ exit app.main()
|
|
1539
2389
|
### Custom Hook of Application
|
1540
2390
|
|
1541
2391
|
* (1) Define subclass of Application class.
|
1542
|
-
* (2) Override
|
2392
|
+
* (2) Override `#handle_action()` method.
|
1543
2393
|
* (3) Create and execute custom application object.
|
1544
2394
|
|
1545
|
-
File:
|
2395
|
+
File: ex46.rb
|
1546
2396
|
|
1547
2397
|
```ruby
|
1548
|
-
|
2398
|
+
# coding: utf-8
|
1549
2399
|
require 'benry/cmdapp'
|
1550
2400
|
|
1551
2401
|
class SampleAction < Benry::CmdApp::Action
|
@@ -1560,78 +2410,37 @@ end
|
|
1560
2410
|
## (1) Define subclass of Application class
|
1561
2411
|
class MyApplication < Benry::CmdApp::Application # !!!!
|
1562
2412
|
|
1563
|
-
## (2) Override
|
1564
|
-
def
|
2413
|
+
## (2) Override method
|
2414
|
+
def handle_action(action, args) # !!!!
|
1565
2415
|
#p @config
|
1566
|
-
|
1567
|
-
|
1568
|
-
require 'logger'
|
1569
|
-
$logger = Logger.new(STDOUT)
|
1570
|
-
end
|
1571
|
-
## if return :SKIP, action skipped (not invoked).
|
1572
|
-
#return :SKIP
|
2416
|
+
$logger.debug("action=#{action}, args=#{args.inspect}") if $logger
|
2417
|
+
super # !!!!
|
1573
2418
|
end
|
1574
2419
|
|
1575
|
-
## or:
|
1576
|
-
#def do_handle_global_options(args, global_opts)
|
1577
|
-
# if global_opts[:logging]
|
1578
|
-
# require 'logger'
|
1579
|
-
# $logger = Logger.new(STDOUT)
|
1580
|
-
# end
|
1581
|
-
# super
|
1582
|
-
#end
|
1583
|
-
|
1584
2420
|
end
|
1585
2421
|
|
1586
2422
|
## (3) create and execute custom application object
|
1587
2423
|
config = Benry::CmdApp::Config.new("sample app")
|
1588
|
-
schema = Benry::CmdApp::
|
2424
|
+
schema = Benry::CmdApp::GlobalOptionSchema.new(config)
|
1589
2425
|
schema.add(:logging, "--logging", "enable logging")
|
1590
2426
|
app = MyApplication.new(config, schema) # !!!!
|
1591
2427
|
exit app.main()
|
1592
2428
|
```
|
1593
2429
|
|
1594
|
-
* [EXPERIMENTAL] Instead of defining subclass of Application, you can pass callback block to Application object.
|
1595
|
-
|
1596
|
-
File: ex28.rb
|
1597
|
-
|
1598
|
-
```ruby
|
1599
|
-
#!/usr/bin/env ruby
|
1600
|
-
require 'benry/cmdapp'
|
1601
|
-
|
1602
|
-
class SampleAction < Benry::CmdApp::Action
|
1603
|
-
|
1604
|
-
@action.("test action")
|
1605
|
-
def test1()
|
1606
|
-
$logger.info("logging message") if $logger
|
1607
|
-
end
|
1608
|
-
|
1609
|
-
end
|
1610
|
-
|
1611
|
-
config = Benry::CmdApp::Config.new("sample app")
|
1612
|
-
schema = Benry::CmdApp::AppOptionSchema.new(config)
|
1613
|
-
schema.add(:logging, "--logging", "enable logging")
|
1614
|
-
app = Benry::CmdApp::Application.new(config, schema) do # !!!!
|
1615
|
-
|args, global_opts, config| # !!!!
|
1616
|
-
if global_opts[:logging] # !!!!
|
1617
|
-
require 'logger' # !!!!
|
1618
|
-
$logger = Logger.new(STDOUT) # !!!!
|
1619
|
-
end # !!!!
|
1620
|
-
#:SKIP # !!!!
|
1621
|
-
end # !!!!
|
1622
|
-
exit app.main()
|
1623
|
-
```
|
1624
2430
|
|
2431
|
+
### Customization of Application Help Message
|
1625
2432
|
|
1626
|
-
|
2433
|
+
If you want to just add more text into application help message,
|
2434
|
+
set the followings:
|
1627
2435
|
|
1628
|
-
|
1629
|
-
|
2436
|
+
.* `config.app_detail = <text>` --- print text before 'Usage:' section.
|
2437
|
+
.* `config.help_description = <text>` --- print text after 'Usage:' section as 'Description:' section.
|
2438
|
+
.* `config.help_postamble = {<head> => <text>}` --- print at end of help message.
|
1630
2439
|
|
1631
|
-
File:
|
2440
|
+
File: ex47.rb
|
1632
2441
|
|
1633
2442
|
```ruby
|
1634
|
-
|
2443
|
+
# coding: utf-8
|
1635
2444
|
require 'benry/cmdapp'
|
1636
2445
|
|
1637
2446
|
class SampleAction < Benry::CmdApp::Action
|
@@ -1643,12 +2452,14 @@ class SampleAction < Benry::CmdApp::Action
|
|
1643
2452
|
|
1644
2453
|
end
|
1645
2454
|
|
1646
|
-
config = Benry::CmdApp::Config.new("sample app")
|
1647
|
-
config.app_detail = "
|
1648
|
-
config.
|
1649
|
-
|
2455
|
+
config = Benry::CmdApp::Config.new("sample app", "1.0.0")
|
2456
|
+
config.app_detail = "See https://...." # !!!!
|
2457
|
+
config.help_description = " Bla bla bla" # !!!!
|
2458
|
+
config.help_postamble = [ # !!!!
|
2459
|
+
{"Example:" => " $ <command> hello Alice\n"}, # !!!!
|
2460
|
+
"(Tips: ....)", # !!!!
|
1650
2461
|
] # !!!!
|
1651
|
-
|
2462
|
+
|
1652
2463
|
app = Benry::CmdApp::Application.new(config)
|
1653
2464
|
exit app.main()
|
1654
2465
|
```
|
@@ -1656,288 +2467,337 @@ exit app.main()
|
|
1656
2467
|
Help message:
|
1657
2468
|
|
1658
2469
|
```console
|
1659
|
-
[bash]$ ruby
|
1660
|
-
|
2470
|
+
[bash]$ ruby ex47.rb -h
|
2471
|
+
ex47.rb --- sample app
|
1661
2472
|
|
1662
|
-
|
2473
|
+
See https://.... # !!!!
|
1663
2474
|
|
1664
2475
|
Usage:
|
1665
|
-
$
|
2476
|
+
$ ex47.rb [<options>] <action> [<arguments>...]
|
2477
|
+
|
2478
|
+
Description: # !!!!
|
2479
|
+
Bla bla bla # !!!!
|
1666
2480
|
|
1667
2481
|
Options:
|
1668
|
-
-h, --help : print help message (of action if
|
2482
|
+
-h, --help : print help message (of action if specified)
|
2483
|
+
-l, --list : list actions and aliases
|
2484
|
+
-a, --all : list hidden actions/options, too
|
1669
2485
|
|
1670
2486
|
Actions:
|
1671
2487
|
hello : test action #1
|
1672
2488
|
|
1673
|
-
Example:
|
1674
|
-
$ <command> hello Alice
|
2489
|
+
Example: # !!!!
|
2490
|
+
$ <command> hello Alice # !!!!
|
1675
2491
|
|
1676
|
-
(Tips: ....)
|
2492
|
+
(Tips: ....) # !!!!
|
1677
2493
|
```
|
1678
2494
|
|
1679
2495
|
If you want to change behaviour of building command help message:
|
1680
2496
|
|
1681
|
-
* (1) Define subclass of `Benry::CmdApp::
|
2497
|
+
* (1) Define subclass of `Benry::CmdApp::ApplicationHelpBuilder` class.
|
1682
2498
|
* (2) Override methods.
|
1683
2499
|
* (3) Create an instance object of the class.
|
1684
2500
|
* (4) Pass it to Application object.
|
1685
2501
|
|
1686
|
-
File:
|
2502
|
+
File: ex48.rb
|
1687
2503
|
|
1688
2504
|
```ruby
|
1689
|
-
|
2505
|
+
# coding: utf-8
|
1690
2506
|
require 'benry/cmdapp'
|
1691
2507
|
|
1692
2508
|
class SampleAction < Benry::CmdApp::Action
|
1693
2509
|
|
1694
|
-
@action.("greeting message")
|
2510
|
+
@action.("print greeting message")
|
1695
2511
|
def hello(user="world")
|
1696
2512
|
puts "Hello, #{user}!"
|
1697
2513
|
end
|
1698
2514
|
|
1699
2515
|
end
|
1700
2516
|
|
1701
|
-
## (1) Define subclass of ``Benry::CmdApp::
|
1702
|
-
class MyAppHelpBuilder < Benry::CmdApp::
|
2517
|
+
## (1) Define subclass of ``Benry::CmdApp::ApplicationHelpBuilder`` class.
|
2518
|
+
class MyAppHelpBuilder < Benry::CmdApp::ApplicationHelpBuilder
|
1703
2519
|
|
1704
2520
|
## (2) Override methods.
|
1705
|
-
def build_help_message(all
|
1706
|
-
super
|
1707
|
-
end
|
1708
|
-
def build_preamble(all=false)
|
2521
|
+
def build_help_message(gschema, all: false)
|
1709
2522
|
super
|
1710
2523
|
end
|
1711
|
-
def
|
2524
|
+
def section_preamble()
|
1712
2525
|
super
|
1713
2526
|
end
|
1714
|
-
def
|
2527
|
+
def section_usage()
|
1715
2528
|
super
|
1716
2529
|
end
|
1717
|
-
def
|
2530
|
+
def section_options(global_opts_schema, all: false)
|
1718
2531
|
super
|
1719
2532
|
end
|
1720
|
-
def
|
2533
|
+
def section_actions(include_aliases=true, all: false)
|
1721
2534
|
super
|
1722
2535
|
end
|
1723
|
-
def
|
2536
|
+
def section_postamble()
|
1724
2537
|
super
|
1725
2538
|
end
|
2539
|
+
### optional (for `-L <topic>` option)
|
2540
|
+
#def section_candidates(prefix, all: false); super; end
|
2541
|
+
#def section_aliases(all: false); super; end
|
2542
|
+
#def section_abbrevs(all: false); super; end
|
2543
|
+
#def section_categories(depth=0, all: false); super; end
|
1726
2544
|
end
|
1727
2545
|
|
1728
2546
|
## (3) Create an instance object of the class.
|
1729
2547
|
config = Benry::CmdApp::Config.new("sample app")
|
1730
|
-
schema = Benry::CmdApp::
|
2548
|
+
schema = Benry::CmdApp::GlobalOptionSchema.new(config)
|
1731
2549
|
schema.add(:logging, "--logging", "enable logging")
|
1732
|
-
|
2550
|
+
app_help_builder = MyAppHelpBuilder.new(config) # !!!!
|
1733
2551
|
|
1734
2552
|
## (4) Pass it to Application object.
|
1735
|
-
app = Benry::CmdApp::Application.new(config, schema,
|
2553
|
+
app = Benry::CmdApp::Application.new(config, schema, app_help_builder) # !!!!
|
1736
2554
|
exit app.main()
|
1737
2555
|
```
|
1738
2556
|
|
1739
2557
|
More simple way:
|
1740
2558
|
|
1741
|
-
* (1) Create a module and override methods of `Benry::CmdApp::
|
1742
|
-
* (2) Prepend it to `Benry::CmdApp::
|
2559
|
+
* (1) Create a module and override methods of `Benry::CmdApp::ApplicationHelpBuilder` class.
|
2560
|
+
* (2) Prepend it to `Benry::CmdApp::ApplicationHelpBuilder` class.
|
1743
2561
|
* (3) Create and execute Application object.
|
1744
2562
|
|
1745
|
-
File:
|
2563
|
+
File: ex49.rb
|
1746
2564
|
|
1747
2565
|
```ruby
|
1748
|
-
|
2566
|
+
# coding: utf-8
|
1749
2567
|
require 'benry/cmdapp'
|
1750
2568
|
|
1751
2569
|
class SampleAction < Benry::CmdApp::Action
|
1752
2570
|
|
1753
|
-
@action.("greeting message")
|
2571
|
+
@action.("print greeting message")
|
1754
2572
|
def hello(user="world")
|
1755
2573
|
puts "Hello, #{user}!"
|
1756
2574
|
end
|
1757
2575
|
|
1758
2576
|
end
|
1759
2577
|
|
1760
|
-
## (1) Create a module and override methods of ``
|
2578
|
+
## (1) Create a module and override methods of ``ApplicationHelpBuilder`` class.
|
1761
2579
|
module MyHelpBuilderMod
|
1762
|
-
def build_help_message(all
|
2580
|
+
def build_help_message(gschema, all: false)
|
1763
2581
|
super
|
1764
2582
|
end
|
1765
|
-
def
|
2583
|
+
def section_preamble()
|
1766
2584
|
super
|
1767
2585
|
end
|
1768
|
-
def
|
2586
|
+
def section_usage()
|
1769
2587
|
super
|
1770
2588
|
end
|
1771
|
-
def
|
2589
|
+
def section_options(global_opts_schema, all: false)
|
1772
2590
|
super
|
1773
2591
|
end
|
1774
|
-
def
|
2592
|
+
def section_actions(include_aliases=true, all: false)
|
1775
2593
|
super
|
1776
2594
|
end
|
1777
|
-
def
|
1778
|
-
super
|
1779
|
-
end
|
1780
|
-
def heading(str)
|
2595
|
+
def section_postamble()
|
1781
2596
|
super
|
1782
2597
|
end
|
2598
|
+
### optional (for `-L <topic>` option)
|
2599
|
+
#def section_candidates(prefix, all: false); super; end
|
2600
|
+
#def section_aliases(all: false); super; end
|
2601
|
+
#def section_abbrevs(all: false); super; end
|
2602
|
+
#def section_categories(depth=0, all: false); super; end
|
1783
2603
|
end
|
1784
2604
|
|
1785
|
-
## (2) Prepend it to ``Benry::CmdApp::
|
1786
|
-
Benry::CmdApp::
|
2605
|
+
## (2) Prepend it to ``Benry::CmdApp::ApplicationHelpBuilder`` class.
|
2606
|
+
Benry::CmdApp::ApplicationHelpBuilder.prepend(MyHelpBuilderMod)
|
1787
2607
|
|
1788
|
-
## (3)
|
1789
|
-
|
1790
|
-
app = Benry::CmdApp::Application.new(config)
|
1791
|
-
exit app.main()
|
2608
|
+
## (3) Run application.
|
2609
|
+
exit Benry::CmdApp.main("sample app")
|
1792
2610
|
```
|
1793
2611
|
|
1794
2612
|
|
1795
2613
|
### Customization of Action Help Message
|
1796
2614
|
|
1797
2615
|
If you want to just add more text into action help message,
|
1798
|
-
pass
|
2616
|
+
pass the following keyword arguments to `@action.()`.
|
1799
2617
|
|
1800
|
-
|
2618
|
+
* `detail: <text>` --- printed before 'Usage:' section.
|
2619
|
+
* `description: <text>` --- printed after 'Usage:' section as 'Description:' section, like `man` command in UNIX.
|
2620
|
+
* `postamble: {<header> => <text>}` --- printed at end of help message as a dedicated section.
|
2621
|
+
|
2622
|
+
File: ex50.rb
|
1801
2623
|
|
1802
2624
|
```ruby
|
1803
|
-
|
2625
|
+
# coding: utf-8
|
1804
2626
|
require 'benry/cmdapp'
|
1805
2627
|
|
1806
2628
|
class SampleAction < Benry::CmdApp::Action
|
1807
2629
|
|
1808
2630
|
@action.("test action #1",
|
1809
|
-
detail: "
|
1810
|
-
|
2631
|
+
detail: "See https://....", # !!!!
|
2632
|
+
description: " Bla bla bla", # !!!!
|
2633
|
+
postamble: {"Example:" => " ...."}) # !!!!
|
1811
2634
|
def hello(user="world")
|
1812
2635
|
puts "Hello, #{user}!"
|
1813
2636
|
end
|
1814
2637
|
|
1815
2638
|
end
|
1816
2639
|
|
1817
|
-
|
1818
|
-
app = Benry::CmdApp::Application.new(config)
|
1819
|
-
exit app.main()
|
2640
|
+
exit Benry::CmdApp.main("sample app")
|
1820
2641
|
```
|
1821
2642
|
|
1822
2643
|
Help message:
|
1823
2644
|
|
1824
2645
|
```console
|
1825
|
-
[bash]$ ruby
|
1826
|
-
|
2646
|
+
[bash]$ ruby ex50.rb -h hello
|
2647
|
+
ex50.rb hello --- test action #1
|
1827
2648
|
|
1828
|
-
|
2649
|
+
See https://.... # !!!!
|
1829
2650
|
|
1830
2651
|
Usage:
|
1831
|
-
$
|
2652
|
+
$ ex50.rb hello [<user>]
|
1832
2653
|
|
1833
|
-
|
2654
|
+
Description: # !!!!
|
2655
|
+
Bla bla bla # !!!!
|
2656
|
+
|
2657
|
+
Example:
|
2658
|
+
.... # !!!!
|
1834
2659
|
```
|
1835
2660
|
|
1836
2661
|
If you want to change behaviour of building action help message:
|
1837
2662
|
|
1838
|
-
* (1)
|
1839
|
-
* (2)
|
1840
|
-
* (3) Create
|
2663
|
+
* (1) Define subclass of `ActionHelpBuilder` class.
|
2664
|
+
* (2) Override methods.
|
2665
|
+
* (3) Create an instance object of the class.
|
2666
|
+
* (4) Pass it to Application object.
|
1841
2667
|
|
1842
|
-
File:
|
2668
|
+
File: ex51.rb
|
1843
2669
|
|
1844
2670
|
```ruby
|
1845
|
-
#!/usr/bin/env ruby
|
1846
2671
|
require 'benry/cmdapp'
|
1847
2672
|
|
1848
2673
|
class SampleAction < Benry::CmdApp::Action
|
1849
2674
|
|
1850
|
-
@action.("greeting message")
|
2675
|
+
@action.("print greeting message")
|
1851
2676
|
def hello(user="world")
|
1852
2677
|
puts "Hello, #{user}!"
|
1853
2678
|
end
|
1854
2679
|
|
1855
2680
|
end
|
1856
2681
|
|
1857
|
-
## (1)
|
1858
|
-
|
1859
|
-
|
2682
|
+
## (1) Define subclass of ``ActionHelpBuilder`` class.
|
2683
|
+
class MyActionHelpBuilder < Benry::CmdApp::ActionHelpBuilder
|
2684
|
+
## (2) Override methods.
|
2685
|
+
def build_help_message(metadata, all: false)
|
1860
2686
|
super
|
1861
2687
|
end
|
1862
|
-
def
|
2688
|
+
def section_preamble(metadata)
|
1863
2689
|
super
|
1864
2690
|
end
|
1865
|
-
def
|
2691
|
+
def section_usage(metadata, all: false)
|
1866
2692
|
super
|
1867
2693
|
end
|
1868
|
-
def
|
2694
|
+
def section_description(metadata)
|
1869
2695
|
super
|
1870
2696
|
end
|
1871
|
-
def
|
2697
|
+
def section_options(metadata, all: false)
|
1872
2698
|
super
|
1873
2699
|
end
|
1874
|
-
def
|
2700
|
+
def section_postamble(metadata)
|
1875
2701
|
super
|
1876
2702
|
end
|
1877
2703
|
end
|
1878
2704
|
|
1879
|
-
## (
|
1880
|
-
Benry::CmdApp::ActionHelpBuilder.prepend(MyActionHelpBuilderMod) # !!!!
|
1881
|
-
|
1882
|
-
## (3) Create and execute Application object.
|
2705
|
+
## (3) Create an instance object of the class.
|
1883
2706
|
config = Benry::CmdApp::Config.new("sample app")
|
1884
|
-
|
2707
|
+
action_help_builder = MyActionHelpBuilder.new(config)
|
2708
|
+
|
2709
|
+
## (4) Pass it to Application object.
|
2710
|
+
schema = Benry::CmdApp::GlobalOptionSchema.new(config)
|
2711
|
+
app = Benry::CmdApp::Application.new(config, schema, nil, action_help_builder)
|
1885
2712
|
exit app.main()
|
1886
2713
|
```
|
1887
2714
|
|
1888
2715
|
Another way:
|
1889
2716
|
|
1890
|
-
* (1)
|
1891
|
-
* (2)
|
1892
|
-
* (3)
|
2717
|
+
* (1) Create a module and override methods of `Benry::CmdApp::ActionHelpBuilder` class.
|
2718
|
+
* (2) Prepend it to `Benry::CmdApp::ActionHelpBuilder` class.
|
2719
|
+
* (3) Run application.
|
1893
2720
|
|
1894
|
-
File:
|
2721
|
+
File: ex52.rb
|
1895
2722
|
|
1896
2723
|
```ruby
|
1897
|
-
|
2724
|
+
# coding: utf-8
|
1898
2725
|
require 'benry/cmdapp'
|
1899
2726
|
|
1900
2727
|
class SampleAction < Benry::CmdApp::Action
|
1901
2728
|
|
1902
|
-
@action.("greeting message")
|
2729
|
+
@action.("print greeting message")
|
1903
2730
|
def hello(user="world")
|
1904
2731
|
puts "Hello, #{user}!"
|
1905
2732
|
end
|
1906
2733
|
|
1907
2734
|
end
|
1908
2735
|
|
1909
|
-
## (1)
|
1910
|
-
|
1911
|
-
def build_help_message(
|
2736
|
+
## (1) Create a module and override methods of ``ActionHelpBuilder`` class.
|
2737
|
+
module MyActionHelpBuilderMod
|
2738
|
+
def build_help_message(metadata, all: false)
|
1912
2739
|
super
|
1913
2740
|
end
|
1914
|
-
def
|
2741
|
+
def section_preamble(metadata)
|
1915
2742
|
super
|
1916
2743
|
end
|
1917
|
-
def
|
2744
|
+
def section_usage(metadata, all: false)
|
1918
2745
|
super
|
1919
2746
|
end
|
1920
|
-
def
|
2747
|
+
def section_description(metadata)
|
1921
2748
|
super
|
1922
2749
|
end
|
1923
|
-
def
|
2750
|
+
def section_options(metadata, all: false)
|
1924
2751
|
super
|
1925
2752
|
end
|
1926
|
-
def
|
2753
|
+
def section_postamble(metadata)
|
1927
2754
|
super
|
1928
2755
|
end
|
1929
2756
|
end
|
1930
2757
|
|
1931
|
-
## (2)
|
1932
|
-
Benry::CmdApp.
|
1933
|
-
remove_const :ACTION_HELP_BUILDER_CLASS
|
1934
|
-
const_set :ACTION_HELP_BUILDER_CLASS, MyActionHelpBuilder
|
1935
|
-
end
|
2758
|
+
## (2) Prepend it to ``Benry::CmdApp::ActionHelpBuilder`` class.
|
2759
|
+
Benry::CmdApp::ActionHelpBuilder.prepend(MyActionHelpBuilderMod) # !!!!
|
1936
2760
|
|
1937
|
-
## (3)
|
1938
|
-
|
1939
|
-
|
1940
|
-
|
2761
|
+
## (3) Run application.
|
2762
|
+
exit Benry::CmdApp::main("sample app")
|
2763
|
+
```
|
2764
|
+
|
2765
|
+
|
2766
|
+
### Customization of Section Title in Help Message
|
2767
|
+
|
2768
|
+
If you want to change section titles such as 'Options:' or 'Actions:'
|
2769
|
+
in the help message, override the constants representing section titles.
|
2770
|
+
|
2771
|
+
The following constants are defined in `BaseHelperBuilder` class.
|
2772
|
+
|
2773
|
+
```ruby
|
2774
|
+
module Benry::CmdApp
|
2775
|
+
class BaseHelpBuilder
|
2776
|
+
HEADER_USAGE = "Usage:"
|
2777
|
+
HEADER_DESCRIPTION = "Description:"
|
2778
|
+
HEADER_OPTIONS = "Options:"
|
2779
|
+
HEADER_ACTIONS = "Actions:"
|
2780
|
+
HEADER_ALIASES = "Aliases:"
|
2781
|
+
HEADER_ABBREVS = "Abbreviations:"
|
2782
|
+
HEADER_CATEGORIES = "Categories:"
|
2783
|
+
```
|
2784
|
+
|
2785
|
+
You can override them in `ApplicationHelpBuilder` or `ActionHelpBuilder`
|
2786
|
+
classes which are subclass of `BaseHandlerBuilder` class.
|
2787
|
+
|
2788
|
+
```ruby
|
2789
|
+
## for example
|
2790
|
+
Benry::CmdApp::ApplicationHelpBuilder::HEADER_ACTIONS = "ACTIONS:"
|
2791
|
+
Benry::CmdApp::ActionHelpBuilder::HEADER_OPTIONS = "OPTIONS:"
|
2792
|
+
```
|
2793
|
+
|
2794
|
+
If you want to change just decoration of section titles,
|
2795
|
+
set `config.deco_header`.
|
2796
|
+
|
2797
|
+
```ruby
|
2798
|
+
config = Benry::CmdApp::Config.new("Test App", "1.0.0")
|
2799
|
+
config.deco_header = "\e[1;34m%s\e[0m" # bold, blue
|
2800
|
+
#config.deco_header = "\e[1;4m%s\e[0m" # bold, underline
|
1941
2801
|
```
|
1942
2802
|
|
1943
2803
|
|
@@ -1945,11 +2805,25 @@ exit app.main()
|
|
1945
2805
|
## Q & A
|
1946
2806
|
|
1947
2807
|
|
1948
|
-
### Q: How to
|
2808
|
+
### Q: How to show all backtraces of exception?
|
2809
|
+
|
2810
|
+
A: Add `--deubg` option.
|
2811
|
+
Benry-CmdApp catches exceptions and handles their backtrace
|
2812
|
+
automatically in default, but doesn't catch them when `--debug`
|
2813
|
+
option is specified.
|
2814
|
+
|
2815
|
+
|
2816
|
+
### Q: How to specify description to arguments of actions?
|
2817
|
+
|
2818
|
+
A: Can't. It is possible to specify description to actions or options,
|
2819
|
+
but not possible to arguments of actions.
|
2820
|
+
|
2821
|
+
|
2822
|
+
### Q: How to append some tasks to an existing action?
|
1949
2823
|
|
1950
2824
|
A: (a) Use method alias, or (b) use prepend.
|
1951
2825
|
|
1952
|
-
File:
|
2826
|
+
File: ex61.rb
|
1953
2827
|
|
1954
2828
|
```ruby
|
1955
2829
|
require 'benry/cmdapp'
|
@@ -1970,7 +2844,7 @@ end
|
|
1970
2844
|
|
1971
2845
|
## (a) use method alias
|
1972
2846
|
class SampleAction # open existing class
|
1973
|
-
alias __old_hello hello # alias
|
2847
|
+
alias __old_hello hello # alias for existing method
|
1974
2848
|
def hello(user="world") # override existing method
|
1975
2849
|
puts "---- >8 ---- >8 ----"
|
1976
2850
|
__old_hello(user) # call original method
|
@@ -1988,31 +2862,34 @@ module SampleMod # define new module
|
|
1988
2862
|
end
|
1989
2863
|
SampleAction.prepend(SampleMod) # prepend it to existing class
|
1990
2864
|
|
1991
|
-
|
1992
|
-
app = Benry::CmdApp::Application.new(config)
|
1993
|
-
exit app.main()
|
2865
|
+
exit Benry::CmdApp.main("sample app")
|
1994
2866
|
```
|
1995
2867
|
|
1996
2868
|
Output:
|
1997
2869
|
|
1998
2870
|
```console
|
1999
|
-
[bash]$ ruby
|
2871
|
+
[bash]$ ruby ex61.rb hello
|
2000
2872
|
---- >8 ---- >8 ----
|
2001
2873
|
Hello, world!
|
2002
2874
|
---- 8< ---- 8< ----
|
2003
2875
|
|
2004
|
-
[bash]$ ruby
|
2876
|
+
[bash]$ ruby ex61.rb hi Alice
|
2005
2877
|
~~~~ >8 ~~~~ >8 ~~~~
|
2006
2878
|
Hi, Alice!
|
2007
2879
|
~~~~ 8< ~~~~ 8< ~~~~
|
2008
2880
|
```
|
2009
2881
|
|
2010
2882
|
|
2011
|
-
### Q: How to
|
2883
|
+
### Q: How to delete an existing action/alias?
|
2012
2884
|
|
2013
|
-
A:
|
2885
|
+
A: Call `Benry::CmdApp.undef_action("<action>")` or `Benry::CmdApp.undef_alias("<alias>")`.
|
2014
2886
|
|
2015
|
-
|
2887
|
+
|
2888
|
+
### Q: How to re-define an existing action?
|
2889
|
+
|
2890
|
+
A: First remove the existing action, then re-define the action.
|
2891
|
+
|
2892
|
+
File: ex62.rb
|
2016
2893
|
|
2017
2894
|
```ruby
|
2018
2895
|
require 'benry/cmdapp'
|
@@ -2026,7 +2903,7 @@ class SampleAction < Benry::CmdApp::Action
|
|
2026
2903
|
|
2027
2904
|
end
|
2028
2905
|
|
2029
|
-
Benry::CmdApp.
|
2906
|
+
Benry::CmdApp.undef_action("hello") # !!!!
|
2030
2907
|
|
2031
2908
|
class OtherAction < Benry::CmdApp::Action
|
2032
2909
|
|
@@ -2037,38 +2914,34 @@ class OtherAction < Benry::CmdApp::Action
|
|
2037
2914
|
|
2038
2915
|
end
|
2039
2916
|
|
2040
|
-
|
2041
|
-
app = Benry::CmdApp::Application.new(config)
|
2042
|
-
exit app.main()
|
2917
|
+
exit Benry::CmdApp.main("sample app")
|
2043
2918
|
```
|
2044
2919
|
|
2045
2920
|
Help message:
|
2046
2921
|
|
2047
2922
|
```console
|
2048
|
-
[bash]$ ruby
|
2049
|
-
|
2923
|
+
[bash]$ ruby ex62.rb -h
|
2924
|
+
ex62.rb --- sample app
|
2050
2925
|
|
2051
2926
|
Usage:
|
2052
|
-
$
|
2927
|
+
$ ex62.rb [<options>] <action> [<arguments>...]
|
2053
2928
|
|
2054
2929
|
Options:
|
2055
|
-
-h, --help : print help message (of action if
|
2930
|
+
-h, --help : print help message (of action if specified)
|
2931
|
+
-l, --list : list actions and aliases
|
2932
|
+
-a, --all : list hidden actions/options, too
|
2056
2933
|
|
2057
2934
|
Actions:
|
2058
2935
|
hello : other action # !!!!
|
2936
|
+
help : print help message (of action if specified)
|
2059
2937
|
```
|
2060
2938
|
|
2061
2939
|
|
2062
|
-
### Q: How to
|
2063
|
-
|
2064
|
-
A: Call `Benry::CmdApp.delete_action("<action>")` or `Benry::CmdApp.delete_alias("<alias>")`.
|
2065
|
-
|
2066
|
-
|
2067
|
-
### Q: How to Show Entering Into or Exitting From Action?
|
2940
|
+
### Q: How to show entering into or exitting from actions?
|
2068
2941
|
|
2069
2942
|
A: Set `config.option_trace = true` and pass `-T` (or `--trace`) option.
|
2070
2943
|
|
2071
|
-
File:
|
2944
|
+
File: ex63.rb
|
2072
2945
|
|
2073
2946
|
```ruby
|
2074
2947
|
require 'benry/cmdapp'
|
@@ -2082,82 +2955,81 @@ class SampleAction < Benry::CmdApp::Action
|
|
2082
2955
|
|
2083
2956
|
@action.("build")
|
2084
2957
|
def build()
|
2085
|
-
|
2958
|
+
run_once("prepare")
|
2086
2959
|
puts "... build something ..."
|
2087
2960
|
end
|
2088
2961
|
|
2089
2962
|
end
|
2090
2963
|
|
2091
|
-
|
2092
|
-
|
2093
|
-
app = Benry::CmdApp::Application.new(config)
|
2094
|
-
exit app.main()
|
2964
|
+
exit Benry::CmdApp.main("sample app", "1.0.0",
|
2965
|
+
option_trace: true) # !!!! (or `:hidden`)
|
2095
2966
|
```
|
2096
2967
|
|
2097
2968
|
Output:
|
2098
2969
|
|
2099
2970
|
```console
|
2100
|
-
[bash]$ ruby
|
2101
|
-
|
2102
|
-
|
2971
|
+
[bash]$ ruby ex63.rb --trace build # !!!!
|
2972
|
+
### enter: build
|
2973
|
+
### enter: prepare
|
2103
2974
|
... prepare something ...
|
2104
|
-
|
2975
|
+
### exit: prepare
|
2105
2976
|
... build something ...
|
2106
|
-
|
2977
|
+
### exit: build
|
2107
2978
|
```
|
2108
2979
|
|
2109
2980
|
|
2110
|
-
### Q: How to
|
2981
|
+
### Q: How to enable/disable color mode?
|
2111
2982
|
|
2112
2983
|
A: Set `config.option_color = true` and pass `--color=on` or `--color=off` option.
|
2113
2984
|
|
2114
|
-
File:
|
2985
|
+
File: ex64.rb
|
2115
2986
|
|
2116
2987
|
```ruby
|
2117
2988
|
require 'benry/cmdapp'
|
2118
2989
|
|
2119
2990
|
class SampleAction < Benry::CmdApp::Action
|
2120
2991
|
|
2121
|
-
@action.("greeting message")
|
2992
|
+
@action.("print greeting message")
|
2122
2993
|
def hello(user="world")
|
2123
2994
|
puts "Hello, #{user}!"
|
2124
2995
|
end
|
2125
2996
|
|
2126
2997
|
end
|
2127
2998
|
|
2128
|
-
|
2129
|
-
|
2130
|
-
app = Benry::CmdApp::Application.new(config)
|
2131
|
-
exit app.main()
|
2999
|
+
exit Benry::CmdApp.main("sample app",
|
3000
|
+
option_color: true) # !!!!
|
2132
3001
|
```
|
2133
3002
|
|
2134
3003
|
Help message:
|
2135
3004
|
|
2136
3005
|
```console
|
2137
|
-
[bash]$ ruby
|
2138
|
-
|
3006
|
+
[bash]$ ruby ex64.rb -h
|
3007
|
+
ex64.rb --- sample app
|
2139
3008
|
|
2140
3009
|
Usage:
|
2141
|
-
$
|
3010
|
+
$ ex64.rb [<options>] <action> [<arguments>...]
|
2142
3011
|
|
2143
3012
|
Options:
|
2144
|
-
-h, --help : print help message (of action if
|
3013
|
+
-h, --help : print help message (of action if specified)
|
3014
|
+
-l, --list : list actions and aliases
|
3015
|
+
-a, --all : list hidden actions/options, too
|
2145
3016
|
--color[=<on|off>] : enable/disable color # !!!!
|
2146
3017
|
|
2147
3018
|
Actions:
|
2148
|
-
hello : greeting message
|
3019
|
+
hello : print greeting message
|
2149
3020
|
|
2150
|
-
[bash]$ ruby
|
3021
|
+
[bash]$ ruby ex64.rb -h --color=off # !!!!
|
2151
3022
|
|
2152
|
-
[bash]$ ruby
|
3023
|
+
[bash]$ ruby ex64.rb -h --color=on # !!!!
|
3024
|
+
[bash]$ ruby ex64.rb -h --color # !!!!
|
2153
3025
|
```
|
2154
3026
|
|
2155
3027
|
|
2156
|
-
### Q: How to
|
3028
|
+
### Q: How to define a multiple option, like `-I` option of Ruby?
|
2157
3029
|
|
2158
3030
|
A: Provide block parameter on `@option.()`.
|
2159
3031
|
|
2160
|
-
File:
|
3032
|
+
File: ex65.rb
|
2161
3033
|
|
2162
3034
|
```ruby
|
2163
3035
|
require 'benry/cmdapp'
|
@@ -2172,30 +3044,33 @@ class TestAction < Benry::CmdApp::Action
|
|
2172
3044
|
## or: # !!!!
|
2173
3045
|
#(options[key] || []) << val # !!!!
|
2174
3046
|
} # !!!!
|
2175
|
-
def
|
3047
|
+
def test_(path: [])
|
2176
3048
|
puts "path=#{path.inspect}" #=> path=["/tmp", "/var/tmp"]
|
2177
3049
|
end
|
2178
3050
|
|
2179
3051
|
end
|
2180
3052
|
|
2181
|
-
|
2182
|
-
app = Benry::CmdApp::Application.new(config)
|
2183
|
-
exit app.main()
|
3053
|
+
exit Benry::CmdApp.main("test app")
|
2184
3054
|
```
|
2185
3055
|
|
2186
3056
|
Output:
|
2187
3057
|
|
2188
3058
|
```console
|
2189
|
-
[bash]$ ruby
|
3059
|
+
[bash]$ ruby ex65.rb test -I /tmp -I /var/tmp # !!!!
|
2190
3060
|
path=["/tmp", "/var/tmp"] # !!!!
|
2191
3061
|
```
|
2192
3062
|
|
2193
3063
|
|
2194
|
-
### Q: How to
|
3064
|
+
### Q: How to show global option `-L <topic>` in help message?
|
3065
|
+
|
3066
|
+
A: Set `config.option_topic = true` (default: `:hidden`).
|
3067
|
+
|
3068
|
+
|
3069
|
+
### Q: How to specify detailed description of options?
|
2195
3070
|
|
2196
3071
|
A: Add `detail:` keyword argument to `@option.()`.
|
2197
3072
|
|
2198
|
-
File:
|
3073
|
+
File: ex66.rb
|
2199
3074
|
|
2200
3075
|
```ruby
|
2201
3076
|
require 'benry/cmdapp'
|
@@ -2204,99 +3079,48 @@ class TestAction < Benry::CmdApp::Action
|
|
2204
3079
|
|
2205
3080
|
@action.("detailed description test")
|
2206
3081
|
@option.(:mode, "-m <mode>", "output mode", detail: <<"END")
|
2207
|
-
|
2208
|
-
|
2209
|
-
|
3082
|
+
v, verbose: print many output
|
3083
|
+
q, quiet: print litte output
|
3084
|
+
c, compact: print summary output
|
2210
3085
|
END
|
2211
|
-
def
|
3086
|
+
def test_(mode: nil)
|
2212
3087
|
puts "mode=#{mode.inspect}"
|
2213
3088
|
end
|
2214
3089
|
|
2215
3090
|
end
|
2216
3091
|
|
2217
|
-
|
2218
|
-
app = Benry::CmdApp::Application.new(config)
|
2219
|
-
exit app.main()
|
3092
|
+
exit Benry::CmdApp.main("test app")
|
2220
3093
|
```
|
2221
3094
|
|
2222
3095
|
Help message:
|
2223
3096
|
|
2224
3097
|
```console
|
2225
|
-
[bash]$ ruby
|
2226
|
-
|
3098
|
+
[bash]$ ruby ex66.rb -h test
|
3099
|
+
ex66.rb test --- detailed description test
|
2227
3100
|
|
2228
3101
|
Usage:
|
2229
|
-
$
|
3102
|
+
$ ex66.rb test [<options>]
|
2230
3103
|
|
2231
3104
|
Options:
|
2232
3105
|
-m <mode> : output mode
|
2233
|
-
|
2234
|
-
|
2235
|
-
|
2236
|
-
```
|
2237
|
-
|
2238
|
-
|
2239
|
-
### Q: How to Copy All Options from Other Action?
|
2240
|
-
|
2241
|
-
A: Use `@copy_options.()`.
|
2242
|
-
|
2243
|
-
File: ex47.rb
|
2244
|
-
|
2245
|
-
```ruby
|
2246
|
-
require 'benry/cmdapp'
|
2247
|
-
|
2248
|
-
class SampleAction < Benry::CmdApp::Action
|
2249
|
-
|
2250
|
-
@action.("test action #1")
|
2251
|
-
@option.(:verbose, "-v, --verbose", "verbose mode")
|
2252
|
-
@option.(:file, "-f, --file=<file>", "filename")
|
2253
|
-
@option.(:indent, "-i, --indent[=<N>]", "indent")
|
2254
|
-
def test1(verbose: false, file: nil, indent: nil)
|
2255
|
-
puts "verbose=#{verbose}, file=#{file}, indent=#{indent}"
|
2256
|
-
end
|
2257
|
-
|
2258
|
-
@action.("test action #2")
|
2259
|
-
@copy_options.("test1") # !!!! copy options from test1 !!!!
|
2260
|
-
@option.(:debug, "-D, --debug", "debug mode")
|
2261
|
-
def test2(verbose: false, file: nil, indent: nil, debug: false)
|
2262
|
-
puts "verbose=#{verbose}, file=#{file}, indent=#{indent}, debug=#{debug}"
|
2263
|
-
end
|
2264
|
-
|
2265
|
-
end
|
2266
|
-
|
2267
|
-
config = Benry::CmdApp::Config.new("sample app")
|
2268
|
-
app = Benry::CmdApp::Application.new(config)
|
2269
|
-
exit app.main()
|
2270
|
-
```
|
2271
|
-
|
2272
|
-
Help message of `test2` action:
|
2273
|
-
|
2274
|
-
```console
|
2275
|
-
[bash]$ ruby ex47.rb -h test2
|
2276
|
-
ex47.rb test2 -- test action #2
|
2277
|
-
|
2278
|
-
Usage:
|
2279
|
-
$ ex47.rb test2 [<options>]
|
2280
|
-
|
2281
|
-
Options:
|
2282
|
-
-v, --verbose : verbose mode # copied!!
|
2283
|
-
-f, --file=<file> : filename # copied!!
|
2284
|
-
-i, --indent[=<N>] : indent # copied!!
|
2285
|
-
-D, --debug : debug mode
|
3106
|
+
v, verbose: print many output
|
3107
|
+
q, quiet: print litte output
|
3108
|
+
c, compact: print summary output
|
2286
3109
|
```
|
2287
3110
|
|
2288
3111
|
|
2289
|
-
|
3112
|
+
<!--
|
3113
|
+
### Q: What is the difference between `category(alias_for:)` and `category(action:)`?
|
2290
3114
|
|
2291
3115
|
A: The former defines an alias, and the latter doesn't.
|
2292
3116
|
|
2293
|
-
File:
|
3117
|
+
File: ex67.rb
|
2294
3118
|
|
2295
3119
|
```ruby
|
2296
3120
|
require 'benry/cmdapp'
|
2297
3121
|
|
2298
3122
|
class AaaAction < Benry::CmdApp::Action
|
2299
|
-
|
3123
|
+
category "aaa:", alias_for: "print"
|
2300
3124
|
|
2301
3125
|
@action.("test #1")
|
2302
3126
|
def print_()
|
@@ -2306,7 +3130,7 @@ class AaaAction < Benry::CmdApp::Action
|
|
2306
3130
|
end
|
2307
3131
|
|
2308
3132
|
class BbbAction < Benry::CmdApp::Action
|
2309
|
-
|
3133
|
+
category "bbb:", action: "print"
|
2310
3134
|
|
2311
3135
|
@action.("test #2")
|
2312
3136
|
def print_()
|
@@ -2315,156 +3139,173 @@ class BbbAction < Benry::CmdApp::Action
|
|
2315
3139
|
|
2316
3140
|
end
|
2317
3141
|
|
2318
|
-
|
2319
|
-
app = Benry::CmdApp::Application.new(config)
|
2320
|
-
exit app.main()
|
3142
|
+
exit Benry::CmdApp.main("sample app")
|
2321
3143
|
```
|
2322
3144
|
|
2323
3145
|
Help message:
|
2324
3146
|
|
2325
3147
|
```console
|
2326
|
-
[bash]$ ruby
|
2327
|
-
|
3148
|
+
[bash]$ ruby ex67.rb -h
|
3149
|
+
ex67.rb --- sample app
|
2328
3150
|
|
2329
3151
|
Usage:
|
2330
|
-
$
|
3152
|
+
$ ex67.rb [<options>] <action> [<arguments>...]
|
2331
3153
|
|
2332
3154
|
Options:
|
2333
|
-
-h, --help : print help message (of action if
|
3155
|
+
-h, --help : print help message (of action if specified)
|
3156
|
+
-l, --list : list actions and aliases
|
3157
|
+
-L <topic> : topic list (actions|aliases|categories|abbrevs)
|
3158
|
+
-a, --all : list hidden actions/options, too
|
2334
3159
|
|
2335
3160
|
Actions:
|
2336
|
-
aaa : alias
|
3161
|
+
aaa : alias for 'aaa:print' action # !!!!
|
2337
3162
|
aaa:print : test #1
|
2338
3163
|
bbb : test #2 # !!!!
|
3164
|
+
help : print help message (of action if specified)
|
2339
3165
|
```
|
2340
3166
|
|
2341
|
-
In the above example, alias `aaa` is defined due to `
|
2342
|
-
and action `bbb` is not an alias due to `
|
3167
|
+
In the above example, alias `aaa` is defined due to `category(alias_for:)`,
|
3168
|
+
and action `bbb` is not an alias due to `category(action:)`.
|
3169
|
+
-->
|
2343
3170
|
|
2344
3171
|
|
2345
|
-
### Q: How to
|
3172
|
+
### Q: How to list only aliases (or actions) excluding actions (or aliases) ?
|
2346
3173
|
|
2347
|
-
A:
|
3174
|
+
A: Specify global option `-L alias` or `-L action`.
|
3175
|
+
|
3176
|
+
```console
|
3177
|
+
[bash]$ ruby gitexample.rb -l
|
3178
|
+
Actions:
|
3179
|
+
git : alias for 'git:status'
|
3180
|
+
git:stage : put changes of files into staging area
|
3181
|
+
git:staged : show changes in staging area
|
3182
|
+
git:status : show status in compact format
|
3183
|
+
git:unstage : remove changes from staging area
|
3184
|
+
stage : alias for 'git:stage'
|
3185
|
+
staged : alias for 'git:staged'
|
3186
|
+
unstage : alias for 'git:unstage'
|
3187
|
+
|
3188
|
+
### list only aliases (ordered by action name automatically)
|
3189
|
+
[bash]$ ruby gitexample.rb -L alias # !!!!
|
3190
|
+
Aliases:
|
3191
|
+
stage : alias for 'git:stage'
|
3192
|
+
staged : alias for 'git:staged'
|
3193
|
+
git : alias for 'git:status'
|
3194
|
+
unstage : alias for 'git:unstage'
|
3195
|
+
|
3196
|
+
### list only actions
|
3197
|
+
[bash]$ ruby gitexample.rb -L action # !!!!
|
3198
|
+
Actions:
|
3199
|
+
git:stage : put changes of files into staging area
|
3200
|
+
git:staged : show changes in staging area
|
3201
|
+
git:status : show status in compact format
|
3202
|
+
git:unstage : remove changes from staging area
|
3203
|
+
```
|
3204
|
+
|
3205
|
+
Notice that `-L alias` sorts aliases by action names.
|
3206
|
+
This is the intended behaviour.
|
2348
3207
|
|
2349
|
-
|
3208
|
+
|
3209
|
+
### Q: How to change the order of options in help message?
|
3210
|
+
|
3211
|
+
A: Call `GlobalOptionSchema#reorder_options()`.
|
3212
|
+
|
3213
|
+
File: ex68.rb
|
2350
3214
|
|
2351
3215
|
```ruby
|
2352
3216
|
require 'benry/cmdapp'
|
2353
3217
|
|
2354
3218
|
config = Benry::CmdApp::Config.new("sample app", "1.0.0",
|
2355
|
-
|
3219
|
+
option_verbose: true,
|
2356
3220
|
option_quiet: true,
|
2357
3221
|
option_color: true,
|
2358
3222
|
)
|
2359
|
-
schema = Benry::CmdApp::
|
2360
|
-
keys = [:
|
2361
|
-
schema.
|
3223
|
+
schema = Benry::CmdApp::GlobalOptionSchema.new(config)
|
3224
|
+
keys = [:verbose, :quiet, :color, :help, :version, :all, :target, :list] # !!!!
|
3225
|
+
schema.reorder_options(*keys) # !!!!
|
2362
3226
|
app = Benry::CmdApp::Application.new(config, schema)
|
2363
3227
|
## or:
|
2364
3228
|
#app = Benry::CmdApp::Application.new(config)
|
2365
|
-
#app.schema.
|
3229
|
+
#app.schema.reorder_options(*keys) # !!!!
|
2366
3230
|
exit app.main()
|
2367
3231
|
```
|
2368
3232
|
|
2369
3233
|
Help message:
|
2370
3234
|
|
2371
3235
|
```console
|
2372
|
-
[bash]$ ruby
|
2373
|
-
|
3236
|
+
[bash]$ ruby ex68.rb -h
|
3237
|
+
ex68.rb (1.0.0) --- sample app
|
2374
3238
|
|
2375
3239
|
Usage:
|
2376
|
-
$
|
3240
|
+
$ ex68.rb [<options>] <action> [<arguments>...]
|
2377
3241
|
|
2378
3242
|
Options:
|
2379
|
-
-
|
3243
|
+
-v, --verbose : verbose mode
|
2380
3244
|
-q, --quiet : quiet mode
|
2381
|
-
--color[=<on|off>] :
|
2382
|
-
-h, --help : print help message (of action if
|
3245
|
+
--color[=<on|off>] : color mode
|
3246
|
+
-h, --help : print help message (of action if specified)
|
2383
3247
|
-V, --version : print version
|
3248
|
+
-a, --all : list hidden actions/options, too
|
3249
|
+
-L <topic> : topic list (actions|aliases|categories|abbrevs)
|
3250
|
+
-l, --list : list actions and aliases
|
2384
3251
|
|
2385
3252
|
Actions:
|
2386
|
-
|
3253
|
+
help : print help message (of action if specified)
|
2387
3254
|
```
|
2388
3255
|
|
2389
3256
|
|
2390
|
-
### Q:
|
3257
|
+
### Q: How to add metadata to actions or options?
|
2391
3258
|
|
2392
|
-
A:
|
3259
|
+
A: Pass `tag:` keyword argument to `@action.()` or `@option.()`.
|
2393
3260
|
|
2394
|
-
|
3261
|
+
* `tag:` keyword argument accept any type of value such as symbol, string, array, and so on.
|
3262
|
+
* Currenty, Benry-CmdApp doesn't provide the good way to use it effectively.
|
3263
|
+
This feature may be used by command-line application or framework based on Benry-CmdApp.
|
3264
|
+
|
3265
|
+
File: ex69.rb
|
2395
3266
|
|
2396
3267
|
```ruby
|
2397
3268
|
require 'benry/cmdapp'
|
2398
3269
|
|
2399
3270
|
class SampleAction < Benry::CmdApp::Action
|
2400
3271
|
|
2401
|
-
@action.("
|
2402
|
-
|
2403
|
-
|
2404
|
-
|
2405
|
-
|
2406
|
-
|
3272
|
+
@action.("print greeting message", tag: :important) # !!!!
|
3273
|
+
@option.(:repeat, "-r <N>", "repeat N times", tag: :important) # !!!!
|
3274
|
+
def hello(user="world", repeat: nil)
|
3275
|
+
(repeat || 1).times do
|
3276
|
+
puts "Hello, #{user}!"
|
3277
|
+
end
|
2407
3278
|
end
|
2408
3279
|
|
2409
3280
|
end
|
2410
3281
|
|
2411
|
-
|
2412
|
-
app = Benry::CmdApp::Application.new(config)
|
2413
|
-
exit app.main()
|
2414
|
-
```
|
2415
|
-
|
2416
|
-
Help message:
|
2417
|
-
|
2418
|
-
```console
|
2419
|
-
[bash]$ ruby ex50.rb -h
|
2420
|
-
ex50.rb -- sample app
|
2421
|
-
|
2422
|
-
Usage:
|
2423
|
-
$ ex50.rb [<options>] [<action> [<arguments>...]]
|
2424
|
-
|
2425
|
-
Options:
|
2426
|
-
-h, --help : print help message (of action if action specified)
|
2427
|
-
|
2428
|
-
Actions:
|
2429
|
-
test1 : empasized # !!!! printed with underline !!!!
|
2430
|
-
test2 : weaken # !!!! printed in gray color !!!!
|
3282
|
+
exit Benry::CmdApp.main("sample app")
|
2431
3283
|
```
|
2432
3284
|
|
2433
3285
|
|
2434
|
-
### Q:
|
2435
|
-
|
2436
|
-
A: Yes. Pass `tag:` keyword argument to `@action.()` or `@option.()`.
|
3286
|
+
### Q: How to remove common help option from all actions?
|
2437
3287
|
|
2438
|
-
|
2439
|
-
* Currenty, Benry::CmdApp doesn't provide the good way to use it effectively.
|
2440
|
-
This feature may be used by command-line application or framework based on Benry::CmdApp.
|
3288
|
+
A: Clears `Benry::CmdApp::ACTION_SHARED_OPTIONS` which is an array of option item.
|
2441
3289
|
|
2442
|
-
File:
|
3290
|
+
File: ex70.rb
|
2443
3291
|
|
2444
3292
|
```ruby
|
2445
3293
|
require 'benry/cmdapp'
|
2446
3294
|
|
2447
|
-
|
3295
|
+
arr = Benry::CmdApp::ACTION_SHARED_OPTIONS
|
3296
|
+
arr.clear()
|
3297
|
+
```
|
2448
3298
|
|
2449
|
-
@action.("print greeting message", tag: :important) # !!!!
|
2450
|
-
@option.(:repeat, "-r <N>", "repeat N times", tag: :important) # !!!!
|
2451
|
-
def hello(user="world", repeat: nil)
|
2452
|
-
(repeat || 1).times do
|
2453
|
-
puts "Hello, #{user}!"
|
2454
|
-
end
|
2455
|
-
end
|
2456
3299
|
|
2457
|
-
|
3300
|
+
### Q: Is it possible to show details of actions and aliases?
|
2458
3301
|
|
2459
|
-
|
2460
|
-
|
2461
|
-
exit app.main()
|
2462
|
-
```
|
3302
|
+
A: Try global option `-L metadata`.
|
3303
|
+
It prints detailed data of actions and aliases in YAML format.
|
2463
3304
|
|
2464
3305
|
|
2465
|
-
### Q: How to
|
3306
|
+
### Q: How to make error messages I18Ned?
|
2466
3307
|
|
2467
|
-
A: Currently not supported. May be supported in
|
3308
|
+
A: Currently not supported. May be supported in a future release.
|
2468
3309
|
|
2469
3310
|
|
2470
3311
|
|