toys-core 0.11.5 → 0.12.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +31 -0
- data/README.md +1 -1
- data/lib/toys-core.rb +4 -1
- data/lib/toys/acceptor.rb +3 -3
- data/lib/toys/arg_parser.rb +6 -7
- data/lib/toys/cli.rb +44 -14
- data/lib/toys/compat.rb +19 -22
- data/lib/toys/completion.rb +3 -1
- data/lib/toys/context.rb +2 -2
- data/lib/toys/core.rb +1 -1
- data/lib/toys/dsl/base.rb +85 -0
- data/lib/toys/dsl/flag.rb +3 -3
- data/lib/toys/dsl/flag_group.rb +7 -7
- data/lib/toys/dsl/internal.rb +206 -0
- data/lib/toys/dsl/positional_arg.rb +3 -3
- data/lib/toys/dsl/tool.rb +174 -216
- data/lib/toys/errors.rb +1 -0
- data/lib/toys/flag.rb +15 -18
- data/lib/toys/flag_group.rb +5 -4
- data/lib/toys/input_file.rb +4 -4
- data/lib/toys/loader.rb +189 -50
- data/lib/toys/middleware.rb +1 -1
- data/lib/toys/mixin.rb +2 -2
- data/lib/toys/positional_arg.rb +3 -3
- data/lib/toys/settings.rb +900 -0
- data/lib/toys/source_info.rb +121 -18
- data/lib/toys/standard_middleware/apply_config.rb +5 -4
- data/lib/toys/standard_middleware/set_default_descriptions.rb +18 -18
- data/lib/toys/standard_middleware/show_help.rb +17 -5
- data/lib/toys/standard_mixins/exec.rb +12 -14
- data/lib/toys/standard_mixins/git_cache.rb +48 -0
- data/lib/toys/standard_mixins/xdg.rb +56 -0
- data/lib/toys/template.rb +2 -2
- data/lib/toys/{tool.rb → tool_definition.rb} +100 -41
- data/lib/toys/utils/exec.rb +4 -5
- data/lib/toys/utils/gems.rb +8 -7
- data/lib/toys/utils/git_cache.rb +184 -0
- data/lib/toys/utils/help_text.rb +90 -34
- data/lib/toys/utils/terminal.rb +1 -1
- data/lib/toys/utils/xdg.rb +293 -0
- metadata +14 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2e6f3ce99b43220466c4b43842c1fa78d3cfca815ecc559be749518d26156be9
|
4
|
+
data.tar.gz: 8a3dbb068001b3a52d5b070ae0f8652aeea5f1763ae19a938aa84da693023c2c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: de8dc024af7e706749b65a8e2b4fe9430e380b58add4bc9b643bc357dce7d5a5109057a2aaccdbfb657410def1372494b020cab59b1ebd03de83d2359a0746ab
|
7
|
+
data.tar.gz: 96b6ca463c27eff9fe403d365afe15a6d4c75bed057b8dc162b40c696b0f31606738197c5bdb68ed759d9c0a0f29af0e4ddd4aed929e41649cb6a46b67909ea8
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,36 @@
|
|
1
1
|
# Release History
|
2
2
|
|
3
|
+
### v0.12.0 / 2021-08-05
|
4
|
+
|
5
|
+
Toys-Core 0.12.0 is a major release with significant new features and bug fixes, and a few breaking interface changes. Additionally, this release now requires Ruby 2.4 or later.
|
6
|
+
|
7
|
+
Breaking interface changes:
|
8
|
+
|
9
|
+
* The Toys::Tool class has been renamed Toys::ToolDefinition so that the old name can be used for class-based tool definition.
|
10
|
+
* Tool definition now raises ToolDefinitionError if whitespace, control characters, or certain punctuation are used in a tool name.
|
11
|
+
* Toys::Loader#add_path no longer supports multiple paths. Use add_path_set instead.
|
12
|
+
* The "name" argument was renamed to "source_name" in Toys::Loader#add_block and Toys::CLI#add_config_block
|
13
|
+
|
14
|
+
New functionality:
|
15
|
+
|
16
|
+
* The DSL now supports a class-based tool definition syntax (in addition to the existing block-based syntax). Some users may prefer this new class-based style as more Ruby-like.
|
17
|
+
* You can now load tools from a remote git repository using the load_git directive.
|
18
|
+
* Whitespace is now automatically considered a name delimiter when defining tools.
|
19
|
+
* There is now an extensible settings mechanism to activate less-common tool behavior. Currently there is one setting, which causes subtools to inherit their parent's methods by default.
|
20
|
+
* The load directive can load into a new tool.
|
21
|
+
* Added a new utility class and mixin that provides XDG Base Directory information.
|
22
|
+
* Added a new utility class and mixin that provides cached access to remote git repos.
|
23
|
+
* The help text generator now supports splitting the subtool list by source.
|
24
|
+
* Loader and CLI methods that add tool configs now uniformly provide optional source_name and context_directory arguments.
|
25
|
+
* Toys::SourceInfo now supports getting the root ancestor and priority of a source.
|
26
|
+
* Toys::ToolDefinition now has a direct accessor for the source root. This is always set for a tool, even if it isn't marked as finished.
|
27
|
+
|
28
|
+
Fixes:
|
29
|
+
|
30
|
+
* Fixed some bundler integration issues that occurred when the bundle is being installed in a separate path such as a vendor directory.
|
31
|
+
* Toys::ContextualError now includes the full backtrace of the cause.
|
32
|
+
* Cleaned up some unused memory objects during tool loading and lookup.
|
33
|
+
|
3
34
|
### v0.11.5 / 2021-03-28
|
4
35
|
|
5
36
|
* BREAKING CHANGE: The exit_on_nonzero_status option to exec now exits on signals and failures to spawn, in addition to error codes.
|
data/README.md
CHANGED
@@ -34,7 +34,7 @@ Install the **toys-core** gem using:
|
|
34
34
|
You may also install the **toys** gem, which brings in **toys-core** as a
|
35
35
|
dependency.
|
36
36
|
|
37
|
-
Toys-Core requires Ruby 2.
|
37
|
+
Toys-Core requires Ruby 2.4 or later.
|
38
38
|
|
39
39
|
Most parts of Toys-Core work on JRuby. However, JRuby is not recommended
|
40
40
|
because of JVM boot latency, lack of support for Kernel#fork, and other issues.
|
data/lib/toys-core.rb
CHANGED
@@ -70,8 +70,10 @@ require "toys/compat"
|
|
70
70
|
require "toys/completion"
|
71
71
|
require "toys/context"
|
72
72
|
require "toys/core"
|
73
|
+
require "toys/dsl/base"
|
73
74
|
require "toys/dsl/flag"
|
74
75
|
require "toys/dsl/flag_group"
|
76
|
+
require "toys/dsl/internal"
|
75
77
|
require "toys/dsl/positional_arg"
|
76
78
|
require "toys/dsl/tool"
|
77
79
|
require "toys/errors"
|
@@ -83,7 +85,8 @@ require "toys/middleware"
|
|
83
85
|
require "toys/mixin"
|
84
86
|
require "toys/module_lookup"
|
85
87
|
require "toys/positional_arg"
|
88
|
+
require "toys/settings"
|
86
89
|
require "toys/source_info"
|
87
90
|
require "toys/template"
|
88
|
-
require "toys/
|
91
|
+
require "toys/tool_definition"
|
89
92
|
require "toys/wrappable_string"
|
data/lib/toys/acceptor.rb
CHANGED
@@ -602,11 +602,11 @@ module Toys
|
|
602
602
|
Simple.new(type_desc: "boolean", well_known_spec: spec) do |s|
|
603
603
|
if s.nil?
|
604
604
|
default
|
605
|
+
elsif s.empty?
|
606
|
+
REJECT
|
605
607
|
else
|
606
608
|
s = s.downcase
|
607
|
-
if
|
608
|
-
REJECT
|
609
|
-
elsif TRUE_STRINGS.any? { |t| t.start_with?(s) }
|
609
|
+
if TRUE_STRINGS.any? { |t| t.start_with?(s) }
|
610
610
|
true
|
611
611
|
elsif FALSE_STRINGS.any? { |f| f.start_with?(s) }
|
612
612
|
false
|
data/lib/toys/arg_parser.rb
CHANGED
@@ -261,7 +261,7 @@ module Toys
|
|
261
261
|
# @param message [String] The message. Required.
|
262
262
|
#
|
263
263
|
def initialize(message)
|
264
|
-
super(message)
|
264
|
+
super(message, name: nil)
|
265
265
|
end
|
266
266
|
end
|
267
267
|
|
@@ -269,7 +269,7 @@ module Toys
|
|
269
269
|
# Create an argument parser for a particular tool.
|
270
270
|
#
|
271
271
|
# @param cli [Toys::CLI] The CLI in effect.
|
272
|
-
# @param tool [Toys::
|
272
|
+
# @param tool [Toys::ToolDefinition] The tool defining the argument format.
|
273
273
|
# @param default_data [Hash] Additional initial data (such as verbosity).
|
274
274
|
# @param require_exact_flag_match [Boolean] Whether to require flag matches
|
275
275
|
# be exact (not partial). Default is false.
|
@@ -295,7 +295,7 @@ module Toys
|
|
295
295
|
|
296
296
|
##
|
297
297
|
# The tool definition governing this parser.
|
298
|
-
# @return [Toys::
|
298
|
+
# @return [Toys::ToolDefinition]
|
299
299
|
#
|
300
300
|
attr_reader :tool
|
301
301
|
|
@@ -429,7 +429,7 @@ module Toys
|
|
429
429
|
Context::Key::TOOL_NAME => tool.full_name,
|
430
430
|
Context::Key::USAGE_ERRORS => [],
|
431
431
|
}
|
432
|
-
|
432
|
+
tool.default_data.each { |k, v| data[k] = v.clone }
|
433
433
|
default_data.each { |k, v| data[k] ||= v }
|
434
434
|
data
|
435
435
|
end
|
@@ -450,7 +450,7 @@ module Toys
|
|
450
450
|
case arg
|
451
451
|
when "--"
|
452
452
|
@flags_allowed = false
|
453
|
-
when /\A(--\w[
|
453
|
+
when /\A(--\w[?\w-]*)=(.*)\z/
|
454
454
|
handle_valued_flag(::Regexp.last_match(1), ::Regexp.last_match(2))
|
455
455
|
when /\A--.+\z/
|
456
456
|
handle_plain_flag(arg)
|
@@ -474,8 +474,7 @@ module Toys
|
|
474
474
|
return "" unless flag_def
|
475
475
|
@seen_flag_keys << flag_def.key
|
476
476
|
if flag_def.flag_type == :boolean
|
477
|
-
add_data(flag_def.key, flag_def.handler, nil, !flag_result.unique_flag_negative?,
|
478
|
-
:flag, name)
|
477
|
+
add_data(flag_def.key, flag_def.handler, nil, !flag_result.unique_flag_negative?, :flag, name)
|
479
478
|
elsif following.empty?
|
480
479
|
if flag_def.value_type == :required || flag_result.unique_flag_syntax.value_delim == " "
|
481
480
|
@active_flag_def = flag_def
|
data/lib/toys/cli.rb
CHANGED
@@ -78,8 +78,8 @@ module Toys
|
|
78
78
|
# with different verbosity settings (since the logger cannot have
|
79
79
|
# multiple level settings simultaneously). In that case, do not set a
|
80
80
|
# global logger, but use the `logger_factory` parameter instead.
|
81
|
-
# @param logger_factory [Proc] A proc that takes a {Toys::
|
82
|
-
# argument, and returns a `Logger` to use when running that tool.
|
81
|
+
# @param logger_factory [Proc] A proc that takes a {Toys::ToolDefinition}
|
82
|
+
# as an argument, and returns a `Logger` to use when running that tool.
|
83
83
|
# Optional. If not provided (and no global logger is set), CLI will use
|
84
84
|
# a default factory that writes generates loggers writing formatted
|
85
85
|
# output to `STDERR`, as defined by {Toys::CLI.default_logger_factory}.
|
@@ -321,10 +321,22 @@ module Toys
|
|
321
321
|
# a Toys directory.
|
322
322
|
# @param high_priority [Boolean] Add the config at the head of the priority
|
323
323
|
# list rather than the tail.
|
324
|
+
# @param source_name [String] A custom name for the root source. Optional.
|
325
|
+
# @param context_directory [String,nil,:path,:parent] The context directory
|
326
|
+
# for tools loaded from this path. You can pass a directory path as a
|
327
|
+
# string, `:path` to denote the given path, `:parent` to denote the
|
328
|
+
# given path's parent directory, or `nil` to denote no context.
|
329
|
+
# Defaults to `:parent`.
|
324
330
|
# @return [self]
|
325
331
|
#
|
326
|
-
def add_config_path(path,
|
327
|
-
|
332
|
+
def add_config_path(path,
|
333
|
+
high_priority: false,
|
334
|
+
source_name: nil,
|
335
|
+
context_directory: :parent)
|
336
|
+
@loader.add_path(path,
|
337
|
+
high_priority: high_priority,
|
338
|
+
source_name: source_name,
|
339
|
+
context_directory: context_directory)
|
328
340
|
self
|
329
341
|
end
|
330
342
|
|
@@ -336,15 +348,24 @@ module Toys
|
|
336
348
|
#
|
337
349
|
# @param high_priority [Boolean] Add the config at the head of the priority
|
338
350
|
# list rather than the tail.
|
339
|
-
# @param
|
340
|
-
# for tools defined in this block. If omitted, a default
|
341
|
-
# will be generated.
|
351
|
+
# @param source_name [String] The source name that will be shown in
|
352
|
+
# documentation for tools defined in this block. If omitted, a default
|
353
|
+
# unique string will be generated.
|
342
354
|
# @param block [Proc] The block of configuration, executed in the context
|
343
355
|
# of the tool DSL {Toys::DSL::Tool}.
|
356
|
+
# @param context_directory [String,nil] The context directory for tools
|
357
|
+
# loaded from this block. You can pass a directory path as a string, or
|
358
|
+
# `nil` to denote no context. Defaults to `nil`.
|
344
359
|
# @return [self]
|
345
360
|
#
|
346
|
-
def add_config_block(high_priority: false,
|
347
|
-
|
361
|
+
def add_config_block(high_priority: false,
|
362
|
+
source_name: nil,
|
363
|
+
context_directory: nil,
|
364
|
+
&block)
|
365
|
+
@loader.add_block(high_priority: high_priority,
|
366
|
+
source_name: source_name,
|
367
|
+
context_directory: context_directory,
|
368
|
+
&block)
|
348
369
|
self
|
349
370
|
end
|
350
371
|
|
@@ -358,19 +379,28 @@ module Toys
|
|
358
379
|
# @param search_path [String] A path to search for configs.
|
359
380
|
# @param high_priority [Boolean] Add the configs at the head of the
|
360
381
|
# priority list rather than the tail.
|
382
|
+
# @param context_directory [String,nil,:path,:parent] The context directory
|
383
|
+
# for tools loaded from this path. You can pass a directory path as a
|
384
|
+
# string, `:path` to denote the given path, `:parent` to denote the
|
385
|
+
# given path's parent directory, or `nil` to denote no context.
|
386
|
+
# Defaults to `:path`.
|
361
387
|
# @return [self]
|
362
388
|
#
|
363
|
-
def add_search_path(search_path,
|
389
|
+
def add_search_path(search_path,
|
390
|
+
high_priority: false,
|
391
|
+
context_directory: :path)
|
364
392
|
paths = []
|
365
393
|
if @config_file_name
|
366
394
|
file_path = ::File.join(search_path, @config_file_name)
|
367
|
-
paths <<
|
395
|
+
paths << @config_file_name if !::File.directory?(file_path) && ::File.readable?(file_path)
|
368
396
|
end
|
369
397
|
if @config_dir_name
|
370
398
|
dir_path = ::File.join(search_path, @config_dir_name)
|
371
|
-
paths <<
|
399
|
+
paths << @config_dir_name if ::File.directory?(dir_path) && ::File.readable?(dir_path)
|
372
400
|
end
|
373
|
-
@loader.
|
401
|
+
@loader.add_path_set(search_path, paths,
|
402
|
+
high_priority: high_priority,
|
403
|
+
context_directory: context_directory)
|
374
404
|
self
|
375
405
|
end
|
376
406
|
|
@@ -443,7 +473,7 @@ module Toys
|
|
443
473
|
# Run the given tool with the given arguments.
|
444
474
|
# Does not handle exceptions.
|
445
475
|
#
|
446
|
-
# @param tool [Toys::
|
476
|
+
# @param tool [Toys::ToolDefinition] The tool to run.
|
447
477
|
# @param args [Array<String>] Command line arguments passed to the tool.
|
448
478
|
# @param default_data [Hash] Initial tool context data.
|
449
479
|
# @return [Integer] The resulting status code
|
data/lib/toys/compat.rb
CHANGED
@@ -53,28 +53,6 @@ module Toys
|
|
53
53
|
end
|
54
54
|
end
|
55
55
|
|
56
|
-
# In Ruby < 2.4, some objects such as nil cannot be cloned.
|
57
|
-
if ruby_version >= 20400
|
58
|
-
# @private
|
59
|
-
def self.merge_clones(hash, orig)
|
60
|
-
orig.each { |k, v| hash[k] = v.clone }
|
61
|
-
hash
|
62
|
-
end
|
63
|
-
else
|
64
|
-
# @private
|
65
|
-
def self.merge_clones(hash, orig)
|
66
|
-
orig.each do |k, v|
|
67
|
-
hash[k] =
|
68
|
-
begin
|
69
|
-
v.clone
|
70
|
-
rescue ::TypeError
|
71
|
-
v
|
72
|
-
end
|
73
|
-
end
|
74
|
-
hash
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
56
|
# The :base argument to Dir.glob requires Ruby 2.5 or later.
|
79
57
|
if ruby_version >= 20500
|
80
58
|
# @private
|
@@ -106,5 +84,24 @@ module Toys
|
|
106
84
|
end
|
107
85
|
end
|
108
86
|
end
|
87
|
+
|
88
|
+
# File.absolute_path? requires Ruby 2.7 or later. For earlier Rubies, use
|
89
|
+
# an ad-hoc mechanism.
|
90
|
+
if ruby_version >= 20700
|
91
|
+
# @private
|
92
|
+
def self.absolute_path?(path)
|
93
|
+
::File.absolute_path?(path)
|
94
|
+
end
|
95
|
+
elsif ::Dir.getwd =~ /^[a-zA-Z]:/
|
96
|
+
# @private
|
97
|
+
def self.absolute_path?(path)
|
98
|
+
/^[a-zA-Z]:/.match?(path)
|
99
|
+
end
|
100
|
+
else
|
101
|
+
# @private
|
102
|
+
def self.absolute_path?(path)
|
103
|
+
path.start_with?("/")
|
104
|
+
end
|
105
|
+
end
|
109
106
|
end
|
110
107
|
end
|
data/lib/toys/completion.rb
CHANGED
@@ -88,7 +88,7 @@ module Toys
|
|
88
88
|
|
89
89
|
##
|
90
90
|
# The tool being invoked, which should control the completion.
|
91
|
-
# @return [Toys::
|
91
|
+
# @return [Toys::ToolDefinition]
|
92
92
|
#
|
93
93
|
def tool
|
94
94
|
lookup_tool
|
@@ -236,6 +236,7 @@ module Toys
|
|
236
236
|
# prefix. Defaults to requiring the prefix be empty.
|
237
237
|
#
|
238
238
|
def initialize(cwd: nil, omit_files: false, omit_directories: false, prefix_constraint: "")
|
239
|
+
super()
|
239
240
|
@cwd = cwd || ::Dir.pwd
|
240
241
|
@include_files = !omit_files
|
241
242
|
@include_directories = !omit_directories
|
@@ -328,6 +329,7 @@ module Toys
|
|
328
329
|
# prefix. Defaults to requiring the prefix be empty.
|
329
330
|
#
|
330
331
|
def initialize(values, prefix_constraint: "")
|
332
|
+
super()
|
331
333
|
@values = values.flatten.map { |v| Candidate.new(v) }.sort
|
332
334
|
@prefix_constraint = prefix_constraint
|
333
335
|
end
|
data/lib/toys/context.rb
CHANGED
@@ -33,7 +33,7 @@ module Toys
|
|
33
33
|
# This module is mixed into the runtime context. This means you can
|
34
34
|
# reference any of these constants directly from your run method.
|
35
35
|
#
|
36
|
-
#
|
36
|
+
# ### Example
|
37
37
|
#
|
38
38
|
# tool "my-name" do
|
39
39
|
# def run
|
@@ -78,7 +78,7 @@ module Toys
|
|
78
78
|
LOGGER = ::Object.new.freeze
|
79
79
|
|
80
80
|
##
|
81
|
-
# Context key for the {Toys::
|
81
|
+
# Context key for the {Toys::ToolDefinition} object being executed.
|
82
82
|
# @return [Object]
|
83
83
|
#
|
84
84
|
TOOL = ::Object.new.freeze
|
data/lib/toys/core.rb
CHANGED
@@ -0,0 +1,85 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
##
|
4
|
+
# Create a base class for defining a tool with a given name.
|
5
|
+
#
|
6
|
+
# This method returns a base class for defining a tool with a given name.
|
7
|
+
# This is useful if the naming behavior of {Toys::Tool} is not adequate for
|
8
|
+
# your tool.
|
9
|
+
#
|
10
|
+
# ### Example
|
11
|
+
#
|
12
|
+
# class FooBar < Toys.Tool("Foo_Bar")
|
13
|
+
# desc "This is a tool called Foo_Bar"
|
14
|
+
#
|
15
|
+
# def run
|
16
|
+
# puts "Foo_Bar called"
|
17
|
+
# end
|
18
|
+
# end
|
19
|
+
#
|
20
|
+
# @param name [String] Name of the tool. Defaults to a name inferred from the
|
21
|
+
# class name. (See {Toys::Tool}.)
|
22
|
+
# @param base [Class] Use this tool class as the base class, and inherit helper
|
23
|
+
# methods from it.
|
24
|
+
# @param args [String,Class] Any string-valued positional argument is
|
25
|
+
# interpreted as the name. Any class-valued positional argument is
|
26
|
+
# interpreted as the base class.
|
27
|
+
#
|
28
|
+
def Toys.Tool(*args, name: nil, base: nil) # rubocop:disable Naming/MethodName
|
29
|
+
args.each do |arg|
|
30
|
+
case arg
|
31
|
+
when ::Class
|
32
|
+
raise ::ArgumentError, "Both base keyword argument and class-valud argument received" if base
|
33
|
+
base = arg
|
34
|
+
when ::String, ::Symbol
|
35
|
+
raise ::ArgumentError, "Both name keyword argument and string-valud argument received" if name
|
36
|
+
name = arg
|
37
|
+
else
|
38
|
+
raise ::ArgumentError, "Unrecognized argument: #{arg}"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
if base && !base.ancestors.include?(::Toys::Context)
|
42
|
+
raise ::ArgumentError, "Base class must itself be a tool"
|
43
|
+
end
|
44
|
+
return base || ::Toys::Tool if name.nil?
|
45
|
+
::Class.new(base || ::Toys::Context) do
|
46
|
+
base_class = self
|
47
|
+
define_singleton_method(:inherited) do |tool_class|
|
48
|
+
::Toys::DSL::Internal.configure_class(tool_class, base_class == self ? name.to_s : nil)
|
49
|
+
super(tool_class)
|
50
|
+
::Toys::DSL::Internal.setup_class_dsl(tool_class)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
module Toys
|
56
|
+
##
|
57
|
+
# Base class for defining tools
|
58
|
+
#
|
59
|
+
# This base class provides an alternative to the {Toys::DSL::Tool#tool}
|
60
|
+
# directive for defining tools in the Toys DSL. Creating a subclass of
|
61
|
+
# `Toys::Tool` will create a tool whose name is the "kebab-case" of the class
|
62
|
+
# name. Subclasses can be created only in the context of a tool configuration
|
63
|
+
# DSL. Furthermore, a class-defined tool can be created only at the top level
|
64
|
+
# of a configuration file, or within another class-defined tool. It cannot
|
65
|
+
# be a subtool of a tool block.
|
66
|
+
#
|
67
|
+
# ### Example
|
68
|
+
#
|
69
|
+
# class FooBar < Toys::Tool
|
70
|
+
# desc "This is a tool called foo-bar"
|
71
|
+
#
|
72
|
+
# def run
|
73
|
+
# puts "foo-bar called"
|
74
|
+
# end
|
75
|
+
# end
|
76
|
+
#
|
77
|
+
class Tool < Context
|
78
|
+
# @private
|
79
|
+
def self.inherited(tool_class)
|
80
|
+
DSL::Internal.configure_class(tool_class)
|
81
|
+
super
|
82
|
+
DSL::Internal.setup_class_dsl(tool_class)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|