toys-core 0.3.2 → 0.3.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -80,7 +80,7 @@ module Toys
80
80
  DEFAULT_VERBOSE_SWITCHES)
81
81
  unless verbose_switches.empty?
82
82
  tool.add_switch(Context::VERBOSITY, *verbose_switches,
83
- doc: "Increase verbosity",
83
+ docs: "Increase verbosity",
84
84
  handler: ->(_val, cur) { cur + 1 },
85
85
  only_unique: true)
86
86
  end
@@ -88,7 +88,7 @@ module Toys
88
88
  DEFAULT_QUIET_SWITCHES)
89
89
  unless quiet_switches.empty?
90
90
  tool.add_switch(Context::VERBOSITY, *quiet_switches,
91
- doc: "Decrease verbosity",
91
+ docs: "Decrease verbosity",
92
92
  handler: ->(_val, cur) { cur - 1 },
93
93
  only_unique: true)
94
94
  end
@@ -27,6 +27,8 @@
27
27
  # POSSIBILITY OF SUCH DAMAGE.
28
28
  ;
29
29
 
30
+ require "highline"
31
+
30
32
  require "toys/middleware/base"
31
33
  require "toys/utils/usage"
32
34
 
@@ -54,9 +56,11 @@ module Toys
54
56
  #
55
57
  def execute(context)
56
58
  if context[Context::USAGE_ERROR]
59
+ width = ::HighLine.new.output_cols
60
+ usage = Utils::Usage.from_context(context)
57
61
  puts(context[Context::USAGE_ERROR])
58
62
  puts("")
59
- puts(Utils::Usage.from_context(context).string(show_path: true))
63
+ puts(usage.string(show_path: true, wrap_width: width))
60
64
  context.exit(@exit_code)
61
65
  else
62
66
  yield
@@ -27,6 +27,8 @@
27
27
  # POSSIBILITY OF SUCH DAMAGE.
28
28
  ;
29
29
 
30
+ require "highline"
31
+
30
32
  require "toys/middleware/base"
31
33
  require "toys/utils/usage"
32
34
 
@@ -112,10 +114,10 @@ module Toys
112
114
  DEFAULT_HELP_SWITCHES)
113
115
  is_default = !tool.includes_executor? && @fallback_execution
114
116
  if !help_switches.empty?
115
- doc = "Show help message"
116
- doc << " (default for groups)" if is_default
117
+ docs = "Show help message"
118
+ docs << " (default for groups)" if is_default
117
119
  tool.add_switch(:_help, *help_switches,
118
- doc: doc,
120
+ docs: docs,
119
121
  default: is_default,
120
122
  only_unique: true)
121
123
  elsif is_default
@@ -134,9 +136,11 @@ module Toys
134
136
  def execute(context)
135
137
  if context[:_help]
136
138
  usage = Utils::Usage.from_context(context)
139
+ width = ::HighLine.new.output_cols
137
140
  puts(usage.string(recursive: context[:_recursive_subcommands],
138
141
  search: context[:_search_subcommands],
139
- show_path: context.verbosity > 0))
142
+ show_path: context.verbosity > 0,
143
+ wrap_width: width))
140
144
  else
141
145
  yield
142
146
  end
@@ -150,8 +154,8 @@ module Toys
150
154
  unless recursive_switches.empty?
151
155
  tool.add_switch(:_recursive_subcommands, *recursive_switches,
152
156
  default: @default_recursive,
153
- doc: "Show all subcommands recursively" \
154
- " (default is #{@default_recursive})",
157
+ docs: "Show all subcommands recursively" \
158
+ " (default is #{@default_recursive})",
155
159
  only_unique: true)
156
160
  end
157
161
  end
@@ -161,7 +165,7 @@ module Toys
161
165
  DEFAULT_SEARCH_SWITCHES)
162
166
  unless search_switches.empty?
163
167
  tool.add_switch(:_search_subcommands, *search_switches,
164
- doc: "Search subcommands for the given term",
168
+ docs: "Search subcommands for the given term",
165
169
  only_unique: true)
166
170
  end
167
171
  end
