toys-core 0.15.6 → 0.17.0
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/README.md +2 -2
- data/docs/guide.md +7 -7
- data/lib/toys/arg_parser.rb +9 -4
- data/lib/toys/cli.rb +8 -10
- data/lib/toys/compat.rb +11 -83
- data/lib/toys/completion.rb +3 -3
- data/lib/toys/core.rb +1 -1
- data/lib/toys/dsl/flag.rb +14 -11
- data/lib/toys/dsl/flag_group.rb +12 -9
- data/lib/toys/dsl/internal.rb +4 -3
- data/lib/toys/dsl/tool.rb +48 -16
- data/lib/toys/flag.rb +15 -12
- data/lib/toys/input_file.rb +3 -5
- data/lib/toys/loader.rb +99 -11
- data/lib/toys/middleware.rb +1 -1
- data/lib/toys/settings.rb +11 -2
- data/lib/toys/source_info.rb +92 -29
- data/lib/toys/standard_mixins/gems.rb +24 -5
- data/lib/toys/standard_mixins/highline.rb +12 -12
- data/lib/toys/tool_definition.rb +22 -28
- data/lib/toys/utils/exec.rb +33 -45
- data/lib/toys/utils/gems.rb +7 -7
- data/lib/toys/utils/git_cache.rb +23 -5
- data/lib/toys/utils/help_text.rb +4 -4
- data/lib/toys/utils/pager.rb +3 -5
- data/lib/toys/utils/terminal.rb +8 -12
- data/lib/toys/utils/xdg.rb +2 -2
- data/lib/toys-core.rb +2 -1
- metadata +21 -10
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: be1392e6cb8f49c19e9472449943cf873209b939d11cdc1e788bb58a1083c013
|
|
4
|
+
data.tar.gz: d78818495765389e99111032e863dc21d4fa982dfde07780a5b1ff9cc96743df
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 63ca5e62ed30e068d7b75a0b08e3916fc19466d92ca165d52f8f333e9538f96358027fdd676690042c5eb55d2e2569c3c1a8b8d9c32dd33f7ec3d4036230bc81
|
|
7
|
+
data.tar.gz: 61821ef2ffde83d82469c6a8d38ba092f1efc2a3254a1f848d877fda09a888fc932274e27c742c53d0480a55abc1b49fc6266359ceeca31e8851e16dac3ce0e8
|
data/CHANGELOG.md
CHANGED
|
@@ -1,8 +1,30 @@
|
|
|
1
1
|
# Release History
|
|
2
2
|
|
|
3
|
+
### v0.17.0 / 2025-11-07
|
|
4
|
+
|
|
5
|
+
Toys-Core 0.17 supports several significant new pieces of functionality:
|
|
6
|
+
|
|
7
|
+
* Support for loading tools from Rubygems. The load_gem directive loads tools from the "toys" directory in a gem, installing the gem if necessary. This makes it easy to distribute tools, securely and versioned, as gems.
|
|
8
|
+
* Flag handlers can now take an optional third argument, the entire options hash. This enables significantly more powerful behavior during flag parsing, such as letting flags affect the behavior of other flags.
|
|
9
|
+
|
|
10
|
+
Additional new features:
|
|
11
|
+
|
|
12
|
+
* When using the :gems mixin, you can now specify installation options such as on_missing not only when you include the mixin, but also when you declare the gem.
|
|
13
|
+
* Added support for an environment variable `TOYS_GIT_CACHE_WRITABLE` to disable the read-only behavior of git cache sources. This improves compatibility with environments that want to delete caches.
|
|
14
|
+
|
|
15
|
+
Other fixes and documentation:
|
|
16
|
+
|
|
17
|
+
* Added the standard logger gem to the toys-core dependencies to silence Ruby 3.5 warnings.
|
|
18
|
+
* Updated the user guide to cover new features and fix some internal links
|
|
19
|
+
|
|
20
|
+
### v0.16.0 / 2025-10-31
|
|
21
|
+
|
|
22
|
+
* ADDED: Updated minimum Ruby version to 2.7
|
|
23
|
+
* FIXED: ToolDefinition#includes_arguments no longer returns true if only default data is set
|
|
24
|
+
|
|
3
25
|
### v0.15.6 / 2024-05-15
|
|
4
26
|
|
|
5
|
-
* FIXED: Fixed argument parsing
|
|
27
|
+
* FIXED: Fixed argument parsing so flags with value delimited by "=" will support values containing newlines
|
|
6
28
|
|
|
7
29
|
### v0.15.5 / 2024-01-31
|
|
8
30
|
|
data/README.md
CHANGED
|
@@ -338,7 +338,7 @@ Detailed usage information can be found in the
|
|
|
338
338
|
|
|
339
339
|
## System requirements
|
|
340
340
|
|
|
341
|
-
Toys-Core requires Ruby 2.
|
|
341
|
+
Toys-Core requires Ruby 2.7 or later.
|
|
342
342
|
|
|
343
343
|
Most parts of Toys-Core work on JRuby. However, JRuby is not recommended
|
|
344
344
|
because of JVM boot latency, lack of support for Kernel#fork, and other issues.
|
|
@@ -348,7 +348,7 @@ recommended because it has a few known bugs that affect Toys.
|
|
|
348
348
|
|
|
349
349
|
## License
|
|
350
350
|
|
|
351
|
-
Copyright 2019-
|
|
351
|
+
Copyright 2019-2025 Daniel Azuma and the Toys contributors
|
|
352
352
|
|
|
353
353
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
354
354
|
of this software and associated documentation files (the "Software"), to deal
|
data/docs/guide.md
CHANGED
|
@@ -159,7 +159,7 @@ If only `foo` is requested, the loader will execute the `tool "foo" do` block
|
|
|
159
159
|
to get that tool definition, but will not execute the `tool "bar" do` block.
|
|
160
160
|
|
|
161
161
|
We will discuss more about the features of the loader below in the section on
|
|
162
|
-
[defining functionality](#
|
|
162
|
+
[defining functionality](#defining-functionality).
|
|
163
163
|
|
|
164
164
|
#### Building context
|
|
165
165
|
|
|
@@ -209,16 +209,16 @@ Generally, you control CLI features by passing arguments to its constructor.
|
|
|
209
209
|
These features include:
|
|
210
210
|
|
|
211
211
|
* How to find toys files and related code and data. See the section on
|
|
212
|
-
[defining functionality](#
|
|
212
|
+
[defining functionality](#defining-functionality).
|
|
213
213
|
* Middleware, providing common behavior for all tools. See the section on
|
|
214
|
-
[customizing the middleware stack](#
|
|
214
|
+
[customizing the middleware stack](#customizing-default-behavior).
|
|
215
215
|
* Common mixins and templates available to all tools. See the section on
|
|
216
|
-
[how to define mixins and templates](#
|
|
216
|
+
[how to define mixins and templates](#defining-mixins-and-templates).
|
|
217
217
|
* How logs, errors, and signals are reported. See the section on
|
|
218
|
-
[customizing tool output](#
|
|
218
|
+
[customizing tool output](#customizing-tool-output).
|
|
219
219
|
* How the executable interacts with the shell, including setting up tab
|
|
220
220
|
completion. See the
|
|
221
|
-
[corresponding section](#
|
|
221
|
+
[corresponding section](#shell-and-command-line-integration).
|
|
222
222
|
|
|
223
223
|
Each of the actual parameters is covered in detail in the documentation for
|
|
224
224
|
{Toys::CLI#initialize}. The configuration of a CLI cannot be changed once the
|
|
@@ -663,7 +663,7 @@ execute.
|
|
|
663
663
|
# This is a context key that will be used to store the "--show-timing"
|
|
664
664
|
# flag state. We can use `Object.new` to ensure that the key is unique
|
|
665
665
|
# across other middlewares and tool definitions.
|
|
666
|
-
KEY = Object.new
|
|
666
|
+
KEY = Object.new.freeze
|
|
667
667
|
|
|
668
668
|
# This method intercepts tool configuration. We use it to add a flag that
|
|
669
669
|
# enables timing display.
|
data/lib/toys/arg_parser.rb
CHANGED
|
@@ -416,7 +416,7 @@ module Toys
|
|
|
416
416
|
private
|
|
417
417
|
|
|
418
418
|
REMAINING_HANDLER = ->(val, prev) { prev.is_a?(::Array) ? prev << val : [val] }
|
|
419
|
-
ARG_HANDLER = ->(val
|
|
419
|
+
ARG_HANDLER = ->(val) { val }
|
|
420
420
|
private_constant :REMAINING_HANDLER, :ARG_HANDLER
|
|
421
421
|
|
|
422
422
|
def initial_data(cli, tool, default_data)
|
|
@@ -465,7 +465,7 @@ module Toys
|
|
|
465
465
|
|
|
466
466
|
def handle_single_flags(str)
|
|
467
467
|
until str.empty?
|
|
468
|
-
str = handle_plain_flag("-#{str[0]}", str[1
|
|
468
|
+
str = handle_plain_flag("-#{str[0]}", str[1..])
|
|
469
469
|
end
|
|
470
470
|
end
|
|
471
471
|
|
|
@@ -521,7 +521,7 @@ module Toys
|
|
|
521
521
|
|
|
522
522
|
def find_flag(name)
|
|
523
523
|
flag_result = @tool.resolve_flag(name)
|
|
524
|
-
if flag_result.not_found? || @require_exact_flag_match && !flag_result.found_exact?
|
|
524
|
+
if flag_result.not_found? || (@require_exact_flag_match && !flag_result.found_exact?)
|
|
525
525
|
@errors << FlagUnrecognizedError.new(
|
|
526
526
|
value: name, suggestions: Compat.suggestions(name, @tool.used_flags)
|
|
527
527
|
)
|
|
@@ -551,7 +551,12 @@ module Toys
|
|
|
551
551
|
value = accept.convert(*Array(match))
|
|
552
552
|
end
|
|
553
553
|
if handler
|
|
554
|
-
|
|
554
|
+
args = [value, @data[key], @data]
|
|
555
|
+
if handler.lambda?
|
|
556
|
+
limit = handler.arity.negative? ? -handler.arity - 1 : handler.arity
|
|
557
|
+
args = args[...limit]
|
|
558
|
+
end
|
|
559
|
+
value = handler.call(*args)
|
|
555
560
|
end
|
|
556
561
|
@data[key] = value
|
|
557
562
|
end
|
data/lib/toys/cli.rb
CHANGED
|
@@ -628,17 +628,15 @@ module Toys
|
|
|
628
628
|
|
|
629
629
|
def build_executor(tool, context)
|
|
630
630
|
executor = proc do
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
yield context
|
|
638
|
-
end
|
|
639
|
-
rescue ::SignalException => e
|
|
640
|
-
handle_signal_by_tool(context, tool, e)
|
|
631
|
+
if !context[Context::Key::USAGE_ERRORS].empty?
|
|
632
|
+
handle_usage_errors(context, tool)
|
|
633
|
+
elsif !tool.runnable?
|
|
634
|
+
raise NotRunnableError, "No implementation for tool #{tool.display_name.inspect}"
|
|
635
|
+
else
|
|
636
|
+
yield context
|
|
641
637
|
end
|
|
638
|
+
rescue ::SignalException => e
|
|
639
|
+
handle_signal_by_tool(context, tool, e)
|
|
642
640
|
end
|
|
643
641
|
tool.built_middleware.reverse_each do |middleware|
|
|
644
642
|
executor = make_executor(middleware, context, executor)
|
data/lib/toys/compat.rb
CHANGED
|
@@ -4,13 +4,17 @@ require "rbconfig"
|
|
|
4
4
|
|
|
5
5
|
module Toys
|
|
6
6
|
##
|
|
7
|
-
# Compatibility wrappers for
|
|
7
|
+
# Compatibility wrappers for certain Ruby implementations and versions, and
|
|
8
|
+
# other environment differences.
|
|
8
9
|
#
|
|
9
10
|
# @private
|
|
10
11
|
#
|
|
11
12
|
module Compat
|
|
12
13
|
parts = ::RUBY_VERSION.split(".")
|
|
13
|
-
ruby_version = parts[0].to_i * 10000 + parts[1].to_i * 100 + parts[2].to_i
|
|
14
|
+
ruby_version = (parts[0].to_i * 10000) + (parts[1].to_i * 100) + parts[2].to_i
|
|
15
|
+
|
|
16
|
+
# @private
|
|
17
|
+
RUBY_VERSION_CODE = ruby_version
|
|
14
18
|
|
|
15
19
|
# @private
|
|
16
20
|
def self.jruby?
|
|
@@ -27,6 +31,11 @@ module Toys
|
|
|
27
31
|
::RbConfig::CONFIG["host_os"] =~ /mswin|msys|mingw|cygwin|bccwin|wince|emc/
|
|
28
32
|
end
|
|
29
33
|
|
|
34
|
+
# @private
|
|
35
|
+
def self.macos?
|
|
36
|
+
::RbConfig::CONFIG["host_os"] =~ /darwin/
|
|
37
|
+
end
|
|
38
|
+
|
|
30
39
|
# @private
|
|
31
40
|
def self.allow_fork?
|
|
32
41
|
!jruby? && !truffleruby? && !windows?
|
|
@@ -58,86 +67,5 @@ module Toys
|
|
|
58
67
|
[]
|
|
59
68
|
end
|
|
60
69
|
end
|
|
61
|
-
|
|
62
|
-
# The :base argument to Dir.glob requires Ruby 2.5 or later.
|
|
63
|
-
if ruby_version >= 20500
|
|
64
|
-
# @private
|
|
65
|
-
def self.glob_in_dir(glob, dir)
|
|
66
|
-
::Dir.glob(glob, base: dir)
|
|
67
|
-
end
|
|
68
|
-
else
|
|
69
|
-
# @private
|
|
70
|
-
def self.glob_in_dir(glob, dir)
|
|
71
|
-
::Dir.chdir(dir) { ::Dir.glob(glob) }
|
|
72
|
-
end
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
# Dir.children requires Ruby 2.5 or later.
|
|
76
|
-
if ruby_version >= 20500
|
|
77
|
-
# @private
|
|
78
|
-
def self.dir_children(dir)
|
|
79
|
-
::Dir.children(dir)
|
|
80
|
-
end
|
|
81
|
-
else
|
|
82
|
-
# @private
|
|
83
|
-
def self.dir_children(dir)
|
|
84
|
-
::Dir.entries(dir) - [".", ".."]
|
|
85
|
-
end
|
|
86
|
-
end
|
|
87
|
-
|
|
88
|
-
# Due to a bug in Ruby < 2.7, passing an empty **kwargs splat to
|
|
89
|
-
# initialize will fail if there are no formal keyword args.
|
|
90
|
-
# This also hits TruffleRuby
|
|
91
|
-
# (see https://github.com/oracle/truffleruby/issues/2567)
|
|
92
|
-
if ruby_version >= 20700 && !truffleruby?
|
|
93
|
-
# @private
|
|
94
|
-
def self.instantiate(klass, args, kwargs, block)
|
|
95
|
-
klass.new(*args, **kwargs, &block)
|
|
96
|
-
end
|
|
97
|
-
else
|
|
98
|
-
# @private
|
|
99
|
-
def self.instantiate(klass, args, kwargs, block)
|
|
100
|
-
formals = klass.instance_method(:initialize).parameters
|
|
101
|
-
if kwargs.empty? && formals.all? { |arg| arg.first != :key && arg.first != :keyrest }
|
|
102
|
-
klass.new(*args, &block)
|
|
103
|
-
else
|
|
104
|
-
klass.new(*args, **kwargs, &block)
|
|
105
|
-
end
|
|
106
|
-
end
|
|
107
|
-
end
|
|
108
|
-
|
|
109
|
-
# File.absolute_path? requires Ruby 2.7 or later. For earlier Rubies, use
|
|
110
|
-
# an ad-hoc mechanism.
|
|
111
|
-
if ruby_version >= 20700
|
|
112
|
-
# @private
|
|
113
|
-
def self.absolute_path?(path)
|
|
114
|
-
::File.absolute_path?(path)
|
|
115
|
-
end
|
|
116
|
-
elsif ::Dir.getwd =~ /^[a-zA-Z]:/
|
|
117
|
-
# @private
|
|
118
|
-
def self.absolute_path?(path)
|
|
119
|
-
/^[a-zA-Z]:/.match?(path)
|
|
120
|
-
end
|
|
121
|
-
else
|
|
122
|
-
# @private
|
|
123
|
-
def self.absolute_path?(path)
|
|
124
|
-
path.start_with?("/")
|
|
125
|
-
end
|
|
126
|
-
end
|
|
127
|
-
|
|
128
|
-
# The second argument to method_defined? and private_method_defined?
|
|
129
|
-
# requires Ruby 2.6 or later.
|
|
130
|
-
if ruby_version >= 20600
|
|
131
|
-
# @private
|
|
132
|
-
def self.method_defined_without_ancestors?(klass, name)
|
|
133
|
-
klass.method_defined?(name, false) || klass.private_method_defined?(name, false)
|
|
134
|
-
end
|
|
135
|
-
else
|
|
136
|
-
# @private
|
|
137
|
-
def self.method_defined_without_ancestors?(klass, name)
|
|
138
|
-
klass.instance_methods(false).include?(name) ||
|
|
139
|
-
klass.private_instance_methods(false).include?(name)
|
|
140
|
-
end
|
|
141
|
-
end
|
|
142
70
|
end
|
|
143
71
|
end
|
data/lib/toys/completion.rb
CHANGED
|
@@ -49,7 +49,7 @@ module Toys
|
|
|
49
49
|
# @return [Toys::Completion::Context]
|
|
50
50
|
#
|
|
51
51
|
def with(**delta_params)
|
|
52
|
-
Context.new(**@params
|
|
52
|
+
Context.new(**@params, **delta_params)
|
|
53
53
|
end
|
|
54
54
|
|
|
55
55
|
##
|
|
@@ -195,7 +195,7 @@ module Toys
|
|
|
195
195
|
# @private
|
|
196
196
|
#
|
|
197
197
|
def hash
|
|
198
|
-
string.hash
|
|
198
|
+
[@string, @partial].hash
|
|
199
199
|
end
|
|
200
200
|
|
|
201
201
|
##
|
|
@@ -295,7 +295,7 @@ module Toys
|
|
|
295
295
|
return [] unless ::File.directory?(dir)
|
|
296
296
|
prefix = nil if [".", ""].include?(prefix)
|
|
297
297
|
omits = [".", "..", ""]
|
|
298
|
-
children =
|
|
298
|
+
children = ::Dir.glob(name, base: dir).find_all do |child|
|
|
299
299
|
!omits.include?(child)
|
|
300
300
|
end
|
|
301
301
|
children += ::Dir.entries(dir).find_all do |child|
|
data/lib/toys/core.rb
CHANGED
data/lib/toys/dsl/flag.rb
CHANGED
|
@@ -114,17 +114,20 @@ module Toys
|
|
|
114
114
|
end
|
|
115
115
|
|
|
116
116
|
##
|
|
117
|
-
# Set the optional handler
|
|
118
|
-
#
|
|
119
|
-
#
|
|
120
|
-
#
|
|
121
|
-
#
|
|
122
|
-
#
|
|
123
|
-
# You
|
|
124
|
-
#
|
|
125
|
-
#
|
|
126
|
-
#
|
|
127
|
-
#
|
|
117
|
+
# Set the optional handler that customizes how a value is set or updated
|
|
118
|
+
# when the flag is parsed.
|
|
119
|
+
#
|
|
120
|
+
# A handler is a proc that takes up to three arguments: the given value,
|
|
121
|
+
# the previous value, and a hash containing all the data collected so far
|
|
122
|
+
# during argument parsing. It must return the new value for the flag. You
|
|
123
|
+
# You may pass the handler as a Proc (or an object responding to the
|
|
124
|
+
# `call` method) or you may provide a block.
|
|
125
|
+
#
|
|
126
|
+
# You may also specify a predefined named handler. The `:set` handler
|
|
127
|
+
# (the default) replaces the previous value (effectively
|
|
128
|
+
# `-> (val) { val }`). The `:push` handler expects the previous value to
|
|
129
|
+
# be an array and pushes the given value onto it; it should be combined
|
|
130
|
+
# with setting the default value to `[]` and is intended for
|
|
128
131
|
# "multi-valued" flags.
|
|
129
132
|
#
|
|
130
133
|
# @param handler [Proc,:set,:push]
|
data/lib/toys/dsl/flag_group.rb
CHANGED
|
@@ -147,15 +147,18 @@ module Toys
|
|
|
147
147
|
# @param default [Object] The default value. This is the value that will
|
|
148
148
|
# be set in the context if this flag is not provided on the command
|
|
149
149
|
# line. Defaults to `nil`.
|
|
150
|
-
# @param handler [Proc,nil,:set,:push] An optional handler
|
|
151
|
-
#
|
|
152
|
-
#
|
|
153
|
-
#
|
|
154
|
-
#
|
|
155
|
-
#
|
|
156
|
-
#
|
|
157
|
-
#
|
|
158
|
-
# `
|
|
150
|
+
# @param handler [Proc,nil,:set,:push] An optional handler that
|
|
151
|
+
# customizes how a value is set or updated when the flag is parsed.
|
|
152
|
+
# A handler is a proc that takes up to three arguments: the given
|
|
153
|
+
# value, the previous value, and a hash containing all the data
|
|
154
|
+
# collected so far during argument parsing. The proc must return the
|
|
155
|
+
# new value for the flag.
|
|
156
|
+
# You may also specify a predefined named handler. The `:set` handler
|
|
157
|
+
# (the default) replaces the previous value (effectively
|
|
158
|
+
# `-> (val) { val }`). The `:push` handler expects the previous value
|
|
159
|
+
# to be an array and pushes the given value onto it; it should be
|
|
160
|
+
# combined with setting the default value to `[]` and is intended for
|
|
161
|
+
# "multi-valued" flags.
|
|
159
162
|
# @param complete_flags [Object] A specifier for shell tab completion
|
|
160
163
|
# for flag names associated with this flag. By default, a
|
|
161
164
|
# {Toys::Flag::DefaultCompletion} is used, which provides the flag's
|
data/lib/toys/dsl/internal.rb
CHANGED
|
@@ -12,8 +12,8 @@ module Toys
|
|
|
12
12
|
# @private A list of method names to avoid using as getters
|
|
13
13
|
#
|
|
14
14
|
AVOID_GETTERS = (::Object.instance_methods + [:run, :initialize])
|
|
15
|
-
.
|
|
16
|
-
.
|
|
15
|
+
.grep(/^[a-z]\w*$/)
|
|
16
|
+
.to_h { |name| [name, true] }
|
|
17
17
|
.freeze
|
|
18
18
|
|
|
19
19
|
class << self
|
|
@@ -109,7 +109,8 @@ module Toys
|
|
|
109
109
|
when nil
|
|
110
110
|
return if !/^[a-zA-Z]\w*[!?]?$/.match?(key.to_s) ||
|
|
111
111
|
AVOID_GETTERS.key?(key) ||
|
|
112
|
-
|
|
112
|
+
tool_class.method_defined?(key, false) ||
|
|
113
|
+
tool_class.private_method_defined?(key, false)
|
|
113
114
|
end
|
|
114
115
|
tool_class.class_eval do
|
|
115
116
|
define_method(key) do
|
data/lib/toys/dsl/tool.rb
CHANGED
|
@@ -436,9 +436,12 @@ module Toys
|
|
|
436
436
|
# current commit if already loading from git, or to `HEAD`.
|
|
437
437
|
# @param as [String] Load into the given tool/namespace. If omitted,
|
|
438
438
|
# configuration will be loaded into the current namespace.
|
|
439
|
-
# @param update [Boolean]
|
|
440
|
-
# is a SHA).
|
|
441
|
-
# names, are up to date.
|
|
439
|
+
# @param update [Boolean,Integer] Whether and when to force-fetch from
|
|
440
|
+
# the remote (unless the commit is a SHA). Force-fetching will ensure
|
|
441
|
+
# that symbolic commits, such as branch names or HEAD, are up to date.
|
|
442
|
+
# You can pass `true` or `false` to specify whether to update, or an
|
|
443
|
+
# integer to update if the last update was done at least that many
|
|
444
|
+
# seconds ago. Default is false.
|
|
442
445
|
#
|
|
443
446
|
# @return [self]
|
|
444
447
|
#
|
|
@@ -453,9 +456,35 @@ module Toys
|
|
|
453
456
|
raise ToolDefinitionError, "Git remote not specified" unless remote
|
|
454
457
|
path ||= ""
|
|
455
458
|
commit ||= source_info.git_commit || "HEAD"
|
|
456
|
-
@__loader.load_git(source_info, remote, path, commit,
|
|
457
|
-
@__words, @__remaining_words, @__priority
|
|
458
|
-
|
|
459
|
+
@__loader.load_git(source_info, remote, path, commit, update,
|
|
460
|
+
@__words, @__remaining_words, @__priority)
|
|
461
|
+
self
|
|
462
|
+
end
|
|
463
|
+
|
|
464
|
+
##
|
|
465
|
+
# Load configuration from a gem, as if its contents were inserted at the
|
|
466
|
+
# current location.
|
|
467
|
+
#
|
|
468
|
+
# @param name [String] Name of the gem
|
|
469
|
+
# @param version [String,Array<String>] Version requirements for the gem.
|
|
470
|
+
# @param path [String] Optional path within the gem to the file or
|
|
471
|
+
# directory to load. Defaults to the root of the gem's toys directory.
|
|
472
|
+
# @param toys_dir [String] Optional override for the gem's toys
|
|
473
|
+
# directory name. If not specified, the default specified by the gem
|
|
474
|
+
# will be used.
|
|
475
|
+
# @param as [String] Load into the given tool/namespace. If omitted,
|
|
476
|
+
# configuration will be loaded into the current namespace.
|
|
477
|
+
#
|
|
478
|
+
def load_gem(name, version: nil, path: nil, toys_dir: nil, as: nil)
|
|
479
|
+
if as
|
|
480
|
+
tool(as) do
|
|
481
|
+
load_gem(name, version: version, path: path, toys_dir: toys_dir)
|
|
482
|
+
end
|
|
483
|
+
return self
|
|
484
|
+
end
|
|
485
|
+
path ||= ""
|
|
486
|
+
@__loader.load_gem(source_info, name, version, toys_dir, path,
|
|
487
|
+
@__words, @__remaining_words, @__priority)
|
|
459
488
|
self
|
|
460
489
|
end
|
|
461
490
|
|
|
@@ -504,7 +533,7 @@ module Toys
|
|
|
504
533
|
if template_class.nil?
|
|
505
534
|
raise ToolDefinitionError, "Template not found: #{name.inspect}"
|
|
506
535
|
end
|
|
507
|
-
template =
|
|
536
|
+
template = template_class.new(*args, **kwargs)
|
|
508
537
|
yield template if block_given?
|
|
509
538
|
class_exec(template, &template_class.expansion)
|
|
510
539
|
self
|
|
@@ -946,15 +975,18 @@ module Toys
|
|
|
946
975
|
# @param default [Object] The default value. This is the value that will
|
|
947
976
|
# be set in the context if this flag is not provided on the command
|
|
948
977
|
# line. Defaults to `nil`.
|
|
949
|
-
# @param handler [Proc,nil,:set,:push] An optional handler
|
|
950
|
-
#
|
|
951
|
-
#
|
|
952
|
-
#
|
|
953
|
-
#
|
|
954
|
-
#
|
|
955
|
-
#
|
|
956
|
-
#
|
|
957
|
-
# `
|
|
978
|
+
# @param handler [Proc,nil,:set,:push] An optional handler that
|
|
979
|
+
# customizes how a value is set or updated when the flag is parsed.
|
|
980
|
+
# A handler is a proc that takes up to three arguments: the given
|
|
981
|
+
# value, the previous value, and a hash containing all the data
|
|
982
|
+
# collected so far during argument parsing. The proc must return the
|
|
983
|
+
# new value for the flag.
|
|
984
|
+
# You may also specify a predefined named handler. The `:set` handler
|
|
985
|
+
# (the default) replaces the previous value (effectively
|
|
986
|
+
# `-> (val) { val }`). The `:push` handler expects the previous value
|
|
987
|
+
# to be an array and pushes the given value onto it; it should be
|
|
988
|
+
# combined with setting the default value to `[]` and is intended for
|
|
989
|
+
# "multi-valued" flags.
|
|
958
990
|
# @param complete_flags [Object] A specifier for shell tab completion
|
|
959
991
|
# for flag names associated with this flag. By default, a
|
|
960
992
|
# {Toys::Flag::DefaultCompletion} is used, which provides the flag's
|
data/lib/toys/flag.rb
CHANGED
|
@@ -374,16 +374,16 @@ module Toys
|
|
|
374
374
|
# The set handler replaces the previous value.
|
|
375
375
|
# @return [Proc]
|
|
376
376
|
#
|
|
377
|
-
SET_HANDLER =
|
|
377
|
+
SET_HANDLER = proc { |val| val }
|
|
378
378
|
|
|
379
379
|
##
|
|
380
380
|
# The push handler pushes the given value using the `<<` operator.
|
|
381
381
|
# @return [Proc]
|
|
382
382
|
#
|
|
383
|
-
PUSH_HANDLER =
|
|
383
|
+
PUSH_HANDLER = proc { |val, prev| prev.nil? ? [val] : prev << val }
|
|
384
384
|
|
|
385
385
|
##
|
|
386
|
-
# The default handler is the set handler,
|
|
386
|
+
# The default handler is the set handler, which replaces the previous value.
|
|
387
387
|
# @return [Proc]
|
|
388
388
|
#
|
|
389
389
|
DEFAULT_HANDLER = SET_HANDLER
|
|
@@ -401,15 +401,18 @@ module Toys
|
|
|
401
401
|
# @param default [Object] The default value. This is the value that will
|
|
402
402
|
# be set in the context if this flag is not provided on the command
|
|
403
403
|
# line. Defaults to `nil`.
|
|
404
|
-
# @param handler [Proc,nil,:set,:push] An optional handler
|
|
405
|
-
#
|
|
406
|
-
#
|
|
407
|
-
#
|
|
408
|
-
#
|
|
409
|
-
#
|
|
410
|
-
#
|
|
411
|
-
#
|
|
412
|
-
# `
|
|
404
|
+
# @param handler [Proc,nil,:set,:push] An optional handler that customizes
|
|
405
|
+
# how a value is set or updated when the flag is parsed.
|
|
406
|
+
# A handler is a proc that takes up to three arguments: the given
|
|
407
|
+
# value, the previous value, and a hash containing all the data
|
|
408
|
+
# collected so far during argument parsing. The proc must return the
|
|
409
|
+
# new value for the flag.
|
|
410
|
+
# You may also specify a predefined named handler. The `:set` handler
|
|
411
|
+
# (the default) replaces the previous value (effectively
|
|
412
|
+
# `-> (val) { val }`). The `:push` handler expects the previous value
|
|
413
|
+
# to be an array and pushes the given value onto it; it should be
|
|
414
|
+
# combined with setting `default: []` and is intended for
|
|
415
|
+
# "multi-valued" flags.
|
|
413
416
|
# @param complete_flags [Object] A specifier for shell tab completion for
|
|
414
417
|
# flag names associated with this flag. By default, a
|
|
415
418
|
# {Toys::Flag::DefaultCompletion} is used, which provides the flag's
|
data/lib/toys/input_file.rb
CHANGED
|
@@ -14,7 +14,7 @@ module Toys::InputFile # rubocop:disable Style/ClassAndModuleChildren
|
|
|
14
14
|
def self.evaluate(tool_class, words, priority, remaining_words, source, loader)
|
|
15
15
|
namespace = ::Module.new
|
|
16
16
|
namespace.module_eval do
|
|
17
|
-
include ::Toys::Context::Key
|
|
17
|
+
include ::Toys::Context::Key # rubocop:disable Layout/EmptyLinesAfterModuleInclusion
|
|
18
18
|
@__tool_class = tool_class
|
|
19
19
|
end
|
|
20
20
|
path = source.source_path
|
|
@@ -25,9 +25,7 @@ module Toys::InputFile # rubocop:disable Style/ClassAndModuleChildren
|
|
|
25
25
|
const_set(name, namespace)
|
|
26
26
|
::Toys::DSL::Internal.prepare(tool_class, words, priority, remaining_words, source, loader) do
|
|
27
27
|
::Toys::ContextualError.capture_path("Error while loading Toys config!", path) do
|
|
28
|
-
# rubocop:disable Security/Eval
|
|
29
|
-
eval(str, __binding, path)
|
|
30
|
-
# rubocop:enable Security/Eval
|
|
28
|
+
eval(str, __binding, path) # rubocop:disable Security/Eval
|
|
31
29
|
end
|
|
32
30
|
end
|
|
33
31
|
end
|
|
@@ -48,7 +46,7 @@ module Toys::InputFile # rubocop:disable Style/ClassAndModuleChildren
|
|
|
48
46
|
return nil if index.nil?
|
|
49
47
|
"#{string[0, index]}" \
|
|
50
48
|
"module #{module_name}; @__tool_class.class_eval do; " \
|
|
51
|
-
"#{string[index
|
|
49
|
+
"#{string[index..]}\n" \
|
|
52
50
|
"end; end\n"
|
|
53
51
|
end
|
|
54
52
|
end
|