toys-core 0.6.1 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -0
- data/lib/toys-core.rb +3 -5
- data/lib/toys/core_version.rb +1 -1
- data/lib/toys/definition/flag.rb +57 -22
- data/lib/toys/definition/flag_group.rb +205 -0
- data/lib/toys/definition/tool.rb +71 -4
- data/lib/toys/dsl/flag.rb +36 -10
- data/lib/toys/dsl/flag_group.rb +108 -0
- data/lib/toys/dsl/tool.rb +177 -4
- data/lib/toys/runner.rb +13 -3
- data/lib/toys/standard_middleware.rb +47 -0
- data/lib/toys/standard_middleware/add_verbosity_flags.rb +5 -2
- data/lib/toys/standard_middleware/show_help.rb +13 -6
- data/lib/toys/utils/exec.rb +7 -4
- data/lib/toys/utils/gems.rb +1 -1
- data/lib/toys/utils/help_text.rb +94 -26
- metadata +5 -2
data/lib/toys/dsl/flag.rb
CHANGED
@@ -40,14 +40,17 @@ module Toys
|
|
40
40
|
#
|
41
41
|
class Flag
|
42
42
|
## @private
|
43
|
-
def initialize(flags, accept, default, handler, report_collisions,
|
43
|
+
def initialize(flags, accept, default, handler, report_collisions,
|
44
|
+
group, desc, long_desc, display_name)
|
44
45
|
@flags = flags
|
45
46
|
@accept = accept
|
46
47
|
@default = default
|
47
48
|
@handler = handler
|
48
49
|
@report_collisions = report_collisions
|
50
|
+
@group = group
|
49
51
|
@desc = desc
|
50
52
|
@long_desc = long_desc || []
|
53
|
+
@display_name = display_name
|
51
54
|
end
|
52
55
|
|
53
56
|
##
|
@@ -55,7 +58,7 @@ module Toys
|
|
55
58
|
# and the results are cumulative.
|
56
59
|
#
|
57
60
|
# @param [String...] flags
|
58
|
-
# @return [Toys::DSL::
|
61
|
+
# @return [Toys::DSL::Flag] self, for chaining.
|
59
62
|
#
|
60
63
|
def flags(*flags)
|
61
64
|
@flags += flags
|
@@ -66,7 +69,7 @@ module Toys
|
|
66
69
|
# Set the OptionParser acceptor.
|
67
70
|
#
|
68
71
|
# @param [Object] accept
|
69
|
-
# @return [Toys::DSL::
|
72
|
+
# @return [Toys::DSL::Flag] self, for chaining.
|
70
73
|
#
|
71
74
|
def accept(accept)
|
72
75
|
@accept = accept
|
@@ -77,7 +80,7 @@ module Toys
|
|
77
80
|
# Set the default value.
|
78
81
|
#
|
79
82
|
# @param [Object] default
|
80
|
-
# @return [Toys::DSL::
|
83
|
+
# @return [Toys::DSL::Flag] self, for chaining.
|
81
84
|
#
|
82
85
|
def default(default)
|
83
86
|
@default = default
|
@@ -92,7 +95,7 @@ module Toys
|
|
92
95
|
# responding to the `call` method) or you may pass a block.
|
93
96
|
#
|
94
97
|
# @param [Proc] handler
|
95
|
-
# @return [Toys::DSL::
|
98
|
+
# @return [Toys::DSL::Flag] self, for chaining.
|
96
99
|
#
|
97
100
|
def handler(handler = nil, &block)
|
98
101
|
@handler = handler || block
|
@@ -104,7 +107,7 @@ module Toys
|
|
104
107
|
# already in use or marked as disabled.
|
105
108
|
#
|
106
109
|
# @param [Boolean] setting
|
107
|
-
# @return [Toys::DSL::
|
110
|
+
# @return [Toys::DSL::Flag] self, for chaining.
|
108
111
|
#
|
109
112
|
def report_collisions(setting)
|
110
113
|
@report_collisions = setting
|
@@ -116,7 +119,7 @@ module Toys
|
|
116
119
|
# formats.
|
117
120
|
#
|
118
121
|
# @param [String,Array<String>,Toys::Utils::WrappableString] desc
|
119
|
-
# @return [Toys::DSL::
|
122
|
+
# @return [Toys::DSL::Flag] self, for chaining.
|
120
123
|
#
|
121
124
|
def desc(desc)
|
122
125
|
@desc = desc
|
@@ -129,19 +132,42 @@ module Toys
|
|
129
132
|
# allowed formats.
|
130
133
|
#
|
131
134
|
# @param [String,Array<String>,Toys::Utils::WrappableString...] long_desc
|
132
|
-
# @return [Toys::DSL::
|
135
|
+
# @return [Toys::DSL::Flag] self, for chaining.
|
133
136
|
#
|
134
137
|
def long_desc(*long_desc)
|
135
138
|
@long_desc += long_desc
|
136
139
|
self
|
137
140
|
end
|
138
141
|
|
142
|
+
##
|
143
|
+
# Set the group. A group may be set by name or group object. Setting
|
144
|
+
# `nil` selects the default group.
|
145
|
+
#
|
146
|
+
# @param [String,Symbol,Toys::Definition::FlagGroup,nil] group
|
147
|
+
# @return [Toys::DSL::Flag] self, for chaining.
|
148
|
+
#
|
149
|
+
def group(group)
|
150
|
+
@group = group
|
151
|
+
self
|
152
|
+
end
|
153
|
+
|
154
|
+
##
|
155
|
+
# Set the display name. This may be used in help text and error messages.
|
156
|
+
#
|
157
|
+
# @param [String] display_name
|
158
|
+
# @return [Toys::DSL::Flag] self, for chaining.
|
159
|
+
#
|
160
|
+
def display_name(display_name)
|
161
|
+
@display_name = display_name
|
162
|
+
self
|
163
|
+
end
|
164
|
+
|
139
165
|
## @private
|
140
166
|
def _add_to(tool, key)
|
141
167
|
tool.add_flag(key, @flags,
|
142
168
|
accept: @accept, default: @default, handler: @handler,
|
143
|
-
report_collisions: @report_collisions,
|
144
|
-
desc: @desc, long_desc: @long_desc)
|
169
|
+
report_collisions: @report_collisions, group: @group,
|
170
|
+
desc: @desc, long_desc: @long_desc, display_name: @display_name)
|
145
171
|
end
|
146
172
|
end
|
147
173
|
end
|
@@ -0,0 +1,108 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright 2018 Daniel Azuma
|
4
|
+
#
|
5
|
+
# All rights reserved.
|
6
|
+
#
|
7
|
+
# Redistribution and use in source and binary forms, with or without
|
8
|
+
# modification, are permitted provided that the following conditions are met:
|
9
|
+
#
|
10
|
+
# * Redistributions of source code must retain the above copyright notice,
|
11
|
+
# this list of conditions and the following disclaimer.
|
12
|
+
# * Redistributions in binary form must reproduce the above copyright notice,
|
13
|
+
# this list of conditions and the following disclaimer in the documentation
|
14
|
+
# and/or other materials provided with the distribution.
|
15
|
+
# * Neither the name of the copyright holder, nor the names of any other
|
16
|
+
# contributors to this software, may be used to endorse or promote products
|
17
|
+
# derived from this software without specific prior written permission.
|
18
|
+
#
|
19
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
20
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
21
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
22
|
+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
23
|
+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
24
|
+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
25
|
+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
26
|
+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
27
|
+
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
28
|
+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
29
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
30
|
+
;
|
31
|
+
|
32
|
+
module Toys
|
33
|
+
module DSL
|
34
|
+
##
|
35
|
+
# DSL for a flag group definition block. Lets you create flags in a group.
|
36
|
+
#
|
37
|
+
# These directives are available inside a block passed to
|
38
|
+
# {Toys::DSL::Tool#flag_group} and related methods.
|
39
|
+
#
|
40
|
+
class FlagGroup
|
41
|
+
## @private
|
42
|
+
def initialize(tool_dsl, tool_definition, flag_group)
|
43
|
+
@tool_dsl = tool_dsl
|
44
|
+
@tool_definition = tool_definition
|
45
|
+
@flag_group = flag_group
|
46
|
+
end
|
47
|
+
|
48
|
+
##
|
49
|
+
# Add a flag to the current tool. Each flag must specify a key which
|
50
|
+
# the script may use to obtain the flag value from the context.
|
51
|
+
# You may then provide the flags themselves in OptionParser form.
|
52
|
+
#
|
53
|
+
# If the given key is a symbol representing a valid method name, then a
|
54
|
+
# helper method is automatically added to retrieve the value. Otherwise,
|
55
|
+
# if the key is a string or does not represent a valid method name, the
|
56
|
+
# tool can retrieve the value by calling {Toys::Tool#get}.
|
57
|
+
#
|
58
|
+
# Attributes of the flag may be passed in as arguments to this method, or
|
59
|
+
# set in a block passed to this method. If you provide a block, you can
|
60
|
+
# use directives in {Toys::DSL::Flag} within the block.
|
61
|
+
#
|
62
|
+
# @param [String,Symbol] key The key to use to retrieve the value from
|
63
|
+
# the execution context.
|
64
|
+
# @param [String...] flags The flags in OptionParser format.
|
65
|
+
# @param [Object] accept An acceptor that validates and/or converts the
|
66
|
+
# value. You may provide either the name of an acceptor you have
|
67
|
+
# defined, or one of the default acceptors provided by OptionParser.
|
68
|
+
# Optional. If not specified, accepts any value as a string.
|
69
|
+
# @param [Object] default The default value. This is the value that will
|
70
|
+
# be set in the context if this flag is not provided on the command
|
71
|
+
# line. Defaults to `nil`.
|
72
|
+
# @param [Proc,nil] handler An optional handler for setting/updating the
|
73
|
+
# value. If given, it should take two arguments, the new given value
|
74
|
+
# and the previous value, and it should return the new value that
|
75
|
+
# should be set. The default handler simply replaces the previous
|
76
|
+
# value. i.e. the default is effectively `-> (val, _prev) { val }`.
|
77
|
+
# @param [Boolean] report_collisions Raise an exception if a flag is
|
78
|
+
# requested that is already in use or marked as unusable. Default is
|
79
|
+
# true.
|
80
|
+
# @param [String,Array<String>,Toys::Utils::WrappableString] desc Short
|
81
|
+
# description for the flag. See {Toys::DSL::Tool#desc} for a
|
82
|
+
# description of the allowed formats. Defaults to the empty string.
|
83
|
+
# @param [Array<String,Array<String>,Toys::Utils::WrappableString>] long_desc
|
84
|
+
# Long description for the flag. See {Toys::DSL::Tool#long_desc} for
|
85
|
+
# a description of the allowed formats. (But note that this param
|
86
|
+
# takes an Array of description lines, rather than a series of
|
87
|
+
# arguments.) Defaults to the empty array.
|
88
|
+
# @param [String] display_name A display name for this flag, used in help
|
89
|
+
# text and error messages.
|
90
|
+
# @yieldparam flag_dsl [Toys::DSL::Flag] An object that lets you
|
91
|
+
# configure this flag in a block.
|
92
|
+
# @return [Toys::DSL::Tool] self, for chaining.
|
93
|
+
#
|
94
|
+
def flag(key, *flags,
|
95
|
+
accept: nil, default: nil, handler: nil,
|
96
|
+
report_collisions: true,
|
97
|
+
desc: nil, long_desc: nil, display_name: nil,
|
98
|
+
&block)
|
99
|
+
flag_dsl = DSL::Flag.new(flags, accept, default, handler, report_collisions,
|
100
|
+
@flag_group, desc, long_desc, display_name)
|
101
|
+
flag_dsl.instance_exec(flag_dsl, &block) if block
|
102
|
+
flag_dsl._add_to(@tool_definition, key)
|
103
|
+
DSL::Tool.maybe_add_getter(@tool_dsl, key)
|
104
|
+
self
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
data/lib/toys/dsl/tool.rb
CHANGED
@@ -324,6 +324,174 @@ module Toys
|
|
324
324
|
self
|
325
325
|
end
|
326
326
|
|
327
|
+
##
|
328
|
+
# Create a flag group. If a block is given, flags defined in the block
|
329
|
+
# belong to the group. The flags in the group are listed together in
|
330
|
+
# help screens.
|
331
|
+
#
|
332
|
+
# Example:
|
333
|
+
#
|
334
|
+
# flag_group desc: "Debug Flags" do
|
335
|
+
# flag :debug, "-D", desc: "Enable debugger"
|
336
|
+
# flag :warnings, "-W[VAL]", desc: "Enable warnings"
|
337
|
+
# end
|
338
|
+
#
|
339
|
+
# @param [Symbol] type The type of group. Allowed values: `:required`,
|
340
|
+
# `:optional`, `:exactly_one`, `:at_most_one`, `:at_least_one`.
|
341
|
+
# Default is `:optional`.
|
342
|
+
# @param [String,Array<String>,Toys::Utils::WrappableString] desc Short
|
343
|
+
# description for the group. See {Toys::Definition::Tool#desc=} for a
|
344
|
+
# description of allowed formats. Defaults to `"Flags"`.
|
345
|
+
# @param [Array<String,Array<String>,Toys::Utils::WrappableString>] long_desc
|
346
|
+
# Long description for the flag group. See
|
347
|
+
# {Toys::Definition::Tool#long_desc=} for a description of allowed
|
348
|
+
# formats. Defaults to the empty array.
|
349
|
+
# @param [String,Symbol,nil] name The name of the group, or nil for no
|
350
|
+
# name.
|
351
|
+
# @param [Boolean] report_collisions If `true`, raise an exception if a
|
352
|
+
# the given name is already taken. If `false`, ignore. Default is
|
353
|
+
# `true`.
|
354
|
+
# @param [Boolean] prepend If `true`, prepend rather than append the
|
355
|
+
# group to the list. Default is `false`.
|
356
|
+
# @yieldparam flag_group_dsl [Toys::DSL::FlagGroup] An object that lets
|
357
|
+
# add flags to this group in a block.
|
358
|
+
# @return [Toys::DSL::Tool] self, for chaining.
|
359
|
+
#
|
360
|
+
def flag_group(type: :optional, desc: nil, long_desc: nil, name: nil,
|
361
|
+
report_collisions: true, prepend: false, &block)
|
362
|
+
cur_tool = DSL::Tool.current_tool(self, true)
|
363
|
+
return self if cur_tool.nil?
|
364
|
+
cur_tool.add_flag_group(type: type, desc: desc, long_desc: long_desc, name: name,
|
365
|
+
report_collisions: report_collisions, prepend: prepend)
|
366
|
+
group = prepend ? cur_tool.flag_groups.first : cur_tool.flag_groups.last
|
367
|
+
flag_group_dsl = DSL::FlagGroup.new(self, cur_tool, group)
|
368
|
+
flag_group_dsl.instance_exec(flag_group_dsl, &block) if block
|
369
|
+
self
|
370
|
+
end
|
371
|
+
|
372
|
+
##
|
373
|
+
# Create a flag group of type `:required`. If a block is given, flags
|
374
|
+
# defined in the block belong to the group. All flags in this group are
|
375
|
+
# required.
|
376
|
+
#
|
377
|
+
# Example:
|
378
|
+
#
|
379
|
+
# all_required do
|
380
|
+
# flag :username, "--username=VAL", desc: "Set the username (required)"
|
381
|
+
# flag :password, "--password=VAL", desc: "Set the password (required)"
|
382
|
+
# end
|
383
|
+
#
|
384
|
+
# @param [String,Array<String>,Toys::Utils::WrappableString] desc Short
|
385
|
+
# description for the group. See {Toys::Definition::Tool#desc=} for a
|
386
|
+
# description of allowed formats. Defaults to `"Flags"`.
|
387
|
+
# @param [Array<String,Array<String>,Toys::Utils::WrappableString>] long_desc
|
388
|
+
# Long description for the flag group. See
|
389
|
+
# {Toys::Definition::Tool#long_desc=} for a description of allowed
|
390
|
+
# formats. Defaults to the empty array.
|
391
|
+
# @param [String,Symbol,nil] name The name of the group, or nil for no
|
392
|
+
# name.
|
393
|
+
# @param [Boolean] report_collisions If `true`, raise an exception if a
|
394
|
+
# the given name is already taken. If `false`, ignore. Default is
|
395
|
+
# `true`.
|
396
|
+
# @param [Boolean] prepend If `true`, prepend rather than append the
|
397
|
+
# group to the list. Default is `false`.
|
398
|
+
# @yieldparam flag_group_dsl [Toys::DSL::FlagGroup] An object that lets
|
399
|
+
# add flags to this group in a block.
|
400
|
+
# @return [Toys::DSL::Tool] self, for chaining.
|
401
|
+
#
|
402
|
+
def all_required(desc: nil, long_desc: nil, name: nil, report_collisions: true,
|
403
|
+
prepend: false, &block)
|
404
|
+
flag_group(type: :required, desc: desc, long_desc: long_desc,
|
405
|
+
name: name, report_collisions: report_collisions, prepend: prepend, &block)
|
406
|
+
end
|
407
|
+
|
408
|
+
##
|
409
|
+
# Create a flag group of type `:at_most_one`. If a block is given, flags
|
410
|
+
# defined in the block belong to the group. At most one flag in this
|
411
|
+
# group must be provided on the command line.
|
412
|
+
#
|
413
|
+
# @param [String,Array<String>,Toys::Utils::WrappableString] desc Short
|
414
|
+
# description for the group. See {Toys::Definition::Tool#desc=} for a
|
415
|
+
# description of allowed formats. Defaults to `"Flags"`.
|
416
|
+
# @param [Array<String,Array<String>,Toys::Utils::WrappableString>] long_desc
|
417
|
+
# Long description for the flag group. See
|
418
|
+
# {Toys::Definition::Tool#long_desc=} for a description of allowed
|
419
|
+
# formats. Defaults to the empty array.
|
420
|
+
# @param [String,Symbol,nil] name The name of the group, or nil for no
|
421
|
+
# name.
|
422
|
+
# @param [Boolean] report_collisions If `true`, raise an exception if a
|
423
|
+
# the given name is already taken. If `false`, ignore. Default is
|
424
|
+
# `true`.
|
425
|
+
# @param [Boolean] prepend If `true`, prepend rather than append the
|
426
|
+
# group to the list. Default is `false`.
|
427
|
+
# @yieldparam flag_group_dsl [Toys::DSL::FlagGroup] An object that lets
|
428
|
+
# add flags to this group in a block.
|
429
|
+
# @return [Toys::DSL::Tool] self, for chaining.
|
430
|
+
#
|
431
|
+
def at_most_one_required(desc: nil, long_desc: nil, name: nil, report_collisions: true,
|
432
|
+
prepend: false, &block)
|
433
|
+
flag_group(type: :at_most_one, desc: desc, long_desc: long_desc,
|
434
|
+
name: name, report_collisions: report_collisions, prepend: prepend, &block)
|
435
|
+
end
|
436
|
+
|
437
|
+
##
|
438
|
+
# Create a flag group of type `:at_least_one`. If a block is given, flags
|
439
|
+
# defined in the block belong to the group. At least one flag in this
|
440
|
+
# group must be provided on the command line.
|
441
|
+
#
|
442
|
+
# @param [String,Array<String>,Toys::Utils::WrappableString] desc Short
|
443
|
+
# description for the group. See {Toys::Definition::Tool#desc=} for a
|
444
|
+
# description of allowed formats. Defaults to `"Flags"`.
|
445
|
+
# @param [Array<String,Array<String>,Toys::Utils::WrappableString>] long_desc
|
446
|
+
# Long description for the flag group. See
|
447
|
+
# {Toys::Definition::Tool#long_desc=} for a description of allowed
|
448
|
+
# formats. Defaults to the empty array.
|
449
|
+
# @param [String,Symbol,nil] name The name of the group, or nil for no
|
450
|
+
# name.
|
451
|
+
# @param [Boolean] report_collisions If `true`, raise an exception if a
|
452
|
+
# the given name is already taken. If `false`, ignore. Default is
|
453
|
+
# `true`.
|
454
|
+
# @param [Boolean] prepend If `true`, prepend rather than append the
|
455
|
+
# group to the list. Default is `false`.
|
456
|
+
# @yieldparam flag_group_dsl [Toys::DSL::FlagGroup] An object that lets
|
457
|
+
# add flags to this group in a block.
|
458
|
+
# @return [Toys::DSL::Tool] self, for chaining.
|
459
|
+
#
|
460
|
+
def at_least_one_required(desc: nil, long_desc: nil, name: nil, report_collisions: true,
|
461
|
+
prepend: false, &block)
|
462
|
+
flag_group(type: :at_least_one, desc: desc, long_desc: long_desc,
|
463
|
+
name: name, report_collisions: report_collisions, prepend: prepend, &block)
|
464
|
+
end
|
465
|
+
|
466
|
+
##
|
467
|
+
# Create a flag group of type `:exactly_one`. If a block is given, flags
|
468
|
+
# defined in the block belong to the group. Exactly one flag in this
|
469
|
+
# group must be provided on the command line.
|
470
|
+
#
|
471
|
+
# @param [String,Array<String>,Toys::Utils::WrappableString] desc Short
|
472
|
+
# description for the group. See {Toys::Definition::Tool#desc=} for a
|
473
|
+
# description of allowed formats. Defaults to `"Flags"`.
|
474
|
+
# @param [Array<String,Array<String>,Toys::Utils::WrappableString>] long_desc
|
475
|
+
# Long description for the flag group. See
|
476
|
+
# {Toys::Definition::Tool#long_desc=} for a description of allowed
|
477
|
+
# formats. Defaults to the empty array.
|
478
|
+
# @param [String,Symbol,nil] name The name of the group, or nil for no
|
479
|
+
# name.
|
480
|
+
# @param [Boolean] report_collisions If `true`, raise an exception if a
|
481
|
+
# the given name is already taken. If `false`, ignore. Default is
|
482
|
+
# `true`.
|
483
|
+
# @param [Boolean] prepend If `true`, prepend rather than append the
|
484
|
+
# group to the list. Default is `false`.
|
485
|
+
# @yieldparam flag_group_dsl [Toys::DSL::FlagGroup] An object that lets
|
486
|
+
# add flags to this group in a block.
|
487
|
+
# @return [Toys::DSL::Tool] self, for chaining.
|
488
|
+
#
|
489
|
+
def exactly_one_required(desc: nil, long_desc: nil, name: nil, report_collisions: true,
|
490
|
+
prepend: false, &block)
|
491
|
+
flag_group(type: :exactly_one, desc: desc, long_desc: long_desc,
|
492
|
+
name: name, report_collisions: report_collisions, prepend: prepend, &block)
|
493
|
+
end
|
494
|
+
|
327
495
|
##
|
328
496
|
# Add a flag to the current tool. Each flag must specify a key which
|
329
497
|
# the script may use to obtain the flag value from the context.
|
@@ -356,6 +524,9 @@ module Toys
|
|
356
524
|
# @param [Boolean] report_collisions Raise an exception if a flag is
|
357
525
|
# requested that is already in use or marked as unusable. Default is
|
358
526
|
# true.
|
527
|
+
# @param [Toys::Definition::FlagGroup,String,Symbol,nil] group Group for
|
528
|
+
# this flag. You may provide a group name, a FlagGroup object, or
|
529
|
+
# `nil` which denotes the default group.
|
359
530
|
# @param [String,Array<String>,Toys::Utils::WrappableString] desc Short
|
360
531
|
# description for the flag. See {Toys::DSL::Tool#desc} for a
|
361
532
|
# description of the allowed formats. Defaults to the empty string.
|
@@ -364,19 +535,21 @@ module Toys
|
|
364
535
|
# a description of the allowed formats. (But note that this param
|
365
536
|
# takes an Array of description lines, rather than a series of
|
366
537
|
# arguments.) Defaults to the empty array.
|
538
|
+
# @param [String] display_name A display name for this flag, used in help
|
539
|
+
# text and error messages.
|
367
540
|
# @yieldparam flag_dsl [Toys::DSL::Flag] An object that lets you
|
368
541
|
# configure this flag in a block.
|
369
542
|
# @return [Toys::DSL::Tool] self, for chaining.
|
370
543
|
#
|
371
544
|
def flag(key, *flags,
|
372
545
|
accept: nil, default: nil, handler: nil,
|
373
|
-
report_collisions: true,
|
374
|
-
desc: nil, long_desc: nil,
|
546
|
+
report_collisions: true, group: nil,
|
547
|
+
desc: nil, long_desc: nil, display_name: nil,
|
375
548
|
&block)
|
376
549
|
cur_tool = DSL::Tool.current_tool(self, true)
|
377
550
|
return self if cur_tool.nil?
|
378
|
-
flag_dsl = DSL::Flag.new(flags, accept, default, handler,
|
379
|
-
|
551
|
+
flag_dsl = DSL::Flag.new(flags, accept, default, handler, report_collisions,
|
552
|
+
group, desc, long_desc, display_name)
|
380
553
|
flag_dsl.instance_exec(flag_dsl, &block) if block
|
381
554
|
flag_dsl._add_to(cur_tool, key)
|
382
555
|
DSL::Tool.maybe_add_getter(self, key)
|
data/lib/toys/runner.rb
CHANGED
@@ -88,8 +88,9 @@ module Toys
|
|
88
88
|
end
|
89
89
|
|
90
90
|
def parse_args(args, data)
|
91
|
-
optparse = create_option_parser(data)
|
91
|
+
optparse, seen = create_option_parser(data)
|
92
92
|
remaining = optparse.parse(args)
|
93
|
+
validate_flags(args, seen)
|
93
94
|
remaining = parse_required_args(remaining, args, data)
|
94
95
|
remaining = parse_optional_args(remaining, data)
|
95
96
|
parse_remaining_args(remaining, args, data)
|
@@ -98,6 +99,7 @@ module Toys
|
|
98
99
|
end
|
99
100
|
|
100
101
|
def create_option_parser(data)
|
102
|
+
seen = []
|
101
103
|
optparse = ::OptionParser.new
|
102
104
|
# The following clears out the Officious (hidden default flags).
|
103
105
|
optparse.remove
|
@@ -106,13 +108,21 @@ module Toys
|
|
106
108
|
optparse.new
|
107
109
|
@tool_definition.flag_definitions.each do |flag|
|
108
110
|
optparse.on(*flag.optparser_info) do |val|
|
111
|
+
seen << flag.key
|
109
112
|
data[flag.key] = flag.handler.call(val, data[flag.key])
|
110
113
|
end
|
111
114
|
end
|
112
115
|
@tool_definition.custom_acceptors do |accept|
|
113
116
|
optparse.accept(accept)
|
114
117
|
end
|
115
|
-
optparse
|
118
|
+
[optparse, seen]
|
119
|
+
end
|
120
|
+
|
121
|
+
def validate_flags(args, seen)
|
122
|
+
@tool_definition.flag_groups.each do |group|
|
123
|
+
error = group.validation_error(seen)
|
124
|
+
raise create_parse_error(args, error) if error
|
125
|
+
end
|
116
126
|
end
|
117
127
|
|
118
128
|
def parse_required_args(remaining, args, data)
|
@@ -148,7 +158,7 @@ module Toys
|
|
148
158
|
end
|
149
159
|
|
150
160
|
def create_parse_error(path, reason)
|
151
|
-
OptionParser::ParseError.new(*path).tap do |e|
|
161
|
+
::OptionParser::ParseError.new(*path).tap do |e|
|
152
162
|
e.reason = reason
|
153
163
|
end
|
154
164
|
end
|