@@ -77,7 +77,7 @@ module Toys
77
77
  version = @version_displayer.call(tool)
78
78
  if version
79
79
  tool.add_switch(:_show_version, *@version_switches,
80
- doc: "Show version",
80
+ docs: "Show version",
81
81
  handler: ->(_val, _prev) { version },
82
82
  only_unique: true)
83
83
  end
@@ -61,7 +61,7 @@ module Toys
61
61
  tool(template.name) do
62
62
  desc "Clean built files and directories."
63
63
 
64
- use :file_utils
64
+ use :fileutils
65
65
 
66
66
  execute do
67
67
  files = []
@@ -88,8 +88,9 @@ module Toys
88
88
  tool(template.name) do
89
89
  desc "#{task_type} the gem: #{template.gem_name}"
90
90
 
91
- use :file_utils
92
91
  use :exec
92
+ use :fileutils
93
+ use :highline
93
94
 
94
95
  execute do
95
96
  configure_exec(exit_on_nonzero_status: true)
@@ -104,6 +105,7 @@ module Toys
104
105
  logger.error "Cannot push the gem when there are uncommited changes"
105
106
  exit(1)
106
107
  end
108
+ exit(1) unless agree("Release #{gemfile}? (y/n) ")
107
109
  sh "gem push pkg/#{gemfile}"
108
110
  if template.tag
109
111
  sh "git tag v#{version}"
@@ -89,9 +89,9 @@ module Toys
89
89
  switch(
90
90
  :warnings, "-w", "--[no-]warnings",
91
91
  default: template.warnings,
92
- doc: "Turn on Ruby warnings (defaults to #{template.warnings})"
92
+ docs: "Turn on Ruby warnings (defaults to #{template.warnings})"
93
93
  )
94
- remaining_args(:tests, doc: "Paths to the tests to run (defaults to all tests)")
94
+ remaining_args(:tests, docs: "Paths to the tests to run (defaults to all tests)")
95
95
 
96
96
  execute do
97
97
  ruby_args = []
data/lib/toys/tool.rb CHANGED
@@ -29,6 +29,8 @@
29
29
 
30
30
  require "optparse"
31
31
 
32
+ require "toys/utils/wrappable_string"
33
+
32
34
  module Toys
33
35
  ##
34
36
  # A Tool is a single command that can be invoked using Toys.
@@ -50,8 +52,8 @@ module Toys
50
52
  @definition_path = nil
51
53
  @definition_finished = false
52
54
 
53
- @desc = nil
54
- @long_desc = nil
55
+ @desc = []
56
+ @long_desc = []
55
57
 
56
58
  @default_data = {}
57
59
  @switch_definitions = []
@@ -168,19 +170,25 @@ module Toys
168
170
  ##
169
171
  # Returns the effective short description for this tool. This will be
170
172
  # displayed when this tool is listed in a command list.
171
- # @return [String]
172
173
  #
173
- def effective_desc
174
- @desc || ""
174
+ # @param [Integer,nil] wrap_width Wrap wrappable strings to the given
175
+ # width, or `nil` for no wrapping.
176
+ # @return [Array<String>]
177
+ #
178
+ def effective_desc(wrap_width: nil)
179
+ Tool.resolve_wrapping(@desc, wrap_width)
175
180
  end
176
181
 
177
182
  ##
178
183
  # Returns the effective long description for this tool. This will be
179
184
  # displayed as part of the usage for this particular tool.
180
- # @return [String]
181
185
  #
182
- def effective_long_desc
183
- @long_desc || @desc || ""
186
+ # @param [Integer,nil] wrap_width Wrap wrappable strings to the given
187
+ # width, or `nil` for no wrapping.
188
+ # @return [Array<String>]
189
+ #
190
+ def effective_long_desc(wrap_width: nil)
191
+ Tool.resolve_wrapping(@long_desc.empty? ? @desc : @long_desc, wrap_width)
184
192
  end
185
193
 
186
194
  ##
@@ -188,7 +196,7 @@ module Toys
188
196
  # @return [Boolean]
189
197
  #
