toys-core 0.10.3 → 0.11.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 +64 -33
- data/README.md +5 -5
- data/docs/guide.md +2 -0
- data/lib/toys/acceptor.rb +1 -1
- data/lib/toys/compat.rb +5 -1
- data/lib/toys/core.rb +1 -1
- data/lib/toys/dsl/flag.rb +2 -2
- data/lib/toys/dsl/flag_group.rb +2 -2
- data/lib/toys/dsl/tool.rb +27 -6
- data/lib/toys/loader.rb +71 -31
- data/lib/toys/source_info.rb +22 -23
- data/lib/toys/standard_mixins/bundler.rb +121 -40
- data/lib/toys/utils/exec.rb +101 -28
- data/lib/toys/utils/gems.rb +118 -31
- data/lib/toys/utils/help_text.rb +54 -59
- data/lib/toys/utils/terminal.rb +1 -1
- metadata +5 -131
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 37117af06be544465a07f95706310e3b8de1ad4dbc58f53e113b2595eed70e47
|
4
|
+
data.tar.gz: 6e27a716c74435ff2060838dbde56af35b4df93dcdc671051397755f478cc233
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a9dc2dc2e8287fbdb1c7695ed9111360d7bfcfc17167c6b790b170843988acb198daa8d99050d910ee5ea41876b2bb6c2e22cbab9629e322c9e7687f90a34c99
|
7
|
+
data.tar.gz: '03283300b1140b477ae56276a066953eb4fc6c71aa2a14b2e0fbe66cc9934c3afbd30862349ee922d98c4e0b9e80e74e50ba180bddc939dec99ead630eb7ddf2'
|
data/CHANGELOG.md
CHANGED
@@ -1,18 +1,49 @@
|
|
1
1
|
# Release History
|
2
2
|
|
3
|
-
###
|
3
|
+
### v0.11.2 / 2020-09-06
|
4
|
+
|
5
|
+
* FIXED: Fix a JRuby-specific race condition when capturing exec streams
|
6
|
+
|
7
|
+
### v0.11.1 / 2020-08-24
|
8
|
+
|
9
|
+
* DOCS: Minor documentation tweaks.
|
10
|
+
|
11
|
+
### v0.11.0 / 2020-08-21
|
12
|
+
|
13
|
+
* ADDED: The load path can be truncated using the `truncate_load_path!` directive.
|
14
|
+
* IMPROVED: Generated help for delegates now includes the information for the target tool, plus subtools of the delegate.
|
15
|
+
* IMPROVED: The `:bundler` mixin searches for `gems.rb` and `.gems.rb` in addition to `Gemfile`.
|
16
|
+
* IMPROVED: The `:budnler` mixin can load a specific Gemfile path.
|
17
|
+
* FIXED: The loader can now find data and lib directories at the root level of a Toys directory.
|
18
|
+
* FIXED: Exec::Result correctly reports processes that terminated due to signals.
|
19
|
+
* FIXED: Fixed a rare Exec capture failure that resulted from a race condition when closing streams.
|
20
|
+
|
21
|
+
### v0.10.5 / 2020-07-18
|
22
|
+
|
23
|
+
* IMPROVED: The bundler mixin silences bundler output during bundle setup.
|
24
|
+
* IMPROVED: The bundler mixin allows toys and toys-core to be in the Gemfile. It checks their version requirements against the running Toys version, and either adds the corret version to the bundle or raises IncompatibleToysError.
|
25
|
+
* IMPROVED: The bundler mixin automatically updates the bundle if install fails (typically because a transitive dependency has been explicitly updated.)
|
26
|
+
* FIXED: Some cases of transitive dependency handling by the bundler mixin.
|
27
|
+
* FIXED: Fixed a crash when computing suggestions, when running with a bundle on Ruby 2.6 or earlier.
|
28
|
+
|
29
|
+
### v0.10.4 / 2020-07-11
|
30
|
+
|
31
|
+
* IMPROVED: Bundler integration can now handle Toys itself being in the bundle, as long as the version requirements cover the running Toys version.
|
32
|
+
* IMPROVED: Passing `static: true` to the `:bundler` mixin installs the bundle at definition rather than execution time.
|
33
|
+
|
34
|
+
### v0.10.3 / 2020-07-04
|
4
35
|
|
5
36
|
* FIXED: The `exec_separate_tool` method in the `:exec` mixin no longer throws ENOEXEC on Windows.
|
6
37
|
|
7
|
-
###
|
38
|
+
### v0.10.2 / 2020-07-03
|
8
39
|
|
9
40
|
* FIXED: The load path no longer loses the toys and toys-core directories after a bundle install.
|
10
41
|
|
11
|
-
###
|
42
|
+
### v0.10.1 / 2020-03-07
|
12
43
|
|
13
44
|
* FIXED: Setting `:exit_on_nonzero_status` explicitly to false now works as expected.
|
14
45
|
|
15
|
-
###
|
46
|
+
### v0.10.0 / 2020-02-24
|
16
47
|
|
17
48
|
Functional changes:
|
18
49
|
|
@@ -42,16 +73,16 @@ Internal interface changes:
|
|
42
73
|
* CHANGED: `Toys::CLI.default_logger` removed and replaced with `Toys::CLI.default_logger_factory`. In general, global loggers for CLI are now discouraged because they are not thread-safe.
|
43
74
|
* CHANGED: `Toys::Loader` uses an internal monitor rather than including `MonitorMixin`.
|
44
75
|
|
45
|
-
###
|
76
|
+
### v0.9.4 / 2020-01-26
|
46
77
|
|
47
78
|
* FIXED: Crash in the loader when a non-ruby file appears in a toys directory
|
48
79
|
|
49
|
-
###
|
80
|
+
### v0.9.3 / 2020-01-05
|
50
81
|
|
51
82
|
* FIXED: `delegate_to` directive could crash if an overriding tool has already been defined.
|
52
83
|
* FIXED: A Ruby 2.7 warning when reporting a Toys file syntax error.
|
53
84
|
|
54
|
-
###
|
85
|
+
### v0.9.2 / 2020-01-03
|
55
86
|
|
56
87
|
* IMPROVED: Mixins can now take real keyword arguments, and will pass them on properly to `on_initialize` and `on_include` blocks.
|
57
88
|
* CHANGED: `Toys::Utils::Exec` and the `:exec` mixin methods now take real keyword arguments rather than an `opts` hash. This means you should use keywords (or the double-splat operator) to avoid a deprecation warning on Ruby 2.7.
|
@@ -59,11 +90,11 @@ Internal interface changes:
|
|
59
90
|
* IMPROVED: `Toys::Loader` is now thread-safe. This means it is now possible for a single `Toys::CLI` to run multiple tools in different threads.
|
60
91
|
* IMPROVED: There is now a class for middleware specs, making possible a nicer syntax for building a middleware stack.
|
61
92
|
|
62
|
-
###
|
93
|
+
### v0.9.1 / 2019-12-22
|
63
94
|
|
64
95
|
* IMPROVED: `delegate_to` and `alias_tool` can take symbols as well as strings.
|
65
96
|
|
66
|
-
###
|
97
|
+
### v0.9.0 / 2019-12-02
|
67
98
|
|
68
99
|
Functional changes:
|
69
100
|
|
@@ -86,12 +117,12 @@ Internal interface changes:
|
|
86
117
|
* ADDED: `Toys::Tool#delegate_to` causes the tool to delegate to another tool.
|
87
118
|
* ADDED: The `Toys::Context::Key::DELEGATED_FROM` key provides the delegating context, if any.
|
88
119
|
|
89
|
-
###
|
120
|
+
### v0.8.1 / 2019-11-19
|
90
121
|
|
91
122
|
* FIXED: Listing subtools would crash if a broken alias was present.
|
92
123
|
* DOCUMENTATION: Switched from redcarpet to kramdown, and tried to make some structural fixes.
|
93
124
|
|
94
|
-
###
|
125
|
+
### v0.8.0 / 2019-06-20
|
95
126
|
|
96
127
|
This is a major update with significant new features and a bunch of fixes. It also includes a significant amount of internal reorganization and cleanup, some of which resulted in backward incompatible changes. Basic use should not be affected. All signifiant features planned for beta are now implemented.
|
97
128
|
|
@@ -190,17 +221,17 @@ Changes to internal interfaces:
|
|
190
221
|
* ADDED: Range acceptor (`Acceptor::Range`) which validates against a range.
|
191
222
|
* ADDED: Class methods `Acceptor.create` and `Acceptor.lookup_well_known`.
|
192
223
|
|
193
|
-
###
|
224
|
+
### v0.7.0 / 2019-01-23
|
194
225
|
|
195
226
|
* ADDED: Flag groups, which enforce policies around which flags are required.
|
196
227
|
* CHANGED: Flags within a group are sorted in help screens.
|
197
228
|
* CHANGED: Canonical flag within a flag definition is now the first rather than the last.
|
198
229
|
|
199
|
-
###
|
230
|
+
### v0.6.1 / 2019-01-07
|
200
231
|
|
201
232
|
* FIXED: The presence of aliases caused subtool listing to crash.
|
202
233
|
|
203
|
-
###
|
234
|
+
### v0.6.0 / 2018-10-22
|
204
235
|
|
205
236
|
* CHANGED: Replaced Toys::Definition::DataFinder with Toys::Definition::SourceInfo.
|
206
237
|
* CHANGED: Removed Toys::Definition#find_data. Use Toys::Definition#source_info and call find_data.
|
@@ -209,7 +240,7 @@ Changes to internal interfaces:
|
|
209
240
|
from subtool lists.
|
210
241
|
* IMPROVED: Optionally omit non-runnable namespaces from recursive subtool lists.
|
211
242
|
|
212
|
-
###
|
243
|
+
### v0.5.0 / 2018-10-07
|
213
244
|
|
214
245
|
* FIXED: Template instantiation was failing if the hosting tool was priority-masked.
|
215
246
|
* ADDED: Several additional characters can optionally be used as tool path delimiters.
|
@@ -219,31 +250,31 @@ Changes to internal interfaces:
|
|
219
250
|
* IMPROVED: The tool directive can now take an array as the tool name.
|
220
251
|
* IMPROVED: The tool directive can now take an `if_defined` argument.
|
221
252
|
|
222
|
-
###
|
253
|
+
### v0.4.5 / 2018-08-05
|
223
254
|
|
224
255
|
* CHANGED: Dropped preload file feature
|
225
256
|
|
226
|
-
###
|
257
|
+
### v0.4.4 / 2018-07-21
|
227
258
|
|
228
259
|
* FIXED: Utils::Exec wasn't closing streams after copying.
|
229
260
|
* IMPROVED: Utils::Exec::Controller can capture or redirect the remainder of a controlled stream.
|
230
261
|
* ADDED: Terminal#ask
|
231
262
|
|
232
|
-
###
|
263
|
+
### v0.4.3 / 2018-07-13
|
233
264
|
|
234
265
|
* IMPROVED: Utils::Exec methods can now spawn subprocesses in the background
|
235
266
|
* IMPROVED: Utils::Exec capture methods can now yield a controller
|
236
267
|
|
237
|
-
###
|
268
|
+
### v0.4.2 / 2018-07-08
|
238
269
|
|
239
270
|
* FIXED: Raise an error rather than cause unexpected behavior if a mixin is included twice.
|
240
271
|
* IMPROVED: The `include?` method extended to support mixin names in a tool dsl.
|
241
272
|
|
242
|
-
###
|
273
|
+
### v0.4.1 / 2018-07-03
|
243
274
|
|
244
275
|
* FIXED: Terminal#confirm uppercased "N" for the wrong default.
|
245
276
|
|
246
|
-
###
|
277
|
+
### v0.4.0 / 2018-07-03
|
247
278
|
|
248
279
|
Now declaring this alpha quality. Backward-incompatible changes are still
|
249
280
|
possible from this point, but I'll try to avoid them.
|
@@ -255,13 +286,13 @@ possible from this point, but I'll try to avoid them.
|
|
255
286
|
* IMPROVED: Utils::Gems installation is now much faster.
|
256
287
|
* FIXED: Utils::Gems didn't reset the specifications on Ruby 2.3.
|
257
288
|
|
258
|
-
###
|
289
|
+
### v0.3.11 / 2018-07-02
|
259
290
|
|
260
291
|
* CHANGED: Require Ruby 2.3 or later
|
261
292
|
* CHANGED: Renamed "set" directive to "static" to reduce confusion with Tool#set.
|
262
293
|
* ADDED: Convenience methods for getting option values
|
263
294
|
|
264
|
-
###
|
295
|
+
### v0.3.10 / 2018-06-30
|
265
296
|
|
266
297
|
* CHANGED: Dropped Tool#option. Use Tool#get instead.
|
267
298
|
* CHANGED: "run" directive renamed to "to_run"
|
@@ -270,11 +301,11 @@ possible from this point, but I'll try to avoid them.
|
|
270
301
|
* ADDED: Mixins can provide initializers
|
271
302
|
* ADDED: Loader can load an inline block
|
272
303
|
|
273
|
-
###
|
304
|
+
### v0.3.9.1 / 2018-06-24
|
274
305
|
|
275
306
|
* FIXED: Built-in flags were interfering with disable_argument_parsing
|
276
307
|
|
277
|
-
###
|
308
|
+
### v0.3.9 / 2018-06-24
|
278
309
|
|
279
310
|
* CHANGED: Cli#add_search_path_hierarchy changed the behavior of the base/terminate param
|
280
311
|
* CHANGED: Removed alias_as directive since it's incompatible with selective loading.
|
@@ -283,7 +314,7 @@ possible from this point, but I'll try to avoid them.
|
|
283
314
|
* ADDED: Exec#exec_proc and Exec#exec_tool that supports all the stream redirects
|
284
315
|
* IMPROVED: Acceptors can be looked up recursively in the same way as mixins and templates
|
285
316
|
|
286
|
-
###
|
317
|
+
### v0.3.8 / 2018-06-10
|
287
318
|
|
288
319
|
* CHANGED: Renamed helpers to mixins.
|
289
320
|
* CHANGED: ModuleLookup is now a customizable class and can have multiple sources.
|
@@ -293,11 +324,11 @@ possible from this point, but I'll try to avoid them.
|
|
293
324
|
* IMPROVED: Exec raises an error if passed an unknown option.
|
294
325
|
* IMPROVED: Exec now accepts nearly all the same stream specifications as Process#spawn.
|
295
326
|
|
296
|
-
###
|
327
|
+
### v0.3.7.1 / 2018-05-30
|
297
328
|
|
298
329
|
* No changes.
|
299
330
|
|
300
|
-
###
|
331
|
+
### v0.3.7 / 2018-05-30
|
301
332
|
|
302
333
|
* CHANGED: Execution runs in the same scope as the DSL, which lets us use normal methods instead of helper-blocks.
|
303
334
|
* CHANGED: Renamed "script" to "run", and allow setting of runnable by defining a "run" method
|
@@ -310,7 +341,7 @@ possible from this point, but I'll try to avoid them.
|
|
310
341
|
* ADDED: Helper modules scoped to the tool hierarchy
|
311
342
|
* ADDED: Utility that installs and activates third-party gems.
|
312
343
|
|
313
|
-
###
|
344
|
+
### v0.3.6 / 2018-05-21
|
314
345
|
|
315
346
|
* CHANGED: Renamed show_version middleware to show_root_version.
|
316
347
|
* CHANGED: Reworked set_default_descriptions interface for more flexibility.
|
@@ -322,14 +353,14 @@ possible from this point, but I'll try to avoid them.
|
|
322
353
|
* IMPROVED: Support custom acceptors.
|
323
354
|
* IMPROVED: Highline helper automatically sets use_color based on the type of stdout.
|
324
355
|
|
325
|
-
###
|
356
|
+
### v0.3.5 / 2018-05-15
|
326
357
|
|
327
358
|
* CHANGED: Exec logic now lives in a utils class.
|
328
359
|
* CHANGED: Moved flag and arg blocks from Tool into the DSL.
|
329
360
|
* CHANGED: Renamed `execute do` to `script do`, and Tool#executor to Tool#script.
|
330
361
|
* IMPROVED: Help display can use `less` if available.
|
331
362
|
|
332
|
-
###
|
363
|
+
### v0.3.4 / 2018-05-14
|
333
364
|
|
334
365
|
* CHANGED: Renamed switch to flag
|
335
366
|
* CHANGED: Renamed Utils::Usage to Utils::HelpText
|
@@ -351,7 +382,7 @@ possible from this point, but I'll try to avoid them.
|
|
351
382
|
* ADDED: Alias DSL methods `required`, `optional`, and `remaining`.
|
352
383
|
* FIXED: Finish definitions for subtools since the desc may depend on it
|
353
384
|
|
354
|
-
###
|
385
|
+
### v0.3.3 / 2018-05-09
|
355
386
|
|
356
387
|
* CHANGED: Renamed file_utils helper to fileutils.
|
357
388
|
* CHANGED: Renamed `doc:` parameter to `docs:`.
|
@@ -364,7 +395,7 @@ possible from this point, but I'll try to avoid them.
|
|
364
395
|
* IMPROVED: Usage can now customize the left column width and indent
|
365
396
|
* IMPROVED: Newlines in documentation are properly indented
|
366
397
|
|
367
|
-
###
|
398
|
+
### v0.3.2 / 2018-05-07
|
368
399
|
|
369
400
|
* CHANGED: Split core engine out into "toys-core" from the "toys" gem.
|
370
401
|
* CHANGED: Renamed path types to "search" and "config" paths, and restricted the former to the CLI.
|
data/README.md
CHANGED
@@ -258,7 +258,7 @@ itself. However, the `toys-core` gem is a dependency, and your users will need
|
|
258
258
|
to have it installed. You could alleviate this by wrapping your executable in a
|
259
259
|
gem that can declare `toys-core` as a dependency explicitly.
|
260
260
|
|
261
|
-
The [examples directory](https://github.com/dazuma/toys/tree/
|
261
|
+
The [examples directory](https://github.com/dazuma/toys/tree/main/toys-core/examples)
|
262
262
|
includes a few simple examples that you can use as a starting point.
|
263
263
|
|
264
264
|
To experiment with the examples, clone the Toys repo from GitHub:
|
@@ -272,7 +272,7 @@ Navigate to the simple-gem example:
|
|
272
272
|
|
273
273
|
This example wraps the simple "greet" executable that we
|
274
274
|
[covered earlier](#Add_some_functionality) in a gem. You can see the
|
275
|
-
[executable file](https://github.com/dazuma/toys/tree/
|
275
|
+
[executable file](https://github.com/dazuma/toys/tree/main/toys-core/examples/simple-gem/bin/toys-core-simple-example)
|
276
276
|
in the bin directory.
|
277
277
|
|
278
278
|
Try it out by building and installing the gem. From the `examples/simple-gem`
|
@@ -297,16 +297,16 @@ break it up into multiple files. The multi-file gem example demonstrates this.
|
|
297
297
|
$ cd ../multi-file-gem
|
298
298
|
|
299
299
|
This executable's implementation resides in its
|
300
|
-
[lib directory](https://github.com/dazuma/toys/tree/
|
300
|
+
[lib directory](https://github.com/dazuma/toys/tree/main/toys-core/examples/multi-file-gem/lib),
|
301
301
|
a technique that may be familiar to writers of command line executables. More
|
302
302
|
interestingly, the tools themselves are no longer defined in a block passed to
|
303
303
|
the CLI object, but have been moved into a separate
|
304
|
-
["tools" directory](https://github.com/dazuma/toys/tree/
|
304
|
+
["tools" directory](https://github.com/dazuma/toys/tree/main/toys-core/examples/multi-file-gem/tools).
|
305
305
|
This directory has the same structure and supports the same features that are
|
306
306
|
available when writing complex sets of tools in a `.toys` directory. You then
|
307
307
|
configure the CLI object to look in this directory for its tools definitions,
|
308
308
|
as you can see in
|
309
|
-
[the code](https://github.com/dazuma/toys/tree/
|
309
|
+
[the code](https://github.com/dazuma/toys/tree/main/toys-core/examples/multi-file-gem/lib/toys-core-multi-gem-example.rb).
|
310
310
|
|
311
311
|
Try it out now. From the `examples/multi-file-gem` directory, run:
|
312
312
|
|
data/docs/guide.md
CHANGED
data/lib/toys/acceptor.rb
CHANGED
@@ -498,7 +498,7 @@ module Toys
|
|
498
498
|
# well-known acceptor.
|
499
499
|
#
|
500
500
|
# @param spec [Object] See the description for recognized values.
|
501
|
-
# @param options [Hash] Additional options to pass to the
|
501
|
+
# @param options [Hash] Additional options to pass to the acceptor.
|
502
502
|
# @param block [Proc] See the description for recognized forms.
|
503
503
|
# @return [Toys::Acceptor::Base,Proc]
|
504
504
|
#
|
data/lib/toys/compat.rb
CHANGED
@@ -33,7 +33,11 @@ module Toys
|
|
33
33
|
require "did_you_mean"
|
34
34
|
rescue ::LoadError
|
35
35
|
require "rubygems"
|
36
|
-
|
36
|
+
begin
|
37
|
+
require "did_you_mean"
|
38
|
+
rescue ::LoadError
|
39
|
+
# Oh well, it's not available
|
40
|
+
end
|
37
41
|
end
|
38
42
|
@supports_suggestions = defined?(::DidYouMean::SpellChecker)
|
39
43
|
end
|
data/lib/toys/core.rb
CHANGED
data/lib/toys/dsl/flag.rb
CHANGED
@@ -75,8 +75,8 @@ module Toys
|
|
75
75
|
# string (e.g. `"foo"`) is taken as the value. Otherwise, the
|
76
76
|
# following argument is taken as the value (e.g. for `--abc foo`, the
|
77
77
|
# value is set to `"foo"`.) The following argument is treated as the
|
78
|
-
# value even if it looks like a flag (e.g. `--abc --
|
79
|
-
# string `"--
|
78
|
+
# value even if it looks like a flag (e.g. `--abc --def` causes the
|
79
|
+
# string `"--def"` to be taken as the value.)
|
80
80
|
# * `--abc[=VAL]` : A long flag that takes an optional value. If this
|
81
81
|
# argument appears with a value attached (e.g. `--abc=foo`), the
|
82
82
|
# attached string (e.g. `"foo"`) is taken as the value. Otherwise,
|
data/lib/toys/dsl/flag_group.rb
CHANGED
@@ -79,8 +79,8 @@ module Toys
|
|
79
79
|
# string (e.g. `"foo"`) is taken as the value. Otherwise, the
|
80
80
|
# following argument is taken as the value (e.g. for `--abc foo`, the
|
81
81
|
# value is set to `"foo"`.) The following argument is treated as the
|
82
|
-
# value even if it looks like a flag (e.g. `--abc --
|
83
|
-
# string `"--
|
82
|
+
# value even if it looks like a flag (e.g. `--abc --def` causes the
|
83
|
+
# string `"--def"` to be taken as the value.)
|
84
84
|
# * `--abc[=VAL]` : A long flag that takes an optional value. If this
|
85
85
|
# argument appears with a value attached (e.g. `--abc=foo`), the
|
86
86
|
# attached string (e.g. `"foo"`) is taken as the value. Otherwise,
|
data/lib/toys/dsl/tool.rb
CHANGED
@@ -814,8 +814,8 @@ module Toys
|
|
814
814
|
# string (e.g. `"foo"`) is taken as the value. Otherwise, the
|
815
815
|
# following argument is taken as the value (e.g. for `--abc foo`, the
|
816
816
|
# value is set to `"foo"`.) The following argument is treated as the
|
817
|
-
# value even if it looks like a flag (e.g. `--abc --
|
818
|
-
# string `"--
|
817
|
+
# value even if it looks like a flag (e.g. `--abc --def` causes the
|
818
|
+
# string `"--def"` to be taken as the value.)
|
819
819
|
# * `--abc[=VAL]` : A long flag that takes an optional value. If this
|
820
820
|
# argument appears with a value attached (e.g. `--abc=foo`), the
|
821
821
|
# attached string (e.g. `"foo"`) is taken as the value. Otherwise,
|
@@ -884,7 +884,8 @@ module Toys
|
|
884
884
|
# @param flags [String...] The flags in OptionParser format.
|
885
885
|
# @param accept [Object] An acceptor that validates and/or converts the
|
886
886
|
# value. You may provide either the name of an acceptor you have
|
887
|
-
# defined,
|
887
|
+
# defined, one of the default acceptors provided by OptionParser, or
|
888
|
+
# any other specification recognized by {Toys::Acceptor.create}.
|
888
889
|
# Optional. If not specified, accepts any value as a string.
|
889
890
|
# @param default [Object] The default value. This is the value that will
|
890
891
|
# be set in the context if this flag is not provided on the command
|
@@ -979,7 +980,8 @@ module Toys
|
|
979
980
|
# the execution context.
|
980
981
|
# @param accept [Object] An acceptor that validates and/or converts the
|
981
982
|
# value. You may provide either the name of an acceptor you have
|
982
|
-
# defined,
|
983
|
+
# defined, one of the default acceptors provided by OptionParser, or
|
984
|
+
# any other specification recognized by {Toys::Acceptor.create}.
|
983
985
|
# Optional. If not specified, accepts any value as a string.
|
984
986
|
# @param complete [Object] A specifier for shell tab completion for
|
985
987
|
# values of this arg. This is the empty completion by default. To
|
@@ -1050,7 +1052,8 @@ module Toys
|
|
1050
1052
|
# line. Defaults to `nil`.
|
1051
1053
|
# @param accept [Object] An acceptor that validates and/or converts the
|
1052
1054
|
# value. You may provide either the name of an acceptor you have
|
1053
|
-
# defined,
|
1055
|
+
# defined, one of the default acceptors provided by OptionParser, or
|
1056
|
+
# any other specification recognized by {Toys::Acceptor.create}.
|
1054
1057
|
# Optional. If not specified, accepts any value as a string.
|
1055
1058
|
# @param complete [Object] A specifier for shell tab completion for
|
1056
1059
|
# values of this arg. This is the empty completion by default. To
|
@@ -1121,7 +1124,8 @@ module Toys
|
|
1121
1124
|
# command line. Defaults to the empty array `[]`.
|
1122
1125
|
# @param accept [Object] An acceptor that validates and/or converts the
|
1123
1126
|
# value. You may provide either the name of an acceptor you have
|
1124
|
-
# defined,
|
1127
|
+
# defined, one of the default acceptors provided by OptionParser, or
|
1128
|
+
# any other specification recognized by {Toys::Acceptor.create}.
|
1125
1129
|
# Optional. If not specified, accepts any value as a string.
|
1126
1130
|
# @param complete [Object] A specifier for shell tab completion for
|
1127
1131
|
# values of this arg. This is the empty completion by default. To
|
@@ -1619,6 +1623,23 @@ module Toys
|
|
1619
1623
|
self
|
1620
1624
|
end
|
1621
1625
|
|
1626
|
+
##
|
1627
|
+
# Remove lower-priority sources from the load path. This prevents lower-
|
1628
|
+
# priority sources (such as Toys files from parent or global directories)
|
1629
|
+
# from executing or defining tools.
|
1630
|
+
#
|
1631
|
+
# This works only if no such sources have already loaded yet.
|
1632
|
+
#
|
1633
|
+
# @raise [Toys::ToolDefinitionError] if any lower-priority tools have
|
1634
|
+
# already been loaded.
|
1635
|
+
#
|
1636
|
+
def truncate_load_path!
|
1637
|
+
unless @__loader.stop_loading_at_priority(@__priority)
|
1638
|
+
raise ToolDefinitionError,
|
1639
|
+
"Cannot truncate load path because tools have already been loaded"
|
1640
|
+
end
|
1641
|
+
end
|
1642
|
+
|
1622
1643
|
##
|
1623
1644
|
# Determines whether the current Toys version satisfies the given
|
1624
1645
|
# requirements.
|
data/lib/toys/loader.rb
CHANGED
@@ -8,6 +8,9 @@ module Toys
|
|
8
8
|
# appropriate tool given a set of command line arguments.
|
9
9
|
#
|
10
10
|
class Loader
|
11
|
+
# @private
|
12
|
+
BASE_PRIORITY = -999_999
|
13
|
+
|
11
14
|
##
|
12
15
|
# Create a Loader
|
13
16
|
#
|
@@ -69,9 +72,11 @@ module Toys
|
|
69
72
|
@worklist = []
|
70
73
|
@tool_data = {}
|
71
74
|
@max_priority = @min_priority = 0
|
75
|
+
@stop_priority = BASE_PRIORITY
|
76
|
+
@min_loaded_priority = 999_999
|
72
77
|
@middleware_stack = Middleware.stack(middleware_stack)
|
73
78
|
@delimiter_handler = DelimiterHandler.new(extra_delimiters)
|
74
|
-
get_tool([],
|
79
|
+
get_tool([], BASE_PRIORITY)
|
75
80
|
end
|
76
81
|
|
77
82
|
##
|
@@ -89,7 +94,7 @@ module Toys
|
|
89
94
|
raise "Cannot add a path after tool loading has started" if @loading_started
|
90
95
|
priority = high_priority ? (@max_priority += 1) : (@min_priority -= 1)
|
91
96
|
paths.each do |path|
|
92
|
-
source = SourceInfo.create_path_root(path)
|
97
|
+
source = SourceInfo.create_path_root(path, @data_dir_name, @lib_dir_name)
|
93
98
|
@worklist << [source, [], priority]
|
94
99
|
end
|
95
100
|
end
|
@@ -114,7 +119,7 @@ module Toys
|
|
114
119
|
@mutex.synchronize do
|
115
120
|
raise "Cannot add a block after tool loading has started" if @loading_started
|
116
121
|
priority = high_priority ? (@max_priority += 1) : (@min_priority -= 1)
|
117
|
-
source = SourceInfo.create_proc_root(block, name)
|
122
|
+
source = SourceInfo.create_proc_root(block, name, @data_dir_name, @lib_dir_name)
|
118
123
|
@worklist << [source, [], priority]
|
119
124
|
end
|
120
125
|
self
|
@@ -178,15 +183,15 @@ module Toys
|
|
178
183
|
load_for_prefix(words)
|
179
184
|
found_tools = []
|
180
185
|
len = words.length
|
181
|
-
|
182
|
-
|
186
|
+
all_cur_definitions.each do |tool|
|
187
|
+
name = tool.full_name
|
188
|
+
next if name.empty?
|
183
189
|
if recursive
|
184
|
-
next if
|
190
|
+
next if name.length <= len || name.slice(0, len) != words
|
185
191
|
else
|
186
|
-
next unless
|
192
|
+
next unless name.slice(0..-2) == words
|
187
193
|
end
|
188
|
-
|
189
|
-
found_tools << tool unless tool.nil?
|
194
|
+
found_tools << tool
|
190
195
|
end
|
191
196
|
sort_tools_by_name(found_tools)
|
192
197
|
include_hidden ? found_tools : filter_hidden_subtools(found_tools)
|
@@ -202,8 +207,9 @@ module Toys
|
|
202
207
|
def has_subtools?(words) # rubocop:disable Naming/PredicateName
|
203
208
|
load_for_prefix(words)
|
204
209
|
len = words.length
|
205
|
-
|
206
|
-
|
210
|
+
all_cur_definitions.each do |tool|
|
211
|
+
name = tool.full_name
|
212
|
+
if !name.empty? && name.length > len && name.slice(0, len) == words
|
207
213
|
return true
|
208
214
|
end
|
209
215
|
end
|
@@ -267,6 +273,20 @@ module Toys
|
|
267
273
|
Tool.new(self, parent, words, priority, middleware_stack, @middleware_lookup)
|
268
274
|
end
|
269
275
|
|
276
|
+
##
|
277
|
+
# Stop search at the given priority. Returns true if successful.
|
278
|
+
# Called only from the DSL.
|
279
|
+
#
|
280
|
+
# @private
|
281
|
+
#
|
282
|
+
def stop_loading_at_priority(priority)
|
283
|
+
@mutex.synchronize do
|
284
|
+
return false if priority > @min_loaded_priority || priority < @stop_priority
|
285
|
+
@stop_priority = priority
|
286
|
+
true
|
287
|
+
end
|
288
|
+
end
|
289
|
+
|
270
290
|
##
|
271
291
|
# Loads the subtree under the given prefix.
|
272
292
|
#
|
@@ -278,6 +298,7 @@ module Toys
|
|
278
298
|
cur_worklist = @worklist
|
279
299
|
@worklist = []
|
280
300
|
cur_worklist.each do |source, words, priority|
|
301
|
+
next if priority < @stop_priority
|
281
302
|
remaining_words = calc_remaining_words(prefix, words)
|
282
303
|
if source.source_proc
|
283
304
|
load_proc(source, words, remaining_words, priority)
|
@@ -349,8 +370,15 @@ module Toys
|
|
349
370
|
|
350
371
|
private
|
351
372
|
|
352
|
-
def
|
353
|
-
|
373
|
+
def all_cur_definitions
|
374
|
+
result = []
|
375
|
+
@mutex.synchronize do
|
376
|
+
@tool_data.map do |_name, td|
|
377
|
+
tool = td.cur_definition
|
378
|
+
result << tool unless tool.nil?
|
379
|
+
end
|
380
|
+
end
|
381
|
+
result
|
354
382
|
end
|
355
383
|
|
356
384
|
def get_tool_data(words)
|
@@ -364,14 +392,16 @@ module Toys
|
|
364
392
|
def finish_definitions_in_tree(words)
|
365
393
|
load_for_prefix(words)
|
366
394
|
len = words.length
|
367
|
-
|
368
|
-
|
369
|
-
|
395
|
+
all_cur_definitions.each do |tool|
|
396
|
+
name = tool.full_name
|
397
|
+
next if name.length < len || name.slice(0, len) != words
|
398
|
+
tool.finish_definition(self)
|
370
399
|
end
|
371
400
|
end
|
372
401
|
|
373
402
|
def load_proc(source, words, remaining_words, priority)
|
374
403
|
if remaining_words
|
404
|
+
update_min_loaded_priority(priority)
|
375
405
|
tool_class = get_tool(words, priority).tool_class
|
376
406
|
DSL::Tool.prepare(tool_class, remaining_words, source) do
|
377
407
|
ContextualError.capture("Error while loading Toys config!") do
|
@@ -393,6 +423,7 @@ module Toys
|
|
393
423
|
|
394
424
|
def load_relevant_path(source, words, remaining_words, priority)
|
395
425
|
if source.source_type == :file
|
426
|
+
update_min_loaded_priority(priority)
|
396
427
|
tool_class = get_tool(words, priority).tool_class
|
397
428
|
InputFile.evaluate(tool_class, remaining_words, source)
|
398
429
|
else
|
@@ -406,7 +437,7 @@ module Toys
|
|
406
437
|
|
407
438
|
def load_index_in(source, words, remaining_words, priority)
|
408
439
|
return unless @index_file_name
|
409
|
-
index_source = source.relative_child(@index_file_name
|
440
|
+
index_source = source.relative_child(@index_file_name)
|
410
441
|
load_relevant_path(index_source, words, remaining_words, priority) if index_source
|
411
442
|
end
|
412
443
|
|
@@ -414,7 +445,7 @@ module Toys
|
|
414
445
|
return if child.start_with?(".") || child == @index_file_name ||
|
415
446
|
child == @preload_file_name || child == @preload_dir_name ||
|
416
447
|
child == @data_dir_name || child == @lib_dir_name
|
417
|
-
child_source = source.relative_child(child
|
448
|
+
child_source = source.relative_child(child)
|
418
449
|
return unless child_source
|
419
450
|
child_word = ::File.basename(child, ".rb")
|
420
451
|
next_words = words + [child_word]
|
@@ -422,6 +453,10 @@ module Toys
|
|
422
453
|
load_validated_path(child_source, next_words, next_remaining, priority)
|
423
454
|
end
|
424
455
|
|
456
|
+
def update_min_loaded_priority(priority)
|
457
|
+
@min_loaded_priority = priority if @min_loaded_priority > priority
|
458
|
+
end
|
459
|
+
|
425
460
|
def do_preload(path)
|
426
461
|
if @preload_file_name
|
427
462
|
preload_file = ::File.join(path, @preload_file_name)
|
@@ -483,37 +518,42 @@ module Toys
|
|
483
518
|
# @private
|
484
519
|
#
|
485
520
|
class ToolData
|
486
|
-
|
521
|
+
# @private
|
487
522
|
def initialize(words)
|
488
523
|
@words = words
|
489
524
|
@definitions = {}
|
490
525
|
@top_priority = @active_priority = nil
|
526
|
+
@mutex = ::Monitor.new
|
491
527
|
end
|
492
528
|
|
493
|
-
|
529
|
+
# @private
|
494
530
|
def cur_definition
|
495
|
-
active_definition || top_definition
|
531
|
+
@mutex.synchronize { active_definition || top_definition }
|
496
532
|
end
|
497
533
|
|
498
|
-
|
534
|
+
# @private
|
499
535
|
def empty?
|
500
536
|
@definitions.empty?
|
501
537
|
end
|
502
538
|
|
503
|
-
|
539
|
+
# @private
|
504
540
|
def get_tool(priority, loader)
|
505
|
-
|
506
|
-
@top_priority
|
541
|
+
@mutex.synchronize do
|
542
|
+
if @top_priority.nil? || @top_priority < priority
|
543
|
+
@top_priority = priority
|
544
|
+
end
|
545
|
+
@definitions[priority] ||= loader.build_tool(@words, priority)
|
507
546
|
end
|
508
|
-
@definitions[priority] ||= loader.build_tool(@words, priority)
|
509
547
|
end
|
510
548
|
|
511
|
-
|
549
|
+
# @private
|
512
550
|
def activate_tool(priority, loader)
|
513
|
-
|
514
|
-
|
515
|
-
|
516
|
-
|
551
|
+
@mutex.synchronize do
|
552
|
+
return active_definition if @active_priority == priority
|
553
|
+
return nil if @active_priority && @active_priority > priority
|
554
|
+
@active_priority = priority
|
555
|
+
get_tool(priority, loader)
|
556
|
+
end
|
517
557
|
end
|
518
558
|
|
519
559
|
private
|