toys-core 0.3.4 → 0.3.5
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/.yardopts +1 -0
- data/CHANGELOG.md +7 -0
- data/README.md +8 -7
- data/docs/getting-started.md +8 -0
- data/lib/toys/cli.rb +2 -1
- data/lib/toys/config_dsl.rb +282 -74
- data/lib/toys/core_version.rb +1 -1
- data/lib/toys/helpers/exec.rb +47 -365
- data/lib/toys/loader.rb +1 -1
- data/lib/toys/middleware/add_verbosity_flags.rb +2 -2
- data/lib/toys/middleware/set_default_descriptions.rb +16 -16
- data/lib/toys/middleware/show_help.rb +35 -11
- data/lib/toys/middleware/show_version.rb +1 -1
- data/lib/toys/template.rb +1 -1
- data/lib/toys/templates/clean.rb +1 -1
- data/lib/toys/templates/gem_build.rb +1 -1
- data/lib/toys/templates/minitest.rb +1 -1
- data/lib/toys/templates/rubocop.rb +1 -1
- data/lib/toys/templates/yardoc.rb +1 -1
- data/lib/toys/tool.rb +110 -235
- data/lib/toys/utils/exec.rb +505 -0
- data/lib/toys/utils/help_text.rb +11 -11
- metadata +7 -4
data/lib/toys/loader.rb
CHANGED
@@ -86,7 +86,7 @@ module Toys
|
|
86
86
|
# handle the command, loading it from the configuration if necessary, and
|
87
87
|
# following aliases.
|
88
88
|
# This always returns a tool. If the specific tool path is not defined and
|
89
|
-
# cannot be found in any configuration, it finds the nearest
|
89
|
+
# cannot be found in any configuration, it finds the nearest namespace that
|
90
90
|
# _would_ contain that tool, up to the root tool.
|
91
91
|
#
|
92
92
|
# Returns a tuple of the found tool, and the array of remaining arguments
|
@@ -88,7 +88,7 @@ module Toys
|
|
88
88
|
DEFAULT_VERBOSE_FLAGS)
|
89
89
|
unless verbose_flags.empty?
|
90
90
|
long_desc = "Increase verbosity, causing additional logging levels to display."
|
91
|
-
tool.add_flag(Context::VERBOSITY,
|
91
|
+
tool.add_flag(Context::VERBOSITY, verbose_flags,
|
92
92
|
desc: "Increase verbosity",
|
93
93
|
long_desc: long_desc,
|
94
94
|
handler: ->(_val, cur) { cur + 1 },
|
@@ -101,7 +101,7 @@ module Toys
|
|
101
101
|
DEFAULT_QUIET_FLAGS)
|
102
102
|
unless quiet_flags.empty?
|
103
103
|
long_desc = "Decrease verbosity, causing fewer logging levels to display."
|
104
|
-
tool.add_flag(Context::VERBOSITY,
|
104
|
+
tool.add_flag(Context::VERBOSITY, quiet_flags,
|
105
105
|
desc: "Decrease verbosity",
|
106
106
|
long_desc: long_desc,
|
107
107
|
handler: ->(_val, cur) { cur - 1 },
|
@@ -34,7 +34,7 @@ module Toys
|
|
34
34
|
##
|
35
35
|
# This middleware sets default description fields for tools that do not
|
36
36
|
# have them set otherwise. You can set separate descriptions for tools,
|
37
|
-
#
|
37
|
+
# namespaces, and the root.
|
38
38
|
#
|
39
39
|
class SetDefaultDescriptions < Base
|
40
40
|
##
|
@@ -44,10 +44,10 @@ module Toys
|
|
44
44
|
DEFAULT_TOOL_DESC = "(No tool description available)".freeze
|
45
45
|
|
46
46
|
##
|
47
|
-
# The default description for
|
47
|
+
# The default description for namespaces.
|
48
48
|
# @return [String]
|
49
49
|
#
|
50
|
-
|
50
|
+
DEFAULT_NAMESPACE_DESC = "(A namespace of tools)".freeze
|
51
51
|
|
52
52
|
##
|
53
53
|
# The default description for the root tool.
|
@@ -92,16 +92,16 @@ module Toys
|
|
92
92
|
# Create a SetDefaultDescriptions middleware given default descriptions.
|
93
93
|
#
|
94
94
|
# @param [String,nil] default_tool_desc The default short description for
|
95
|
-
# tools with an
|
95
|
+
# tools with an script, or `nil` not to set one. Defaults to
|
96
96
|
# {DEFAULT_TOOL_DESC}.
|
97
97
|
# @param [String,nil] default_tool_long_desc The default long description
|
98
|
-
# for tools with an
|
98
|
+
# for tools with an script, or `nil` not to set one. Defaults to
|
99
99
|
# `nil`.
|
100
|
-
# @param [String,nil]
|
101
|
-
# for tools with no
|
102
|
-
# {DEFAULT_TOOL_DESC}.
|
103
|
-
# @param [String,nil]
|
104
|
-
# description for tools with no
|
100
|
+
# @param [String,nil] default_namespace_desc The default short
|
101
|
+
# description for tools with no script, or `nil` not to set one.
|
102
|
+
# Defaults to {DEFAULT_TOOL_DESC}.
|
103
|
+
# @param [String,nil] default_namespace_long_desc The default long
|
104
|
+
# description for tools with no script, or `nil` not to set one.
|
105
105
|
# Defaults to `nil`.
|
106
106
|
# @param [String,nil] default_root_desc The default short description for
|
107
107
|
# the root tool, or `nil` not to set one. Defaults to
|
@@ -134,8 +134,8 @@ module Toys
|
|
134
134
|
#
|
135
135
|
def initialize(default_tool_desc: DEFAULT_TOOL_DESC,
|
136
136
|
default_tool_long_desc: nil,
|
137
|
-
|
138
|
-
|
137
|
+
default_namespace_desc: DEFAULT_NAMESPACE_DESC,
|
138
|
+
default_namespace_long_desc: nil,
|
139
139
|
default_root_desc: DEFAULT_ROOT_DESC,
|
140
140
|
default_root_long_desc: DEFAULT_ROOT_LONG_DESC,
|
141
141
|
default_flag_desc: DEFAULT_FLAG_DESC,
|
@@ -148,8 +148,8 @@ module Toys
|
|
148
148
|
default_remaining_arg_long_desc: nil)
|
149
149
|
@default_tool_desc = default_tool_desc
|
150
150
|
@default_tool_long_desc = default_tool_long_desc
|
151
|
-
@
|
152
|
-
@
|
151
|
+
@default_namespace_desc = default_namespace_desc
|
152
|
+
@default_namespace_long_desc = default_namespace_long_desc
|
153
153
|
@default_root_desc = default_root_desc
|
154
154
|
@default_root_long_desc = default_root_long_desc
|
155
155
|
@default_flag_desc = default_flag_desc
|
@@ -168,10 +168,10 @@ module Toys
|
|
168
168
|
def config(tool, _loader)
|
169
169
|
if tool.root?
|
170
170
|
config_descs(tool, @default_root_desc, @default_root_long_desc)
|
171
|
-
elsif tool.
|
171
|
+
elsif tool.includes_script?
|
172
172
|
config_descs(tool, @default_tool_desc, @default_tool_long_desc)
|
173
173
|
else
|
174
|
-
config_descs(tool, @
|
174
|
+
config_descs(tool, @default_namespace_desc, @default_namespace_long_desc)
|
175
175
|
end
|
176
176
|
tool.flag_definitions.each do |flag|
|
177
177
|
config_descs(flag, @default_flag_desc, @default_flag_long_desc)
|
@@ -30,6 +30,7 @@
|
|
30
30
|
require "highline"
|
31
31
|
|
32
32
|
require "toys/middleware/base"
|
33
|
+
require "toys/utils/exec"
|
33
34
|
require "toys/utils/help_text"
|
34
35
|
require "toys/utils/line_output"
|
35
36
|
|
@@ -38,9 +39,9 @@ module Toys
|
|
38
39
|
##
|
39
40
|
# A middleware that shows help text for the tool when a flag (typically
|
40
41
|
# `--help`) is provided. It can also be configured to show help by
|
41
|
-
# default if the tool is a
|
42
|
+
# default if the tool is a namespace with no script.
|
42
43
|
#
|
43
|
-
# If a tool has no
|
44
|
+
# If a tool has no script, this middleware can also add a
|
44
45
|
# `--[no-]recursive` flag, which, when set to `true` (the default), shows
|
45
46
|
# all subtools recursively rather than only immediate subtools. This
|
46
47
|
# middleware can also search for keywords in its subtools.
|
@@ -102,13 +103,15 @@ module Toys
|
|
102
103
|
# @param [Boolean] default_recursive Whether to search recursively for
|
103
104
|
# subtools by default. Default is `false`.
|
104
105
|
# @param [Boolean] fallback_execution Cause the tool to display its own
|
105
|
-
# help text if it does not otherwise have an
|
106
|
-
#
|
107
|
-
#
|
106
|
+
# help text if it does not otherwise have an script. This is mostly
|
107
|
+
# useful for namespaces, which have children but no script. Default
|
108
|
+
# is `false`.
|
108
109
|
# @param [Boolean] allow_root_args If the root tool includes flags for
|
109
110
|
# help or usage, and doesn't otherwise use positional arguments,
|
110
111
|
# then a tool name can be passed as arguments to display help for
|
111
112
|
# that tool.
|
113
|
+
# @param [Boolean] use_less If the `less` tool is available, and the
|
114
|
+
# output stream is a tty, then use `less` to display help text.
|
112
115
|
# @param [IO] stream Output stream to write to. Default is stdout.
|
113
116
|
# @param [Boolean,nil] styled_output Cause the tool to display help text
|
114
117
|
# with ansi styles. If `nil`, display styles if the output stream is
|
@@ -121,6 +124,7 @@ module Toys
|
|
121
124
|
default_recursive: false,
|
122
125
|
fallback_execution: false,
|
123
126
|
allow_root_args: false,
|
127
|
+
use_less: false,
|
124
128
|
stream: $stdout,
|
125
129
|
styled_output: nil)
|
126
130
|
@help_flags = help_flags
|
@@ -132,6 +136,7 @@ module Toys
|
|
132
136
|
@allow_root_args = allow_root_args
|
133
137
|
@stream = stream
|
134
138
|
@styled_output = styled_output
|
139
|
+
@use_less = use_less
|
135
140
|
end
|
136
141
|
|
137
142
|
##
|
@@ -161,13 +166,13 @@ module Toys
|
|
161
166
|
help_text = get_help_text(context)
|
162
167
|
str = help_text.usage_string(wrap_width: output_cols)
|
163
168
|
output.puts(str)
|
164
|
-
elsif @fallback_execution && !context[Context::TOOL].
|
169
|
+
elsif @fallback_execution && !context[Context::TOOL].includes_script? ||
|
165
170
|
context[:_show_help]
|
166
171
|
help_text = get_help_text(context)
|
167
172
|
str = help_text.help_string(recursive: context[:_recursive_subtools],
|
168
173
|
search: context[:_search_subtools],
|
169
174
|
wrap_width: output_cols)
|
170
|
-
|
175
|
+
output_help(str)
|
171
176
|
else
|
172
177
|
yield
|
173
178
|
end
|
@@ -183,6 +188,25 @@ module Toys
|
|
183
188
|
@output ||= Utils::LineOutput.new(@stream, styled: @styled_output)
|
184
189
|
end
|
185
190
|
|
191
|
+
def output_help(str)
|
192
|
+
if less_path
|
193
|
+
Utils::Exec.new.exec([less_path, "-R"], in_from: str)
|
194
|
+
else
|
195
|
+
output.puts(str)
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
def less_path
|
200
|
+
unless defined? @less_path
|
201
|
+
@less_path =
|
202
|
+
if @use_less && @stream.tty?
|
203
|
+
path = `which less`.strip
|
204
|
+
path.empty? ? nil : path
|
205
|
+
end
|
206
|
+
end
|
207
|
+
@less_path
|
208
|
+
end
|
209
|
+
|
186
210
|
def get_help_text(context)
|
187
211
|
tool_name = context[:_tool_name]
|
188
212
|
return Utils::HelpText.from_context(context) if tool_name.nil? || tool_name.empty?
|
@@ -204,7 +228,7 @@ module Toys
|
|
204
228
|
help_flags = Middleware.resolve_flags_spec(@help_flags, tool,
|
205
229
|
DEFAULT_HELP_FLAGS)
|
206
230
|
unless help_flags.empty?
|
207
|
-
tool.add_flag(:_show_help,
|
231
|
+
tool.add_flag(:_show_help, help_flags,
|
208
232
|
desc: "Display help for this tool", only_unique: true)
|
209
233
|
end
|
210
234
|
help_flags
|
@@ -214,7 +238,7 @@ module Toys
|
|
214
238
|
usage_flags = Middleware.resolve_flags_spec(@usage_flags, tool,
|
215
239
|
DEFAULT_USAGE_FLAGS)
|
216
240
|
unless usage_flags.empty?
|
217
|
-
tool.add_flag(:_show_usage,
|
241
|
+
tool.add_flag(:_show_usage, usage_flags,
|
218
242
|
desc: "Display a brief usage string for this tool", only_unique: true)
|
219
243
|
end
|
220
244
|
usage_flags
|
@@ -224,7 +248,7 @@ module Toys
|
|
224
248
|
recursive_flags = Middleware.resolve_flags_spec(@recursive_flags, tool,
|
225
249
|
DEFAULT_RECURSIVE_FLAGS)
|
226
250
|
unless recursive_flags.empty?
|
227
|
-
tool.add_flag(:_recursive_subtools,
|
251
|
+
tool.add_flag(:_recursive_subtools, recursive_flags,
|
228
252
|
default: @default_recursive,
|
229
253
|
desc: "Show all subtools recursively (default is #{@default_recursive})",
|
230
254
|
only_unique: true)
|
@@ -235,7 +259,7 @@ module Toys
|
|
235
259
|
search_flags = Middleware.resolve_flags_spec(@search_flags, tool,
|
236
260
|
DEFAULT_SEARCH_FLAGS)
|
237
261
|
unless search_flags.empty?
|
238
|
-
tool.add_flag(:_search_subtools,
|
262
|
+
tool.add_flag(:_search_subtools, search_flags,
|
239
263
|
desc: "Search subtools for the given regular expression",
|
240
264
|
only_unique: true)
|
241
265
|
end
|
@@ -80,7 +80,7 @@ module Toys
|
|
80
80
|
def config(tool, _loader)
|
81
81
|
version = @version_displayer.call(tool)
|
82
82
|
if version
|
83
|
-
tool.add_flag(:_show_version,
|
83
|
+
tool.add_flag(:_show_version, @version_flags,
|
84
84
|
desc: "Display the version",
|
85
85
|
handler: ->(_val, _prev) { version },
|
86
86
|
only_unique: true)
|
data/lib/toys/template.rb
CHANGED
data/lib/toys/templates/clean.rb
CHANGED
data/lib/toys/tool.rb
CHANGED
@@ -63,7 +63,7 @@ module Toys
|
|
63
63
|
|
64
64
|
@helpers = {}
|
65
65
|
@modules = []
|
66
|
-
@
|
66
|
+
@script = nil
|
67
67
|
end
|
68
68
|
|
69
69
|
##
|
@@ -129,10 +129,10 @@ module Toys
|
|
129
129
|
attr_reader :helpers
|
130
130
|
|
131
131
|
##
|
132
|
-
# Return the
|
132
|
+
# Return the script block, or `nil` if not present.
|
133
133
|
# @return [Proc,nil]
|
134
134
|
#
|
135
|
-
attr_reader :
|
135
|
+
attr_reader :script
|
136
136
|
|
137
137
|
##
|
138
138
|
# Returns the middleware stack
|
@@ -172,11 +172,11 @@ module Toys
|
|
172
172
|
end
|
173
173
|
|
174
174
|
##
|
175
|
-
# Returns true if this tool has an
|
175
|
+
# Returns true if this tool has an script defined.
|
176
176
|
# @return [Boolean]
|
177
177
|
#
|
178
|
-
def
|
179
|
-
|
178
|
+
def includes_script?
|
179
|
+
script.is_a?(::Proc)
|
180
180
|
end
|
181
181
|
|
182
182
|
##
|
@@ -212,7 +212,7 @@ module Toys
|
|
212
212
|
# @return [Boolean]
|
213
213
|
#
|
214
214
|
def includes_definition?
|
215
|
-
includes_arguments? ||
|
215
|
+
includes_arguments? || includes_script? || includes_helpers?
|
216
216
|
end
|
217
217
|
|
218
218
|
##
|
@@ -342,22 +342,22 @@ module Toys
|
|
342
342
|
|
343
343
|
##
|
344
344
|
# Add a flag to the current tool. Each flag must specify a key which
|
345
|
-
# the
|
345
|
+
# the script may use to obtain the flag value from the context.
|
346
346
|
# You may then provide the flags themselves in `OptionParser` form.
|
347
347
|
#
|
348
348
|
# @param [Symbol] key The key to use to retrieve the value from the
|
349
349
|
# execution context.
|
350
|
-
# @param [String
|
350
|
+
# @param [Array<String>] flags The flags in OptionParser format.
|
351
351
|
# @param [Object,nil] accept An OptionParser acceptor. Optional.
|
352
352
|
# @param [Object] default The default value. This is the value that will
|
353
353
|
# be set in the context if this flag is not provided on the command
|
354
354
|
# line. Defaults to `nil`.
|
355
|
-
# @param [String,Toys::Utils::WrappableString
|
356
|
-
#
|
357
|
-
#
|
358
|
-
# @param [String,Toys::Utils::WrappableString
|
359
|
-
#
|
360
|
-
# description
|
355
|
+
# @param [String,Array<String>,Toys::Utils::WrappableString] desc Short
|
356
|
+
# description for the flag. See {Toys::Tool#desc=} for a description of
|
357
|
+
# allowed formats. Defaults to the empty string.
|
358
|
+
# @param [Array<String,Array<String>,Toys::Utils::WrappableString>] long_desc
|
359
|
+
# Long description for the flag. See {Toys::Tool#long_desc=} for a
|
360
|
+
# description of allowed formats. Defaults to the empty array.
|
361
361
|
# @param [Boolean] only_unique If true, any flags that are already
|
362
362
|
# defined in this tool are removed from this flag. For example, if
|
363
363
|
# an earlier flag uses `-a`, and this flag wants to use both
|
@@ -369,27 +369,20 @@ module Toys
|
|
369
369
|
# should be set. The default handler simply replaces the previous
|
370
370
|
# value. i.e. the default is effectively `-> (val, _prev) { val }`.
|
371
371
|
#
|
372
|
-
def add_flag(key,
|
373
|
-
accept: nil, default: nil, desc: nil, long_desc: nil,
|
374
|
-
only_unique: false
|
372
|
+
def add_flag(key, flags = [],
|
373
|
+
accept: nil, default: nil, handler: nil, desc: nil, long_desc: nil,
|
374
|
+
only_unique: false)
|
375
375
|
check_definition_state
|
376
|
-
flag_def = FlagDefinition.new(
|
377
|
-
flag_def.add_flags(flags)
|
378
|
-
flag_def.accept = accept
|
379
|
-
flag_def.handler = handler
|
380
|
-
flag_def.default = default
|
381
|
-
flag_def.desc = desc unless desc.nil?
|
382
|
-
flag_def.long_desc = long_desc unless long_desc.nil?
|
383
|
-
yield flag_def if block_given?
|
384
|
-
flag_def.create_default_flag_if_needed
|
376
|
+
flag_def = FlagDefinition.new(key, flags, accept, handler, desc, long_desc, default)
|
385
377
|
flag_def.remove_flags(used_flags) if only_unique
|
386
378
|
@flag_definitions << flag_def if flag_def.active?
|
379
|
+
@default_data[key] = default
|
387
380
|
self
|
388
381
|
end
|
389
382
|
|
390
383
|
##
|
391
384
|
# Add a required positional argument to the current tool. You must specify
|
392
|
-
# a key which the
|
385
|
+
# a key which the script may use to obtain the argument value from the
|
393
386
|
# context.
|
394
387
|
#
|
395
388
|
# @param [Symbol] key The key to use to retrieve the value from the
|
@@ -397,29 +390,23 @@ module Toys
|
|
397
390
|
# @param [Object,nil] accept An OptionParser acceptor. Optional.
|
398
391
|
# @param [String] display_name A name to use for display (in help text and
|
399
392
|
# error reports). Defaults to the key in upper case.
|
400
|
-
# @param [String,Toys::Utils::WrappableString
|
401
|
-
#
|
402
|
-
#
|
403
|
-
# @param [String,Toys::Utils::WrappableString
|
404
|
-
#
|
405
|
-
# description
|
393
|
+
# @param [String,Array<String>,Toys::Utils::WrappableString] desc Short
|
394
|
+
# description for the flag. See {Toys::Tool#desc=} for a description of
|
395
|
+
# allowed formats. Defaults to the empty string.
|
396
|
+
# @param [Array<String,Array<String>,Toys::Utils::WrappableString>] long_desc
|
397
|
+
# Long description for the flag. See {Toys::Tool#long_desc=} for a
|
398
|
+
# description of allowed formats. Defaults to the empty array.
|
406
399
|
#
|
407
400
|
def add_required_arg(key, accept: nil, display_name: nil, desc: nil, long_desc: nil)
|
408
401
|
check_definition_state
|
409
|
-
arg_def = ArgDefinition.new(
|
410
|
-
arg_def.accept = accept
|
411
|
-
arg_def.default = nil
|
412
|
-
arg_def.display_name = display_name unless display_name.nil?
|
413
|
-
arg_def.desc = desc unless desc.nil?
|
414
|
-
arg_def.long_desc = long_desc unless long_desc.nil?
|
415
|
-
yield arg_def if block_given?
|
402
|
+
arg_def = ArgDefinition.new(key, :required, accept, desc, long_desc, display_name)
|
416
403
|
@required_arg_definitions << arg_def
|
417
404
|
self
|
418
405
|
end
|
419
406
|
|
420
407
|
##
|
421
408
|
# Add an optional positional argument to the current tool. You must specify
|
422
|
-
# a key which the
|
409
|
+
# a key which the script may use to obtain the argument value from the
|
423
410
|
# context. If an optional argument is not given on the command line, the
|
424
411
|
# value is set to the given default.
|
425
412
|
#
|
@@ -431,30 +418,25 @@ module Toys
|
|
431
418
|
# @param [Object,nil] accept An OptionParser acceptor. Optional.
|
432
419
|
# @param [String] display_name A name to use for display (in help text and
|
433
420
|
# error reports). Defaults to the key in upper case.
|
434
|
-
# @param [String,Toys::Utils::WrappableString
|
435
|
-
#
|
436
|
-
#
|
437
|
-
# @param [String,Toys::Utils::WrappableString
|
438
|
-
#
|
439
|
-
# description
|
421
|
+
# @param [String,Array<String>,Toys::Utils::WrappableString] desc Short
|
422
|
+
# description for the flag. See {Toys::Tool#desc=} for a description of
|
423
|
+
# allowed formats. Defaults to the empty string.
|
424
|
+
# @param [Array<String,Array<String>,Toys::Utils::WrappableString>] long_desc
|
425
|
+
# Long description for the flag. See {Toys::Tool#long_desc=} for a
|
426
|
+
# description of allowed formats. Defaults to the empty array.
|
440
427
|
#
|
441
428
|
def add_optional_arg(key, default: nil, accept: nil, display_name: nil,
|
442
429
|
desc: nil, long_desc: nil)
|
443
430
|
check_definition_state
|
444
|
-
arg_def = ArgDefinition.new(
|
445
|
-
arg_def.accept = accept
|
446
|
-
arg_def.default = default
|
447
|
-
arg_def.display_name = display_name unless display_name.nil?
|
448
|
-
arg_def.desc = desc unless desc.nil?
|
449
|
-
arg_def.long_desc = long_desc unless long_desc.nil?
|
450
|
-
yield arg_def if block_given?
|
431
|
+
arg_def = ArgDefinition.new(key, :optional, accept, desc, long_desc, display_name)
|
451
432
|
@optional_arg_definitions << arg_def
|
433
|
+
@default_data[key] = default
|
452
434
|
self
|
453
435
|
end
|
454
436
|
|
455
437
|
##
|
456
438
|
# Specify what should be done with unmatched positional arguments. You must
|
457
|
-
# specify a key which the
|
439
|
+
# specify a key which the script may use to obtain the remaining args
|
458
440
|
# from the context.
|
459
441
|
#
|
460
442
|
# @param [Symbol] key The key to use to retrieve the value from the
|
@@ -465,36 +447,31 @@ module Toys
|
|
465
447
|
# @param [Object,nil] accept An OptionParser acceptor. Optional.
|
466
448
|
# @param [String] display_name A name to use for display (in help text and
|
467
449
|
# error reports). Defaults to the key in upper case.
|
468
|
-
# @param [String,Toys::Utils::WrappableString
|
469
|
-
#
|
470
|
-
#
|
471
|
-
# @param [String,Toys::Utils::WrappableString
|
472
|
-
#
|
473
|
-
# description
|
450
|
+
# @param [String,Array<String>,Toys::Utils::WrappableString] desc Short
|
451
|
+
# description for the flag. See {Toys::Tool#desc=} for a description of
|
452
|
+
# allowed formats. Defaults to the empty string.
|
453
|
+
# @param [Array<String,Array<String>,Toys::Utils::WrappableString>] long_desc
|
454
|
+
# Long description for the flag. See {Toys::Tool#long_desc=} for a
|
455
|
+
# description of allowed formats. Defaults to the empty array.
|
474
456
|
#
|
475
457
|
def set_remaining_args(key, default: [], accept: nil, display_name: nil,
|
476
458
|
desc: nil, long_desc: nil)
|
477
459
|
check_definition_state
|
478
|
-
arg_def = ArgDefinition.new(
|
479
|
-
arg_def.accept = accept
|
480
|
-
arg_def.default = default
|
481
|
-
arg_def.display_name = display_name unless display_name.nil?
|
482
|
-
arg_def.desc = desc unless desc.nil?
|
483
|
-
arg_def.long_desc = long_desc unless long_desc.nil?
|
484
|
-
yield arg_def if block_given?
|
460
|
+
arg_def = ArgDefinition.new(key, :remaining, accept, desc, long_desc, display_name)
|
485
461
|
@remaining_args_definition = arg_def
|
462
|
+
@default_data[key] = default
|
486
463
|
self
|
487
464
|
end
|
488
465
|
|
489
466
|
##
|
490
|
-
# Set the
|
467
|
+
# Set the script for this tool. This is a proc that will be called,
|
491
468
|
# with `self` set to a {Toys::Context}.
|
492
469
|
#
|
493
|
-
# @param [Proc]
|
470
|
+
# @param [Proc] script The script for this tool.
|
494
471
|
#
|
495
|
-
def
|
472
|
+
def script=(script)
|
496
473
|
check_definition_state
|
497
|
-
@
|
474
|
+
@script = script
|
498
475
|
end
|
499
476
|
|
500
477
|
##
|
@@ -591,14 +568,16 @@ module Toys
|
|
591
568
|
#
|
592
569
|
# @param [Symbol] key This flag will set the given context key.
|
593
570
|
#
|
594
|
-
def initialize(
|
595
|
-
@tool = tool
|
571
|
+
def initialize(key, flags, accept, handler, desc, long_desc, default)
|
596
572
|
@key = key
|
597
|
-
@flag_syntax =
|
598
|
-
@accept =
|
599
|
-
@handler = DEFAULT_HANDLER
|
600
|
-
@desc =
|
601
|
-
@long_desc =
|
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
|
602
581
|
reset_data
|
603
582
|
end
|
604
583
|
|
@@ -638,87 +617,6 @@ module Toys
|
|
638
617
|
#
|
639
618
|
attr_reader :handler
|
640
619
|
|
641
|
-
##
|
642
|
-
# Adds the given flags.
|
643
|
-
# @param [Array<String>] flags Flags in OptionParser format
|
644
|
-
#
|
645
|
-
def add_flags(flags)
|
646
|
-
@flag_syntax.concat(flags.map { |s| FlagSyntax.new(s) })
|
647
|
-
reset_data
|
648
|
-
self
|
649
|
-
end
|
650
|
-
|
651
|
-
##
|
652
|
-
# Set the acceptor.
|
653
|
-
# @param [Object] accept Acceptor. May be `nil` for the default.
|
654
|
-
#
|
655
|
-
def accept=(accept)
|
656
|
-
@accept = accept
|
657
|
-
reset_data
|
658
|
-
end
|
659
|
-
|
660
|
-
##
|
661
|
-
# Set the default.
|
662
|
-
# @param [Object] default The default value.
|
663
|
-
#
|
664
|
-
def default=(default)
|
665
|
-
@tool.default_data[@key] = default
|
666
|
-
end
|
667
|
-
|
668
|
-
##
|
669
|
-
# Set the handler for setting/updating the value.
|
670
|
-
# @param [Proc,nil] handler The handler for setting/updating the value.
|
671
|
-
# The handler should take two arguments, the new given value and the
|
672
|
-
# previous value, and it should return the new value that should be
|
673
|
-
# set. If `nil`, uses {DEFAULT_HANDLER}.
|
674
|
-
#
|
675
|
-
def handler=(handler)
|
676
|
-
@handler = handler || DEFAULT_HANDLER
|
677
|
-
end
|
678
|
-
|
679
|
-
##
|
680
|
-
# Set the short description string.
|
681
|
-
#
|
682
|
-
# The description may be provided as a {Toys::Utils::WrappableString}, a
|
683
|
-
# single string (which will be wrapped), or an array of strings, which
|
684
|
-
# will be interpreted as string fragments that will be concatenated and
|
685
|
-
# wrapped.
|
686
|
-
#
|
687
|
-
# @param [Toys::Utils::WrappableString,String,Array<String>] desc
|
688
|
-
#
|
689
|
-
def desc=(desc)
|
690
|
-
@desc = Tool.canonicalize_desc(desc)
|
691
|
-
end
|
692
|
-
|
693
|
-
##
|
694
|
-
# Set the long description strings.
|
695
|
-
#
|
696
|
-
# Each string may be provided as a {Toys::Utils::WrappableString}, a
|
697
|
-
# single string (which will be wrapped), or an array of strings, which
|
698
|
-
# will be interpreted as string fragments that will be concatenated and
|
699
|
-
# wrapped.
|
700
|
-
#
|
701
|
-
# @param [Array<Toys::Utils::WrappableString,String,Array<String>>] descs
|
702
|
-
#
|
703
|
-
def long_desc=(descs)
|
704
|
-
@long_desc = Tool.canonicalize_long_desc(descs)
|
705
|
-
end
|
706
|
-
|
707
|
-
##
|
708
|
-
# Set the long description strings.
|
709
|
-
#
|
710
|
-
# Each string may be provided as a {Toys::Utils::WrappableString}, a
|
711
|
-
# single string (which will be wrapped), or an array of strings, which
|
712
|
-
# will be interpreted as string fragments that will be concatenated and
|
713
|
-
# wrapped.
|
714
|
-
#
|
715
|
-
# @param [Toys::Utils::WrappableString,String,Array<String>...] descs
|
716
|
-
#
|
717
|
-
def populate_long_desc(*descs)
|
718
|
-
@long_desc = Tool.canonicalize_long_desc(descs)
|
719
|
-
self
|
720
|
-
end
|
721
|
-
|
722
620
|
##
|
723
621
|
# Returns an array of FlagSyntax including only single-dash flags
|
724
622
|
# @return [Array<FlagSyntax>]
|
@@ -785,6 +683,22 @@ module Toys
|
|
785
683
|
@value_delim
|
786
684
|
end
|
787
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
|
+
|
788
702
|
## @private
|
789
703
|
def remove_flags(flags)
|
790
704
|
flags = flags.map { |f| FlagSyntax.new(f).flags }.flatten
|
@@ -792,18 +706,6 @@ module Toys
|
|
792
706
|
ss.flags.all? { |s| !flags.include?(s) }
|
793
707
|
end
|
794
708
|
reset_data
|
795
|
-
self
|
796
|
-
end
|
797
|
-
|
798
|
-
## @private
|
799
|
-
def create_default_flag_if_needed
|
800
|
-
return unless @flag_syntax.empty?
|
801
|
-
canonical_flag = key.to_s.downcase.tr("_", "-").gsub(/[^a-z0-9-]/, "").sub(/^-+/, "")
|
802
|
-
unless canonical_flag.empty?
|
803
|
-
flag = @accept ? "--#{canonical_flag}=VALUE" : "--#{canonical_flag}"
|
804
|
-
@flag_syntax << FlagSyntax.new(flag)
|
805
|
-
end
|
806
|
-
reset_data
|
807
709
|
end
|
808
710
|
|
809
711
|
private
|
@@ -817,10 +719,19 @@ module Toys
|
|
817
719
|
@value_delim = nil
|
818
720
|
end
|
819
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
|
+
|
820
731
|
def find_canonical_value_label
|
821
732
|
return if @value_delim
|
822
|
-
@value_label = @
|
823
|
-
@value_delim = @
|
733
|
+
@value_label = @needs_val ? "VALUE" : nil
|
734
|
+
@value_delim = @needs_val ? " " : ""
|
824
735
|
single_flag_syntax.each do |ss|
|
825
736
|
next unless ss.value_label
|
826
737
|
@value_label = ss.value_label
|
@@ -845,14 +756,13 @@ module Toys
|
|
845
756
|
# @param [Symbol] key This argument will set the given context key.
|
846
757
|
# @param [:required,:optional,:remaining] type Type of this argument
|
847
758
|
#
|
848
|
-
def initialize(
|
849
|
-
@tool = tool
|
759
|
+
def initialize(key, type, accept, desc, long_desc, display_name)
|
850
760
|
@key = key
|
851
761
|
@type = type
|
852
|
-
@accept =
|
853
|
-
@desc =
|
854
|
-
@long_desc =
|
855
|
-
@display_name = key.to_s.tr("-", "_").gsub(/\W/, "").upcase
|
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
|
856
766
|
end
|
857
767
|
|
858
768
|
##
|
@@ -891,57 +801,6 @@ module Toys
|
|
891
801
|
#
|
892
802
|
attr_accessor :display_name
|
893
803
|
|
894
|
-
##
|
895
|
-
# Set the default.
|
896
|
-
# @param [Object] default The default value.
|
897
|
-
#
|
898
|
-
def default=(default)
|
899
|
-
@tool.default_data[@key] = default
|
900
|
-
end
|
901
|
-
|
902
|
-
##
|
903
|
-
# Set the short description string.
|
904
|
-
#
|
905
|
-
# The description may be provided as a {Toys::Utils::WrappableString}, a
|
906
|
-
# single string (which will be wrapped), or an array of strings, which
|
907
|
-
# will be interpreted as string fragments that will be concatenated and
|
908
|
-
# wrapped.
|
909
|
-
#
|
910
|
-
# @param [Toys::Utils::WrappableString,String,Array<String>] desc
|
911
|
-
#
|
912
|
-
def desc=(desc)
|
913
|
-
@desc = Tool.canonicalize_desc(desc)
|
914
|
-
end
|
915
|
-
|
916
|
-
##
|
917
|
-
# Set the long description strings.
|
918
|
-
#
|
919
|
-
# Each string may be provided as a {Toys::Utils::WrappableString}, a
|
920
|
-
# single string (which will be wrapped), or an array of strings, which
|
921
|
-
# will be interpreted as string fragments that will be concatenated and
|
922
|
-
# wrapped.
|
923
|
-
#
|
924
|
-
# @param [Array<Toys::Utils::WrappableString,String,Array<String>>] descs
|
925
|
-
#
|
926
|
-
def long_desc=(descs)
|
927
|
-
@long_desc = Tool.canonicalize_long_desc(descs)
|
928
|
-
end
|
929
|
-
|
930
|
-
##
|
931
|
-
# Set the long description strings.
|
932
|
-
#
|
933
|
-
# Each string may be provided as a {Toys::Utils::WrappableString}, a
|
934
|
-
# single string (which will be wrapped), or an array of strings, which
|
935
|
-
# will be interpreted as string fragments that will be concatenated and
|
936
|
-
# wrapped.
|
937
|
-
#
|
938
|
-
# @param [Toys::Utils::WrappableString,String,Array<String>...] descs
|
939
|
-
#
|
940
|
-
def populate_long_desc(*descs)
|
941
|
-
@long_desc = Tool.canonicalize_long_desc(descs)
|
942
|
-
self
|
943
|
-
end
|
944
|
-
|
945
804
|
##
|
946
805
|
# Process the given value through the acceptor.
|
947
806
|
# May raise an exception if the acceptor rejected the input.
|
@@ -957,6 +816,22 @@ module Toys
|
|
957
816
|
optparse.parse(["--abc", input])
|
958
817
|
result
|
959
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
|
960
835
|
end
|
961
836
|
|
962
837
|
private
|
@@ -1061,7 +936,7 @@ module Toys
|
|
1061
936
|
def parse_remaining_args(remaining, args)
|
1062
937
|
return if remaining.empty?
|
1063
938
|
unless @tool.remaining_args_definition
|
1064
|
-
if @tool.
|
939
|
+
if @tool.includes_script?
|
1065
940
|
raise create_parse_error(remaining, "Extra arguments provided")
|
1066
941
|
else
|
1067
942
|
raise create_parse_error(@tool.full_name + args, "Tool not found")
|
@@ -1089,8 +964,8 @@ module Toys
|
|
1089
964
|
|
1090
965
|
def perform_execution(context)
|
1091
966
|
executor = proc do
|
1092
|
-
if @tool.
|
1093
|
-
context.instance_eval(&@tool.
|
967
|
+
if @tool.includes_script?
|
968
|
+
context.instance_eval(&@tool.script)
|
1094
969
|
else
|
1095
970
|
context.logger.fatal("No implementation for tool #{@tool.display_name.inspect}")
|
1096
971
|
context.exit(-1)
|