190
198
  def includes_description?
191
- !@long_desc.nil? || !@desc.nil?
199
+ !@long_desc.empty? || !@desc.empty?
192
200
  end
193
201
 
194
202
  ##
@@ -224,7 +232,7 @@ module Toys
224
232
  # @return [Array<String>]
225
233
  #
226
234
  def used_switches
227
- @switch_definitions.reduce([]) { |used, sdef| used + sdef.switches }.uniq
235
+ @switch_definitions.reduce([]) { |used, sdef| used + sdef.effective_switches }.uniq
228
236
  end
229
237
 
230
238
  ##
@@ -246,21 +254,21 @@ module Toys
246
254
  ##
247
255
  # Set the short description.
248
256
  #
249
- # @param [String] str The short description
257
+ # @param [String,Array<String>] strs The short description
250
258
  #
251
- def desc=(str)
259
+ def desc=(strs)
252
260
  check_definition_state
253
- @desc = str
261
+ @desc = Tool.canonicalize_desc(strs)
254
262
  end
255
263
 
256
264
  ##
257
265
  # Set the long description.
258
266
  #
259
- # @param [String] str The long description
267
+ # @param [String,Array<String>] strs The long description
260
268
  #
261
- def long_desc=(str)
269
+ def long_desc=(strs)
262
270
  check_definition_state
263
- @long_desc = str
271
+ @long_desc = Tool.canonicalize_desc(strs)
264
272
  end
265
273
 
266
274
  ##
@@ -315,8 +323,9 @@ module Toys
315
323
  # @param [Object] default The default value. This is the value that will
316
324
  # be set in the context if this switch is not provided on the command
317
325
  # line. Defaults to `nil`.
318
- # @param [String,nil] doc The documentation for the switch, which appears
319
- # in the usage documentation. Defaults to `nil` for no documentation.
326
+ # @param [String,Toys::Utils::WrappableString,
327
+ # Array<String,Toys::Utils::WrappableString>] docs Documentation for
328
+ # the switch. Defaults to empty array.
320
329
  # @param [Boolean] only_unique If true, any switches that are already
321
330
  # defined in this tool are removed from this switch. For example, if
322
331
  # an earlier switch uses `-a`, and this switch wants to use both
@@ -329,14 +338,9 @@ module Toys
329
338
  # value. i.e. the default is effectively `-> (val, _prev) { val }`.
330
339
  #
331
340
  def add_switch(key, *switches,
332
- accept: nil, default: nil, doc: nil, only_unique: false, handler: nil)
341
+ accept: nil, default: nil, docs: nil, only_unique: false, handler: nil)
333
342
  check_definition_state
334
- switches << "--#{Tool.canonical_switch(key)}=VALUE" if switches.empty?
335
- bad_switch = switches.find { |s| Tool.extract_switch(s).empty? }
336
- if bad_switch
337
- raise ToolDefinitionError, "Illegal switch: #{bad_switch.inspect}"
338
- end
339
- switch_info = SwitchDefinition.new(key, switches + Array(accept) + Array(doc), handler)
343
+ switch_info = SwitchDefinition.new(key, switches, accept, docs, handler)
340
344
  if only_unique
341
345
  switch_info.remove_switches(used_switches)
342
346
  end
@@ -355,13 +359,14 @@ module Toys
355
359
  # @param [Symbol] key The key to use to retrieve the value from the
356
360
  # execution context.
357
361
  # @param [Object,nil] accept An OptionParser acceptor. Optional.
358
- # @param [String,nil] doc The documentation for the switch, which appears
359
- # in the usage documentation. Defaults to `nil` for no documentation.
362
+ # @param [String,Toys::Utils::WrappableString,
363
+ # Array<String,Toys::Utils::WrappableString>] docs Documentation for
364
+ # the arg. Defaults to empty array.
360
365
  #
361
- def add_required_arg(key, accept: nil, doc: nil)
366
+ def add_required_arg(key, accept: nil, docs: nil)
362
367
  check_definition_state
363
368
  @default_data[key] = nil
