benry-cmdopt 2.0.1 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
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