benry-cmdapp 0.2.0 → 1.0.0

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