364
- @required_arg_definitions << ArgDefinition.new(key, accept, Array(doc))
369
+ @required_arg_definitions << ArgDefinition.new(key, accept, docs)
365
370
  self
366
371
  end
367
372
 
@@ -377,13 +382,14 @@ module Toys
377
382
  # @param [Object] default The default value. This is the value that will
378
383
  # be set in the context if this argument is not provided on the command
379
384
  # line. Defaults to `nil`.
380
- # @param [String,nil] doc The documentation for the argument, which appears
381
- # in the usage documentation. Defaults to `nil` for no documentation.
385
+ # @param [String,Toys::Utils::WrappableString,
386
+ # Array<String,Toys::Utils::WrappableString>] docs Documentation for
387
+ # the arg. Defaults to empty array.
382
388
  #
383
- def add_optional_arg(key, accept: nil, default: nil, doc: nil)
389
+ def add_optional_arg(key, accept: nil, default: nil, docs: nil)
384
390
  check_definition_state
385
391
  @default_data[key] = default
386
- @optional_arg_definitions << ArgDefinition.new(key, accept, Array(doc))
392
+ @optional_arg_definitions << ArgDefinition.new(key, accept, docs)
387
393
  self
388
394
  end
389
395
 
@@ -398,14 +404,14 @@ module Toys
398
404
  # @param [Object] default The default value. This is the value that will
399
405
  # be set in the context if no unmatched arguments are provided on the
400
406
  # command line. Defaults to the empty array `[]`.
401
- # @param [String,nil] doc The documentation for the remaining arguments,
402
- # which appears in the usage documentation. Defaults to `nil` for no
403
- # documentation.
407
+ # @param [String,Toys::Utils::WrappableString,
408
+ # Array<String,Toys::Utils::WrappableString>] docs Documentation for
409
+ # the args. Defaults to empty array.
404
410
  #
405
- def set_remaining_args(key, accept: nil, default: [], doc: nil)
411
+ def set_remaining_args(key, accept: nil, default: [], docs: nil)
406
412
  check_definition_state
407
413
  @default_data[key] = default
408
- @remaining_args_definition = ArgDefinition.new(key, accept, Array(doc))
414
+ @remaining_args_definition = ArgDefinition.new(key, accept, docs)
409
415
  self
410
416
  end
411
417
 
@@ -452,51 +458,58 @@ module Toys
452
458
  self
453
459
  end
454
460
 
455
- private
456
-
457
- def make_config_proc(middleware, next_config)
458
- proc { middleware.config(self, &next_config) }
459
- end
460
-
461
- def check_definition_state
462
- if @definition_finished
463
- raise ToolDefinitionError,
464
- "Defintion of tool #{display_name.inspect} is already finished"
465
- end
466
- end
467
-
468
- class << self
469
- ## @private
470
- def canonical_switch(name)
471
- name.to_s.downcase.tr("_", "-").gsub(/[^a-z0-9-]/, "")
472
- end
473
-
474
- ## @private
475
- def extract_switch(str)
476
- if !str.is_a?(String)
477
- []
478
- elsif str =~ /^(-[\?\w])(\s?\w+)?$/
479
- [$1]
461
+ ##
462
+ # Representation of a single switch
463
+ #
464
+ class SwitchSyntax
465
+ ##
466
+ # Parse switch syntax
467
+ # @param [String] str syntax.
468
+ #
469
+ def initialize(str)
470
+ if str =~ /^(-[\?\w])(\s?(\w+))?$/
471
+ setup(str, [$1], $1, "-", " ", $3)
480
472
  elsif str =~ /^--\[no-\](\w[\?\w-]*)$/
481
- ["--#{$1}", "--no-#{$1}"]
482
- elsif str =~ /^(--\w[\?\w-]*)([=\s]\w+)?$/
483
- [$1]
473
+ setup(str, ["--#{$1}", "--no-#{$1}"], "--[no-]#{$1}", "--", nil, nil)
474
+ elsif str =~ /^(--\w[\?\w-]*)(([=\s])(\w+))?$/
475
+ setup(str, [$1], $1, "--", $3, $4)
484
476
  else
