toys-core 0.6.1 → 0.7.0
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.
- 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
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9266b9c87907b8844cd20529fd8102391737845d2e85cecc6674d6657a9d0d27
|
4
|
+
data.tar.gz: da4bf58af8136859679ee2d8123e649310af0b82dbe896730af081d4e18c2c5d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 511416609364d830a23c27279ddcd545182cbca9fc0fc2727f832c75d4cfedaab0e4faa2d23456c880d202c4fb18e95239948bfbbdbe46035ccc008d0d84996b
|
7
|
+
data.tar.gz: '075912df93384641e0c7b43807571d8ac4873af0906f022265db1483b66258fea88e7026d0a35c4716a5f96ac237ef9965b53398cdcf31d7254c2b5e2fb85895'
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,11 @@
|
|
1
1
|
# Release History
|
2
2
|
|
3
|
+
### 0.7.0 / 2019-01-23
|
4
|
+
|
5
|
+
* ADDED: Flag groups, which enforce policies around which flags are required.
|
6
|
+
* CHANGED: Flags within a group are sorted in help screens.
|
7
|
+
* CHANGED: Canonical flag within a flag definition is now the first rather than the last.
|
8
|
+
|
3
9
|
### 0.6.1 / 2019-01-07
|
4
10
|
|
5
11
|
* FIXED: The presence of aliases caused subtool listing to crash.
|
data/lib/toys-core.rb
CHANGED
@@ -52,11 +52,6 @@ module Toys
|
|
52
52
|
#
|
53
53
|
module StandardMixins; end
|
54
54
|
|
55
|
-
##
|
56
|
-
# Namespace for standard middleware classes.
|
57
|
-
#
|
58
|
-
module StandardMiddleware; end
|
59
|
-
|
60
55
|
##
|
61
56
|
# Namespace for common utility classes.
|
62
57
|
#
|
@@ -69,10 +64,12 @@ require "toys/definition/acceptor"
|
|
69
64
|
require "toys/definition/alias"
|
70
65
|
require "toys/definition/arg"
|
71
66
|
require "toys/definition/flag"
|
67
|
+
require "toys/definition/flag_group"
|
72
68
|
require "toys/definition/source_info"
|
73
69
|
require "toys/definition/tool"
|
74
70
|
require "toys/dsl/arg"
|
75
71
|
require "toys/dsl/flag"
|
72
|
+
require "toys/dsl/flag_group"
|
76
73
|
require "toys/dsl/tool"
|
77
74
|
require "toys/errors"
|
78
75
|
require "toys/input_file"
|
@@ -80,6 +77,7 @@ require "toys/loader"
|
|
80
77
|
require "toys/middleware"
|
81
78
|
require "toys/mixin"
|
82
79
|
require "toys/runner"
|
80
|
+
require "toys/standard_middleware"
|
83
81
|
require "toys/template"
|
84
82
|
require "toys/tool"
|
85
83
|
require "toys/utils/exec"
|
data/lib/toys/core_version.rb
CHANGED
data/lib/toys/definition/flag.rb
CHANGED
@@ -41,24 +41,24 @@ module Toys
|
|
41
41
|
#
|
42
42
|
def initialize(str)
|
43
43
|
case str
|
44
|
-
when /^(-[\?\w])$/
|
45
|
-
setup(str, [$1], $1, "-", nil, nil, nil, nil)
|
46
|
-
when /^(-[\?\w])( ?)\[(\w+)\]$/
|
47
|
-
setup(str, [$1], $1, "-", :value, :optional, $
|
48
|
-
when /^(-[\?\w])\[( )(\w+)\]$/
|
49
|
-
setup(str, [$1], $1, "-", :value, :optional, $
|
50
|
-
when /^(-[\?\w])( ?)(\w+)$/
|
51
|
-
setup(str, [$1], $1, "-", :value, :required, $
|
44
|
+
when /^(-([\?\w]))$/
|
45
|
+
setup(str, [$1], $1, $2, "-", nil, nil, nil, nil)
|
46
|
+
when /^(-([\?\w]))( ?)\[(\w+)\]$/
|
47
|
+
setup(str, [$1], $1, $2, "-", :value, :optional, $3, $4)
|
48
|
+
when /^(-([\?\w]))\[( )(\w+)\]$/
|
49
|
+
setup(str, [$1], $1, $2, "-", :value, :optional, $3, $4)
|
50
|
+
when /^(-([\?\w]))( ?)(\w+)$/
|
51
|
+
setup(str, [$1], $1, $2, "-", :value, :required, $3, $4)
|
52
52
|
when /^--\[no-\](\w[\?\w-]*)$/
|
53
|
-
setup(str, ["--#{$1}", "--no-#{$1}"], str, "--", :boolean, nil, nil, nil)
|
54
|
-
when /^(
|
55
|
-
setup(str, [$1], $1, "--", nil, nil, nil, nil)
|
56
|
-
when /^(
|
57
|
-
setup(str, [$1], $1, "--", :value, :optional, $
|
58
|
-
when /^(
|
59
|
-
setup(str, [$1], $1, "--", :value, :optional, $
|
60
|
-
when /^(
|
61
|
-
setup(str, [$1], $1, "--", :value, :required, $
|
53
|
+
setup(str, ["--#{$1}", "--no-#{$1}"], str, $1, "--", :boolean, nil, nil, nil)
|
54
|
+
when /^(--(\w[\?\w-]*))$/
|
55
|
+
setup(str, [$1], $1, $2, "--", nil, nil, nil, nil)
|
56
|
+
when /^(--(\w[\?\w-]*))([= ])\[(\w+)\]$/
|
57
|
+
setup(str, [$1], $1, $2, "--", :value, :optional, $3, $4)
|
58
|
+
when /^(--(\w[\?\w-]*))\[([= ])(\w+)\]$/
|
59
|
+
setup(str, [$1], $1, $2, "--", :value, :optional, $3, $4)
|
60
|
+
when /^(--(\w[\?\w-]*))([= ])(\w+)$/
|
61
|
+
setup(str, [$1], $1, $2, "--", :value, :required, $3, $4)
|
62
62
|
else
|
63
63
|
raise ToolDefinitionError, "Illegal flag: #{str.inspect}"
|
64
64
|
end
|
@@ -67,6 +67,7 @@ module Toys
|
|
67
67
|
attr_reader :original_str
|
68
68
|
attr_reader :flags
|
69
69
|
attr_reader :str_without_value
|
70
|
+
attr_reader :sort_str
|
70
71
|
attr_reader :flag_style
|
71
72
|
attr_reader :flag_type
|
72
73
|
attr_reader :value_type
|
@@ -91,11 +92,12 @@ module Toys
|
|
91
92
|
|
92
93
|
private
|
93
94
|
|
94
|
-
def setup(original_str, flags, str_without_value, flag_style, flag_type,
|
95
|
-
value_delim, value_label)
|
95
|
+
def setup(original_str, flags, str_without_value, sort_str, flag_style, flag_type,
|
96
|
+
value_type, value_delim, value_label)
|
96
97
|
@original_str = original_str
|
97
98
|
@flags = flags
|
98
99
|
@str_without_value = str_without_value
|
100
|
+
@sort_str = sort_str
|
99
101
|
@flag_style = flag_style
|
100
102
|
@flag_type = flag_type
|
101
103
|
@value_type = value_type
|
@@ -120,7 +122,9 @@ module Toys
|
|
120
122
|
# Create a Flag definition
|
121
123
|
# @private
|
122
124
|
#
|
123
|
-
def initialize(key, flags, used_flags, report_collisions, accept, handler,
|
125
|
+
def initialize(key, flags, used_flags, report_collisions, accept, handler,
|
126
|
+
default, display_name, group)
|
127
|
+
@group = group
|
124
128
|
@key = key
|
125
129
|
@flag_syntax = flags.map { |s| FlagSyntax.new(s) }
|
126
130
|
@accept = accept
|
@@ -133,8 +137,15 @@ module Toys
|
|
133
137
|
create_default_flag_if_needed(needs_val)
|
134
138
|
remove_used_flags(used_flags, report_collisions)
|
135
139
|
canonicalize(needs_val)
|
140
|
+
summarize(display_name)
|
136
141
|
end
|
137
142
|
|
143
|
+
##
|
144
|
+
# Returns the flag group containing this flag
|
145
|
+
# @return [Toys::Definition::FlagGroup]
|
146
|
+
#
|
147
|
+
attr_reader :group
|
148
|
+
|
138
149
|
##
|
139
150
|
# Returns the key.
|
140
151
|
# @return [Symbol]
|
@@ -205,6 +216,18 @@ module Toys
|
|
205
216
|
#
|
206
217
|
attr_reader :value_delim
|
207
218
|
|
219
|
+
##
|
220
|
+
# Returns the display name of this flag.
|
221
|
+
# @return [String]
|
222
|
+
#
|
223
|
+
attr_reader :display_name
|
224
|
+
|
225
|
+
##
|
226
|
+
# Returns a string that can be used to sort this flag
|
227
|
+
# @return [String]
|
228
|
+
#
|
229
|
+
attr_reader :sort_str
|
230
|
+
|
208
231
|
##
|
209
232
|
# Returns an array of FlagSyntax including only single-dash flags
|
210
233
|
# @return [Array<FlagSyntax>]
|
@@ -302,10 +325,10 @@ module Toys
|
|
302
325
|
@value_type = nil
|
303
326
|
@value_label = needs_val ? "VALUE" : nil
|
304
327
|
@value_delim = " "
|
305
|
-
single_flag_syntax.
|
328
|
+
single_flag_syntax.reverse_each do |flag|
|
306
329
|
analyze_flag_syntax(flag)
|
307
330
|
end
|
308
|
-
double_flag_syntax.
|
331
|
+
double_flag_syntax.reverse_each do |flag|
|
309
332
|
analyze_flag_syntax(flag)
|
310
333
|
end
|
311
334
|
@flag_type ||= :boolean
|
@@ -330,6 +353,18 @@ module Toys
|
|
330
353
|
@value_label = flag.value_label
|
331
354
|
@value_delim = flag.value_delim
|
332
355
|
end
|
356
|
+
|
357
|
+
def summarize(name)
|
358
|
+
@display_name =
|
359
|
+
name ||
|
360
|
+
double_flag_syntax.first&.canonical_str ||
|
361
|
+
single_flag_syntax.first&.canonical_str ||
|
362
|
+
key.to_s
|
363
|
+
@sort_str =
|
364
|
+
double_flag_syntax.first&.sort_str ||
|
365
|
+
single_flag_syntax.first&.sort_str ||
|
366
|
+
""
|
367
|
+
end
|
333
368
|
end
|
334
369
|
end
|
335
370
|
end
|
@@ -0,0 +1,205 @@
|
|
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 Definition
|
34
|
+
##
|
35
|
+
# Representation of a group of flags with the same requirement settings.
|
36
|
+
#
|
37
|
+
class FlagGroup
|
38
|
+
##
|
39
|
+
# Create a flag group.
|
40
|
+
# @private
|
41
|
+
#
|
42
|
+
def initialize(name, desc, long_desc)
|
43
|
+
@name = name
|
44
|
+
@desc = Utils::WrappableString.make(desc || default_desc)
|
45
|
+
@long_desc = Utils::WrappableString.make_array(long_desc || default_long_desc)
|
46
|
+
@flag_definitions = []
|
47
|
+
end
|
48
|
+
|
49
|
+
##
|
50
|
+
# Returns the symbolic name for this group
|
51
|
+
# @return [String,Symbol,nil]
|
52
|
+
#
|
53
|
+
attr_reader :name
|
54
|
+
|
55
|
+
##
|
56
|
+
# Returns the short description string.
|
57
|
+
# @return [Toys::Utils::WrappableString]
|
58
|
+
#
|
59
|
+
attr_reader :desc
|
60
|
+
|
61
|
+
##
|
62
|
+
# Returns the long description strings as an array.
|
63
|
+
# @return [Array<Toys::Utils::WrappableString>]
|
64
|
+
#
|
65
|
+
attr_reader :long_desc
|
66
|
+
|
67
|
+
##
|
68
|
+
# Returns an array of flags that are in this group.
|
69
|
+
# Do not modify the returned array.
|
70
|
+
# @return [Array<Toys::Definition::Flag>]
|
71
|
+
#
|
72
|
+
attr_reader :flag_definitions
|
73
|
+
|
74
|
+
##
|
75
|
+
# Returns true if this group is empty
|
76
|
+
# @return [Boolean]
|
77
|
+
#
|
78
|
+
def empty?
|
79
|
+
flag_definitions.empty?
|
80
|
+
end
|
81
|
+
|
82
|
+
## @private
|
83
|
+
def <<(flag)
|
84
|
+
flag_definitions << flag
|
85
|
+
end
|
86
|
+
|
87
|
+
## @private
|
88
|
+
def default_desc
|
89
|
+
"Flags"
|
90
|
+
end
|
91
|
+
|
92
|
+
## @private
|
93
|
+
def default_long_desc
|
94
|
+
nil
|
95
|
+
end
|
96
|
+
|
97
|
+
## @private
|
98
|
+
def validation_error(_seen)
|
99
|
+
nil
|
100
|
+
end
|
101
|
+
|
102
|
+
##
|
103
|
+
# A FlagGroup containing all required flags
|
104
|
+
#
|
105
|
+
class Required < FlagGroup
|
106
|
+
## @private
|
107
|
+
def validation_error(seen)
|
108
|
+
flag_definitions.each do |flag|
|
109
|
+
unless seen.include?(flag.key)
|
110
|
+
return "Flag \"#{flag.display_name}\" is required"
|
111
|
+
end
|
112
|
+
end
|
113
|
+
nil
|
114
|
+
end
|
115
|
+
|
116
|
+
## @private
|
117
|
+
def default_desc
|
118
|
+
"Required Flags"
|
119
|
+
end
|
120
|
+
|
121
|
+
## @private
|
122
|
+
def default_long_desc
|
123
|
+
"These flags are required."
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
##
|
128
|
+
# A FlagGroup containing all optional flags
|
129
|
+
#
|
130
|
+
class Optional < FlagGroup
|
131
|
+
end
|
132
|
+
|
133
|
+
##
|
134
|
+
# A FlagGroup in which exactly one flag must be set
|
135
|
+
#
|
136
|
+
class ExactlyOne < FlagGroup
|
137
|
+
## @private
|
138
|
+
def validation_error(seen)
|
139
|
+
set_flag = nil
|
140
|
+
flag_definitions.each do |flag|
|
141
|
+
if seen.include?(flag.key)
|
142
|
+
if set_flag
|
143
|
+
return "Exactly one out of group \"#{desc}\" is required, but both" \
|
144
|
+
" \"#{set_flag.display_name}\" and \"#{flag.display_name}\" were set"
|
145
|
+
else
|
146
|
+
set_flag = flag
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
return "Exactly one out of group \"#{desc}\" is required" unless set_flag
|
151
|
+
nil
|
152
|
+
end
|
153
|
+
|
154
|
+
## @private
|
155
|
+
def default_long_desc
|
156
|
+
"Exactly one of these flags must be set."
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
##
|
161
|
+
# A FlagGroup in which at most one flag must be set
|
162
|
+
#
|
163
|
+
class AtMostOne < FlagGroup
|
164
|
+
## @private
|
165
|
+
def validation_error(seen)
|
166
|
+
set_flag = nil
|
167
|
+
flag_definitions.each do |flag|
|
168
|
+
if seen.include?(flag.key)
|
169
|
+
if set_flag
|
170
|
+
return "At most one out of group \"#{desc}\" is required, but both" \
|
171
|
+
" \"#{set_flag.display_name}\" and \"#{flag.display_name}\" were set"
|
172
|
+
else
|
173
|
+
set_flag = flag
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
177
|
+
nil
|
178
|
+
end
|
179
|
+
|
180
|
+
## @private
|
181
|
+
def default_long_desc
|
182
|
+
"At most one of these flags must be set."
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
##
|
187
|
+
# A FlagGroup in which at least one flag must be set
|
188
|
+
#
|
189
|
+
class AtLeastOne < FlagGroup
|
190
|
+
## @private
|
191
|
+
def validation_error(seen)
|
192
|
+
flag_definitions.each do |flag|
|
193
|
+
return nil if seen.include?(flag.key)
|
194
|
+
end
|
195
|
+
"At least one out of group \"#{desc}\" is required"
|
196
|
+
end
|
197
|
+
|
198
|
+
## @private
|
199
|
+
def default_long_desc
|
200
|
+
"At least one of these flags must be set."
|
201
|
+
end
|
202
|
+
end
|
203
|
+
end
|
204
|
+
end
|
205
|
+
end
|
data/lib/toys/definition/tool.rb
CHANGED
@@ -101,6 +101,10 @@ module Toys
|
|
101
101
|
@used_flags = []
|
102
102
|
@initializers = []
|
103
103
|
|
104
|
+
default_flag_group = Definition::FlagGroup.new(nil, nil, nil)
|
105
|
+
@flag_groups = [default_flag_group]
|
106
|
+
@flag_group_names = {nil => default_flag_group}
|
107
|
+
|
104
108
|
@flag_definitions = []
|
105
109
|
@required_arg_definitions = []
|
106
110
|
@optional_arg_definitions = []
|
@@ -142,6 +146,12 @@ module Toys
|
|
142
146
|
#
|
143
147
|
attr_reader :long_desc
|
144
148
|
|
149
|
+
##
|
150
|
+
# Return a list of all defined flag groups, in order.
|
151
|
+
# @return [Array<Toys::Definition::FlagGroup>]
|
152
|
+
#
|
153
|
+
attr_reader :flag_groups
|
154
|
+
|
145
155
|
##
|
146
156
|
# Return a list of all defined flags.
|
147
157
|
# @return [Array<Toys::Definition::Flag>]
|
@@ -491,6 +501,47 @@ module Toys
|
|
491
501
|
self
|
492
502
|
end
|
493
503
|
|
504
|
+
##
|
505
|
+
# Add a flag group to the group list.
|
506
|
+
#
|
507
|
+
# @param [Symbol] type The type of group. Allowed values: `:required`,
|
508
|
+
# `:optional`, `:exactly_one`, `:at_most_one`, `:at_least_one`.
|
509
|
+
# Default is `:optional`.
|
510
|
+
# @param [String,Array<String>,Toys::Utils::WrappableString] desc Short
|
511
|
+
# description for the group. See {Toys::Definition::Tool#desc=} for a
|
512
|
+
# description of allowed formats. Defaults to `"Flags"`.
|
513
|
+
# @param [Array<String,Array<String>,Toys::Utils::WrappableString>] long_desc
|
514
|
+
# Long description for the flag group. See
|
515
|
+
# {Toys::Definition::Tool#long_desc=} for a description of allowed
|
516
|
+
# formats. Defaults to the empty array.
|
517
|
+
# @param [String,Symbol,nil] name The name of the group, or nil for no
|
518
|
+
# name.
|
519
|
+
# @param [Boolean] report_collisions If `true`, raise an exception if a
|
520
|
+
# the given name is already taken. If `false`, ignore. Default is
|
521
|
+
# `true`.
|
522
|
+
# @param [Boolean] prepend If `true`, prepend rather than append the
|
523
|
+
# group to the list. Default is `false`.
|
524
|
+
#
|
525
|
+
def add_flag_group(type: :optional, desc: nil, long_desc: nil,
|
526
|
+
name: nil, report_collisions: true, prepend: false)
|
527
|
+
if !name.nil? && @flag_group_names.key?(name)
|
528
|
+
return self unless report_collisions
|
529
|
+
raise ToolDefinitionError, "Flag group #{name} already exists"
|
530
|
+
end
|
531
|
+
unless type.is_a?(::Class)
|
532
|
+
type = Utils::ModuleLookup.to_module_name(type)
|
533
|
+
type = Definition::FlagGroup.const_get(type)
|
534
|
+
end
|
535
|
+
group = type.new(name, desc, long_desc)
|
536
|
+
@flag_group_names[name] = group unless name.nil?
|
537
|
+
if prepend
|
538
|
+
@flag_groups.unshift(group)
|
539
|
+
else
|
540
|
+
@flag_groups.push(group)
|
541
|
+
end
|
542
|
+
self
|
543
|
+
end
|
544
|
+
|
494
545
|
##
|
495
546
|
# Add a flag to the current tool. Each flag must specify a key which
|
496
547
|
# the script may use to obtain the flag value from the context.
|
@@ -514,6 +565,9 @@ module Toys
|
|
514
565
|
# @param [Boolean] report_collisions Raise an exception if a flag is
|
515
566
|
# requested that is already in use or marked as disabled. Default is
|
516
567
|
# true.
|
568
|
+
# @param [Toys::Definition::FlagGroup,String,Symbol,nil] group Group for
|
569
|
+
# this flag. You may provide a group name, a FlagGroup object, or
|
570
|
+
# `nil` which denotes the default group.
|
517
571
|
# @param [String,Array<String>,Toys::Utils::WrappableString] desc Short
|
518
572
|
# description for the flag. See {Toys::Definition::Tool#desc=} for a
|
519
573
|
# description of allowed formats. Defaults to the empty string.
|
@@ -521,18 +575,28 @@ module Toys
|
|
521
575
|
# Long description for the flag. See
|
522
576
|
# {Toys::Definition::Tool#long_desc=} for a description of allowed
|
523
577
|
# formats. Defaults to the empty array.
|
578
|
+
# @param [String] display_name A display name for this flag, used in help
|
579
|
+
# text and error messages.
|
524
580
|
#
|
525
581
|
def add_flag(key, flags = [],
|
526
582
|
accept: nil, default: nil, handler: nil,
|
527
|
-
report_collisions: true,
|
528
|
-
desc: nil, long_desc: nil)
|
583
|
+
report_collisions: true, group: nil,
|
584
|
+
desc: nil, long_desc: nil, display_name: nil)
|
585
|
+
unless group.is_a?(Definition::FlagGroup)
|
586
|
+
group_name = group
|
587
|
+
group = @flag_group_names[group_name]
|
588
|
+
raise ToolDefinitionError, "No such flag group: #{group_name.inspect}" if group.nil?
|
589
|
+
end
|
529
590
|
check_definition_state(is_arg: true)
|
530
591
|
accept = resolve_acceptor(accept)
|
531
592
|
flag_def = Definition::Flag.new(key, flags, @used_flags, report_collisions,
|
532
|
-
accept, handler, default)
|
593
|
+
accept, handler, default, display_name, group)
|
533
594
|
flag_def.desc = desc if desc
|
534
595
|
flag_def.long_desc = long_desc if long_desc
|
535
|
-
|
596
|
+
if flag_def.active?
|
597
|
+
@flag_definitions << flag_def
|
598
|
+
group << flag_def
|
599
|
+
end
|
536
600
|
@default_data[key] = default
|
537
601
|
self
|
538
602
|
end
|
@@ -732,6 +796,9 @@ module Toys
|
|
732
796
|
end
|
733
797
|
config_proc.call
|
734
798
|
end
|
799
|
+
flag_groups.each do |flag_group|
|
800
|
+
flag_group.flag_definitions.sort_by!(&:sort_str)
|
801
|
+
end
|
735
802
|
@definition_finished = true
|
736
803
|
end
|
737
804
|
self
|