toys-core 0.3.3 → 0.3.4
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 +23 -1
- data/lib/toys-core.rb +2 -0
- data/lib/toys/cli.rb +108 -15
- data/lib/toys/config_dsl.rb +101 -55
- data/lib/toys/context.rb +3 -3
- data/lib/toys/core_version.rb +1 -1
- data/lib/toys/errors.rb +76 -0
- data/lib/toys/helpers/highline.rb +0 -2
- data/lib/toys/helpers/spinner.rb +17 -11
- data/lib/toys/loader.rb +43 -18
- data/lib/toys/middleware.rb +14 -14
- data/lib/toys/middleware/add_verbosity_flags.rb +113 -0
- data/lib/toys/middleware/base.rb +1 -1
- data/lib/toys/middleware/handle_usage_errors.rb +15 -9
- data/lib/toys/middleware/set_default_descriptions.rb +114 -37
- data/lib/toys/middleware/show_help.rb +245 -0
- data/lib/toys/middleware/show_version.rb +20 -16
- data/lib/toys/templates/clean.rb +4 -1
- data/lib/toys/templates/gem_build.rb +3 -1
- data/lib/toys/templates/minitest.rb +5 -6
- data/lib/toys/tool.rb +418 -213
- data/lib/toys/utils/help_text.rb +487 -0
- data/lib/toys/utils/line_output.rb +105 -0
- data/lib/toys/utils/wrappable_string.rb +67 -19
- metadata +6 -5
- data/lib/toys/middleware/add_verbosity_switches.rb +0 -99
- data/lib/toys/middleware/show_usage.rb +0 -174
- data/lib/toys/utils/usage.rb +0 -250
@@ -28,20 +28,21 @@
|
|
28
28
|
;
|
29
29
|
|
30
30
|
require "toys/middleware/base"
|
31
|
+
require "toys/utils/line_output"
|
31
32
|
|
32
33
|
module Toys
|
33
34
|
module Middleware
|
34
35
|
##
|
35
36
|
# A middleware that displays a version string for certain tools if the
|
36
|
-
# `--version`
|
37
|
-
# this
|
37
|
+
# `--version` flag is given. You can specify which tools respond to
|
38
|
+
# this flag, and the string that will be displayed.
|
38
39
|
#
|
39
40
|
class ShowVersion < Base
|
40
41
|
##
|
41
|
-
# Default version
|
42
|
+
# Default version flags
|
42
43
|
# @return [Array<String>]
|
43
44
|
#
|
44
|
-
|
45
|
+
DEFAULT_VERSION_FLAGS = ["--version"].freeze
|
45
46
|
|
46
47
|
##
|
47
48
|
# Return a simple version displayer that returns the given string for
|
@@ -58,28 +59,31 @@ module Toys
|
|
58
59
|
#
|
59
60
|
# @param [Proc] version_displayer A proc that takes a tool and returns
|
60
61
|
# either the version string that should be displayed, or a falsy
|
61
|
-
# value to indicate the tool should not have a `--version`
|
62
|
+
# value to indicate the tool should not have a `--version` flag.
|
62
63
|
# Defaults to a "null" displayer that returns false for all tools.
|
63
|
-
# @param [Array<String>]
|
64
|
+
# @param [Array<String>] version_flags A list of flags that should
|
64
65
|
# trigger displaying the version. Default is
|
65
|
-
# {
|
66
|
+
# {DEFAULT_VERSION_FLAGS}.
|
67
|
+
# @param [IO] stream Output stream to write to. Default is stdout.
|
66
68
|
#
|
67
69
|
def initialize(version_displayer: nil,
|
68
|
-
|
70
|
+
version_flags: DEFAULT_VERSION_FLAGS,
|
71
|
+
stream: $stdout)
|
69
72
|
@version_displayer = version_displayer || proc { |_| false }
|
70
|
-
@
|
73
|
+
@version_flags = version_flags
|
74
|
+
@output = Utils::LineOutput.new(stream)
|
71
75
|
end
|
72
76
|
|
73
77
|
##
|
74
|
-
# Adds the version
|
78
|
+
# Adds the version flag if requested.
|
75
79
|
#
|
76
|
-
def config(tool)
|
80
|
+
def config(tool, _loader)
|
77
81
|
version = @version_displayer.call(tool)
|
78
82
|
if version
|
79
|
-
tool.
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
+
tool.add_flag(:_show_version, *@version_flags,
|
84
|
+
desc: "Display the version",
|
85
|
+
handler: ->(_val, _prev) { version },
|
86
|
+
only_unique: true)
|
83
87
|
end
|
84
88
|
yield
|
85
89
|
end
|
@@ -89,7 +93,7 @@ module Toys
|
|
89
93
|
#
|
90
94
|
def execute(context)
|
91
95
|
if context[:_show_version]
|
92
|
-
puts context[:_show_version]
|
96
|
+
@output.puts context[:_show_version]
|
93
97
|
else
|
94
98
|
yield
|
95
99
|
end
|
data/lib/toys/templates/clean.rb
CHANGED
@@ -88,6 +88,8 @@ module Toys
|
|
88
88
|
tool(template.name) do
|
89
89
|
desc "#{task_type} the gem: #{template.gem_name}"
|
90
90
|
|
91
|
+
flag :yes, "-y", "--yes", desc: "Do not ask for interactive confirmation"
|
92
|
+
|
91
93
|
use :exec
|
92
94
|
use :fileutils
|
93
95
|
use :highline
|
@@ -105,7 +107,7 @@ module Toys
|
|
105
107
|
logger.error "Cannot push the gem when there are uncommited changes"
|
106
108
|
exit(1)
|
107
109
|
end
|
108
|
-
exit(1) unless agree("Release #{gemfile}? (y/n) ")
|
110
|
+
exit(1) unless options[:yes] || agree("Release #{gemfile}? (y/n) ")
|
109
111
|
sh "gem push pkg/#{gemfile}"
|
110
112
|
if template.tag
|
111
113
|
sh "git tag v#{version}"
|
@@ -86,12 +86,11 @@ module Toys
|
|
86
86
|
|
87
87
|
use :exec
|
88
88
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
)
|
94
|
-
remaining_args(:tests, docs: "Paths to the tests to run (defaults to all tests)")
|
89
|
+
flag :warnings, "-w", "--[no-]warnings",
|
90
|
+
default: template.warnings,
|
91
|
+
desc: "Turn on Ruby warnings (defaults to #{template.warnings})"
|
92
|
+
|
93
|
+
remaining_args :tests, desc: "Paths to the tests to run (defaults to all tests)"
|
95
94
|
|
96
95
|
execute do
|
97
96
|
ruby_args = []
|
data/lib/toys/tool.rb
CHANGED
@@ -35,7 +35,7 @@ module Toys
|
|
35
35
|
##
|
36
36
|
# A Tool is a single command that can be invoked using Toys.
|
37
37
|
# It has a name, a series of one or more words that you use to identify
|
38
|
-
# the tool on the command line. It also has a set of formal
|
38
|
+
# the tool on the command line. It also has a set of formal flags and
|
39
39
|
# command line arguments supported, and a block that gets run when the
|
40
40
|
# tool is executed.
|
41
41
|
#
|
@@ -52,11 +52,11 @@ module Toys
|
|
52
52
|
@definition_path = nil
|
53
53
|
@definition_finished = false
|
54
54
|
|
55
|
-
@desc =
|
55
|
+
@desc = Toys::Utils::WrappableString.new("")
|
56
56
|
@long_desc = []
|
57
57
|
|
58
58
|
@default_data = {}
|
59
|
-
@
|
59
|
+
@flag_definitions = []
|
60
60
|
@required_arg_definitions = []
|
61
61
|
@optional_arg_definitions = []
|
62
62
|
@remaining_args_definition = nil
|
@@ -74,10 +74,22 @@ module Toys
|
|
74
74
|
attr_reader :full_name
|
75
75
|
|
76
76
|
##
|
77
|
-
#
|
78
|
-
# @return [
|
77
|
+
# Returns the short description string.
|
78
|
+
# @return [Toys::Utils::WrappableString]
|
79
79
|
#
|
80
|
-
attr_reader :
|
80
|
+
attr_reader :desc
|
81
|
+
|
82
|
+
##
|
83
|
+
# Returns the long description strings as an array.
|
84
|
+
# @return [Array<Toys::Utils::WrappableString>]
|
85
|
+
#
|
86
|
+
attr_reader :long_desc
|
87
|
+
|
88
|
+
##
|
89
|
+
# Return a list of all defined flags.
|
90
|
+
# @return [Array<Toys::Tool::FlagDefinition>]
|
91
|
+
#
|
92
|
+
attr_reader :flag_definitions
|
81
93
|
|
82
94
|
##
|
83
95
|
# Return a list of all defined required positional arguments.
|
@@ -167,45 +179,21 @@ module Toys
|
|
167
179
|
executor.is_a?(::Proc)
|
168
180
|
end
|
169
181
|
|
170
|
-
##
|
171
|
-
# Returns the effective short description for this tool. This will be
|
172
|
-
# displayed when this tool is listed in a command list.
|
173
|
-
#
|
174
|
-
# @param [Integer,nil] wrap_width Wrap wrappable strings to the given
|
175
|
-
# width, or `nil` for no wrapping.
|
176
|
-
# @return [Array<String>]
|
177
|
-
#
|
178
|
-
def effective_desc(wrap_width: nil)
|
179
|
-
Tool.resolve_wrapping(@desc, wrap_width)
|
180
|
-
end
|
181
|
-
|
182
|
-
##
|
183
|
-
# Returns the effective long description for this tool. This will be
|
184
|
-
# displayed as part of the usage for this particular tool.
|
185
|
-
#
|
186
|
-
# @param [Integer,nil] wrap_width Wrap wrappable strings to the given
|
187
|
-
# width, or `nil` for no wrapping.
|
188
|
-
# @return [Array<String>]
|
189
|
-
#
|
190
|
-
def effective_long_desc(wrap_width: nil)
|
191
|
-
Tool.resolve_wrapping(@long_desc.empty? ? @desc : @long_desc, wrap_width)
|
192
|
-
end
|
193
|
-
|
194
182
|
##
|
195
183
|
# Returns true if there is a specific description set for this tool.
|
196
184
|
# @return [Boolean]
|
197
185
|
#
|
198
186
|
def includes_description?
|
199
|
-
|
187
|
+
!long_desc.empty? || !desc.empty?
|
200
188
|
end
|
201
189
|
|
202
190
|
##
|
203
|
-
# Returns true if at least one
|
191
|
+
# Returns true if at least one flag or positional argument is defined
|
204
192
|
# for this tool.
|
205
193
|
# @return [Boolean]
|
206
194
|
#
|
207
195
|
def includes_arguments?
|
208
|
-
!default_data.empty? || !
|
196
|
+
!default_data.empty? || !flag_definitions.empty? ||
|
209
197
|
!required_arg_definitions.empty? || !optional_arg_definitions.empty? ||
|
210
198
|
!remaining_args_definition.nil?
|
211
199
|
end
|
@@ -228,11 +216,29 @@ module Toys
|
|
228
216
|
end
|
229
217
|
|
230
218
|
##
|
231
|
-
# Returns
|
219
|
+
# Returns true if this tool's definition has been finished and is locked.
|
220
|
+
# @return [Boolean]
|
221
|
+
#
|
222
|
+
def definition_finished?
|
223
|
+
@definition_finished
|
224
|
+
end
|
225
|
+
|
226
|
+
##
|
227
|
+
# Returns all arg definitions in order: required, optional, remaining.
|
228
|
+
# @return [Array<Toys::Tool::ArgDefinition>]
|
229
|
+
#
|
230
|
+
def arg_definitions
|
231
|
+
result = required_arg_definitions + optional_arg_definitions
|
232
|
+
result << remaining_args_definition if remaining_args_definition
|
233
|
+
result
|
234
|
+
end
|
235
|
+
|
236
|
+
##
|
237
|
+
# Returns a list of flags used by this tool.
|
232
238
|
# @return [Array<String>]
|
233
239
|
#
|
234
|
-
def
|
235
|
-
|
240
|
+
def used_flags
|
241
|
+
flag_definitions.reduce([]) { |used, fdef| used + fdef.effective_flags }.uniq
|
236
242
|
end
|
237
243
|
|
238
244
|
##
|
@@ -242,33 +248,56 @@ module Toys
|
|
242
248
|
#
|
243
249
|
# @param [String] path The path to the file defining this tool
|
244
250
|
#
|
245
|
-
def
|
246
|
-
if
|
251
|
+
def lock_definition_path(path)
|
252
|
+
if definition_path && definition_path != path
|
247
253
|
raise ToolDefinitionError,
|
248
254
|
"Cannot redefine tool #{display_name.inspect} in #{path}" \
|
249
|
-
" (already defined in #{
|
255
|
+
" (already defined in #{definition_path})"
|
250
256
|
end
|
251
257
|
@definition_path = path
|
252
258
|
end
|
253
259
|
|
254
260
|
##
|
255
|
-
# Set the short description.
|
261
|
+
# Set the short description string.
|
262
|
+
#
|
263
|
+
# The description may be provided as a {Toys::Utils::WrappableString}, a
|
264
|
+
# single string (which will be wrapped), or an array of strings, which will
|
265
|
+
# be interpreted as string fragments that will be concatenated and wrapped.
|
256
266
|
#
|
257
|
-
# @param [String,Array<String>]
|
267
|
+
# @param [Toys::Utils::WrappableString,String,Array<String>] desc
|
258
268
|
#
|
259
|
-
def desc=(
|
269
|
+
def desc=(desc)
|
260
270
|
check_definition_state
|
261
|
-
@desc = Tool.canonicalize_desc(
|
271
|
+
@desc = Tool.canonicalize_desc(desc)
|
262
272
|
end
|
263
273
|
|
264
274
|
##
|
265
|
-
# Set the long description.
|
275
|
+
# Set the long description strings.
|
266
276
|
#
|
267
|
-
#
|
277
|
+
# Each string may be provided as a {Toys::Utils::WrappableString}, a single
|
278
|
+
# string (which will be wrapped), or an array of strings, which will be
|
279
|
+
# interpreted as string fragments that will be concatenated and wrapped.
|
268
280
|
#
|
269
|
-
|
281
|
+
# @param [Array<Toys::Utils::WrappableString,String,Array<String>>] descs
|
282
|
+
#
|
283
|
+
def long_desc=(descs)
|
270
284
|
check_definition_state
|
271
|
-
@long_desc = Tool.
|
285
|
+
@long_desc = Tool.canonicalize_long_desc(descs)
|
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
|
272
301
|
end
|
273
302
|
|
274
303
|
##
|
@@ -312,24 +341,27 @@ module Toys
|
|
312
341
|
end
|
313
342
|
|
314
343
|
##
|
315
|
-
# Add a
|
316
|
-
# the executor may use to obtain the
|
317
|
-
# You may then provide the
|
344
|
+
# Add a flag to the current tool. Each flag must specify a key which
|
345
|
+
# the executor may use to obtain the flag value from the context.
|
346
|
+
# You may then provide the flags themselves in `OptionParser` form.
|
318
347
|
#
|
319
348
|
# @param [Symbol] key The key to use to retrieve the value from the
|
320
349
|
# execution context.
|
321
|
-
# @param [String...]
|
350
|
+
# @param [String...] flags The flags in OptionParser format.
|
322
351
|
# @param [Object,nil] accept An OptionParser acceptor. Optional.
|
323
352
|
# @param [Object] default The default value. This is the value that will
|
324
|
-
# be set in the context if this
|
353
|
+
# be set in the context if this flag is not provided on the command
|
325
354
|
# line. Defaults to `nil`.
|
326
355
|
# @param [String,Toys::Utils::WrappableString,
|
327
|
-
# Array<String,Toys::Utils::WrappableString>]
|
328
|
-
# the
|
329
|
-
# @param [
|
330
|
-
#
|
331
|
-
#
|
332
|
-
#
|
356
|
+
# Array<String,Toys::Utils::WrappableString>] desc Short description
|
357
|
+
# for the flag. Defaults to empty array.
|
358
|
+
# @param [String,Toys::Utils::WrappableString,
|
359
|
+
# Array<String,Toys::Utils::WrappableString>] long_desc Long
|
360
|
+
# description for the flag. Defaults to 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.
|
333
365
|
# Defaults to false.
|
334
366
|
# @param [Proc,nil] handler An optional handler for setting/updating the
|
335
367
|
# value. If given, it should take two arguments, the new given value
|
@@ -337,17 +369,21 @@ module Toys
|
|
337
369
|
# should be set. The default handler simply replaces the previous
|
338
370
|
# value. i.e. the default is effectively `-> (val, _prev) { val }`.
|
339
371
|
#
|
340
|
-
def
|
341
|
-
|
372
|
+
def add_flag(key, *flags,
|
373
|
+
accept: nil, default: nil, desc: nil, long_desc: nil,
|
374
|
+
only_unique: false, handler: nil)
|
342
375
|
check_definition_state
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
376
|
+
flag_def = FlagDefinition.new(self, key)
|
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
|
385
|
+
flag_def.remove_flags(used_flags) if only_unique
|
386
|
+
@flag_definitions << flag_def if flag_def.active?
|
351
387
|
self
|
352
388
|
end
|
353
389
|
|
@@ -359,14 +395,25 @@ module Toys
|
|
359
395
|
# @param [Symbol] key The key to use to retrieve the value from the
|
360
396
|
# execution context.
|
361
397
|
# @param [Object,nil] accept An OptionParser acceptor. Optional.
|
398
|
+
# @param [String] display_name A name to use for display (in help text and
|
399
|
+
# error reports). Defaults to the key in upper case.
|
400
|
+
# @param [String,Toys::Utils::WrappableString,
|
401
|
+
# Array<String,Toys::Utils::WrappableString>] desc Short description
|
402
|
+
# for the arg. Defaults to empty array.
|
362
403
|
# @param [String,Toys::Utils::WrappableString,
|
363
|
-
# Array<String,Toys::Utils::WrappableString>]
|
364
|
-
# the arg. Defaults to empty array.
|
404
|
+
# Array<String,Toys::Utils::WrappableString>] long_desc Long
|
405
|
+
# description for the arg. Defaults to empty array.
|
365
406
|
#
|
366
|
-
def add_required_arg(key, accept: nil,
|
407
|
+
def add_required_arg(key, accept: nil, display_name: nil, desc: nil, long_desc: nil)
|
367
408
|
check_definition_state
|
368
|
-
|
369
|
-
|
409
|
+
arg_def = ArgDefinition.new(self, key, :required)
|
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?
|
416
|
+
@required_arg_definitions << arg_def
|
370
417
|
self
|
371
418
|
end
|
372
419
|
|
@@ -378,18 +425,30 @@ module Toys
|
|
378
425
|
#
|
379
426
|
# @param [Symbol] key The key to use to retrieve the value from the
|
380
427
|
# execution context.
|
381
|
-
# @param [Object,nil] accept An OptionParser acceptor. Optional.
|
382
428
|
# @param [Object] default The default value. This is the value that will
|
383
429
|
# be set in the context if this argument is not provided on the command
|
384
430
|
# line. Defaults to `nil`.
|
431
|
+
# @param [Object,nil] accept An OptionParser acceptor. Optional.
|
432
|
+
# @param [String] display_name A name to use for display (in help text and
|
433
|
+
# error reports). Defaults to the key in upper case.
|
385
434
|
# @param [String,Toys::Utils::WrappableString,
|
386
|
-
# Array<String,Toys::Utils::WrappableString>]
|
387
|
-
# the arg. Defaults to empty array.
|
435
|
+
# Array<String,Toys::Utils::WrappableString>] desc Short description
|
436
|
+
# for the arg. Defaults to empty array.
|
437
|
+
# @param [String,Toys::Utils::WrappableString,
|
438
|
+
# Array<String,Toys::Utils::WrappableString>] long_desc Long
|
439
|
+
# description for the arg. Defaults to empty array.
|
388
440
|
#
|
389
|
-
def add_optional_arg(key,
|
441
|
+
def add_optional_arg(key, default: nil, accept: nil, display_name: nil,
|
442
|
+
desc: nil, long_desc: nil)
|
390
443
|
check_definition_state
|
391
|
-
|
392
|
-
|
444
|
+
arg_def = ArgDefinition.new(self, key, :optional)
|
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?
|
451
|
+
@optional_arg_definitions << arg_def
|
393
452
|
self
|
394
453
|
end
|
395
454
|
|
@@ -400,18 +459,30 @@ module Toys
|
|
400
459
|
#
|
401
460
|
# @param [Symbol] key The key to use to retrieve the value from the
|
402
461
|
# execution context.
|
403
|
-
# @param [Object,nil] accept An OptionParser acceptor. Optional.
|
404
462
|
# @param [Object] default The default value. This is the value that will
|
405
463
|
# be set in the context if no unmatched arguments are provided on the
|
406
464
|
# command line. Defaults to the empty array `[]`.
|
465
|
+
# @param [Object,nil] accept An OptionParser acceptor. Optional.
|
466
|
+
# @param [String] display_name A name to use for display (in help text and
|
467
|
+
# error reports). Defaults to the key in upper case.
|
468
|
+
# @param [String,Toys::Utils::WrappableString,
|
469
|
+
# Array<String,Toys::Utils::WrappableString>] desc Short description
|
470
|
+
# for the arg. Defaults to empty array.
|
407
471
|
# @param [String,Toys::Utils::WrappableString,
|
408
|
-
# Array<String,Toys::Utils::WrappableString>]
|
409
|
-
# the
|
472
|
+
# Array<String,Toys::Utils::WrappableString>] long_desc Long
|
473
|
+
# description for the arg. Defaults to empty array.
|
410
474
|
#
|
411
|
-
def set_remaining_args(key,
|
475
|
+
def set_remaining_args(key, default: [], accept: nil, display_name: nil,
|
476
|
+
desc: nil, long_desc: nil)
|
412
477
|
check_definition_state
|
413
|
-
|
414
|
-
|
478
|
+
arg_def = ArgDefinition.new(self, key, :remaining)
|
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?
|
485
|
+
@remaining_args_definition = arg_def
|
415
486
|
self
|
416
487
|
end
|
417
488
|
|
@@ -437,33 +508,40 @@ module Toys
|
|
437
508
|
# @return [Integer] The result code.
|
438
509
|
#
|
439
510
|
def execute(cli, args, verbosity: 0)
|
440
|
-
|
441
|
-
|
511
|
+
ContextualError.capture_path(
|
512
|
+
"Error during tool execution!", definition_path,
|
513
|
+
tool_name: full_name, tool_args: args
|
514
|
+
) do
|
515
|
+
Execution.new(self).execute(cli, args, verbosity: verbosity)
|
516
|
+
end
|
442
517
|
end
|
443
518
|
|
444
519
|
##
|
445
520
|
# Complete definition and run middleware configs
|
521
|
+
# @param [Toys::Loader] loader
|
446
522
|
#
|
447
523
|
# @private
|
448
524
|
#
|
449
|
-
def finish_definition
|
525
|
+
def finish_definition(loader)
|
450
526
|
unless @definition_finished
|
451
|
-
|
452
|
-
|
453
|
-
|
527
|
+
ContextualError.capture("Error installing tool middleware!", tool_name: full_name) do
|
528
|
+
config_proc = proc {}
|
529
|
+
middleware_stack.reverse.each do |middleware|
|
530
|
+
config_proc = make_config_proc(middleware, loader, config_proc)
|
531
|
+
end
|
532
|
+
config_proc.call
|
454
533
|
end
|
455
|
-
config_proc.call
|
456
534
|
@definition_finished = true
|
457
535
|
end
|
458
536
|
self
|
459
537
|
end
|
460
538
|
|
461
539
|
##
|
462
|
-
# Representation of a single
|
540
|
+
# Representation of a single flag
|
463
541
|
#
|
464
|
-
class
|
542
|
+
class FlagSyntax
|
465
543
|
##
|
466
|
-
# Parse
|
544
|
+
# Parse flag syntax
|
467
545
|
# @param [String] str syntax.
|
468
546
|
#
|
469
547
|
def initialize(str)
|
@@ -474,58 +552,54 @@ module Toys
|
|
474
552
|
elsif str =~ /^(--\w[\?\w-]*)(([=\s])(\w+))?$/
|
475
553
|
setup(str, [$1], $1, "--", $3, $4)
|
476
554
|
else
|
477
|
-
raise ToolDefinitionError, "Illegal
|
555
|
+
raise ToolDefinitionError, "Illegal flag: #{str.inspect}"
|
478
556
|
end
|
479
557
|
end
|
480
558
|
|
481
|
-
attr_reader :
|
559
|
+
attr_reader :original_str
|
482
560
|
attr_reader :str_without_value
|
483
|
-
attr_reader :
|
484
|
-
attr_reader :
|
561
|
+
attr_reader :flags
|
562
|
+
attr_reader :flag_style
|
485
563
|
attr_reader :value_delim
|
486
564
|
attr_reader :value_label
|
487
565
|
|
488
566
|
private
|
489
567
|
|
490
|
-
def setup(
|
491
|
-
@
|
492
|
-
@
|
568
|
+
def setup(original_str, flags, str_without_value, flag_style, value_delim, value_label)
|
569
|
+
@original_str = original_str
|
570
|
+
@flags = flags
|
493
571
|
@str_without_value = str_without_value
|
494
|
-
@
|
572
|
+
@flag_style = flag_style
|
495
573
|
@value_delim = value_delim
|
496
|
-
@value_label = value_label
|
574
|
+
@value_label = value_label ? value_label.upcase : value_label
|
497
575
|
end
|
498
576
|
end
|
499
577
|
|
500
578
|
##
|
501
|
-
# Representation of a formal set of
|
579
|
+
# Representation of a formal set of flags.
|
502
580
|
#
|
503
|
-
class
|
581
|
+
class FlagDefinition
|
582
|
+
##
|
583
|
+
# The default handler replaces the previous value.
|
584
|
+
# @return [Proc]
|
585
|
+
#
|
586
|
+
DEFAULT_HANDLER = ->(val, _prev) { val }
|
587
|
+
|
504
588
|
##
|
505
|
-
# Create a
|
589
|
+
# Create a FlagDefinition
|
506
590
|
# @private
|
507
591
|
#
|
508
|
-
# @param [Symbol] key This
|
509
|
-
#
|
510
|
-
|
511
|
-
|
512
|
-
# Array<String,Toys::Utils::WrappableString>] docs Documentation
|
513
|
-
# @param [Proc,nil] handler An optional handler for setting/updating the
|
514
|
-
# value. If given, it should take two arguments, the new given value
|
515
|
-
# and the previous value, and it should return the new value that
|
516
|
-
# should be set. If `nil`, uses a default handler that just replaces
|
517
|
-
# the previous value. i.e. the default is effectively
|
518
|
-
# `-> (val, _prev) { val }`.
|
519
|
-
#
|
520
|
-
def initialize(key, switches, accept, docs, handler = nil)
|
592
|
+
# @param [Symbol] key This flag will set the given context key.
|
593
|
+
#
|
594
|
+
def initialize(tool, key)
|
595
|
+
@tool = tool
|
521
596
|
@key = key
|
522
|
-
|
523
|
-
@
|
524
|
-
@
|
525
|
-
@
|
526
|
-
@
|
597
|
+
@flag_syntax = []
|
598
|
+
@accept = nil
|
599
|
+
@handler = DEFAULT_HANDLER
|
600
|
+
@desc = ""
|
601
|
+
@long_desc = []
|
527
602
|
reset_data
|
528
|
-
@effective_switches = nil
|
529
603
|
end
|
530
604
|
|
531
605
|
##
|
@@ -535,10 +609,10 @@ module Toys
|
|
535
609
|
attr_reader :key
|
536
610
|
|
537
611
|
##
|
538
|
-
# Returns an array of
|
539
|
-
# @return [Array<
|
612
|
+
# Returns an array of FlagSyntax for the flags.
|
613
|
+
# @return [Array<FlagSyntax>]
|
540
614
|
#
|
541
|
-
attr_reader :
|
615
|
+
attr_reader :flag_syntax
|
542
616
|
|
543
617
|
##
|
544
618
|
# Returns the acceptor, which may be `nil`.
|
@@ -547,66 +621,150 @@ module Toys
|
|
547
621
|
attr_reader :accept
|
548
622
|
|
549
623
|
##
|
550
|
-
# Returns the
|
551
|
-
# @return [
|
624
|
+
# Returns the short description string.
|
625
|
+
# @return [Toys::Utils::WrappableString]
|
626
|
+
#
|
627
|
+
attr_reader :desc
|
628
|
+
|
629
|
+
##
|
630
|
+
# Returns the long description strings as an array.
|
631
|
+
# @return [Array<Toys::Utils::WrappableString>]
|
552
632
|
#
|
553
|
-
attr_reader :
|
633
|
+
attr_reader :long_desc
|
554
634
|
|
555
635
|
##
|
556
|
-
# Returns the handler.
|
636
|
+
# Returns the handler for setting/updating the value.
|
557
637
|
# @return [Proc]
|
558
638
|
#
|
559
639
|
attr_reader :handler
|
560
640
|
|
561
641
|
##
|
562
|
-
#
|
563
|
-
# @
|
642
|
+
# Adds the given flags.
|
643
|
+
# @param [Array<String>] flags Flags in OptionParser format
|
564
644
|
#
|
565
|
-
def
|
566
|
-
@
|
645
|
+
def add_flags(flags)
|
646
|
+
@flag_syntax.concat(flags.map { |s| FlagSyntax.new(s) })
|
647
|
+
reset_data
|
648
|
+
self
|
567
649
|
end
|
568
650
|
|
569
651
|
##
|
570
|
-
#
|
571
|
-
# @
|
652
|
+
# Set the acceptor.
|
653
|
+
# @param [Object] accept Acceptor. May be `nil` for the default.
|
572
654
|
#
|
573
|
-
def
|
574
|
-
@
|
655
|
+
def accept=(accept)
|
656
|
+
@accept = accept
|
657
|
+
reset_data
|
575
658
|
end
|
576
659
|
|
577
660
|
##
|
578
|
-
#
|
579
|
-
# @
|
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.
|
580
700
|
#
|
581
|
-
|
582
|
-
|
701
|
+
# @param [Array<Toys::Utils::WrappableString,String,Array<String>>] descs
|
702
|
+
#
|
703
|
+
def long_desc=(descs)
|
704
|
+
@long_desc = Tool.canonicalize_long_desc(descs)
|
583
705
|
end
|
584
706
|
|
585
707
|
##
|
586
|
-
#
|
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.
|
587
714
|
#
|
588
|
-
# @param [
|
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
|
+
##
|
723
|
+
# Returns an array of FlagSyntax including only single-dash flags
|
724
|
+
# @return [Array<FlagSyntax>]
|
725
|
+
#
|
726
|
+
def single_flag_syntax
|
727
|
+
@single_flag_syntax ||= flag_syntax.find_all { |ss| ss.flag_style == "-" }
|
728
|
+
end
|
729
|
+
|
730
|
+
##
|
731
|
+
# Returns an array of FlagSyntax including only double-dash flags
|
732
|
+
# @return [Array<FlagSyntax>]
|
733
|
+
#
|
734
|
+
def double_flag_syntax
|
735
|
+
@double_flag_syntax ||= flag_syntax.find_all { |ss| ss.flag_style == "--" }
|
736
|
+
end
|
737
|
+
|
738
|
+
##
|
739
|
+
# Returns the list of effective flags used.
|
589
740
|
# @return [Array<String>]
|
590
741
|
#
|
591
|
-
def
|
592
|
-
|
742
|
+
def effective_flags
|
743
|
+
@effective_flags ||= flag_syntax.map(&:flags).flatten
|
593
744
|
end
|
594
745
|
|
595
746
|
##
|
596
|
-
# All optparser
|
747
|
+
# All optparser flags and acceptor if present
|
597
748
|
# @return [Array]
|
598
749
|
#
|
599
750
|
def optparser_info
|
600
|
-
@optparser_info ||=
|
751
|
+
@optparser_info ||= begin
|
752
|
+
flags = flag_syntax.map do |fs|
|
753
|
+
f = fs.str_without_value
|
754
|
+
f = "#{f} #{value_label}" if value_label
|
755
|
+
f
|
756
|
+
end
|
757
|
+
flags + Array(accept)
|
758
|
+
end
|
601
759
|
end
|
602
760
|
|
603
761
|
##
|
604
|
-
# Returns true if this
|
605
|
-
#
|
762
|
+
# Returns true if this flag is active. That is, it has a nonempty
|
763
|
+
# flags list.
|
606
764
|
# @return [Boolean]
|
607
765
|
#
|
608
766
|
def active?
|
609
|
-
!
|
767
|
+
!effective_flags.empty?
|
610
768
|
end
|
611
769
|
|
612
770
|
##
|
@@ -627,47 +785,52 @@ module Toys
|
|
627
785
|
@value_delim
|
628
786
|
end
|
629
787
|
|
630
|
-
##
|
631
|
-
|
632
|
-
|
633
|
-
|
634
|
-
|
635
|
-
@switch_syntax.select! do |ss|
|
636
|
-
ss.switches.all? { |s| !switches.include?(s) }
|
788
|
+
## @private
|
789
|
+
def remove_flags(flags)
|
790
|
+
flags = flags.map { |f| FlagSyntax.new(f).flags }.flatten
|
791
|
+
@flag_syntax.select! do |ss|
|
792
|
+
ss.flags.all? { |s| !flags.include?(s) }
|
637
793
|
end
|
638
794
|
reset_data
|
639
795
|
self
|
640
796
|
end
|
641
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
|
+
end
|
808
|
+
|
642
809
|
private
|
643
810
|
|
644
811
|
def reset_data
|
645
|
-
@
|
812
|
+
@effective_flags = nil
|
646
813
|
@optparser_info = nil
|
647
|
-
@
|
648
|
-
@
|
814
|
+
@single_flag_syntax = nil
|
815
|
+
@double_flag_syntax = nil
|
649
816
|
@value_label = nil
|
650
817
|
@value_delim = nil
|
651
818
|
end
|
652
819
|
|
653
820
|
def find_canonical_value_label
|
654
821
|
return if @value_delim
|
655
|
-
|
822
|
+
@value_label = @accept ? "VALUE" : nil
|
823
|
+
@value_delim = @accept ? " " : ""
|
824
|
+
single_flag_syntax.each do |ss|
|
656
825
|
next unless ss.value_label
|
657
826
|
@value_label = ss.value_label
|
658
827
|
@value_delim = ss.value_delim
|
659
|
-
break
|
660
828
|
end
|
661
|
-
|
662
|
-
single_switch_syntax.reverse_each do |ss|
|
829
|
+
double_flag_syntax.each do |ss|
|
663
830
|
next unless ss.value_label
|
664
831
|
@value_label = ss.value_label
|
665
832
|
@value_delim = ss.value_delim
|
666
|
-
break
|
667
833
|
end
|
668
|
-
return if @value_delim
|
669
|
-
@value_label = nil
|
670
|
-
@value_delim = ""
|
671
834
|
end
|
672
835
|
end
|
673
836
|
|
@@ -680,14 +843,16 @@ module Toys
|
|
680
843
|
# @private
|
681
844
|
#
|
682
845
|
# @param [Symbol] key This argument will set the given context key.
|
683
|
-
# @param [
|
684
|
-
# @param [String,Toys::Utils::WrappableString,
|
685
|
-
# Array<String,Toys::Utils::WrappableString>] docs Documentation
|
846
|
+
# @param [:required,:optional,:remaining] type Type of this argument
|
686
847
|
#
|
687
|
-
def initialize(
|
848
|
+
def initialize(tool, key, type)
|
849
|
+
@tool = tool
|
688
850
|
@key = key
|
689
|
-
@
|
690
|
-
@
|
851
|
+
@type = type
|
852
|
+
@accept = nil
|
853
|
+
@desc = ""
|
854
|
+
@long_desc = []
|
855
|
+
@display_name = key.to_s.tr("-", "_").gsub(/\W/, "").upcase
|
691
856
|
end
|
692
857
|
|
693
858
|
##
|
@@ -696,35 +861,85 @@ module Toys
|
|
696
861
|
#
|
697
862
|
attr_reader :key
|
698
863
|
|
864
|
+
##
|
865
|
+
# Type of this argument.
|
866
|
+
# @return [:required,:optional,:remaining]
|
867
|
+
#
|
868
|
+
attr_reader :type
|
869
|
+
|
699
870
|
##
|
700
871
|
# Returns the acceptor, which may be `nil`.
|
701
872
|
# @return [Object]
|
702
873
|
#
|
703
|
-
|
874
|
+
attr_accessor :accept
|
704
875
|
|
705
876
|
##
|
706
|
-
# Returns the
|
707
|
-
# @return [
|
877
|
+
# Returns the short description string.
|
878
|
+
# @return [Toys::Utils::WrappableString]
|
708
879
|
#
|
709
|
-
attr_reader :
|
880
|
+
attr_reader :desc
|
710
881
|
|
711
882
|
##
|
712
|
-
#
|
883
|
+
# Returns the long description strings as an array.
|
884
|
+
# @return [Array<Toys::Utils::WrappableString>]
|
713
885
|
#
|
886
|
+
attr_reader :long_desc
|
887
|
+
|
888
|
+
##
|
889
|
+
# Returns the displayable name.
|
714
890
|
# @return [String]
|
715
891
|
#
|
716
|
-
|
717
|
-
|
892
|
+
attr_accessor :display_name
|
893
|
+
|
894
|
+
##
|
895
|
+
# Set the default.
|
896
|
+
# @param [Object] default The default value.
|
897
|
+
#
|
898
|
+
def default=(default)
|
899
|
+
@tool.default_data[@key] = default
|
718
900
|
end
|
719
901
|
|
720
902
|
##
|
721
|
-
#
|
903
|
+
# Set the short description string.
|
722
904
|
#
|
723
|
-
#
|
724
|
-
#
|
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.
|
725
909
|
#
|
726
|
-
|
727
|
-
|
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
|
728
943
|
end
|
729
944
|
|
730
945
|
##
|
@@ -736,19 +951,18 @@ module Toys
|
|
736
951
|
#
|
737
952
|
def process_value(input)
|
738
953
|
return input unless accept
|
739
|
-
n = canonical_name
|
740
954
|
result = input
|
741
955
|
optparse = ::OptionParser.new
|
742
|
-
optparse.on("
|
743
|
-
optparse.parse(["
|
956
|
+
optparse.on("--abc=VALUE", accept) { |v| result = v }
|
957
|
+
optparse.parse(["--abc", input])
|
744
958
|
result
|
745
959
|
end
|
746
960
|
end
|
747
961
|
|
748
962
|
private
|
749
963
|
|
750
|
-
def make_config_proc(middleware, next_config)
|
751
|
-
proc { middleware.config(self, &next_config) }
|
964
|
+
def make_config_proc(middleware, loader, next_config)
|
965
|
+
proc { middleware.config(self, loader, &next_config) }
|
752
966
|
end
|
753
967
|
|
754
968
|
def check_definition_state
|
@@ -759,23 +973,14 @@ module Toys
|
|
759
973
|
end
|
760
974
|
|
761
975
|
class << self
|
762
|
-
## @private
|
763
|
-
def canonical_switch(name)
|
764
|
-
name.to_s.downcase.tr("_", "-").gsub(/[^a-z0-9-]/, "")
|
765
|
-
end
|
766
|
-
|
767
976
|
## @private
|
768
977
|
def canonicalize_desc(desc)
|
769
|
-
|
770
|
-
d.is_a?(Utils::WrappableString) ? d : d.split("\n")
|
771
|
-
end.flatten.freeze
|
978
|
+
desc.is_a?(Utils::WrappableString) ? desc : Utils::WrappableString.new(desc)
|
772
979
|
end
|
773
980
|
|
774
981
|
## @private
|
775
|
-
def
|
776
|
-
|
777
|
-
s.is_a?(Utils::WrappableString) && !wrap_width.nil? ? s.wrap(wrap_width) : s.to_s
|
778
|
-
end.flatten
|
982
|
+
def canonicalize_long_desc(descs)
|
983
|
+
Array(descs).map { |desc| canonicalize_desc(desc) }.freeze
|
779
984
|
end
|
780
985
|
end
|
781
986
|
|
@@ -821,14 +1026,14 @@ module Toys
|
|
821
1026
|
|
822
1027
|
def create_option_parser
|
823
1028
|
optparse = ::OptionParser.new
|
824
|
-
# The following clears out the Officious (hidden default
|
1029
|
+
# The following clears out the Officious (hidden default flags).
|
825
1030
|
optparse.remove
|
826
1031
|
optparse.remove
|
827
1032
|
optparse.new
|
828
1033
|
optparse.new
|
829
|
-
@tool.
|
830
|
-
optparse.on(*
|
831
|
-
@data[
|
1034
|
+
@tool.flag_definitions.each do |flag|
|
1035
|
+
optparse.on(*flag.optparser_info) do |val|
|
1036
|
+
@data[flag.key] = flag.handler.call(val, @data[flag.key])
|
832
1037
|
end
|
833
1038
|
end
|
834
1039
|
optparse
|
@@ -837,7 +1042,7 @@ module Toys
|
|
837
1042
|
def parse_required_args(remaining, args)
|
838
1043
|
@tool.required_arg_definitions.each do |arg_info|
|
839
1044
|
if remaining.empty?
|
840
|
-
reason = "No value given for required argument
|
1045
|
+
reason = "No value given for required argument #{arg_info.display_name}"
|
841
1046
|
raise create_parse_error(args, reason)
|
842
1047
|
end
|
843
1048
|
@data[arg_info.key] = arg_info.process_value(remaining.shift)
|
@@ -887,7 +1092,7 @@ module Toys
|
|
887
1092
|
if @tool.includes_executor?
|
888
1093
|
context.instance_eval(&@tool.executor)
|
889
1094
|
else
|
890
|
-
context.logger.fatal("No implementation for #{@tool.display_name.inspect}")
|
1095
|
+
context.logger.fatal("No implementation for tool #{@tool.display_name.inspect}")
|
891
1096
|
context.exit(-1)
|
892
1097
|
end
|
893
1098
|
end
|