485
- []
477
+ raise ToolDefinitionError, "Illegal switch: #{str.inspect}"
486
478
  end
487
479
  end
480
+
481
+ attr_reader :str
482
+ attr_reader :str_without_value
483
+ attr_reader :switches
484
+ attr_reader :switch_style
485
+ attr_reader :value_delim
486
+ attr_reader :value_label
487
+
488
+ private
489
+
490
+ def setup(str, switches, str_without_value, switch_style, value_delim, value_label)
491
+ @str = str
492
+ @switches = switches
493
+ @str_without_value = str_without_value
494
+ @switch_style = switch_style
495
+ @value_delim = value_delim
496
+ @value_label = value_label
497
+ end
488
498
  end
489
499
 
490
500
  ##
491
- # Representation of a formal switch.
501
+ # Representation of a formal set of switches.
492
502
  #
493
503
  class SwitchDefinition
494
504
  ##
495
505
  # Create a SwitchDefinition
506
+ # @private
496
507
  #
497
508
  # @param [Symbol] key This switch will set the given context key.
498
- # @param [Array<String>] optparse_info The switch definition in
499
- # OptionParser format
509
+ # @param [Array<String>] switches Switches in OptionParser format
510
+ # @param [Object] accept An OptionParser acceptor, or `nil` for none.
511
+ # @param [String,Toys::Utils::WrappableString,
512
+ # Array<String,Toys::Utils::WrappableString>] docs Documentation
500
513
  # @param [Proc,nil] handler An optional handler for setting/updating the
501
514
  # value. If given, it should take two arguments, the new given value
502
515
  # and the previous value, and it should return the new value that
@@ -504,11 +517,15 @@ module Toys
504
517
  # the previous value. i.e. the default is effectively
505
518
  # `-> (val, _prev) { val }`.
506
519
  #
507
- def initialize(key, optparse_info, handler = nil)
520
+ def initialize(key, switches, accept, docs, handler = nil)
508
521
  @key = key
509
- @optparse_info = optparse_info
522
+ switches = ["--#{Tool.canonical_switch(key)}=VALUE"] if switches.empty?
523
+ @switch_syntax = switches.map { |s| SwitchSyntax.new(s) }
524
+ @accept = accept
525
+ @docs = Tool.canonicalize_desc(docs)
510
526
  @handler = handler || ->(val, _prev) { val }
511
- @switches = nil
527
+ reset_data
528
+ @effective_switches = nil
512
529
  end
513
530
 
514
531
  ##
@@ -518,10 +535,22 @@ module Toys
518
535
  attr_reader :key
519
536
 
520
537
  ##
521
- # Returns the OptionParser definition.
538
+ # Returns an array of SwitchSyntax for the switches.
539
+ # @return [Array<SwitchSyntax>]
540
+ #
541
+ attr_reader :switch_syntax
542
+
543
+ ##
544
+ # Returns the acceptor, which may be `nil`.
545
+ # @return [Object]
546
+ #
547
+ attr_reader :accept
548
+
549
+ ##
550
+ # Returns the documentation strings, which may be the empty array.
522
551
  # @return [Array<String>]
523
552
  #
524
- attr_reader :optparse_info
553
+ attr_reader :docs
525
554
 
526
555
  ##
527
556
  # Returns the handler.
@@ -530,11 +559,45 @@ module Toys
530
559
  attr_reader :handler
531
560
 
532
561
  ##
533
- # Returns the list of switches used.
562
+ # Returns an array of SwitchSyntax including only single-dash switches
563
+ # @return [Array<SwitchSyntax>]
564
+ #
565
+ def single_switch_syntax
566
+ @single_switch_syntax ||= switch_syntax.find_all { |ss| ss.switch_style == "-" }
567
+ end
568
+
569
+ ##
570
+ # Returns an array of SwitchSyntax including only double-dash switches
571
+ # @return [Array<SwitchSyntax>]
572
+ #
573
+ def double_switch_syntax
574
+ @double_switch_syntax ||= switch_syntax.find_all { |ss| ss.switch_style == "--" }
575
+ end
576
+
577
+ ##
578
+ # Returns the list of effective switches used.
534
579
  # @return [Array<String>]
