benry-cmdapp 0.2.0 → 1.1.0

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