toys-core 0.3.5 → 0.3.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +12 -0
- data/lib/toys/cli.rb +15 -10
- data/lib/toys/config_dsl.rb +103 -17
- data/lib/toys/context.rb +60 -48
- data/lib/toys/core_version.rb +1 -1
- data/lib/toys/helpers/exec.rb +1 -1
- data/lib/toys/helpers/highline.rb +4 -9
- data/lib/toys/middleware/add_verbosity_flags.rb +6 -6
- data/lib/toys/middleware/set_default_descriptions.rb +162 -92
- data/lib/toys/middleware/show_help.rb +12 -6
- data/lib/toys/middleware/{show_version.rb → show_root_version.rb} +14 -23
- data/lib/toys/tool.rb +122 -372
- data/lib/toys/tool/acceptor.rb +190 -0
- data/lib/toys/tool/arg_definition.rb +130 -0
- data/lib/toys/tool/flag_definition.rb +322 -0
- data/lib/toys/utils/exec.rb +1 -1
- data/lib/toys/utils/help_text.rb +21 -15
- data/lib/toys/utils/line_output.rb +29 -12
- data/lib/toys/utils/wrappable_string.rb +23 -0
- metadata +6 -3
@@ -33,11 +33,10 @@ require "toys/utils/line_output"
|
|
33
33
|
module Toys
|
34
34
|
module Middleware
|
35
35
|
##
|
36
|
-
# A middleware that displays a version string for
|
37
|
-
# `--version` flag is given.
|
38
|
-
# this flag, and the string that will be displayed.
|
36
|
+
# A middleware that displays a version string for the root tool if the
|
37
|
+
# `--version` flag is given.
|
39
38
|
#
|
40
|
-
class
|
39
|
+
class ShowRootVersion < Base
|
41
40
|
##
|
42
41
|
# Default version flags
|
43
42
|
# @return [Array<String>]
|
@@ -45,32 +44,27 @@ module Toys
|
|
45
44
|
DEFAULT_VERSION_FLAGS = ["--version"].freeze
|
46
45
|
|
47
46
|
##
|
48
|
-
#
|
49
|
-
#
|
47
|
+
# Default description for the version flags
|
48
|
+
# @return [String]
|
50
49
|
#
|
51
|
-
|
52
|
-
#
|
53
|
-
def self.root_version_displayer(version)
|
54
|
-
proc { |tool| tool.root? ? version : false }
|
55
|
-
end
|
50
|
+
DEFAULT_VERSION_FLAG_DESC = "Display the version".freeze
|
56
51
|
|
57
52
|
##
|
58
53
|
# Create a ShowVersion middleware
|
59
54
|
#
|
60
|
-
# @param [
|
61
|
-
# either the version string that should be displayed, or a falsy
|
62
|
-
# value to indicate the tool should not have a `--version` flag.
|
63
|
-
# Defaults to a "null" displayer that returns false for all tools.
|
55
|
+
# @param [String] version_string The string that should be displayed.
|
64
56
|
# @param [Array<String>] version_flags A list of flags that should
|
65
57
|
# trigger displaying the version. Default is
|
66
58
|
# {DEFAULT_VERSION_FLAGS}.
|
67
59
|
# @param [IO] stream Output stream to write to. Default is stdout.
|
68
60
|
#
|
69
|
-
def initialize(
|
61
|
+
def initialize(version_string: nil,
|
70
62
|
version_flags: DEFAULT_VERSION_FLAGS,
|
63
|
+
version_flag_desc: DEFAULT_VERSION_FLAG_DESC,
|
71
64
|
stream: $stdout)
|
72
|
-
@
|
65
|
+
@version_string = version_string
|
73
66
|
@version_flags = version_flags
|
67
|
+
@version_flag_desc = version_flag_desc
|
74
68
|
@output = Utils::LineOutput.new(stream)
|
75
69
|
end
|
76
70
|
|
@@ -78,12 +72,9 @@ module Toys
|
|
78
72
|
# Adds the version flag if requested.
|
79
73
|
#
|
80
74
|
def config(tool, _loader)
|
81
|
-
|
82
|
-
if version
|
75
|
+
if @version_string && tool.root?
|
83
76
|
tool.add_flag(:_show_version, @version_flags,
|
84
|
-
|
85
|
-
handler: ->(_val, _prev) { version },
|
86
|
-
only_unique: true)
|
77
|
+
report_collisions: false, desc: @version_flag_desc)
|
87
78
|
end
|
88
79
|
yield
|
89
80
|
end
|
@@ -93,7 +84,7 @@ module Toys
|
|
93
84
|
#
|
94
85
|
def execute(context)
|
95
86
|
if context[:_show_version]
|
96
|
-
@output.puts
|
87
|
+
@output.puts(@version_string)
|
97
88
|
else
|
98
89
|
yield
|
99
90
|
end
|
data/lib/toys/tool.rb
CHANGED
@@ -40,6 +40,27 @@ module Toys
|
|
40
40
|
# tool is executed.
|
41
41
|
#
|
42
42
|
class Tool
|
43
|
+
##
|
44
|
+
# Built-in acceptors (i.e. those recognized by OptionParser).
|
45
|
+
# You can reference these acceptors directly. Otherwise, you have to add
|
46
|
+
# one explicitly to the tool using {Tool#add_acceptor}.
|
47
|
+
#
|
48
|
+
OPTPARSER_ACCEPTORS = [
|
49
|
+
::Object,
|
50
|
+
::NilClass,
|
51
|
+
::String,
|
52
|
+
::Integer,
|
53
|
+
::Float,
|
54
|
+
::Numeric,
|
55
|
+
::TrueClass,
|
56
|
+
::FalseClass,
|
57
|
+
::Array,
|
58
|
+
::Regexp,
|
59
|
+
::OptionParser::DecimalInteger,
|
60
|
+
::OptionParser::OctalInteger,
|
61
|
+
::OptionParser::DecimalNumeric
|
62
|
+
].freeze
|
63
|
+
|
43
64
|
##
|
44
65
|
# Create a new tool.
|
45
66
|
#
|
@@ -56,6 +77,10 @@ module Toys
|
|
56
77
|
@long_desc = []
|
57
78
|
|
58
79
|
@default_data = {}
|
80
|
+
@acceptors = {}
|
81
|
+
OPTPARSER_ACCEPTORS.each { |a| @acceptors[a] = a }
|
82
|
+
@used_flags = []
|
83
|
+
|
59
84
|
@flag_definitions = []
|
60
85
|
@required_arg_definitions = []
|
61
86
|
@optional_arg_definitions = []
|
@@ -110,6 +135,12 @@ module Toys
|
|
110
135
|
#
|
111
136
|
attr_reader :remaining_args_definition
|
112
137
|
|
138
|
+
##
|
139
|
+
# Return a list of flags that have been used in the flag definitions.
|
140
|
+
# @return [Array<String>]
|
141
|
+
#
|
142
|
+
attr_reader :used_flags
|
143
|
+
|
113
144
|
##
|
114
145
|
# Return the default argument data.
|
115
146
|
# @return [Hash]
|
@@ -234,11 +265,18 @@ module Toys
|
|
234
265
|
end
|
235
266
|
|
236
267
|
##
|
237
|
-
# Returns a list of
|
238
|
-
# @return [Array<
|
268
|
+
# Returns a list of all custom acceptors used by this tool.
|
269
|
+
# @return [Array<Toys::Tool::Acceptor>]
|
239
270
|
#
|
240
|
-
def
|
241
|
-
|
271
|
+
def custom_acceptors
|
272
|
+
result = []
|
273
|
+
flag_definitions.each do |f|
|
274
|
+
result << f.accept if f.accept.is_a?(Acceptor)
|
275
|
+
end
|
276
|
+
arg_definitions.each do |a|
|
277
|
+
result << a.accept if a.accept.is_a?(Acceptor)
|
278
|
+
end
|
279
|
+
result.uniq
|
242
280
|
end
|
243
281
|
|
244
282
|
##
|
@@ -268,7 +306,7 @@ module Toys
|
|
268
306
|
#
|
269
307
|
def desc=(desc)
|
270
308
|
check_definition_state
|
271
|
-
@desc =
|
309
|
+
@desc = Utils::WrappableString.make(desc)
|
272
310
|
end
|
273
311
|
|
274
312
|
##
|
@@ -282,22 +320,7 @@ module Toys
|
|
282
320
|
#
|
283
321
|
def long_desc=(descs)
|
284
322
|
check_definition_state
|
285
|
-
@long_desc =
|
286
|
-
end
|
287
|
-
|
288
|
-
##
|
289
|
-
# Set the long description strings.
|
290
|
-
#
|
291
|
-
# Each string may be provided as a {Toys::Utils::WrappableString}, a single
|
292
|
-
# string (which will be wrapped), or an array of strings, which will be
|
293
|
-
# interpreted as string fragments that will be concatenated and wrapped.
|
294
|
-
#
|
295
|
-
# @param [Toys::Utils::WrappableString,String,Array<String>...] descs
|
296
|
-
#
|
297
|
-
def populate_long_desc(*descs)
|
298
|
-
check_definition_state
|
299
|
-
@long_desc = Tool.canonicalize_long_desc(descs)
|
300
|
-
self
|
323
|
+
@long_desc = Utils::WrappableString.make_array(descs)
|
301
324
|
end
|
302
325
|
|
303
326
|
##
|
@@ -340,6 +363,17 @@ module Toys
|
|
340
363
|
self
|
341
364
|
end
|
342
365
|
|
366
|
+
##
|
367
|
+
# Add an acceptor to the tool. This acceptor may be refereneced by name
|
368
|
+
# when adding a flag or an arg.
|
369
|
+
#
|
370
|
+
# @param [Toys::Tool::Acceptor] acceptor The acceptor to add.
|
371
|
+
#
|
372
|
+
def add_acceptor(acceptor)
|
373
|
+
@acceptors[acceptor.name] = acceptor
|
374
|
+
self
|
375
|
+
end
|
376
|
+
|
343
377
|
##
|
344
378
|
# Add a flag to the current tool. Each flag must specify a key which
|
345
379
|
# the script may use to obtain the flag value from the context.
|
@@ -348,38 +382,60 @@ module Toys
|
|
348
382
|
# @param [Symbol] key The key to use to retrieve the value from the
|
349
383
|
# execution context.
|
350
384
|
# @param [Array<String>] flags The flags in OptionParser format.
|
351
|
-
# @param [Object
|
385
|
+
# @param [Object] accept An acceptor that validates and/or converts the
|
386
|
+
# value. You may provide either the name of an acceptor you have
|
387
|
+
# defined, or one of the default acceptors provided by OptionParser.
|
388
|
+
# Optional. If not specified, accepts any value as a string.
|
352
389
|
# @param [Object] default The default value. This is the value that will
|
353
390
|
# be set in the context if this flag is not provided on the command
|
354
391
|
# line. Defaults to `nil`.
|
392
|
+
# @param [Proc,nil] handler An optional handler for setting/updating the
|
393
|
+
# value. If given, it should take two arguments, the new given value
|
394
|
+
# and the previous value, and it should return the new value that
|
395
|
+
# should be set. The default handler simply replaces the previous
|
396
|
+
# value. i.e. the default is effectively `-> (val, _prev) { val }`.
|
397
|
+
# @param [Boolean] report_collisions Raise an exception if a flag is
|
398
|
+
# requested that is already in use or marked as disabled. Default is
|
399
|
+
# true.
|
355
400
|
# @param [String,Array<String>,Toys::Utils::WrappableString] desc Short
|
356
401
|
# description for the flag. See {Toys::Tool#desc=} for a description of
|
357
402
|
# allowed formats. Defaults to the empty string.
|
358
403
|
# @param [Array<String,Array<String>,Toys::Utils::WrappableString>] long_desc
|
359
404
|
# Long description for the flag. See {Toys::Tool#long_desc=} for a
|
360
405
|
# description of allowed formats. Defaults to the empty array.
|
361
|
-
# @param [Boolean] only_unique If true, any flags that are already
|
362
|
-
# defined in this tool are removed from this flag. For example, if
|
363
|
-
# an earlier flag uses `-a`, and this flag wants to use both
|
364
|
-
# `-a` and `-b`, then only `-b` will be assigned to this flag.
|
365
|
-
# Defaults to false.
|
366
|
-
# @param [Proc,nil] handler An optional handler for setting/updating the
|
367
|
-
# value. If given, it should take two arguments, the new given value
|
368
|
-
# and the previous value, and it should return the new value that
|
369
|
-
# should be set. The default handler simply replaces the previous
|
370
|
-
# value. i.e. the default is effectively `-> (val, _prev) { val }`.
|
371
406
|
#
|
372
407
|
def add_flag(key, flags = [],
|
373
|
-
accept: nil, default: nil, handler: nil,
|
374
|
-
|
408
|
+
accept: nil, default: nil, handler: nil,
|
409
|
+
report_collisions: true,
|
410
|
+
desc: nil, long_desc: nil)
|
375
411
|
check_definition_state
|
376
|
-
|
377
|
-
flag_def.
|
412
|
+
accept = resolve_acceptor(accept)
|
413
|
+
flag_def = FlagDefinition.new(key, flags, @used_flags, report_collisions,
|
414
|
+
accept, handler, default)
|
415
|
+
flag_def.desc = desc if desc
|
416
|
+
flag_def.long_desc = long_desc if long_desc
|
378
417
|
@flag_definitions << flag_def if flag_def.active?
|
379
418
|
@default_data[key] = default
|
380
419
|
self
|
381
420
|
end
|
382
421
|
|
422
|
+
##
|
423
|
+
# Mark one or more flags as disabled, preventing their use by any
|
424
|
+
# subsequent flag definition. This may be used to prevent middleware from
|
425
|
+
# defining a particular flag.
|
426
|
+
#
|
427
|
+
# @param [String...] flags The flags to disable
|
428
|
+
#
|
429
|
+
def disable_flag(*flags)
|
430
|
+
flags = flags.uniq
|
431
|
+
intersection = @used_flags & flags
|
432
|
+
unless intersection.empty?
|
433
|
+
raise ToolDefinitionError, "Cannot disable flags already used: #{intersection.inspect}"
|
434
|
+
end
|
435
|
+
@used_flags.concat(flags)
|
436
|
+
self
|
437
|
+
end
|
438
|
+
|
383
439
|
##
|
384
440
|
# Add a required positional argument to the current tool. You must specify
|
385
441
|
# a key which the script may use to obtain the argument value from the
|
@@ -387,7 +443,10 @@ module Toys
|
|
387
443
|
#
|
388
444
|
# @param [Symbol] key The key to use to retrieve the value from the
|
389
445
|
# execution context.
|
390
|
-
# @param [Object
|
446
|
+
# @param [Object] accept An acceptor that validates and/or converts the
|
447
|
+
# value. You may provide either the name of an acceptor you have
|
448
|
+
# defined, or one of the default acceptors provided by OptionParser.
|
449
|
+
# Optional. If not specified, accepts any value as a string.
|
391
450
|
# @param [String] display_name A name to use for display (in help text and
|
392
451
|
# error reports). Defaults to the key in upper case.
|
393
452
|
# @param [String,Array<String>,Toys::Utils::WrappableString] desc Short
|
@@ -399,7 +458,8 @@ module Toys
|
|
399
458
|
#
|
400
459
|
def add_required_arg(key, accept: nil, display_name: nil, desc: nil, long_desc: nil)
|
401
460
|
check_definition_state
|
402
|
-
|
461
|
+
accept = resolve_acceptor(accept)
|
462
|
+
arg_def = ArgDefinition.new(key, :required, accept, nil, desc, long_desc, display_name)
|
403
463
|
@required_arg_definitions << arg_def
|
404
464
|
self
|
405
465
|
end
|
@@ -415,7 +475,10 @@ module Toys
|
|
415
475
|
# @param [Object] default The default value. This is the value that will
|
416
476
|
# be set in the context if this argument is not provided on the command
|
417
477
|
# line. Defaults to `nil`.
|
418
|
-
# @param [Object
|
478
|
+
# @param [Object] accept An acceptor that validates and/or converts the
|
479
|
+
# value. You may provide either the name of an acceptor you have
|
480
|
+
# defined, or one of the default acceptors provided by OptionParser.
|
481
|
+
# Optional. If not specified, accepts any value as a string.
|
419
482
|
# @param [String] display_name A name to use for display (in help text and
|
420
483
|
# error reports). Defaults to the key in upper case.
|
421
484
|
# @param [String,Array<String>,Toys::Utils::WrappableString] desc Short
|
@@ -428,7 +491,8 @@ module Toys
|
|
428
491
|
def add_optional_arg(key, default: nil, accept: nil, display_name: nil,
|
429
492
|
desc: nil, long_desc: nil)
|
430
493
|
check_definition_state
|
431
|
-
|
494
|
+
accept = resolve_acceptor(accept)
|
495
|
+
arg_def = ArgDefinition.new(key, :optional, accept, default, desc, long_desc, display_name)
|
432
496
|
@optional_arg_definitions << arg_def
|
433
497
|
@default_data[key] = default
|
434
498
|
self
|
@@ -444,7 +508,10 @@ module Toys
|
|
444
508
|
# @param [Object] default The default value. This is the value that will
|
445
509
|
# be set in the context if no unmatched arguments are provided on the
|
446
510
|
# command line. Defaults to the empty array `[]`.
|
447
|
-
# @param [Object
|
511
|
+
# @param [Object] accept An acceptor that validates and/or converts the
|
512
|
+
# value. You may provide either the name of an acceptor you have
|
513
|
+
# defined, or one of the default acceptors provided by OptionParser.
|
514
|
+
# Optional. If not specified, accepts any value as a string.
|
448
515
|
# @param [String] display_name A name to use for display (in help text and
|
449
516
|
# error reports). Defaults to the key in upper case.
|
450
517
|
# @param [String,Array<String>,Toys::Utils::WrappableString] desc Short
|
@@ -457,7 +524,8 @@ module Toys
|
|
457
524
|
def set_remaining_args(key, default: [], accept: nil, display_name: nil,
|
458
525
|
desc: nil, long_desc: nil)
|
459
526
|
check_definition_state
|
460
|
-
|
527
|
+
accept = resolve_acceptor(accept)
|
528
|
+
arg_def = ArgDefinition.new(key, :remaining, accept, default, desc, long_desc, display_name)
|
461
529
|
@remaining_args_definition = arg_def
|
462
530
|
@default_data[key] = default
|
463
531
|
self
|
@@ -513,327 +581,6 @@ module Toys
|
|
513
581
|
self
|
514
582
|
end
|
515
583
|
|
516
|
-
##
|
517
|
-
# Representation of a single flag
|
518
|
-
#
|
519
|
-
class FlagSyntax
|
520
|
-
##
|
521
|
-
# Parse flag syntax
|
522
|
-
# @param [String] str syntax.
|
523
|
-
#
|
524
|
-
def initialize(str)
|
525
|
-
if str =~ /^(-[\?\w])(\s?(\w+))?$/
|
526
|
-
setup(str, [$1], $1, "-", " ", $3)
|
527
|
-
elsif str =~ /^--\[no-\](\w[\?\w-]*)$/
|
528
|
-
setup(str, ["--#{$1}", "--no-#{$1}"], "--[no-]#{$1}", "--", nil, nil)
|
529
|
-
elsif str =~ /^(--\w[\?\w-]*)(([=\s])(\w+))?$/
|
530
|
-
setup(str, [$1], $1, "--", $3, $4)
|
531
|
-
else
|
532
|
-
raise ToolDefinitionError, "Illegal flag: #{str.inspect}"
|
533
|
-
end
|
534
|
-
end
|
535
|
-
|
536
|
-
attr_reader :original_str
|
537
|
-
attr_reader :str_without_value
|
538
|
-
attr_reader :flags
|
539
|
-
attr_reader :flag_style
|
540
|
-
attr_reader :value_delim
|
541
|
-
attr_reader :value_label
|
542
|
-
|
543
|
-
private
|
544
|
-
|
545
|
-
def setup(original_str, flags, str_without_value, flag_style, value_delim, value_label)
|
546
|
-
@original_str = original_str
|
547
|
-
@flags = flags
|
548
|
-
@str_without_value = str_without_value
|
549
|
-
@flag_style = flag_style
|
550
|
-
@value_delim = value_delim
|
551
|
-
@value_label = value_label ? value_label.upcase : value_label
|
552
|
-
end
|
553
|
-
end
|
554
|
-
|
555
|
-
##
|
556
|
-
# Representation of a formal set of flags.
|
557
|
-
#
|
558
|
-
class FlagDefinition
|
559
|
-
##
|
560
|
-
# The default handler replaces the previous value.
|
561
|
-
# @return [Proc]
|
562
|
-
#
|
563
|
-
DEFAULT_HANDLER = ->(val, _prev) { val }
|
564
|
-
|
565
|
-
##
|
566
|
-
# Create a FlagDefinition
|
567
|
-
# @private
|
568
|
-
#
|
569
|
-
# @param [Symbol] key This flag will set the given context key.
|
570
|
-
#
|
571
|
-
def initialize(key, flags, accept, handler, desc, long_desc, default)
|
572
|
-
@key = key
|
573
|
-
@flag_syntax = flags.map { |s| FlagSyntax.new(s) }
|
574
|
-
@accept = accept
|
575
|
-
@handler = handler || DEFAULT_HANDLER
|
576
|
-
@desc = Tool.canonicalize_desc(desc)
|
577
|
-
@long_desc = Tool.canonicalize_long_desc(long_desc)
|
578
|
-
@needs_val = !@accept.nil? ||
|
579
|
-
(!default.nil? && default != true && default != false)
|
580
|
-
create_default_flag_if_needed
|
581
|
-
reset_data
|
582
|
-
end
|
583
|
-
|
584
|
-
##
|
585
|
-
# Returns the key.
|
586
|
-
# @return [Symbol]
|
587
|
-
#
|
588
|
-
attr_reader :key
|
589
|
-
|
590
|
-
##
|
591
|
-
# Returns an array of FlagSyntax for the flags.
|
592
|
-
# @return [Array<FlagSyntax>]
|
593
|
-
#
|
594
|
-
attr_reader :flag_syntax
|
595
|
-
|
596
|
-
##
|
597
|
-
# Returns the acceptor, which may be `nil`.
|
598
|
-
# @return [Object]
|
599
|
-
#
|
600
|
-
attr_reader :accept
|
601
|
-
|
602
|
-
##
|
603
|
-
# Returns the short description string.
|
604
|
-
# @return [Toys::Utils::WrappableString]
|
605
|
-
#
|
606
|
-
attr_reader :desc
|
607
|
-
|
608
|
-
##
|
609
|
-
# Returns the long description strings as an array.
|
610
|
-
# @return [Array<Toys::Utils::WrappableString>]
|
611
|
-
#
|
612
|
-
attr_reader :long_desc
|
613
|
-
|
614
|
-
##
|
615
|
-
# Returns the handler for setting/updating the value.
|
616
|
-
# @return [Proc]
|
617
|
-
#
|
618
|
-
attr_reader :handler
|
619
|
-
|
620
|
-
##
|
621
|
-
# Returns an array of FlagSyntax including only single-dash flags
|
622
|
-
# @return [Array<FlagSyntax>]
|
623
|
-
#
|
624
|
-
def single_flag_syntax
|
625
|
-
@single_flag_syntax ||= flag_syntax.find_all { |ss| ss.flag_style == "-" }
|
626
|
-
end
|
627
|
-
|
628
|
-
##
|
629
|
-
# Returns an array of FlagSyntax including only double-dash flags
|
630
|
-
# @return [Array<FlagSyntax>]
|
631
|
-
#
|
632
|
-
def double_flag_syntax
|
633
|
-
@double_flag_syntax ||= flag_syntax.find_all { |ss| ss.flag_style == "--" }
|
634
|
-
end
|
635
|
-
|
636
|
-
##
|
637
|
-
# Returns the list of effective flags used.
|
638
|
-
# @return [Array<String>]
|
639
|
-
#
|
640
|
-
def effective_flags
|
641
|
-
@effective_flags ||= flag_syntax.map(&:flags).flatten
|
642
|
-
end
|
643
|
-
|
644
|
-
##
|
645
|
-
# All optparser flags and acceptor if present
|
646
|
-
# @return [Array]
|
647
|
-
#
|
648
|
-
def optparser_info
|
649
|
-
@optparser_info ||= begin
|
650
|
-
flags = flag_syntax.map do |fs|
|
651
|
-
f = fs.str_without_value
|
652
|
-
f = "#{f} #{value_label}" if value_label
|
653
|
-
f
|
654
|
-
end
|
655
|
-
flags + Array(accept)
|
656
|
-
end
|
657
|
-
end
|
658
|
-
|
659
|
-
##
|
660
|
-
# Returns true if this flag is active. That is, it has a nonempty
|
661
|
-
# flags list.
|
662
|
-
# @return [Boolean]
|
663
|
-
#
|
664
|
-
def active?
|
665
|
-
!effective_flags.empty?
|
666
|
-
end
|
667
|
-
|
668
|
-
##
|
669
|
-
# Return the value label if one exists
|
670
|
-
# @return [String,nil]
|
671
|
-
#
|
672
|
-
def value_label
|
673
|
-
find_canonical_value_label
|
674
|
-
@value_label
|
675
|
-
end
|
676
|
-
|
677
|
-
##
|
678
|
-
# Return the value delimiter if one exists
|
679
|
-
# @return [String,nil]
|
680
|
-
#
|
681
|
-
def value_delim
|
682
|
-
find_canonical_value_label
|
683
|
-
@value_delim
|
684
|
-
end
|
685
|
-
|
686
|
-
##
|
687
|
-
# Set description
|
688
|
-
# @param [String,Array<String>,Toys::Utils::WrappableString] desc
|
689
|
-
#
|
690
|
-
def desc=(desc)
|
691
|
-
@desc = Tool.canonicalize_desc(desc)
|
692
|
-
end
|
693
|
-
|
694
|
-
##
|
695
|
-
# Set long description
|
696
|
-
# @param [Array<String,Array<String>,Toys::Utils::WrappableString>] long_desc
|
697
|
-
#
|
698
|
-
def long_desc=(long_desc)
|
699
|
-
@long_desc = Tool.canonicalize_long_desc(long_desc)
|
700
|
-
end
|
701
|
-
|
702
|
-
## @private
|
703
|
-
def remove_flags(flags)
|
704
|
-
flags = flags.map { |f| FlagSyntax.new(f).flags }.flatten
|
705
|
-
@flag_syntax.select! do |ss|
|
706
|
-
ss.flags.all? { |s| !flags.include?(s) }
|
707
|
-
end
|
708
|
-
reset_data
|
709
|
-
end
|
710
|
-
|
711
|
-
private
|
712
|
-
|
713
|
-
def reset_data
|
714
|
-
@effective_flags = nil
|
715
|
-
@optparser_info = nil
|
716
|
-
@single_flag_syntax = nil
|
717
|
-
@double_flag_syntax = nil
|
718
|
-
@value_label = nil
|
719
|
-
@value_delim = nil
|
720
|
-
end
|
721
|
-
|
722
|
-
def create_default_flag_if_needed
|
723
|
-
return unless @flag_syntax.empty?
|
724
|
-
canonical_flag = key.to_s.downcase.tr("_", "-").gsub(/[^a-z0-9-]/, "").sub(/^-+/, "")
|
725
|
-
unless canonical_flag.empty?
|
726
|
-
flag = @needs_val ? "--#{canonical_flag}=VALUE" : "--#{canonical_flag}"
|
727
|
-
@flag_syntax << FlagSyntax.new(flag)
|
728
|
-
end
|
729
|
-
end
|
730
|
-
|
731
|
-
def find_canonical_value_label
|
732
|
-
return if @value_delim
|
733
|
-
@value_label = @needs_val ? "VALUE" : nil
|
734
|
-
@value_delim = @needs_val ? " " : ""
|
735
|
-
single_flag_syntax.each do |ss|
|
736
|
-
next unless ss.value_label
|
737
|
-
@value_label = ss.value_label
|
738
|
-
@value_delim = ss.value_delim
|
739
|
-
end
|
740
|
-
double_flag_syntax.each do |ss|
|
741
|
-
next unless ss.value_label
|
742
|
-
@value_label = ss.value_label
|
743
|
-
@value_delim = ss.value_delim
|
744
|
-
end
|
745
|
-
end
|
746
|
-
end
|
747
|
-
|
748
|
-
##
|
749
|
-
# Representation of a formal positional argument
|
750
|
-
#
|
751
|
-
class ArgDefinition
|
752
|
-
##
|
753
|
-
# Create an ArgDefinition
|
754
|
-
# @private
|
755
|
-
#
|
756
|
-
# @param [Symbol] key This argument will set the given context key.
|
757
|
-
# @param [:required,:optional,:remaining] type Type of this argument
|
758
|
-
#
|
759
|
-
def initialize(key, type, accept, desc, long_desc, display_name)
|
760
|
-
@key = key
|
761
|
-
@type = type
|
762
|
-
@accept = accept
|
763
|
-
@desc = Tool.canonicalize_desc(desc)
|
764
|
-
@long_desc = Tool.canonicalize_long_desc(long_desc)
|
765
|
-
@display_name = display_name || key.to_s.tr("-", "_").gsub(/\W/, "").upcase
|
766
|
-
end
|
767
|
-
|
768
|
-
##
|
769
|
-
# Returns the key.
|
770
|
-
# @return [Symbol]
|
771
|
-
#
|
772
|
-
attr_reader :key
|
773
|
-
|
774
|
-
##
|
775
|
-
# Type of this argument.
|
776
|
-
# @return [:required,:optional,:remaining]
|
777
|
-
#
|
778
|
-
attr_reader :type
|
779
|
-
|
780
|
-
##
|
781
|
-
# Returns the acceptor, which may be `nil`.
|
782
|
-
# @return [Object]
|
783
|
-
#
|
784
|
-
attr_accessor :accept
|
785
|
-
|
786
|
-
##
|
787
|
-
# Returns the short description string.
|
788
|
-
# @return [Toys::Utils::WrappableString]
|
789
|
-
#
|
790
|
-
attr_reader :desc
|
791
|
-
|
792
|
-
##
|
793
|
-
# Returns the long description strings as an array.
|
794
|
-
# @return [Array<Toys::Utils::WrappableString>]
|
795
|
-
#
|
796
|
-
attr_reader :long_desc
|
797
|
-
|
798
|
-
##
|
799
|
-
# Returns the displayable name.
|
800
|
-
# @return [String]
|
801
|
-
#
|
802
|
-
attr_accessor :display_name
|
803
|
-
|
804
|
-
##
|
805
|
-
# Process the given value through the acceptor.
|
806
|
-
# May raise an exception if the acceptor rejected the input.
|
807
|
-
#
|
808
|
-
# @param [String] input Input value
|
809
|
-
# @return [Object] Accepted value
|
810
|
-
#
|
811
|
-
def process_value(input)
|
812
|
-
return input unless accept
|
813
|
-
result = input
|
814
|
-
optparse = ::OptionParser.new
|
815
|
-
optparse.on("--abc=VALUE", accept) { |v| result = v }
|
816
|
-
optparse.parse(["--abc", input])
|
817
|
-
result
|
818
|
-
end
|
819
|
-
|
820
|
-
##
|
821
|
-
# Set description
|
822
|
-
# @param [String,Array<String>,Toys::Utils::WrappableString] desc
|
823
|
-
#
|
824
|
-
def desc=(desc)
|
825
|
-
@desc = Tool.canonicalize_desc(desc)
|
826
|
-
end
|
827
|
-
|
828
|
-
##
|
829
|
-
# Set long description
|
830
|
-
# @param [Array<String,Array<String>,Toys::Utils::WrappableString>] long_desc
|
831
|
-
#
|
832
|
-
def long_desc=(long_desc)
|
833
|
-
@long_desc = Tool.canonicalize_long_desc(long_desc)
|
834
|
-
end
|
835
|
-
end
|
836
|
-
|
837
584
|
private
|
838
585
|
|
839
586
|
def make_config_proc(middleware, loader, next_config)
|
@@ -847,16 +594,12 @@ module Toys
|
|
847
594
|
end
|
848
595
|
end
|
849
596
|
|
850
|
-
|
851
|
-
|
852
|
-
|
853
|
-
|
854
|
-
end
|
855
|
-
|
856
|
-
## @private
|
857
|
-
def canonicalize_long_desc(descs)
|
858
|
-
Array(descs).map { |desc| canonicalize_desc(desc) }.freeze
|
597
|
+
def resolve_acceptor(accept)
|
598
|
+
return accept if accept.nil? || accept.is_a?(Acceptor)
|
599
|
+
unless @acceptors.key?(accept)
|
600
|
+
raise ToolDefinitionError, "Unknown acceptor: #{accept.inspect}"
|
859
601
|
end
|
602
|
+
@acceptors[accept]
|
860
603
|
end
|
861
604
|
|
862
605
|
##
|
@@ -911,6 +654,9 @@ module Toys
|
|
911
654
|
@data[flag.key] = flag.handler.call(val, @data[flag.key])
|
912
655
|
end
|
913
656
|
end
|
657
|
+
@tool.custom_acceptors do |accept|
|
658
|
+
optparse.accept(accept)
|
659
|
+
end
|
914
660
|
optparse
|
915
661
|
end
|
916
662
|
|
@@ -986,3 +732,7 @@ module Toys
|
|
986
732
|
end
|
987
733
|
end
|
988
734
|
end
|
735
|
+
|
736
|
+
require "toys/tool/acceptor"
|
737
|
+
require "toys/tool/arg_definition"
|
738
|
+
require "toys/tool/flag_definition"
|