535
580
  #
536
- def switches
537
- @switches ||= optparse_info.map { |s| Tool.extract_switch(s) }.flatten
581
+ def effective_switches
582
+ @effective_switches ||= switch_syntax.map(&:switches).flatten
583
+ end
584
+
585
+ ##
586
+ # Returns the documentation strings with wrapping resolved.
587
+ #
588
+ # @param [Integer,nil] width Wrapping width, or `nil` to use default.
589
+ # @return [Array<String>]
590
+ #
591
+ def wrapped_docs(width)
592
+ Tool.resolve_wrapping(docs, width)
593
+ end
594
+
595
+ ##
596
+ # All optparser switches and acceptor if present
597
+ # @return [Array]
598
+ #
599
+ def optparser_info
600
+ @optparser_info ||= switch_syntax.map(&:str) + Array(accept)
538
601
  end
539
602
 
540
603
  ##
@@ -543,7 +606,25 @@ module Toys
543
606
  # @return [Boolean]
544
607
  #
545
608
  def active?
546
- !switches.empty?
609
+ !effective_switches.empty?
610
+ end
611
+
612
+ ##
613
+ # Return the value label if one exists
614
+ # @return [String,nil]
615
+ #
616
+ def value_label
617
+ find_canonical_value_label
618
+ @value_label
619
+ end
620
+
621
+ ##
622
+ # Return the value delimiter if one exists
623
+ # @return [String,nil]
624
+ #
625
+ def value_delim
626
+ find_canonical_value_label
627
+ @value_delim
547
628
  end
548
629
 
549
630
  ##
@@ -551,12 +632,43 @@ module Toys
551
632
  # @param [Array<String>] switches
552
633
  #
553
634
  def remove_switches(switches)
554
- @optparse_info.select! do |s|
555
- Tool.extract_switch(s).all? { |ss| !switches.include?(ss) }
635
+ @switch_syntax.select! do |ss|
636
+ ss.switches.all? { |s| !switches.include?(s) }
556
637
  end
557
- @switches = nil
638
+ reset_data
558
639
  self
559
640
  end
641
+
642
+ private
643
+
644
+ def reset_data
645
+ @effective_switches = nil
646
+ @optparser_info = nil
647
+ @single_switch_syntax = nil
648
+ @double_switch_syntax = nil
649
+ @value_label = nil
650
+ @value_delim = nil
651
+ end
652
+
653
+ def find_canonical_value_label
654
+ return if @value_delim
655
+ double_switch_syntax.reverse_each do |ss|
656
+ next unless ss.value_label
657
+ @value_label = ss.value_label
658
+ @value_delim = ss.value_delim
659
+ break
660
+ end
661
+ return if @value_delim
662
+ single_switch_syntax.reverse_each do |ss|
663
+ next unless ss.value_label
664
+ @value_label = ss.value_label
665
+ @value_delim = ss.value_delim
666
+ break
667
+ end
668
+ return if @value_delim
669
+ @value_label = nil
670
+ @value_delim = ""
671
+ end
560
672
  end
561
673
 
562
674
  ##
@@ -565,15 +677,17 @@ module Toys
565
677
  class ArgDefinition
566
678
  ##
567
679
  # Create an ArgDefinition
680
+ # @private
568
681
  #
569
682
  # @param [Symbol] key This argument will set the given context key.
570
- # @param [Object] accept An OptionParser acceptor
571
- # @param [Array<String>] doc An array of documentation strings
683
+ # @param [Object] accept An OptionParser acceptor, or `nil` for none.
684
+ # @param [String,Toys::Utils::WrappableString,
685
+ # Array<String,Toys::Utils::WrappableString>] docs Documentation
572
686
  #
573
- def initialize(key, accept, doc)
687
+ def initialize(key, accept, docs)
574
688
  @key = key
575
689
  @accept = accept
576
- @doc = doc
690
+ @docs = Tool.canonicalize_desc(docs)
577
691
  end
578
692
 
579
693
  ##
