benry-cmdapp 0.2.0 → 1.1.0

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