benry-cmdapp 0.2.0 → 1.0.0

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