@@ -583,16 +697,16 @@ module Toys
583
697
  attr_reader :key
584
698
 
585
699
  ##
586
- # Returns the acceptor.
700
+ # Returns the acceptor, which may be `nil`.
587
701
  # @return [Object]
588
702
  #
589
703
  attr_reader :accept
590
704
 
591
705
  ##
592
- # Returns the documentation strings.
593
- # @return [Array<String>]
706
+ # Returns the documentation strings, which may be the empty array.
707
+ # @return [Array<String,Toys::Utils::WrappableString>]
594
708
  #
595
- attr_reader :doc
709
+ attr_reader :docs
596
710
 
597
711
  ##
598
712
  # Return a canonical name for this arg. Used in usage documentation.
@@ -603,22 +717,68 @@ module Toys
603
717
  Tool.canonical_switch(key)
604
718
  end
605
719
 
720
+ ##
721
+ # Returns the documentation strings with wrapping resolved.
722
+ #
723
+ # @param [Integer,nil] width Wrapping width, or `nil` to use default.
724
+ # @return [Array<String>]
725
+ #
726
+ def wrapped_docs(width)
727
+ Tool.resolve_wrapping(docs, width)
728
+ end
729
+
606
730
  ##
607
731
  # Process the given value through the acceptor.
732
+ # May raise an exception if the acceptor rejected the input.
608
733
  #
609
- # @private
734
+ # @param [String] input Input value
735
+ # @return [Object] Accepted value
610
736
  #
611
- def process_value(val)
612
- return val unless accept
737
+ def process_value(input)
738
+ return input unless accept
613
739
  n = canonical_name
614
- result = val
740
+ result = input
615
741
  optparse = ::OptionParser.new
616
742
  optparse.on("--#{n}=VALUE", accept) { |v| result = v }
617
- optparse.parse(["--#{n}", val])
743
+ optparse.parse(["--#{n}", input])
618
744
  result
619
745
  end
620
746
  end
621
747
 
748
+ private
749
+
750
+ def make_config_proc(middleware, next_config)
751
+ proc { middleware.config(self, &next_config) }
752
+ end
753
+
754
+ def check_definition_state
755
+ if @definition_finished
756
+ raise ToolDefinitionError,
757
+ "Defintion of tool #{display_name.inspect} is already finished"
758
+ end
759
+ end
760
+
761
+ class << self
762
+ ## @private
763
+ def canonical_switch(name)
764
+ name.to_s.downcase.tr("_", "-").gsub(/[^a-z0-9-]/, "")
765
+ end
766
+
767
+ ## @private
768
+ def canonicalize_desc(desc)
769
+ Array(desc).map do |d|
770
+ d.is_a?(Utils::WrappableString) ? d : d.split("\n")
771
+ end.flatten.freeze
772
+ end
773
+
774
+ ## @private
775
+ def resolve_wrapping(strs, wrap_width)
776
+ strs.map do |s|
777
+ s.is_a?(Utils::WrappableString) && !wrap_width.nil? ? s.wrap(wrap_width) : s.to_s
778
+ end.flatten
779
+ end
780
+ end
781
+
622
782
  ##
623
783
  # An internal class that manages execution of a tool
624
784
  # @private
@@ -667,7 +827,7 @@ module Toys
667
827
  optparse.new
668
828
  optparse.new
669
829
  @tool.switch_definitions.each do |switch|
670
- optparse.on(*switch.optparse_info) do |val|
830
+ optparse.on(*switch.optparser_info) do |val|
671
831
  @data[switch.key] = switch.handler.call(val, @data[switch.key])
672
832
  end
673
833
  end
@@ -714,9 +874,8 @@ module Toys
714
874
 
715
875
  def create_child_context(cli)
716
876
  context = Context.new(cli, @data)
717
- @tool.modules.each do |mod|
718
- context.extend(mod)
719
- end
877
+ modules = @tool.modules
878
+ context.extend(*modules) unless modules.empty?
720
879
  @tool.helpers.each do |name, block|
721
880
  context.define_singleton_method(name, &block)
722
881
  end