benry-cmdopt 2.0.1 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fa5cc6fe56fade46613abc3f6d3c7430ec0585a9c21535e478debe20500829c0
4
- data.tar.gz: eeb5e6c9d78008b92a68662d55c6c45f9fbb4cacb983f66667db32fa537855f8
3
+ metadata.gz: 5e37b3eb5a8294bfae3627f384720f843e2c6ae9c79ec0cc704b732368d46437
4
+ data.tar.gz: 3a3b34226485ae5c0aaa3f3b90d6ba281b34f7843d5e03179235784af0fc2467
5
5
  SHA512:
6
- metadata.gz: 84af5c4bc66e2066213dcc907c3fd2e1cb380278552a4e5e900c256e95fc10f6a1f2d2127a995fd5f1496f0bb239f1e1c68afe06536300d180c530a5196a0b89
7
- data.tar.gz: dd51bc08bd53742b5556f47887bd9a80ffac505608b5d79a55aa53d4a5023d5472f9b7015bf3f6144456695edbe793e5fb80878432b25a59ed0b4dfa2885c782
6
+ metadata.gz: f1aae8384f952ddbc0ba5408e39e5b289d09c9b9e768a4cee237c723d7f0bef459b2ab7c8e3639705e8495790fb02bb6fced99bf9a3676e772d4b0c2d622961d
7
+ data.tar.gz: 737074f681fa450d2e0fc9b82b85aedba8088db313b522c32b1c01cae6a68ed091da08ca437f58e543b0a6d896618c42a078ded25bba9fba971c3e3ec90bc82f
data/CHANGES.md CHANGED
@@ -2,6 +2,21 @@ CHANGES
2
2
  =======
3
3
 
4
4
 
5
+ Release 2.1.0 (2023-10-15)
6
+ --------------------------
7
+
8
+ * [enhance] Add `hidden: true` keyword argument to `Benry::Schema#add()` and `Benry::Facade#add()`. This keyword argument makes the option as hidden option.
9
+ * [change] Option which name stars with '_' is now not regarded as hidden option. Use `hidden: true` instead.
10
+ * [enhance] Add `important: (true|false)` keyword argument to `Benry::Schema#add()` and `Benry::Facade#add()`. This keyword argument makes help message of the option printed in decorated format.
11
+
12
+
13
+ Release 2.0.2 (2023-10-12)
14
+ --------------------------
15
+
16
+ * [change] remove unnecessary files from gem.
17
+ * [bugfix] fix to add missing test cases.
18
+
19
+
5
20
  Release 2.0.1 (2023-10-11)
6
21
  --------------------------
7
22
 
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Benry-CmdOpt
2
2
 
3
- ($Release: 2.0.1 $)
3
+ ($Release: 2.1.0 $)
4
4
 
5
5
 
6
6
 
