benry-cmdapp 0.2.0 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGES.md +6 -0
- data/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
|
|