toys 0.13.1 → 0.14.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +37 -0
- data/README.md +18 -17
- data/builtins/system/.toys.rb +40 -0
- data/builtins/system/git-cache.rb +15 -10
- data/builtins/system/test.rb +2 -3
- data/builtins/system/tools.rb +145 -0
- data/core-docs/toys/acceptor.rb +50 -8
- data/core-docs/toys/cli.rb +3 -3
- data/core-docs/toys/completion.rb +11 -0
- data/core-docs/toys/context.rb +16 -2
- data/core-docs/toys/core.rb +1 -1
- data/core-docs/toys/dsl/tool.rb +15 -7
- data/core-docs/toys/errors.rb +33 -0
- data/core-docs/toys/flag.rb +11 -0
- data/core-docs/toys/input_file.rb +6 -0
- data/core-docs/toys/loader.rb +146 -5
- data/core-docs/toys/middleware.rb +42 -2
- data/core-docs/toys/settings.rb +17 -0
- data/core-docs/toys/source_info.rb +95 -0
- data/core-docs/toys/standard_mixins/exec.rb +69 -22
- data/core-docs/toys/standard_mixins/pager.rb +46 -0
- data/core-docs/toys/standard_mixins/xdg.rb +7 -7
- data/core-docs/toys/tool_definition.rb +69 -0
- data/core-docs/toys/utils/exec.rb +61 -27
- data/core-docs/toys/utils/pager.rb +104 -0
- data/core-docs/toys/wrappable_string.rb +12 -0
- data/docs/guide.md +92 -67
- data/lib/toys/testing.rb +33 -2
- data/lib/toys/version.rb +1 -1
- metadata +10 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5605477c7993fad15f1c79740f8de6b90f4aef19becdc00a236e71853cb4d9a8
|
4
|
+
data.tar.gz: 1c63369d5c4302356f412e25904bd6db43ca93b9896c687c6ae5bbfd4fe24fc8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c312c18f2fa8d57f6dbeb8def6b434a611030387e289a370bcb96faadf90a49b948cfc7ac17b14f9e7b97a942a85b133d384ad37705aed9b833fca3f650517d1
|
7
|
+
data.tar.gz: 1f7125dbf036acb25b0352de30b68f95c229610572c754b8cdf3e1c633e03f5a6318eeb5de56df1d229402f4915d16aacb794d62fcd571007a604aec4ad6070f
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,42 @@
|
|
1
1
|
# Release History
|
2
2
|
|
3
|
+
### v0.14.2 / 2022-10-09
|
4
|
+
|
5
|
+
* ADDED: The tool directive supports the delegate_relative argument, as a preferred alternative over alias_tool.
|
6
|
+
* FIXED: The toys file reference now properly appears in error messages on Ruby 3.1.
|
7
|
+
* FIXED: Error messages show the correct toys file line number on TruffleRuby.
|
8
|
+
* FIXED: Inspect strings for tool classes are less opaque and include the tool name.
|
9
|
+
* FIXED: The presence of an acceptor forces an ambiguous flag to take a value rather than erroring.
|
10
|
+
|
11
|
+
### v0.14.1 / 2022-10-03
|
12
|
+
|
13
|
+
* FIXED: Fixed a crash due to a missing file in the gem
|
14
|
+
|
15
|
+
### v0.14.0 / 2022-10-03
|
16
|
+
|
17
|
+
Toys 0.14.0 is a major release with new system tools for introspecting defined tools, pager support, support for tees and pipes in the Exec utility, some cleanup of the behavior of Acceptors, and other improvements.
|
18
|
+
|
19
|
+
Fixes that are potentially breaking:
|
20
|
+
|
21
|
+
* Disallowed acceptors on flags that are explicitly boolean.
|
22
|
+
* Acceptors no longer sometimes apply to the boolean setting of a flag with an optional value.
|
23
|
+
|
24
|
+
New functionality:
|
25
|
+
|
26
|
+
* Implemented new builtins for obtaining information about defined tools: `system tools show` and `system tools list`.
|
27
|
+
* Implemented a utility class and mixin for output pagers.
|
28
|
+
* Builtin commands that display data can format as either YAML or JSON.
|
29
|
+
* The Exec utility and mixin can tee (i.e. duplicate and split) output streams.
|
30
|
+
* The Exec utility and mixin can take pipes as input and output streams.
|
31
|
+
* The Exec mixin provides a `verbosity_flags` convenience method.
|
32
|
+
|
33
|
+
Fixes:
|
34
|
+
|
35
|
+
* The `system test` builtin no longer requires toys to be installed as a gem.
|
36
|
+
* Fixed a failure when passing a relative path to `system test --directory`.
|
37
|
+
* Contents of preload directories are loaded in sorted order.
|
38
|
+
* Various clarifications, fixes, and updates to the users guide and documentation.
|
39
|
+
|
3
40
|
### v0.13.1 / 2022-03-01
|
4
41
|
|
5
42
|
* FIXED: Bundler integration no longer fails if a bundle was locked to a different version of a builtin gem
|
data/README.md
CHANGED
@@ -19,7 +19,7 @@ gem. For more info on using toys-core, see
|
|
19
19
|
|
20
20
|
Here's a tutorial to help you get a feel of what Toys can do.
|
21
21
|
|
22
|
-
### Install Toys
|
22
|
+
### Install and try out Toys
|
23
23
|
|
24
24
|
Install the **toys** gem using:
|
25
25
|
|
@@ -50,14 +50,6 @@ Toys does not yet specially implement tab completion for zsh or other shells.
|
|
50
50
|
However, if you are using zsh, installing bash completion using `bashcompinit`
|
51
51
|
*mostly* works.
|
52
52
|
|
53
|
-
Toys requires Ruby 2.4 or later.
|
54
|
-
|
55
|
-
Most parts of Toys work on JRuby. However, JRuby is not recommended because of
|
56
|
-
JVM boot latency, lack of support for Kernel#fork, and other issues.
|
57
|
-
|
58
|
-
Most parts of Toys work on TruffleRuby. However, TruffleRuby is not recommended
|
59
|
-
because it has a few known bugs that affect Toys.
|
60
|
-
|
61
53
|
### Write your first tool
|
62
54
|
|
63
55
|
You can define tools by creating a *Toys file*. Go into any directory, and,
|
@@ -244,8 +236,7 @@ you may need to add Toys to your Gemfile and use Bundler to invoke Toys (i.e.
|
|
244
236
|
`bundle exec toys test`). This is because Toys is just calling the Rake API to
|
245
237
|
run your task, and the Rake task might require the bundle. However, when Toys
|
246
238
|
is not wrapping Rake, typical practice is actually *not* to use `bundle exec`.
|
247
|
-
Toys provides its own mechanisms to
|
248
|
-
install individual gems.
|
239
|
+
Toys provides its own mechanisms to manage bundles or install gems for you.
|
249
240
|
|
250
241
|
So far, we've made Toys a front-end for your Rake tasks. This may be useful by
|
251
242
|
itself. Toys lets you pass command line arguments "normally" to tools, whereas
|
@@ -256,11 +247,11 @@ than Rake does.
|
|
256
247
|
But you also might find Toys a more natural way to *write* tasks, and indeed
|
257
248
|
you can often rewrite an entire Rakefile as a Toys file and get quite a bit of
|
258
249
|
benefit in readability and maintainability. For an example, see the
|
259
|
-
[Toys file for the Toys
|
260
|
-
It contains
|
261
|
-
|
262
|
-
|
263
|
-
|
250
|
+
[Toys file for the Toys gem itself](https://github.com/dazuma/toys/blob/main/toys/.toys/.toys.rb).
|
251
|
+
It contains Toys scripts that I use to develop, test, and release Toys itself.
|
252
|
+
Yes, Toys is self-hosted. You'll notice most of this Toys file consists of
|
253
|
+
template expansions. Toys provides templates for a lot of common build, test,
|
254
|
+
and release tasks for Ruby projects.
|
264
255
|
|
265
256
|
If you're feeling adventurous, try translating some of your Rake tasks into
|
266
257
|
native Toys tools. You can do so in your existing `.toys.rb` file. Keep the
|
@@ -305,7 +296,7 @@ them. Furthermore, when writing new scripts, I was repeating the same
|
|
305
296
|
OptionParser boilerplate and common functionality.
|
306
297
|
|
307
298
|
Toys was designed to address those problems by providing a framework for
|
308
|
-
writing
|
299
|
+
writing and organizing your own command line scripts. You provide the actual
|
309
300
|
functionality by writing Toys files, and Toys takes care of all the other
|
310
301
|
details expected from a good command line tool. It provides a streamlined
|
311
302
|
interface for defining and handling command line flags and positional
|
@@ -320,6 +311,16 @@ scripts written for Toys can be invoked and passed arguments and flags using
|
|
320
311
|
familiar unix command line conventions. The Toys github repo itself comes with
|
321
312
|
Toys scripts instead of Rakefiles.
|
322
313
|
|
314
|
+
## System requirements
|
315
|
+
|
316
|
+
Toys requires Ruby 2.4 or later.
|
317
|
+
|
318
|
+
Most parts of Toys work on JRuby. However, JRuby is not recommended because of
|
319
|
+
JVM boot latency, lack of support for Kernel#fork, and other issues.
|
320
|
+
|
321
|
+
Most parts of Toys work on TruffleRuby. However, TruffleRuby is not recommended
|
322
|
+
because it has a few known bugs that affect Toys.
|
323
|
+
|
323
324
|
## License
|
324
325
|
|
325
326
|
Copyright 2019-2022 Daniel Azuma and the Toys contributors
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
desc "A set of system commands for Toys"
|
4
|
+
|
5
|
+
long_desc "Contains tools that inspect, configure, and update Toys itself."
|
6
|
+
|
7
|
+
tool "version" do
|
8
|
+
desc "Print the current Toys version"
|
9
|
+
|
10
|
+
def run
|
11
|
+
puts ::Toys::VERSION
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
mixin "output-tools" do
|
16
|
+
on_include do
|
17
|
+
flag :output_format, "--format=FORMAT" do
|
18
|
+
accept ["json", "json-compact", "yaml"]
|
19
|
+
desc 'The output format. Recognized values are "yaml" (the default), "json", and ' \
|
20
|
+
'"json-compact".'
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def generate_output(object)
|
25
|
+
case output_format
|
26
|
+
when "json"
|
27
|
+
require "json"
|
28
|
+
::JSON.pretty_generate(object)
|
29
|
+
when "json-compact"
|
30
|
+
require "json"
|
31
|
+
::JSON.generate(object)
|
32
|
+
when nil, "yaml"
|
33
|
+
require "psych"
|
34
|
+
::Psych.dump(object)
|
35
|
+
else
|
36
|
+
logger.error("Unknown output format: #{format}")
|
37
|
+
exit(1)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -23,15 +23,16 @@ tool "list" do
|
|
23
23
|
desc "The base directory for the cache. Optional. Defaults to the standard cache directory."
|
24
24
|
end
|
25
25
|
|
26
|
+
include "output-tools"
|
27
|
+
|
26
28
|
def run
|
27
|
-
require "psych"
|
28
29
|
require "toys/utils/git_cache"
|
29
30
|
git_cache = ::Toys::Utils::GitCache.new(cache_dir: cache_dir)
|
30
31
|
output = {
|
31
32
|
"cache_dir" => git_cache.cache_dir,
|
32
33
|
"remotes" => git_cache.remotes,
|
33
34
|
}
|
34
|
-
puts(
|
35
|
+
puts(generate_output(output))
|
35
36
|
end
|
36
37
|
end
|
37
38
|
|
@@ -48,8 +49,9 @@ tool "show" do
|
|
48
49
|
desc "The base directory for the cache. Optional. Defaults to the standard cache directory."
|
49
50
|
end
|
50
51
|
|
52
|
+
include "output-tools"
|
53
|
+
|
51
54
|
def run
|
52
|
-
require "psych"
|
53
55
|
require "toys/utils/git_cache"
|
54
56
|
git_cache = ::Toys::Utils::GitCache.new(cache_dir: cache_dir)
|
55
57
|
info = git_cache.repo_info(remote)
|
@@ -57,7 +59,7 @@ tool "show" do
|
|
57
59
|
logger.fatal("Unknown remote: #{remote}")
|
58
60
|
exit(1)
|
59
61
|
end
|
60
|
-
puts(
|
62
|
+
puts(generate_output(info.to_h))
|
61
63
|
end
|
62
64
|
end
|
63
65
|
|
@@ -130,8 +132,9 @@ tool "remove" do
|
|
130
132
|
desc "Remove all repositories. Required unless specific remotes are provided."
|
131
133
|
end
|
132
134
|
|
135
|
+
include "output-tools"
|
136
|
+
|
133
137
|
def run
|
134
|
-
require "psych"
|
135
138
|
require "toys/utils/git_cache"
|
136
139
|
if remotes.empty? == !all
|
137
140
|
logger.fatal("You must specify at least one remote to clear, or --all to clear all remotes.")
|
@@ -142,7 +145,7 @@ tool "remove" do
|
|
142
145
|
output = {
|
143
146
|
"removed" => removed,
|
144
147
|
}
|
145
|
-
puts(
|
148
|
+
puts(generate_output(output))
|
146
149
|
end
|
147
150
|
end
|
148
151
|
|
@@ -175,8 +178,9 @@ tool "remove-refs" do
|
|
175
178
|
desc "The base directory for the cache. Optional. Defaults to the standard cache directory."
|
176
179
|
end
|
177
180
|
|
181
|
+
include "output-tools"
|
182
|
+
|
178
183
|
def run
|
179
|
-
require "psych"
|
180
184
|
require "toys/utils/git_cache"
|
181
185
|
git_cache = ::Toys::Utils::GitCache.new(cache_dir: cache_dir)
|
182
186
|
removed = git_cache.remove_refs(remote, refs: refs)
|
@@ -188,7 +192,7 @@ tool "remove-refs" do
|
|
188
192
|
"remote" => remote,
|
189
193
|
"removed_refs" => removed.map(&:to_h),
|
190
194
|
}
|
191
|
-
puts(
|
195
|
+
puts(generate_output(output))
|
192
196
|
end
|
193
197
|
end
|
194
198
|
|
@@ -220,8 +224,9 @@ tool "remove-sources" do
|
|
220
224
|
desc "The base directory for the cache. Optional. Defaults to the standard cache directory."
|
221
225
|
end
|
222
226
|
|
227
|
+
include "output-tools"
|
228
|
+
|
223
229
|
def run
|
224
|
-
require "psych"
|
225
230
|
require "toys/utils/git_cache"
|
226
231
|
git_cache = ::Toys::Utils::GitCache.new(cache_dir: cache_dir)
|
227
232
|
removed = git_cache.remove_sources(remote, commits: commits)
|
@@ -233,6 +238,6 @@ tool "remove-sources" do
|
|
233
238
|
"remote" => remote,
|
234
239
|
"removed_sources" => removed.map(&:to_h),
|
235
240
|
}
|
236
|
-
puts(
|
241
|
+
puts(generate_output(output))
|
237
242
|
end
|
238
243
|
end
|
data/builtins/system/test.rb
CHANGED
@@ -30,7 +30,6 @@ include :terminal
|
|
30
30
|
|
31
31
|
def run
|
32
32
|
load_minitest_gems
|
33
|
-
::Dir.chdir(tool_dir)
|
34
33
|
test_files = find_test_files
|
35
34
|
result = exec_ruby(ruby_args, in: :controller, log_cmd: "Starting minitest...") do |controller|
|
36
35
|
controller.in.puts("gem 'minitest', '= #{::Minitest::VERSION}'")
|
@@ -43,7 +42,6 @@ def run
|
|
43
42
|
controller.in.puts("gem 'minitest-rg', '= #{::MiniTest::RG::VERSION}'")
|
44
43
|
controller.in.puts("require 'minitest/rg'")
|
45
44
|
end
|
46
|
-
controller.in.puts("gem 'toys', '= #{::Toys::VERSION}'")
|
47
45
|
controller.in.puts("require 'toys'")
|
48
46
|
controller.in.puts("require 'toys/testing'")
|
49
47
|
if directory
|
@@ -79,7 +77,8 @@ end
|
|
79
77
|
def find_test_files
|
80
78
|
glob = ".test/**/test_*.rb"
|
81
79
|
glob = "**/#{glob}" if recursive
|
82
|
-
|
80
|
+
glob = "#{tool_dir}/#{glob}"
|
81
|
+
test_files = Dir.glob(glob)
|
83
82
|
if test_files.empty?
|
84
83
|
logger.warn("No test files found")
|
85
84
|
exit
|
@@ -0,0 +1,145 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
mixin "tool-methods" do
|
4
|
+
def format_tool(tool, namespace, detailed: false)
|
5
|
+
output = {
|
6
|
+
"name" => tool.full_name[namespace.length..-1].join(" "),
|
7
|
+
"desc" => tool.desc.to_s,
|
8
|
+
"runnable" => tool.runnable?,
|
9
|
+
}
|
10
|
+
if detailed
|
11
|
+
output["exists"] = true
|
12
|
+
output["long_desc"] = tool.long_desc.map(&:to_s)
|
13
|
+
end
|
14
|
+
output
|
15
|
+
end
|
16
|
+
|
17
|
+
def choose_loader(local, from_dir)
|
18
|
+
return cli.loader unless local || from_dir
|
19
|
+
if from_dir
|
20
|
+
unless ::File.directory?(from_dir)
|
21
|
+
logger.fatal("Not a directory: #{from_dir}")
|
22
|
+
exit(1)
|
23
|
+
end
|
24
|
+
if ::File.basename(from_dir) == ".toys"
|
25
|
+
from_dir = ::File.dirname(from_dir)
|
26
|
+
elsif from_dir =~ %r{(^|/)\.toys/}
|
27
|
+
logger.fatal("Directory is inside a toys directory: #{from_dir}")
|
28
|
+
exit(1)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
special_cli = if local
|
32
|
+
cli.child.add_search_path(from_dir || ::Dir.getwd)
|
33
|
+
else
|
34
|
+
::Toys::StandardCLI.new(cur_dir: from_dir)
|
35
|
+
end
|
36
|
+
special_cli.loader
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
desc "Tools that introspect available tools"
|
41
|
+
|
42
|
+
long_desc \
|
43
|
+
"Tools that introspect the available tools."
|
44
|
+
|
45
|
+
tool "list" do
|
46
|
+
desc "Output a list of the tools under the given namespace."
|
47
|
+
|
48
|
+
long_desc \
|
49
|
+
"Outputs a list of the tools under the given namespace, in YAML format, to the standard " \
|
50
|
+
"output stream."
|
51
|
+
|
52
|
+
remaining_args :namespace
|
53
|
+
|
54
|
+
flag :local do
|
55
|
+
desc "List only tools defined locally in the current directory."
|
56
|
+
end
|
57
|
+
flag :recursive, "--[no-]recursive" do
|
58
|
+
desc "Recursively list subtools"
|
59
|
+
end
|
60
|
+
flag :flatten, "--[no-]flatten" do
|
61
|
+
desc "Display a flattened list of tools"
|
62
|
+
end
|
63
|
+
flag :from_dir, "--dir=PATH" do
|
64
|
+
desc "List tools from the given directory."
|
65
|
+
end
|
66
|
+
flag :show_all, "--all" do
|
67
|
+
desc "Show all tools, including hidden tools and non-runnable namespaces"
|
68
|
+
end
|
69
|
+
|
70
|
+
include "tool-methods"
|
71
|
+
include "output-tools"
|
72
|
+
|
73
|
+
def run
|
74
|
+
loader = choose_loader(local, from_dir)
|
75
|
+
words = namespace
|
76
|
+
words = loader.split_path(words.first) if words.size == 1
|
77
|
+
tool_list = loader.list_subtools(words,
|
78
|
+
recursive: recursive,
|
79
|
+
include_hidden: show_all,
|
80
|
+
include_namespaces: show_all || !flatten,
|
81
|
+
include_non_runnable: show_all)
|
82
|
+
output = {
|
83
|
+
"namespace" => words.join(" "),
|
84
|
+
"tools" => [],
|
85
|
+
}
|
86
|
+
if flatten
|
87
|
+
output["tools"] = tool_list.map { |tool| format_tool(tool, words) }
|
88
|
+
else
|
89
|
+
format_tool_list(tool_list, output, words)
|
90
|
+
end
|
91
|
+
puts(generate_output(output))
|
92
|
+
end
|
93
|
+
|
94
|
+
def format_tool_list(tool_list, toplevel, cur_ns)
|
95
|
+
stack = [toplevel]
|
96
|
+
tool_list.each do |tool|
|
97
|
+
tool_name_size = tool.full_name.size
|
98
|
+
while cur_ns.size >= tool_name_size
|
99
|
+
stack.pop
|
100
|
+
cur_ns.pop
|
101
|
+
end
|
102
|
+
formatted = format_tool(tool, cur_ns)
|
103
|
+
(stack.last["tools"] ||= []) << formatted
|
104
|
+
stack.push(formatted)
|
105
|
+
cur_ns.push(tool.full_name.last)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
tool "show" do
|
111
|
+
desc "Show detailed information about a single tool"
|
112
|
+
|
113
|
+
long_desc \
|
114
|
+
"Outputs details about the given tool, in YAML format, to the standard output stream."
|
115
|
+
|
116
|
+
remaining_args :name
|
117
|
+
|
118
|
+
flag :local do
|
119
|
+
desc "Show only tools defined locally in the current directory."
|
120
|
+
end
|
121
|
+
flag :from_dir, "--dir=PATH" do
|
122
|
+
desc "Show a tool accessible from the given directory."
|
123
|
+
end
|
124
|
+
|
125
|
+
include "tool-methods"
|
126
|
+
include "output-tools"
|
127
|
+
|
128
|
+
def run
|
129
|
+
loader = choose_loader(local, from_dir)
|
130
|
+
words = name
|
131
|
+
words = loader.split_path(words.first) if words.size == 1
|
132
|
+
tool = loader.lookup_specific(words)
|
133
|
+
output =
|
134
|
+
if tool.nil?
|
135
|
+
{
|
136
|
+
"name" => words.join(" "),
|
137
|
+
"exists" => false,
|
138
|
+
}
|
139
|
+
else
|
140
|
+
format_tool(tool, [], detailed: true)
|
141
|
+
end
|
142
|
+
puts(generate_output(output))
|
143
|
+
exit(tool.nil? ? 1 : 0)
|
144
|
+
end
|
145
|
+
end
|
data/core-docs/toys/acceptor.rb
CHANGED
@@ -84,7 +84,7 @@ module Toys
|
|
84
84
|
# When given a valid input, return an array in which the first element is
|
85
85
|
# the original input string, and the remaining elements (which may be
|
86
86
|
# empty) comprise any additional information that may be useful during
|
87
|
-
# conversion. If there is no additional information, you
|
87
|
+
# conversion. If there is no additional information, you can return the
|
88
88
|
# original input string by itself without wrapping in an array.
|
89
89
|
#
|
90
90
|
# When given an invalid input, return a falsy value such as `nil`.
|
@@ -96,8 +96,7 @@ module Toys
|
|
96
96
|
# as the only array element, indicating all inputs are valid. You can
|
97
97
|
# override this method to provide a different validation function.
|
98
98
|
#
|
99
|
-
# @param str [String
|
100
|
-
# value is optional and not provided.
|
99
|
+
# @param str [String] The input argument string.
|
101
100
|
# @return [String,Array,nil]
|
102
101
|
#
|
103
102
|
def match(str)
|
@@ -111,8 +110,7 @@ module Toys
|
|
111
110
|
# original input string and any other values returned from {#match}. It
|
112
111
|
# must return the final converted value to use.
|
113
112
|
#
|
114
|
-
# @param str [String
|
115
|
-
# value is optional and not provided.
|
113
|
+
# @param str [String] Original argument string.
|
116
114
|
# @param extra [Object...] Zero or more additional arguments comprising
|
117
115
|
# additional elements returned from the match function.
|
118
116
|
# @return [Object] The converted argument as it should be stored in the
|
@@ -337,9 +335,7 @@ module Toys
|
|
337
335
|
#
|
338
336
|
NUMERIC_CONVERTER =
|
339
337
|
proc do |s|
|
340
|
-
if s.
|
341
|
-
nil
|
342
|
-
elsif s.include?("/")
|
338
|
+
if s.include?("/")
|
343
339
|
Rational(s)
|
344
340
|
elsif s.include?(".") || (s.include?("e") && s !~ /\A-?0x/)
|
345
341
|
Float(s)
|
@@ -348,6 +344,41 @@ module Toys
|
|
348
344
|
end
|
349
345
|
end
|
350
346
|
|
347
|
+
##
|
348
|
+
# A set of strings that are considered true for boolean acceptors.
|
349
|
+
# Currently set to `["+", "true", "yes"]`.
|
350
|
+
# @return [Array<String>]
|
351
|
+
#
|
352
|
+
TRUE_STRINGS = ["+", "true", "yes"].freeze
|
353
|
+
|
354
|
+
##
|
355
|
+
# A set of strings that are considered false for boolean acceptors.
|
356
|
+
# Currently set to `["-", "false", "no", "nil"]`.
|
357
|
+
# @return [Array<String>]
|
358
|
+
#
|
359
|
+
FALSE_STRINGS = ["-", "false", "no", "nil"].freeze
|
360
|
+
|
361
|
+
##
|
362
|
+
# A converter proc that handles boolean strings. Recognizes {TRUE_STRINGS}
|
363
|
+
# and {FALSE_STRINGS}. Useful for Simple acceptors.
|
364
|
+
# @return [Proc]
|
365
|
+
#
|
366
|
+
BOOLEAN_CONVERTER =
|
367
|
+
proc do |s|
|
368
|
+
if s.empty?
|
369
|
+
REJECT
|
370
|
+
else
|
371
|
+
s = s.downcase
|
372
|
+
if TRUE_STRINGS.any? { |t| t.start_with?(s) }
|
373
|
+
true
|
374
|
+
elsif FALSE_STRINGS.any? { |f| f.start_with?(s) }
|
375
|
+
false
|
376
|
+
else
|
377
|
+
REJECT
|
378
|
+
end
|
379
|
+
end
|
380
|
+
end
|
381
|
+
|
351
382
|
class << self
|
352
383
|
##
|
353
384
|
# Lookup a standard acceptor name recognized by OptionParser.
|
@@ -427,6 +458,17 @@ module Toys
|
|
427
458
|
def create(spec = nil, **options, &block)
|
428
459
|
# Source available in the toys-core gem
|
429
460
|
end
|
461
|
+
|
462
|
+
##
|
463
|
+
# Take the various ways to express an acceptor spec, and convert them to
|
464
|
+
# a canonical form expressed as a single object. This is called from the
|
465
|
+
# DSL to generate a spec object that can be stored.
|
466
|
+
#
|
467
|
+
# @private This interface is internal and subject to change without warning.
|
468
|
+
#
|
469
|
+
def scalarize_spec(spec, options, block)
|
470
|
+
# Source available in the toys-core gem
|
471
|
+
end
|
430
472
|
end
|
431
473
|
end
|
432
474
|
end
|
data/core-docs/toys/cli.rb
CHANGED
@@ -193,9 +193,9 @@ module Toys
|
|
193
193
|
end
|
194
194
|
|
195
195
|
##
|
196
|
-
# Make a clone with the same settings but no
|
197
|
-
#
|
198
|
-
#
|
196
|
+
# Make a clone with the same settings but no config blocks and no paths in
|
197
|
+
# the loader. This is sometimes useful for calling another tool that has to
|
198
|
+
# be loaded from a different configuration.
|
199
199
|
#
|
200
200
|
# @param opts [keywords] Any configuration arguments that should be
|
201
201
|
# modified from the original. See {#initialize} for a list of
|
@@ -325,5 +325,16 @@ module Toys
|
|
325
325
|
def self.create(spec = nil, **options, &block)
|
326
326
|
# Source available in the toys-core gem
|
327
327
|
end
|
328
|
+
|
329
|
+
##
|
330
|
+
# Take the various ways to express a completion spec, and convert them to a
|
331
|
+
# canonical form expressed as a single object. This is called from the DSL
|
332
|
+
# DSL to generate a spec object that can be stored.
|
333
|
+
#
|
334
|
+
# @private This interface is internal and subject to change without warning.
|
335
|
+
#
|
336
|
+
def self.scalarize_spec(spec, options, block)
|
337
|
+
# Source available in the toys-core gem
|
338
|
+
end
|
328
339
|
end
|
329
340
|
end
|
data/core-docs/toys/context.rb
CHANGED
@@ -297,7 +297,7 @@ module Toys
|
|
297
297
|
end
|
298
298
|
|
299
299
|
##
|
300
|
-
# Exit immediately with the given status code
|
300
|
+
# Exit immediately with the given status code.
|
301
301
|
#
|
302
302
|
# @param code [Integer] The status code, which should be 0 for no error,
|
303
303
|
# or nonzero for an error condition. Default is 0.
|
@@ -308,7 +308,8 @@ module Toys
|
|
308
308
|
end
|
309
309
|
|
310
310
|
##
|
311
|
-
# Exit immediately with the given status code
|
311
|
+
# Exit immediately with the given status code. This class method can be
|
312
|
+
# called if the instance method is or could be replaced by the tool.
|
312
313
|
#
|
313
314
|
# @param code [Integer] The status code, which should be 0 for no error,
|
314
315
|
# or nonzero for an error condition. Default is 0.
|
@@ -317,5 +318,18 @@ module Toys
|
|
317
318
|
def self.exit(code = 0)
|
318
319
|
# Source available in the toys-core gem
|
319
320
|
end
|
321
|
+
|
322
|
+
##
|
323
|
+
# Create a Context object. Applications generally will not need to create
|
324
|
+
# these objects directly; they are created by the tool when it is preparing
|
325
|
+
# for execution.
|
326
|
+
#
|
327
|
+
# @param data [Hash]
|
328
|
+
#
|
329
|
+
# @private This interface is internal and subject to change without warning.
|
330
|
+
#
|
331
|
+
def initialize(data)
|
332
|
+
# Source available in the toys-core gem
|
333
|
+
end
|
320
334
|
end
|
321
335
|
end
|
data/core-docs/toys/core.rb
CHANGED
data/core-docs/toys/dsl/tool.rb
CHANGED
@@ -263,7 +263,8 @@ module Toys
|
|
263
263
|
# end
|
264
264
|
# end
|
265
265
|
#
|
266
|
-
# The following example
|
266
|
+
# The following example uses `delegate_to` to define a tool that runs one
|
267
|
+
# of its subtools.
|
267
268
|
#
|
268
269
|
# tool "test", delegate_to: ["test", "unit"] do
|
269
270
|
# tool "unit" do
|
@@ -284,19 +285,22 @@ module Toys
|
|
284
285
|
# delegate to another tool, specified by the full path. This path may
|
285
286
|
# be given as an array of strings, or a single string possibly
|
286
287
|
# delimited by path separators.
|
288
|
+
# @param delegate_relative [String,Array<String>] Optional. Similar to
|
289
|
+
# delegate_to, but takes a delegate name relative to the context in
|
290
|
+
# which this tool is being defined.
|
287
291
|
# @param block [Proc] Defines the subtool.
|
288
292
|
# @return [self]
|
289
293
|
#
|
290
|
-
def tool(words, if_defined: :combine, delegate_to: nil, &block)
|
294
|
+
def tool(words, if_defined: :combine, delegate_to: nil, delegate_relative: nil, &block)
|
291
295
|
# Source available in the toys-core gem
|
292
296
|
end
|
293
297
|
|
294
298
|
##
|
295
299
|
# Create an alias, representing an "alternate name" for a tool.
|
296
300
|
#
|
297
|
-
# This is functionally equivalent to creating a
|
298
|
-
# `
|
299
|
-
#
|
301
|
+
# Note: This is functionally equivalent to creating a tool with the
|
302
|
+
# `:delegate_relative` option. As such, `alias_tool` is considered
|
303
|
+
# deprecated.
|
300
304
|
#
|
301
305
|
# ### Example
|
302
306
|
#
|
@@ -309,20 +313,24 @@ module Toys
|
|
309
313
|
# end
|
310
314
|
# end
|
311
315
|
# alias_tool "t", "test"
|
316
|
+
# # Note: the following is preferred over alias_tool:
|
317
|
+
# # tool "t", delegate_relative: "test"
|
312
318
|
#
|
313
319
|
# @param word [String] The name of the alias
|
314
320
|
# @param target [String,Array<String>] Relative path to the target of the
|
315
321
|
# alias. This path may be given as an array of strings, or a single
|
316
322
|
# string possibly delimited by path separators.
|
317
323
|
# @return [self]
|
324
|
+
# @deprecated Use {#tool} and pass `:delegate_relative` instead
|
318
325
|
#
|
319
326
|
def alias_tool(word, target)
|
320
327
|
# Source available in the toys-core gem
|
321
328
|
end
|
322
329
|
|
323
330
|
##
|
324
|
-
# Causes the current tool to delegate to another tool
|
325
|
-
# simply invokes the target tool with the
|
331
|
+
# Causes the current tool to delegate to another tool, specified by the
|
332
|
+
# full tool name. When run, it simply invokes the target tool with the
|
333
|
+
# same arguments.
|
326
334
|
#
|
327
335
|
# ### Example
|
328
336
|
#
|