toys-core 0.3.2 → 0.3.3

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.
@@ -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