@@ -38,6 +38,7 @@ Benry-CmdOpt requires Ruby >= 2.3.
38
38
  * [Global Options with Sub-Commands](#global-options-with-sub-commands)
39
39
  * [Detailed Description of Option](#detailed-description-of-option)
40
40
  * [Option Tag](#option-tag)
41
+ * [Important Options](#important-options)
41
42
  * [Not Supported](#not-supported)
42
43
  * [Internal Classes](#internal-classes)
43
44
  * [License and Copyright](#license-and-copyright)
@@ -470,22 +471,20 @@ p options #=> {:lib=>["foo", "bar", "baz"]}
470
471
 
471
472
  Benry-CmdOpt regards the following options as hidden.
472
473
 
473
- * Key name starts with `_` (for example `:_debug`).
474
+ * Keyword argument `hidden: true` is passed to `.add()` method.
474
475
  * Or description is nil.
475
476
 
476
- The former is better than the latter, because even hidden option should have its own description.
477
-
478
- These hidden options are not included in help message.
477
+ Hidden options are not included in help message.
479
478
 
480
479
  ```ruby
481
480
  require 'benry/cmdopt'
482
481
  cmdopt = Benry::CmdOpt.new
483
- cmdopt.add(:help , '-h', "help message")
484
- cmdopt.add(:debug, '-D', nil) # hidden (because description is nil)
485
- cmdopt.add(:_log , '-L', "logging") # hidden (because key starts with '_')
482
+ cmdopt.add(:help , '-h', "help message")
483
+ cmdopt.add(:logging, '-L', "logging", hidden: true) # hidden
484
+ cmdopt.add(:debug , '-D', nil) # hidden (desc is nil)
486
485
  puts cmdopt.to_s()
487
486
 
488
- ### output (neither '-D' nor '-L' is shown because hidden options)
487
+ ### output (neither '-L' nor '-D' is shown because hidden options)
489
488
  # -h : help message
490
489
  ```
491
490
 
@@ -497,8 +496,8 @@ puts cmdopt.to_s(all: true) # or: cmdopt.to_s(nil, all: true)
497
496
 
498
497
  ### output
499
498
  # -h : help message
500
- # -D :
501
499
  # -L : logging
500
+ # -D :
502
501
  ```
503
502
 
504
503
 
@@ -613,11 +612,37 @@ end
613
612
  ```
614
613
 
615
614
 
615
+ ### Important Options
616
+
617
+ You can specify that the option is important or not.
618
+ Pass `important: true` or `important: false` keyword argument to `#add()` method of `Benry::CmdOpt` or `Benry::CmdOpt::Schema` object.
619
+
620
+ The help message of options is decorated according to value of `important:` keyword argument.
621
+
622
+ * Printed in bold font when `important: true` specified to the option.
623
+ * Printed in gray color when `important: false` specified to the option.
624
+
625
+ ```ruby
626
+ require 'benry/cmdopt'
627
+
628
+ cmdopt = Benry::CmdOpt.new()
629
+ cmdopt.add(:help , "-h", "help message")
630
+ cmdopt.add(:verbose, "-v", "verbose mode", important: true) # !!!
631
+ cmdopt.add(:debug , "-D", "debug mode" , important: false) # !!!
632
+ puts cmdopt.option_help()
633
+
634
+ ## output:
635
+ # -h : help message
636
+ # -v : verbose mode # bold font
637
+ # -D : debug mode # gray color
638
+ ```
639
+
640
+
616
641
  ### Not Supported
617
642
 
618
- * default value
643
+ * default value when the option not specified in command-line
619
644
  * `--no-xxx` style option
620
- * bash/zsh completion
645
+ * bash/zsh completion (may be supported in the future)
621
646
  * I18N of error message (may be supported in the future)
622
647
 
623
648
 
data/benry-cmdopt.gemspec CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |spec|
4
4
  spec.name = "benry-cmdopt"
5
- spec.version = "$Release: 2.0.1 $".split()[1]
5
+ spec.version = "$Release: 2.1.0 $".split()[1]
6
6
  spec.author = "kwatch"
7
7
  spec.email = "kwatch@gmail.com"
8
8
  spec.platform = Gem::Platform::RUBY
@@ -16,10 +16,9 @@ END
16
16
  spec.license = "MIT"
17
17
  spec.files = Dir[
18
18
  "README.md", "MIT-LICENSE", "CHANGES.md",
19
- "Rakefile.rb", "#{spec.name}.gemspec",
20
- "lib/**/*.rb", "test/**/*.rb", "task/**/*.rb",
21
- #"bin/*", "examples/**/*",
22
- "doc/*.html", "doc/css/*",
19
+ "#{spec.name}.gemspec",
20
+ "lib/**/*.rb", "test/**/*.rb", #"bin/*", "examples/**/*",
21
+ "doc/*.html", "doc/css/*.css",
23
22
  ]
24
23
  #spec.executables = []
25
24
  spec.bindir = "bin"
@@ -21,7 +21,7 @@
21
21
  <ul class="nav">
22
22
  </ul>
23
23
  </nav>
24
- <p>($Release: 2.0.1 $)</p>
24
+ <p>($Release: 2.1.0 $)</p>
25
25
  <section class="section" id="whats-this">
26
26
  <h2>What's This?</h2>
27
27
  <p>Benry-CmdOpt is a command option parser library, like <code>optparse.rb</code>
@@ -53,6 +53,7 @@ and easy to understahnd.</p>
53
53
  <li><a href="#global-options-with-sub-commands">Global Options with Sub-Commands</a></li>
54
54
  <li><a href="#detailed-description-of-option">Detailed Description of Option</a></li>
55
55
  <li><a href="#option-tag">Option Tag</a></li>
56
+ <li><a href="#important-options">Important Options</a></li>
56
57
  <li><a href="#not-supported">Not Supported</a></li>
57
58
  </ul></li>
58
59
  <li><a href="#internal-classes">Internal Classes</a></li>
@@ -462,20 +463,19 @@ p options #=&gt; <strong>{:lib=&gt;["foo", "bar", "baz"]}</strong>
462
463
  <h3>Hidden Option</h3>
463
464
  <p>Benry-CmdOpt regards the following options as hidden.</p>
464
465
  <ul>
465
- <li>Key name starts with <code>_</code> (for example <code>:_debug</code>).</li>
466
+ <li>Keyword argument <code>hidden: true</code> is passed to <code>.add()</code> method.</li>
466
467
  <li>Or description is nil.</li>
467
468
  </ul>
468
- <p>The former is better than the latter, because even hidden option should have its own description.</p>
469
- <p>These hidden options are not included in help message.</p>
469
+ <p>Hidden options are not included in help message.</p>
470
470
  <pre class="language-ruby">
471
471
  require 'benry/cmdopt'
472
472
  cmdopt = Benry::CmdOpt.new
473
- cmdopt.add(:help , '-h', "help message")
474
- cmdopt.add(:debug, '-D', <strong>nil</strong>) # hidden (because description is nil)
475
- cmdopt.add(<strong>:_log</strong> , '-L', "logging") # hidden (because key starts with '_')
473
+ cmdopt.add(:help , '-h', "help message")
474
+ cmdopt.add(:logging, '-L', "logging", <strong>hidden: true</strong>) # hidden
475
+ cmdopt.add(:debug , '-D', <strong>nil</strong>) # hidden (desc is nil)
476
476
  puts cmdopt.to_s()
477
477
 
478
- ### output (neither '-D' nor '-L' is shown because hidden options)
478
+ ### output (neither '-L' nor '-D' is shown because hidden options)
479
479
  # -h : help message
480
480
  </pre>
481
481
  <p>To show all options including hidden ones, add <code>all: true</code> to <code>cmdopt.to_s()</code>.</p>
@@ -485,8 +485,8 @@ puts cmdopt.to_s(<strong>all: true</strong>) # or: cmdopt.to_s(nil, all: true)
485
485
 
486
486
  ### output
487
487
  # -h : help message
488
- # <strong>-D :</strong>
489
488
  # <strong>-L : logging</strong>
489
+ # <strong>-D : </strong>
490
490
  </pre>
491
491
  </section>
492
492
  <section class="subsection" id="global-options-with-sub-commands">
@@ -591,12 +591,36 @@ end
591
591
  #version: <strong>tag=nil</strong>
592
592
  </pre>
593
593
  </section>
594
+ <section class="subsection" id="important-options">
595
+ <h3>Important Options</h3>
596
+ <p>You can specify that the option is important or not.
597
+ Pass <code>important: true</code> or <code>important: false</code> keyword argument to <code>#add()</code> method of <code>Benry::CmdOpt</code> or <code>Benry::CmdOpt::Schema</code> object.</p>
598
+ <p>The help message of options is decorated according to value of <code>important:</code> keyword argument.</p>
599
+ <ul>
600
+ <li>Printed in bold font when <code>important: true</code> specified to the option.</li>
601
+ <li>Printed in gray color when <code>important: false</code> specified to the option.</li>
602
+ </ul>
603
+ <pre class="language-ruby">
604
+ require 'benry/cmdopt'
605
+
606
+ cmdopt = Benry::CmdOpt.new()
607
+ cmdopt.add(:help , "-h", "help message")
608
+ cmdopt.add(:verbose, "-v", "verbose mode", <strong>important: true</strong>) # !!!
609
+ cmdopt.add(:debug , "-D", "debug mode" , <strong>important: false</strong>) # !!!
610
+ puts cmdopt.option_help()
611
+
612
+ ## output:
613
+ # -h : help message
614
+ # -v : verbose mode # bold font
615
+ # -D : debug mode # gray color
616
+ </pre>
617
+ </section>
594
618
  <section class="subsection" id="not-supported">
595
619
  <h3>Not Supported</h3>
596
620
  <ul>
597
- <li>default value</li>
621
+ <li>default value when the option not specified in command-line</li>
598
622
  <li><code>--no-xxx</code> style option</li>
599
- <li>bash/zsh completion</li>
623
+ <li>bash/zsh completion (may be supported in the future)</li>
600
624
  <li>I18N of error message (may be supported in the future)</li>
601
625
  </ul>
602
626
  </section>
data/lib/benry/cmdopt.rb CHANGED
@@ -2,7 +2,7 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  ###
5
- ### $Release: 2.0.1 $
5
+ ### $Release: 2.1.0 $
6
6
  ### $Copyright: copyright(c) 2021 kwatch@gmail.com $
7
7
  ### $License: MIT License $
8
8
  ###
@@ -23,7 +23,7 @@ end
23
23
  module Benry::CmdOpt
24
24
 
25
25
 
26
- VERSION = '$Release: 2.0.1 $'.split()[1]
26
+ VERSION = '$Release: 2.1.0 $'.split()[1]
27
27
 
28
28
 
29
29
  def self.new()
@@ -40,11 +40,11 @@ module Benry::CmdOpt
40
40
 
41
41
  attr_reader :schema
42
42
 
43
- def add(key, optdef, desc, *rest, type: nil, rexp: nil, pattern: nil, enum: nil, range: nil, value: nil, detail: nil, tag: nil, &callback)
43
+ def add(key, optdef, desc, *rest, type: nil, rexp: nil, pattern: nil, enum: nil, range: nil, value: nil, detail: nil, hidden: nil, important: nil, tag: nil, &callback)
44
44
  rexp ||= pattern # for backward compatibility
45
45
  #; [!vmb3r] defines command option.
46
46
  #; [!71cvg] type, rexp, enum, and range are can be passed as positional args as well as keyword args.
47
- @schema.add(key, optdef, desc, *rest, type: type, rexp: rexp, enum: enum, range: range, value: value, detail: detail, tag: tag, &callback)
47
+ @schema.add(key, optdef, desc, *rest, type: type, rexp: rexp, enum: enum, range: range, value: value, detail: detail, hidden: hidden, important: important, tag: tag, &callback)
48
48
  #; [!tu4k3] returns self.
49
49
  self
50
50
  end
@@ -103,7 +103,7 @@ module Benry::CmdOpt
103
103
  self
104
104
  end
105
105
 
106
- def add(key, optdef, desc, *rest, type: nil, rexp: nil, pattern: nil, enum: nil, range: nil, value: nil, detail: nil, tag: nil, &callback)
106
+ def add(key, optdef, desc, *rest, type: nil, rexp: nil, pattern: nil, enum: nil, range: nil, value: nil, detail: nil, hidden: nil, important: nil, tag: nil, &callback)
107
107
  rexp ||= pattern # for backward compatibility
108
108
  #; [!kuhf9] type, rexp, enum, and range are can be passed as positional args as well as keyword args.
109
109
  rest.each do |x|
@@ -120,7 +120,7 @@ module Benry::CmdOpt
120
120
  #; [!rhhji] raises SchemaError when key is not a Symbol.
121
121
  key.nil? || key.is_a?(Symbol) or
122
122
  raise _error("add(#{key.inspect}, #{optdef.inspect}): The first arg should be a Symbol as an option key.")
123
- #; [!vq6eq] raises SchemaError when help message is missing."
123
+ #; [!vq6eq] raises SchemaError when help message is missing.
124
124
  desc.nil? || desc.is_a?(String) or
125
125
  raise _error("add(#{key.inspect}, #{optdef.inspect}): Help message required as 3rd argument.")
126
126
  #; [!7hi2d] takes command option definition string.
@@ -137,7 +137,7 @@ module Benry::CmdOpt
137
137
  end
138
138
  #; [!yht0v] keeps command option definitions.
139
139
  item = SchemaItem.new(key, optdef, desc, short, long, param, required,
140
- type: type, rexp: rexp, enum: enum, range: range, value: value, detail: detail, tag: tag, &callback)
140
+ type: type, rexp: rexp, enum: enum, range: range, value: value, detail: detail, hidden: hidden, important: important, tag: tag, &callback)
141
141
  @items << item
142
142
  item
143
143
  end
@@ -157,10 +157,16 @@ module Benry::CmdOpt
157
157
  #; [!to1th] includes all option help when `all` is true.
158
158
  #; [!a4qe4] option should not be hidden if description is empty string.
159
159
  sb = []
160
- width = nil; indent = nil
161
- each_option_and_desc(all: all) do |opt, desc, detail|
162
- sb << format % [opt, desc || ""] << "\n"
160
+ width = nil; indent = nil; color_p = $stdout.tty?
161
+ @items.each do |item|
162
+ next if ! all && item.hidden?
163
+ #; [!jrwb6] decorates help message according to `important:` value of option.
164
+ #; [!9nlfb] not decorate help message when stdout is not a tty.
165
+ s = format % [item.optdef, item.desc || ""]
166
+ s = _decorate_str(s, item.important?) if color_p
167
+ sb << s << "\n"
163
168
  #; [!848rm] supports multi-lines help message.
169
+ detail = item.detail
164
170
  if detail
165
171
  width ||= (format % ['', '']).length
166
172
  indent ||= ' ' * width
@@ -276,12 +282,20 @@ module Benry::CmdOpt
276
282
  return short_p ? 8 : long_p ? 20 : 14
277
283
  end
278
284
 
285
+ def _decorate_str(str, important)
286
+ case important
287
+ when true ; return "\e[1m#{str}\e[0m" # bold
288
+ when false ; return "\e[2m#{str}\e[0m" # gray
289
+ else ; return str
290
+ end
291
+ end
292
+
279
293
  end
280
294
 
281
295
 
282
296
  class SchemaItem # avoid Struct
283
297
 
284
- def initialize(key, optdef, desc, short, long, param, required, type: nil, rexp: nil, pattern: nil, enum: nil, range: nil, detail: nil, value: nil, tag: nil, &callback)
298
+ def initialize(key, optdef, desc, short, long, param, required, type: nil, rexp: nil, pattern: nil, enum: nil, range: nil, detail: nil, value: nil, hidden: nil, important: nil, tag: nil, &callback)
285
299
  rexp ||= pattern # for backward compatibility
286
300
  _init_validation(param, required, type, rexp, enum, range, value)
287
301
  @key = key unless nil == key
@@ -297,6 +311,8 @@ module Benry::CmdOpt
297
311
  @range = range unless nil == range
298
312
  @detail = detail unless nil == detail
299
313
  @value = value unless nil == value
314
+ @hidden = hidden unless nil == hidden
315
+ @important = important unless nil == important
300
316
  @tag = tag unless nil == tag
301
317
  @callback = callback unless nil == callback
302
318
  #; [!nn4cp] freezes enum object.
@@ -324,10 +340,18 @@ module Benry::CmdOpt
324
340
  end
325
341
 
326
342
  def hidden?()
343
+ #; [!no6ov] returns true if @hidden is true.
344
+ #; [!ej8ot] returns false if @hidden is false.
345
+ return @hidden if @hidden != nil
327
346
  #; [!h0uxs] returns true if desc is nil.
328
- #; [!su00g] returns true if key starts with '_'.
329
347
  #; [!28vzx] returns false if else.
330
- return @desc == nil || @key.to_s.start_with?('_')
348
+ return @desc == nil
349
+ end
350
+
351
+ def important?()
352
+ #; [!ua8kt] returns true/false if `important:` kwarg passed to constructor.
353
+ #; [!hz9sx] returns nil if `important:` kwarg not passed to constructor.
354
+ return @important
331
355
  end
332
356
 
333
357
  def validate_and_convert(val, optdict)
data/test/cmdopt_test.rb CHANGED
@@ -342,13 +342,49 @@ END
342
342
  spec "[!a4qe4] option should not be hidden if description is empty string." do
343
343
  sc = Benry::CmdOpt::Schema.new
344
344
  sc.add(:debug , "-D", nil) # hidden
345
- sc.add(:_trace, "-T", "trace") # hidden
345
+ sc.add(:trace, "-T", "trace", hidden: true) # hidden
346
346
  sc.add(:what , "-W", "") # NOT hidden!
347
347
  ok {sc.option_help()} == <<END
348
348
  -W :
349
349
  END
350
350
  end
351
351
 
352
+ fixture :schema_with_importance do
353
+ sc = Benry::CmdOpt::Schema.new
354
+ sc.add(:help , "-h, --help" , "help message")
355
+ sc.add(:trace , "-T, --trace", "trace" , important: true)
356
+ sc.add(:debug , "-D, --debug", "debug mode" , important: false)
357
+ sc.add(:quiet , "-q, --quiet", "quiet mode")
358
+ sc
359
+ end
360
+
361
+ spec "[!jrwb6] decorates help message according to `important:` value of option." do
362
+ |schema_with_importance|
363
+ sc = schema_with_importance
364
+ ok {sc.option_help()} == <<END
365
+ -h, --help : help message
366
+ \e[1m -T, --trace : trace\e[0m
367
+ \e[2m -D, --debug : debug mode\e[0m
368
+ -q, --quiet : quiet mode
369
+ END
370
+ end
371
+
372
+ spec "[!9nlfb] not decorate help message when stdout is not a tty." do
373
+ |schema_with_importance|
374
+ sc = schema_with_importance
375
+ output = nil
376
+ capture_sio() {
377
+ ok {$stdout}.NOT.tty?
378
+ output = sc.option_help()
379
+ }
380
+ ok {output} == <<END
381
+ -h, --help : help message
382
+ -T, --trace : trace
383
+ -D, --debug : debug mode
384
+ -q, --quiet : quiet mode
385
+ END
386
+ end
387
+
352
388
  end
353
389
 
354
390
 
@@ -445,7 +481,7 @@ END
445
481
  sc.add(:help, "-h, --help", "show help message")
446
482
  sc.add(:version, " --version", "print version")
447
483
  sc.add(:debug , "-d, --debug" , nil) # hidden
448
- sc.add(:_DEBUG , "-D, --DEBUG" , "debug mode") # hidden
484
+ sc.add(:DEBUG , "-D, --DEBUG" , "debug mode", hidden: true) # hidden
449
485
  @schema = sc
450
486
  end
451
487
 
@@ -532,7 +568,7 @@ END
532
568
  spec "[!icvm1] ignores hidden items if 'all: false' kwarg specified." do
533
569
  schema = Benry::CmdOpt::Schema.new
534
570
  schema.add(:debug , "-D", nil)
535
- schema.add(:_trace, "-T", "trace")
571
+ schema.add(:trace, "-T", "trace", hidden: true)
536
572
  ok {schema.empty?()} == false
537
573
  ok {schema.empty?(all: true)} == false
538
574
  ok {schema.empty?(all: false)} == true
@@ -898,15 +934,19 @@ END
898
934
 
899
935
  topic '#hidden?()' do
900
936
 
901
- spec "[!h0uxs] returns true if desc is nil." do
902
- desc = nil
903
- item = Benry::CmdOpt::SchemaItem.new(:debug, "-D", desc, "D", nil, nil, nil)
937
+ spec "[!no6ov] returns true if @hidden is true." do
938
+ item = Benry::CmdOpt::SchemaItem.new(:debug, "-D", "debug mode", "D", nil, nil, nil, hidden: true)
904
939
  ok {item.hidden?} == true
905
940
  end
906
941
 
907
- spec "[!su00g] returns true if key starts with '_'." do
908
- desc = "debug mode"
909
- item = Benry::CmdOpt::SchemaItem.new(:_debug, "-D", desc, "D", nil, nil, nil)
942
+ spec "[!ej8ot] returns false if @hidden is false." do
943
+ item = Benry::CmdOpt::SchemaItem.new(:debug, "-D", "debug mode", "D", nil, nil, nil, hidden: false)
944
+ ok {item.hidden?} == false
945
+ end
946
+
947
+ spec "[!h0uxs] returns true if desc is nil." do
948
+ desc = nil
949
+ item = Benry::CmdOpt::SchemaItem.new(:debug, "-D", desc, "D", nil, nil, nil)
910
950
  ok {item.hidden?} == true
911
951
  end
912
952
 
@@ -919,6 +959,23 @@ END
919
959
  end
920
960
 
921
961
 
962
+ topic '#important?()' do
963
+
964
+ spec "[!ua8kt] returns true/false if `important:` kwarg passed to constructor." do
965
+ item1 = Benry::CmdOpt::SchemaItem.new(:debug, "-D", "debug mode", "D", nil, nil, nil, important: true)
966
+ ok {item1.important?} == true
967
+ item2 = Benry::CmdOpt::SchemaItem.new(:debug, "-D", "debug mode", "D", nil, nil, nil, important: false)
968
+ ok {item2.important?} == false
969
+ end
970
+
971
+ spec "[!hz9sx] returns nil if `important:` kwarg not passed to constructor." do
972
+ item3 = Benry::CmdOpt::SchemaItem.new(:debug, "-D", "debug mode", "D", nil, nil, nil)
973
+ ok {item3.important?} == nil
974
+ end
975
+
976
+ end
977
+
978
+
922
979
  topic '#validate_and_convert()' do
923
980
 
924
981
  def new_item(key, optstr, desc, short, long, param, required,
@@ -1471,6 +1528,12 @@ END
1471
1528
  ok {item.value} == 4
1472
1529
  end
1473
1530
 
1531
+ spec "[!tu4k3] returns self." do
1532
+ cmdopt = Benry::CmdOpt.new()
1533
+ x = cmdopt.add(:version, "-v, --version", "version")
1534
+ ok {x}.same?(cmdopt)
1535
+ end
1536
+
1474
1537
  end
1475
1538
 
1476
1539
 
@@ -1514,7 +1577,7 @@ END
1514
1577
  @cmdopt.add(:help , "-h, --help" , "show help message")
1515
1578
  @cmdopt.add(:version, " --version" , "print version")
1516
1579
  @cmdopt.add(:debug , "-D" , nil) # hidden option
1517
- @cmdopt.add(:_trace , "-T" , "trace") # hidden option
1580
+ @cmdopt.add(:trace , "-T" , "trace", hidden: true) # hidden option
1518
1581
  end
1519
1582
 
1520
1583
  spec "[!bw9qx] yields each option definition string and help message." do
@@ -1569,6 +1632,17 @@ END
1569
1632
  @cmdopt.add(:debug, "-d, --debug[=<LEVEL>]", "debug", type: Integer)
1570
1633
  end
1571
1634
 
1635
+ spec "[!7gc2m] parses command options." do
1636
+ args = ["-d", "x", "y"]
1637
+ @cmdopt.parse(args)
1638
+ ok {args} == ["x", "y"]
1639
+ end
1640
+
1641
+ spec "[!no4xu] returns option values as dict." do
1642
+ args = ["-d", "x"]
1643
+ ok {@cmdopt.parse(args)} == {:debug=>true}
1644
+ end
1645
+
1572
1646
  spec "[!areof] handles only OptionError when block given." do
1573
1647
  errmsg = nil
1574
1648
  errcls = nil
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: benry-cmdopt
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.1
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - kwatch
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-10-11 00:00:00.000000000 Z
11
+ date: 2023-10-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: oktest
@@ -36,15 +36,10 @@ files:
36
36
  - CHANGES.md
37
37
  - MIT-LICENSE
38
38
  - README.md
39
- - Rakefile.rb
40
39
  - benry-cmdopt.gemspec
41
40
  - doc/benry-cmdopt.html
42
41
  - doc/css/style.css
43
42
  - lib/benry/cmdopt.rb
44
- - task/common-task.rb
45
- - task/package-task.rb
46
- - task/readme-task.rb
47
- - task/test-task.rb
48
43
  - test/cmdopt_test.rb
49
44
  homepage: https://kwatch.github.io/benry-ruby/benry-cmdopt.html
50
45
  licenses:
data/Rakefile.rb DELETED
@@ -1,11 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
-
3
-
4
- PROJECT = "benry-cmdopt"
5
- RELEASE = ENV['RELEASE'] || "0.0.0"
6
- COPYRIGHT = "copyright(c) 2021 kwatch@gmail.com"
7
- LICENSE = "MIT License"
8
-
9
- #RUBY_VERSIONS = ["3.2", "3.1", "3.0", "2.7", "2.6", "2.5", "2.4", "2.3"]
10
-
11
- Dir.glob('./task/*-task.rb').sort.each {|x| require x }
data/task/common-task.rb DELETED
@@ -1,139 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
-
3
-
4
- defined? PROJECT or abort "PROJECT required."
5
- defined? RELEASE or abort "RELEASE required."
6
- defined? COPYRIGHT or abort "COPYRIGHT required."
7
- defined? LICENSE or abort "LICENSE required."
8
-
9
- RELEASE =~ /\A\d+\.\d+\.\d+/ or abort "RELEASE=#{RELEASE}: invalid release number."
10
-
11
-
12
- require 'rake/clean'
13
- CLEAN << "build"
14
- CLEAN.concat Dir.glob("#{PROJECT}-*.gem").collect {|x| x.sub(/\.gem$/, '') }
15
- CLOBBER.concat Dir.glob("#{PROJECT}-*.gem")
16
-
17
-
18
- task :default do
19
- sh "rake -T", verbose: false
20
- end unless Rake::Task.task_defined?(:default)
21
-
22
-
23
- desc "show release guide"
24
- task :guide do
25
- do_guide()
26
- end
27
-
28
- def do_guide()
29
- RELEASE != '0.0.0' or abort "** ERROR: 'RELEASE=X.X.X' required."
30
- puts guide_message(PROJECT, RELEASE)
31
- end
32
-
33
- def guide_message(project, release)
34
- target = "#{project}-#{release}"
35
- tag = "#{project}-#{release}"
36
- puts <<END
37
- How to release:
38
-
39
- $ git diff .
40
- $ git status .
41
- $ which ruby
42
- $ rake test
43
- $ rake test:all
44
- $ rake readme:execute # optional
45
- $ rake readme:toc # optional
46
- $ rake package RELEASE=#{release}
47
- $ rake package:extract # confirm files in gem file
48
- $ (cd #{target}/data; find . -type f)
49
- $ gem install #{target}.gem # confirm gem package
50
- $ gem uninstall #{project}
51
- $ gem push #{target}.gem # publish gem to rubygems.org
52
- $ git tag #{tag} # or: git tag ruby-#{tag}
53
- $ git push
54
- $ git push --tags
55
- $ rake clean
56
- $ mv #{target}.gem archive/
57
- END
58
- end
59
-
60
-
61
- desc "create 'README.md' and 'doc/*.html'"
62
- task :doc do
63
- x = PROJECT
64
- cd "doc" do
65
- sh "../../docs/md2 --md #{x}.mdx > ../README.md"
66
- sh "../../docs/md2 #{x}.mdx > #{x}.html"
67
- end
68
- end
69
-
70
- desc "copy 'doc/*.html' to '../docs/'"
71
- task 'doc:export' do
72
- RELEASE != '0.0.0' or abort "** ERROR: 'RELEASE=X.X.X' required."
73
- x = PROJECT
74
- cp "doc/#{x}.html", "../docs/"
75
- edit_file!("../docs/#{x}.html")
76
- end
77
-
78
-
79
- desc "edit metadata in files"
80
- task :edit do
81
- do_edit()
82
- end
83
-
84
- def do_edit()
85
- target_files().each do |fname|
86
- edit_file!(fname)
87
- end
88
- end
89
-
90
- def target_files()
91
- $_target_files ||= begin
92
- spec_src = File.read("#{PROJECT}.gemspec", encoding: 'utf-8')
93
- spec = eval spec_src
94
- spec.name == PROJECT or
95
- abort "** ERROR: '#{PROJECT}' != '#{spec.name}' (project name in gemspec file)"
96
- spec.files + Dir.glob("doc/*.mdx")
97
- end
98
- return $_target_files
99
- end
100
-
101
- def edit_file!(filename, verbose: true)
102
- changed = edit_file(filename) do |s|
103
- s = s.gsub(/\$Release[:].*?\$/, "$"+"Release: #{RELEASE} $")
104
- s = s.gsub(/\$Copyright[:].*?\$/, "$"+"Copyright: #{COPYRIGHT} $")
105
- s = s.gsub(/\$License[:].*?\$/, "$"+"License: #{LICENSE} $")
106
- s
107
- end
108
- if verbose
109
- puts "[C] #{filename}" if changed
110
- puts "[U] #{filename}" unless changed
111
- end
112
- return changed
113
- end
114
-
115
- def edit_file(filename)
116
- File.open(filename, 'rb+') do |f|
117
- s1 = f.read()
118
- s2 = yield s1
119
- if s1 != s2
120
- f.rewind()
121
- f.truncate(0)
122
- f.write(s2)
123
- true
124
- else
125
- false
126
- end
127
- end
128
- end
129
-
130
-
131
- desc nil
132
- task :'relink' do
133
- Dir.glob("task/*.rb").each do |x|
134
- src = "../" + x
135
- next if File.identical?(src, x)
136
- rm x
137
- ln src, x
138
- end
139
- end
data/task/package-task.rb DELETED
@@ -1,72 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
-
3
-
4
- desc "create package (*.gem)"
5
- task :package do
6
- do_package()
7
- end
8
-
9
- def do_package()
10
- RELEASE != '0.0.0' or abort "** ERROR: 'RELEASE=X.X.X' required."
11
- ## copy
12
- dir = "build"
13
- rm_rf dir if File.exist?(dir)
14
- mkdir dir
15
- target_files().each do |file|
16
- dest = File.join(dir, File.dirname(file))
17
- mkdir_p dest, :verbose=>false unless File.exist?(dest)
18
- cp file, "#{dir}/#{file}"
19
- end
20
- ## edit
21
- Dir.glob("#{dir}/**/*").each do |file|
22
- next unless File.file?(file)
23
- edit_file!(file, verbose: false)
24
- end
25
- ## build
26
- chdir dir do
27
- sh "gem build #{PROJECT}.gemspec"
28
- end
29
- mv "#{dir}/#{PROJECT}-#{RELEASE}.gem", "."
30
- rm_rf dir
31
- end
32
-
33
-
34
- desc "extract latest gem file"
35
- task :'package:extract' do
36
- do_package_extract()
37
- end
38
-
39
- def do_package_extract()
40
- gemfile = Dir.glob("#{PROJECT}-*.gem").sort_by {|x| File.mtime(x) }.last
41
- dir = gemfile.sub(/\.gem$/, '')
42
- rm_rf dir if File.exist?(dir)
43
- mkdir dir
44
- mkdir "#{dir}/data"
45
- cd dir do
46
- sh "tar xvf ../#{gemfile}"
47
- sh "gunzip *.gz"
48
- cd "data" do
49
- sh "tar xvf ../data.tar"
50
- end
51
- end
52
- end
53
-
54
-
55
- desc "upload gem file to rubygems.org"
56
- task :publish do
57
- do_publish()
58
- end
59
-
60
- def do_publish()
61
- RELEASE != '0.0.0' or abort "** ERROR: 'RELEASE=X.X.X' required."
62
- gemfile = "#{PROJECT}-#{RELEASE}.gem"
63
- print "** Are you sure to publish #{gemfile}? [y/N]: "
64
- answer = $stdin.gets().strip()
65
- if answer.downcase == "y"
66
- sh "gem push #{gemfile}"
67
- #sh "git tag ruby-#{PROJECT}-#{RELEASE}"
68
- sh "git tag #{PROJECT}-#{RELEASE}"
69
- sh "#git push"
70
- sh "#git push --tags"
71
- end
72
- end
data/task/readme-task.rb DELETED
@@ -1,125 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
-
3
- README_FILE = "README.md" unless defined? README_FILE
4
- README_EXTRACT = /^[Ff]ile: +(\S+)/ unless defined? README_EXTRACT
5
- README_CODESTART = /^```\w+$/ unless defined? README_CODESTART
6
- README_CODEEND = /^```$/ unless defined? README_CODEEND
7
- README_DESTDIR = "tmp/readme" unless defined? README_DESTDIR
8
-
9
- require 'rake/clean'
10
- CLEAN << "README.html"
11
-
12
-
13
- def readme_extract_callback(filename, str)
14
- return str
15
- end
16
-
17
-
18
- namespace :readme do
19
-
20
-
21
- desc "retrieve scripts from #{README_FILE}"
22
- task :retrieve do
23
- do_readme_retrieve()
24
- end
25
-
26
- def do_readme_retrieve()
27
- dir = README_DESTDIR
28
- rm_rf dir if File.exist?(dir)
29
- mkdir_p dir
30
- s = File.read(README_FILE, encoding: 'utf-8')
31
- filename = nil
32
- buf = nil
33
- s.each_line do |line|
34
- case line
35
- when README_EXTRACT
36
- filename = $1
37
- next
38
- when README_CODESTART
39
- if filename
40
- buf = []
41
- end
42
- next
43
- when README_CODEEND
44
- if filename && buf
45
- newfile = "#{dir}/#{filename}"
46
- unless File.exist?(File.dirname(newfile))
47
- mkdir_p File.dirname(newfile)
48
- end
49
- str = readme_extract_callback(filename, buf.join())
50
- File.write(newfile, str, encoding: 'utf-8')
51
- puts "[retrieve] #{newfile}"
52
- end
53
- filename = nil
54
- buf = nil
55
- next
56
- end
57
- #
58
- if buf
59
- buf << line
60
- end
61
- end
62
- end
63
-
64
-
65
- desc "execute code in readme file"
66
- task :execute => :retrieve do
67
- do_readme_execute()
68
- end
69
-
70
- def do_readme_execute()
71
- Dir.glob(README_DESTDIR+'/**/*.rb').sort.each do |fpath|
72
- puts "========================================"
73
- sh "ruby -I lib #{fpath}" do end
74
- end
75
- end
76
-
77
-
78
- desc "builds table of contents"
79
- task :toc do
80
- do_readme_toc()
81
- end
82
-
83
- def do_readme_toc()
84
- url = ENV['README_URL'] or abort "$README_URL required."
85
- mkdir "tmp" unless Dir.exist?("tmp")
86
- htmlfile = "tmp/README.html"
87
- sh "curl -s -o #{htmlfile} #{url}"
88
- #rexp = /<h(\d) dir="auto"><a id="(.*?)" class="anchor".*><\/a>(.*)<\/h\1>/
89
- rexp = /<h(\d) id="user-content-.*?" dir="auto"><a class="heading-link" href="#(.*?)">(.*)<svg/
90
- html_str = File.read(htmlfile, encoding: 'utf-8')
91
- buf = []
92
- html_str.scan(rexp) do
93
- level = $1.to_i
94
- id = $2
95
- title = $3
96
- next if title =~ /Table of Contents/
97
- title = title.gsub(/<\/?code>/, '`')
98
- anchor = id.sub(/^user-content-/, '')
99
- indent = " " * (level - 1)
100
- buf << "#{indent}* <a href=\"##{anchor}\">#{title}</a>\n"
101
- end
102
- buf.shift() if buf[0] && buf[0] =~ /^\* /
103
- toc_str = buf.join()
104
- #
105
- mdfile = README_FILE
106
- changed = File.open(mdfile, "r+", encoding: 'utf-8') do |f|
107
- s1 = f.read()
108
- s2 = s1.sub(/(<!-- TOC -->\n).*(<!-- \/TOC -->\n)/m) {
109
- [$1, toc_str, $2].join("\n")
110
- }
111
- if s1 != s2
112
- f.rewind()
113
- f.truncate(0)
114
- f.write(s2)
115
- true
116
- else
117
- false
118
- end
119
- end
120
- puts "[changed] #{mdfile}" if changed
121
- puts "[not changed] #{mdfile}" unless changed
122
- end
123
-
124
-
125
- end
data/task/test-task.rb DELETED
@@ -1,81 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
-
3
-
4
- unless defined?(RUBY_VERSIONS)
5
- RUBY_VERSIONS = (
6
- if ENV['RUBY_VERSIONS']
7
- ENV['RUBY_VERSIONS'].split()
8
- else
9
- ["3.2", "3.1", "3.0", "2.7", "2.6", "2.5", "2.4", "2.3"]
10
- end
11
- )
12
- end
13
-
14
-
15
- desc "run test"
16
- task :test do
17
- do_test()
18
- end
19
-
20
- def do_test()
21
- run_test()
22
- end
23
-
24
- def run_test(ruby=nil, &b)
25
- run_oktest(ruby, &b)
26
- end
27
-
28
- def run_minitest(ruby=nil, &b)
29
- files = File.exist?("test/run_all.rb") \
30
- ? ["test/run_all.rb"] \
31
- : Dir.glob("test/**/*_test.rb")
32
- if ruby
33
- sh(ruby, *files, &b)
34
- else
35
- ruby(*files, &b)
36
- end
37
- end
38
-
39
- def run_oktest(ruby=nil, &b)
40
- argstr = "-r oktest -e Oktest.main -- test -sp"
41
- if ruby
42
- sh("#{ruby} #{argstr}", &b)
43
- else
44
- ruby(argstr, &b)
45
- end
46
- end
47
-
48
-
49
- desc "run test in different ruby versions"
50
- task :'test:all' do
51
- do_test_all()
52
- end
53
-
54
- def do_test_all()
55
- ENV['VS_HOME'] or
56
- abort "[ERROR] rake test:all: '$VS_HOME' environment var required."
57
- vs_home = ENV['VS_HOME'].split(/[:;]/).first
58
- ruby_versions = RUBY_VERSIONS
59
- test_all(vs_home, ruby_versions)
60
- end
61
-
62
- def test_all(vs_home, ruby_versions)
63
- header = proc {|s| "\033[0;36m=============== #{s} ===============\033[0m" }
64
- error = proc {|s| "\033[0;31m** #{s}\033[0m" }
65
- comp = proc {|x, y| x.to_s.split('.').map(&:to_i) <=> y.to_s.split('.').map(&:to_i) }
66
- ruby_versions.each do |ver|
67
- dir = Dir.glob("#{vs_home}/ruby/#{ver}.*/").sort_by(&comp).last
68
- puts ""
69
- if dir
70
- puts header.("#{ver} (#{dir})")
71
- run_test("#{dir}/bin/ruby") do |ok, res|
72
- $stderr.puts error.("test failed") unless ok
73
- end
74
- sleep 0.2
75
- else
76
- puts header.(ver)
77
- $stderr.puts error.("ruby #{ver} not found")
78
- sleep 1.0
79
- end
80
- end
81
- end