toys-core 0.12.2 → 0.13.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 +22 -0
- data/LICENSE.md +1 -1
- data/README.md +4 -1
- data/docs/guide.md +1 -1
- data/lib/toys/acceptor.rb +10 -1
- data/lib/toys/arg_parser.rb +1 -0
- data/lib/toys/cli.rb +127 -107
- data/lib/toys/compat.rb +54 -3
- data/lib/toys/completion.rb +15 -5
- data/lib/toys/context.rb +22 -20
- data/lib/toys/core.rb +6 -2
- data/lib/toys/dsl/base.rb +2 -0
- data/lib/toys/dsl/flag.rb +23 -17
- data/lib/toys/dsl/flag_group.rb +11 -7
- data/lib/toys/dsl/positional_arg.rb +23 -13
- data/lib/toys/dsl/tool.rb +10 -6
- data/lib/toys/errors.rb +63 -8
- data/lib/toys/flag.rb +660 -651
- data/lib/toys/flag_group.rb +19 -6
- data/lib/toys/input_file.rb +9 -3
- data/lib/toys/loader.rb +129 -115
- data/lib/toys/middleware.rb +45 -21
- data/lib/toys/mixin.rb +8 -6
- data/lib/toys/positional_arg.rb +18 -17
- data/lib/toys/settings.rb +81 -67
- data/lib/toys/source_info.rb +33 -24
- data/lib/toys/standard_middleware/add_verbosity_flags.rb +2 -0
- data/lib/toys/standard_middleware/apply_config.rb +1 -0
- data/lib/toys/standard_middleware/handle_usage_errors.rb +1 -0
- data/lib/toys/standard_middleware/set_default_descriptions.rb +1 -0
- data/lib/toys/standard_middleware/show_help.rb +2 -0
- data/lib/toys/standard_middleware/show_root_version.rb +2 -0
- data/lib/toys/standard_mixins/bundler.rb +22 -14
- data/lib/toys/standard_mixins/exec.rb +31 -20
- data/lib/toys/standard_mixins/fileutils.rb +3 -1
- data/lib/toys/standard_mixins/gems.rb +21 -17
- data/lib/toys/standard_mixins/git_cache.rb +5 -7
- data/lib/toys/standard_mixins/highline.rb +8 -8
- data/lib/toys/standard_mixins/terminal.rb +5 -5
- data/lib/toys/standard_mixins/xdg.rb +5 -5
- data/lib/toys/template.rb +9 -7
- data/lib/toys/tool_definition.rb +209 -202
- data/lib/toys/utils/completion_engine.rb +7 -2
- data/lib/toys/utils/exec.rb +158 -127
- data/lib/toys/utils/gems.rb +81 -57
- data/lib/toys/utils/git_cache.rb +674 -45
- data/lib/toys/utils/help_text.rb +27 -3
- data/lib/toys/utils/terminal.rb +10 -2
- data/lib/toys/wrappable_string.rb +9 -2
- data/lib/toys-core.rb +14 -5
- metadata +4 -4
data/lib/toys/settings.rb
CHANGED
@@ -299,26 +299,16 @@ module Toys
|
|
299
299
|
# grandchild_settings.str # => "value_from_root"
|
300
300
|
#
|
301
301
|
class Settings
|
302
|
+
# A special value indicating a type check failure.
|
303
|
+
ILLEGAL_VALUE = ::Object.new.freeze
|
304
|
+
|
305
|
+
# A special type specification indicating infer from the default value.
|
306
|
+
DEFAULT_TYPE = ::Object.new.freeze
|
307
|
+
|
302
308
|
##
|
303
309
|
# Error raised when a value does not match the type constraint.
|
304
310
|
#
|
305
311
|
class FieldError < ::StandardError
|
306
|
-
# @private
|
307
|
-
def initialize(value, settings_class, field_name, type_description)
|
308
|
-
@value = value
|
309
|
-
@settings_class = settings_class
|
310
|
-
@field_name = field_name
|
311
|
-
@type_description = type_description
|
312
|
-
message = "unable to set #{settings_class}##{field_name}"
|
313
|
-
message =
|
314
|
-
if type_description
|
315
|
-
"#{message}: value #{value.inspect} does not match type #{type_description}"
|
316
|
-
else
|
317
|
-
"#{message}: field does not exist"
|
318
|
-
end
|
319
|
-
super(message)
|
320
|
-
end
|
321
|
-
|
322
312
|
##
|
323
313
|
# The value that did not match
|
324
314
|
# @return [Object]
|
@@ -342,13 +332,25 @@ module Toys
|
|
342
332
|
# @return [String, nil]
|
343
333
|
#
|
344
334
|
attr_reader :type_description
|
345
|
-
end
|
346
335
|
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
336
|
+
##
|
337
|
+
# @private
|
338
|
+
#
|
339
|
+
def initialize(value, settings_class, field_name, type_description)
|
340
|
+
@value = value
|
341
|
+
@settings_class = settings_class
|
342
|
+
@field_name = field_name
|
343
|
+
@type_description = type_description
|
344
|
+
message = "unable to set #{settings_class}##{field_name}"
|
345
|
+
message =
|
346
|
+
if type_description
|
347
|
+
"#{message}: value #{value.inspect} does not match type #{type_description}"
|
348
|
+
else
|
349
|
+
"#{message}: field does not exist"
|
350
|
+
end
|
351
|
+
super(message)
|
352
|
+
end
|
353
|
+
end
|
352
354
|
|
353
355
|
##
|
354
356
|
# A type object that checks values.
|
@@ -558,7 +560,9 @@ module Toys
|
|
558
560
|
end
|
559
561
|
end
|
560
562
|
|
563
|
+
##
|
561
564
|
# @private
|
565
|
+
#
|
562
566
|
CONVERTERS = {
|
563
567
|
::Date => date_converter,
|
564
568
|
::DateTime => datetime_converter,
|
@@ -570,51 +574,6 @@ module Toys
|
|
570
574
|
}.freeze
|
571
575
|
end
|
572
576
|
|
573
|
-
# @private
|
574
|
-
SETTINGS_TYPE = Type.new("(settings object)") do |val|
|
575
|
-
val.nil? || val.is_a?(Settings) ? val : ILLEGAL_VALUE
|
576
|
-
end
|
577
|
-
|
578
|
-
# @private
|
579
|
-
class Field
|
580
|
-
def initialize(container, name, type_spec, default_or_group_class)
|
581
|
-
@container = container
|
582
|
-
@name = name
|
583
|
-
if type_spec == SETTINGS_TYPE
|
584
|
-
@default = nil
|
585
|
-
@group_class = default_or_group_class
|
586
|
-
@type = type_spec
|
587
|
-
else
|
588
|
-
@group_class = nil
|
589
|
-
if type_spec == DEFAULT_TYPE
|
590
|
-
@default = default_or_group_class
|
591
|
-
@type = Type.for_default_value(@default)
|
592
|
-
else
|
593
|
-
@type = Type.for_type_spec(type_spec)
|
594
|
-
@default = validate(default_or_group_class)
|
595
|
-
end
|
596
|
-
end
|
597
|
-
end
|
598
|
-
|
599
|
-
attr_reader :container
|
600
|
-
attr_reader :name
|
601
|
-
attr_reader :type
|
602
|
-
attr_reader :default
|
603
|
-
attr_reader :group_class
|
604
|
-
|
605
|
-
def group?
|
606
|
-
!@group_class.nil?
|
607
|
-
end
|
608
|
-
|
609
|
-
def validate(value)
|
610
|
-
validated_value = @type.call(value)
|
611
|
-
if validated_value == ILLEGAL_VALUE
|
612
|
-
raise FieldError.new(value, container, name, @type.description)
|
613
|
-
end
|
614
|
-
validated_value
|
615
|
-
end
|
616
|
-
end
|
617
|
-
|
618
577
|
##
|
619
578
|
# Create a settings instance.
|
620
579
|
#
|
@@ -716,6 +675,7 @@ module Toys
|
|
716
675
|
|
717
676
|
##
|
718
677
|
# @private
|
678
|
+
#
|
719
679
|
# Internal get field value, with fallback to parents.
|
720
680
|
#
|
721
681
|
def get!(field)
|
@@ -743,6 +703,7 @@ module Toys
|
|
743
703
|
|
744
704
|
##
|
745
705
|
# @private
|
706
|
+
#
|
746
707
|
# Internal set field value, with validation.
|
747
708
|
#
|
748
709
|
def set!(field, value)
|
@@ -754,6 +715,7 @@ module Toys
|
|
754
715
|
|
755
716
|
##
|
756
717
|
# @private
|
718
|
+
#
|
757
719
|
# Internal determine if the field is set locally.
|
758
720
|
#
|
759
721
|
def set?(field)
|
@@ -764,6 +726,7 @@ module Toys
|
|
764
726
|
|
765
727
|
##
|
766
728
|
# @private
|
729
|
+
#
|
767
730
|
# Internal unset field value.
|
768
731
|
#
|
769
732
|
def unset!(field)
|
@@ -772,6 +735,55 @@ module Toys
|
|
772
735
|
end
|
773
736
|
end
|
774
737
|
|
738
|
+
##
|
739
|
+
# @private
|
740
|
+
#
|
741
|
+
SETTINGS_TYPE = Type.new("(settings object)") do |val|
|
742
|
+
val.nil? || val.is_a?(Settings) ? val : ILLEGAL_VALUE
|
743
|
+
end
|
744
|
+
|
745
|
+
##
|
746
|
+
# @private
|
747
|
+
#
|
748
|
+
class Field
|
749
|
+
def initialize(container, name, type_spec, default_or_group_class)
|
750
|
+
@container = container
|
751
|
+
@name = name
|
752
|
+
if type_spec == SETTINGS_TYPE
|
753
|
+
@default = nil
|
754
|
+
@group_class = default_or_group_class
|
755
|
+
@type = type_spec
|
756
|
+
else
|
757
|
+
@group_class = nil
|
758
|
+
if type_spec == DEFAULT_TYPE
|
759
|
+
@default = default_or_group_class
|
760
|
+
@type = Type.for_default_value(@default)
|
761
|
+
else
|
762
|
+
@type = Type.for_type_spec(type_spec)
|
763
|
+
@default = validate(default_or_group_class)
|
764
|
+
end
|
765
|
+
end
|
766
|
+
end
|
767
|
+
|
768
|
+
attr_reader :container
|
769
|
+
attr_reader :name
|
770
|
+
attr_reader :type
|
771
|
+
attr_reader :default
|
772
|
+
attr_reader :group_class
|
773
|
+
|
774
|
+
def group?
|
775
|
+
!@group_class.nil?
|
776
|
+
end
|
777
|
+
|
778
|
+
def validate(value)
|
779
|
+
validated_value = @type.call(value)
|
780
|
+
if validated_value == ILLEGAL_VALUE
|
781
|
+
raise FieldError.new(value, container, name, @type.description)
|
782
|
+
end
|
783
|
+
validated_value
|
784
|
+
end
|
785
|
+
end
|
786
|
+
|
775
787
|
class << self
|
776
788
|
##
|
777
789
|
# Add an attribute field.
|
@@ -824,6 +836,7 @@ module Toys
|
|
824
836
|
|
825
837
|
##
|
826
838
|
# @private
|
839
|
+
#
|
827
840
|
# Returns the fields hash. This is shared between the settings class and
|
828
841
|
# all its instances.
|
829
842
|
#
|
@@ -833,6 +846,7 @@ module Toys
|
|
833
846
|
|
834
847
|
##
|
835
848
|
# @private
|
849
|
+
#
|
836
850
|
# When this base class is inherited, if its enclosing module is also a
|
837
851
|
# Settings, add the new class as a group in the enclosing class.
|
838
852
|
#
|
data/lib/toys/source_info.rb
CHANGED
@@ -6,30 +6,6 @@ module Toys
|
|
6
6
|
# or block that defined it.
|
7
7
|
#
|
8
8
|
class SourceInfo
|
9
|
-
##
|
10
|
-
# Create a SourceInfo.
|
11
|
-
# @private
|
12
|
-
#
|
13
|
-
def initialize(parent, priority, context_directory, source_type, source_path, source_proc,
|
14
|
-
git_remote, git_path, git_commit, source_name, data_dir_name, lib_dir_name)
|
15
|
-
@parent = parent
|
16
|
-
@root = parent&.root || self
|
17
|
-
@priority = priority
|
18
|
-
@context_directory = context_directory
|
19
|
-
@source_type = source_type
|
20
|
-
@source = source_type == :proc ? source_proc : source_path
|
21
|
-
@source_path = source_path
|
22
|
-
@source_proc = source_proc
|
23
|
-
@git_remote = git_remote
|
24
|
-
@git_path = git_path
|
25
|
-
@git_commit = git_commit
|
26
|
-
@source_name = source_name
|
27
|
-
@data_dir_name = data_dir_name
|
28
|
-
@lib_dir_name = lib_dir_name
|
29
|
-
@data_dir = find_special_dir(data_dir_name)
|
30
|
-
@lib_dir = find_special_dir(lib_dir_name)
|
31
|
-
end
|
32
|
-
|
33
9
|
##
|
34
10
|
# The parent of this SourceInfo.
|
35
11
|
#
|
@@ -161,8 +137,34 @@ module Toys
|
|
161
137
|
self
|
162
138
|
end
|
163
139
|
|
140
|
+
##
|
141
|
+
# Create a SourceInfo.
|
142
|
+
#
|
143
|
+
# @private
|
144
|
+
#
|
145
|
+
def initialize(parent, priority, context_directory, source_type, source_path, source_proc,
|
146
|
+
git_remote, git_path, git_commit, source_name, data_dir_name, lib_dir_name)
|
147
|
+
@parent = parent
|
148
|
+
@root = parent&.root || self
|
149
|
+
@priority = priority
|
150
|
+
@context_directory = context_directory
|
151
|
+
@source_type = source_type
|
152
|
+
@source = source_type == :proc ? source_proc : source_path
|
153
|
+
@source_path = source_path
|
154
|
+
@source_proc = source_proc
|
155
|
+
@git_remote = git_remote
|
156
|
+
@git_path = git_path
|
157
|
+
@git_commit = git_commit
|
158
|
+
@source_name = source_name
|
159
|
+
@data_dir_name = data_dir_name
|
160
|
+
@lib_dir_name = lib_dir_name
|
161
|
+
@data_dir = find_special_dir(data_dir_name)
|
162
|
+
@lib_dir = find_special_dir(lib_dir_name)
|
163
|
+
end
|
164
|
+
|
164
165
|
##
|
165
166
|
# Create a child SourceInfo relative to the parent path.
|
167
|
+
#
|
166
168
|
# @private
|
167
169
|
#
|
168
170
|
def relative_child(filename, source_name: nil)
|
@@ -186,6 +188,7 @@ module Toys
|
|
186
188
|
|
187
189
|
##
|
188
190
|
# Create a child SourceInfo with an absolute path.
|
191
|
+
#
|
189
192
|
# @private
|
190
193
|
#
|
191
194
|
def absolute_child(child_path, source_name: nil)
|
@@ -197,6 +200,7 @@ module Toys
|
|
197
200
|
|
198
201
|
##
|
199
202
|
# Create a child SourceInfo with a git source.
|
203
|
+
#
|
200
204
|
# @private
|
201
205
|
#
|
202
206
|
def git_child(child_git_remote, child_git_path, child_git_commit, child_path,
|
@@ -211,6 +215,7 @@ module Toys
|
|
211
215
|
|
212
216
|
##
|
213
217
|
# Create a proc child SourceInfo
|
218
|
+
#
|
214
219
|
# @private
|
215
220
|
#
|
216
221
|
def proc_child(child_proc, source_name: nil)
|
@@ -222,6 +227,7 @@ module Toys
|
|
222
227
|
|
223
228
|
##
|
224
229
|
# Create a root source info for a file path.
|
230
|
+
#
|
225
231
|
# @private
|
226
232
|
#
|
227
233
|
def self.create_path_root(source_path, priority,
|
@@ -243,6 +249,7 @@ module Toys
|
|
243
249
|
|
244
250
|
##
|
245
251
|
# Create a root source info for a cached git repo.
|
252
|
+
#
|
246
253
|
# @private
|
247
254
|
#
|
248
255
|
def self.create_git_root(git_remote, git_path, git_commit, source_path, priority,
|
@@ -258,6 +265,7 @@ module Toys
|
|
258
265
|
|
259
266
|
##
|
260
267
|
# Create a root source info for a proc.
|
268
|
+
#
|
261
269
|
# @private
|
262
270
|
#
|
263
271
|
def self.create_proc_root(source_proc, priority,
|
@@ -272,6 +280,7 @@ module Toys
|
|
272
280
|
|
273
281
|
##
|
274
282
|
# Check a path and determine the canonical path and type.
|
283
|
+
#
|
275
284
|
# @private
|
276
285
|
#
|
277
286
|
def self.check_path(path, lenient)
|
@@ -48,6 +48,7 @@ module Toys
|
|
48
48
|
|
49
49
|
##
|
50
50
|
# Configure the tool flags.
|
51
|
+
#
|
51
52
|
# @private
|
52
53
|
#
|
53
54
|
def config(tool, _loader)
|
@@ -63,6 +64,7 @@ module Toys
|
|
63
64
|
|
64
65
|
INCREMENT_HANDLER = ->(_val, cur) { cur.to_i + 1 }
|
65
66
|
DECREMENT_HANDLER = ->(_val, cur) { cur.to_i - 1 }
|
67
|
+
private_constant :INCREMENT_HANDLER, :DECREMENT_HANDLER
|
66
68
|
|
67
69
|
def add_verbose_flags(tool)
|
68
70
|
verbose_flags = resolve_flags_spec(@verbose_flags, tool, DEFAULT_VERBOSE_FLAGS)
|
@@ -202,6 +202,7 @@ module Toys
|
|
202
202
|
|
203
203
|
##
|
204
204
|
# Configure flags and default data.
|
205
|
+
#
|
205
206
|
# @private
|
206
207
|
#
|
207
208
|
def config(tool, loader)
|
@@ -224,6 +225,7 @@ module Toys
|
|
224
225
|
|
225
226
|
##
|
226
227
|
# Display help text if requested.
|
228
|
+
#
|
227
229
|
# @private
|
228
230
|
#
|
229
231
|
def run(context)
|
@@ -67,20 +67,6 @@ module Toys
|
|
67
67
|
module Bundler
|
68
68
|
include Mixin
|
69
69
|
|
70
|
-
on_initialize do |static: false, **kwargs|
|
71
|
-
unless static
|
72
|
-
context_directory = self[::Toys::Context::Key::CONTEXT_DIRECTORY]
|
73
|
-
source_info = self[::Toys::Context::Key::TOOL_SOURCE]
|
74
|
-
::Toys::StandardMixins::Bundler.setup_bundle(context_directory, source_info, **kwargs)
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
on_include do |static: false, **kwargs|
|
79
|
-
if static
|
80
|
-
::Toys::StandardMixins::Bundler.setup_bundle(context_directory, source_info, **kwargs)
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
70
|
##
|
85
71
|
# Default search directories for Gemfiles.
|
86
72
|
# @return [Array<String,Symbol>]
|
@@ -93,7 +79,9 @@ module Toys
|
|
93
79
|
#
|
94
80
|
DEFAULT_TOYS_GEMFILE_NAMES = [".gems.rb", "Gemfile"].freeze
|
95
81
|
|
82
|
+
##
|
96
83
|
# @private
|
84
|
+
#
|
97
85
|
def self.setup_bundle(context_directory,
|
98
86
|
source_info,
|
99
87
|
gemfile_path: nil,
|
@@ -118,9 +106,27 @@ module Toys
|
|
118
106
|
gems.bundle(groups: groups, gemfile_path: gemfile_path, retries: retries)
|
119
107
|
end
|
120
108
|
|
109
|
+
on_initialize do |static: false, **kwargs|
|
110
|
+
unless static
|
111
|
+
context_directory = self[::Toys::Context::Key::CONTEXT_DIRECTORY]
|
112
|
+
source_info = self[::Toys::Context::Key::TOOL_SOURCE]
|
113
|
+
::Toys::StandardMixins::Bundler.setup_bundle(context_directory, source_info, **kwargs)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
on_include do |static: false, **kwargs|
|
118
|
+
if static
|
119
|
+
::Toys::StandardMixins::Bundler.setup_bundle(context_directory, source_info, **kwargs)
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
##
|
121
124
|
# @private
|
125
|
+
#
|
122
126
|
class GemfileFinder
|
127
|
+
##
|
123
128
|
# @private
|
129
|
+
#
|
124
130
|
def initialize(context_directory, source_info, gemfile_names, toys_gemfile_names)
|
125
131
|
@context_directory = context_directory
|
126
132
|
@source_info = source_info
|
@@ -128,7 +134,9 @@ module Toys
|
|
128
134
|
@toys_gemfile_names = toys_gemfile_names || DEFAULT_TOYS_GEMFILE_NAMES
|
129
135
|
end
|
130
136
|
|
137
|
+
##
|
131
138
|
# @private
|
139
|
+
#
|
132
140
|
def search(search_dir)
|
133
141
|
case search_dir
|
134
142
|
when ::Array
|
@@ -229,20 +229,6 @@ module Toys
|
|
229
229
|
#
|
230
230
|
KEY = ::Object.new.freeze
|
231
231
|
|
232
|
-
on_initialize do |**opts|
|
233
|
-
require "toys/utils/exec"
|
234
|
-
context = self
|
235
|
-
opts = Exec._setup_exec_opts(opts, context)
|
236
|
-
context[KEY] = Utils::Exec.new(**opts) do |k|
|
237
|
-
case k
|
238
|
-
when :logger
|
239
|
-
context[Context::Key::LOGGER]
|
240
|
-
when :cli
|
241
|
-
context[Context::Key::CLI]
|
242
|
-
end
|
243
|
-
end
|
244
|
-
end
|
245
|
-
|
246
232
|
##
|
247
233
|
# Set default configuration options.
|
248
234
|
#
|
@@ -305,7 +291,7 @@ module Toys
|
|
305
291
|
#
|
306
292
|
# Execute a small script with warnings
|
307
293
|
#
|
308
|
-
# exec_ruby("-w", "-e", "(1..10).each { |i| puts i }")
|
294
|
+
# exec_ruby(["-w", "-e", "(1..10).each { |i| puts i }"])
|
309
295
|
#
|
310
296
|
# @param args [String,Array<String>] The arguments to ruby.
|
311
297
|
# @param opts [keywords] The command options. See the section on
|
@@ -397,6 +383,7 @@ module Toys
|
|
397
383
|
def exec_tool(cmd, **opts, &block)
|
398
384
|
func = Exec._make_tool_caller(cmd)
|
399
385
|
opts = Exec._setup_exec_opts(opts, self)
|
386
|
+
opts = {log_cmd: "exec tool: #{cmd.inspect}"}.merge(opts)
|
400
387
|
self[KEY].exec_proc(func, **opts, &block)
|
401
388
|
end
|
402
389
|
|
@@ -675,13 +662,17 @@ module Toys
|
|
675
662
|
0
|
676
663
|
end
|
677
664
|
|
678
|
-
##
|
665
|
+
##
|
666
|
+
# @private
|
667
|
+
#
|
679
668
|
def self._make_tool_caller(cmd)
|
680
669
|
cmd = ::Shellwords.split(cmd) if cmd.is_a?(::String)
|
681
670
|
proc { |config| ::Kernel.exit(config[:cli].run(*cmd)) }
|
682
671
|
end
|
683
672
|
|
684
|
-
##
|
673
|
+
##
|
674
|
+
# @private
|
675
|
+
#
|
685
676
|
def self._setup_exec_opts(opts, context)
|
686
677
|
count = 0
|
687
678
|
result_callback = nil
|
@@ -704,7 +695,9 @@ module Toys
|
|
704
695
|
opts
|
705
696
|
end
|
706
697
|
|
707
|
-
##
|
698
|
+
##
|
699
|
+
# @private
|
700
|
+
#
|
708
701
|
def self._interpret_e(value, context)
|
709
702
|
return nil unless value
|
710
703
|
proc do |result|
|
@@ -718,7 +711,9 @@ module Toys
|
|
718
711
|
end
|
719
712
|
end
|
720
713
|
|
721
|
-
##
|
714
|
+
##
|
715
|
+
# @private
|
716
|
+
#
|
722
717
|
def self._interpret_result_callback(value, context)
|
723
718
|
if value.is_a?(::Symbol)
|
724
719
|
context.method(value)
|
@@ -731,7 +726,9 @@ module Toys
|
|
731
726
|
end
|
732
727
|
end
|
733
728
|
|
734
|
-
##
|
729
|
+
##
|
730
|
+
# @private
|
731
|
+
#
|
735
732
|
def self._setup_clean_process(cmd)
|
736
733
|
raise ::ArgumentError, "Toys process is unknown" unless ::Toys.executable_path
|
737
734
|
cmd = ::Shellwords.split(cmd) if cmd.is_a?(::String)
|
@@ -746,6 +743,20 @@ module Toys
|
|
746
743
|
yield(cmd)
|
747
744
|
end
|
748
745
|
end
|
746
|
+
|
747
|
+
on_initialize do |**opts|
|
748
|
+
require "toys/utils/exec"
|
749
|
+
context = self
|
750
|
+
opts = Exec._setup_exec_opts(opts, context)
|
751
|
+
context[KEY] = Utils::Exec.new(**opts) do |k|
|
752
|
+
case k
|
753
|
+
when :logger
|
754
|
+
context[Context::Key::LOGGER]
|
755
|
+
when :cli
|
756
|
+
context[Context::Key::CLI]
|
757
|
+
end
|
758
|
+
end
|
759
|
+
end
|
749
760
|
end
|
750
761
|
end
|
751
762
|
end
|
@@ -25,23 +25,6 @@ module Toys
|
|
25
25
|
module Gems
|
26
26
|
include Mixin
|
27
27
|
|
28
|
-
on_include do |**opts|
|
29
|
-
@__gems_opts = opts
|
30
|
-
|
31
|
-
## @private
|
32
|
-
def self.gems
|
33
|
-
require "toys/utils/gems"
|
34
|
-
# rubocop:disable Naming/MemoizedInstanceVariableName
|
35
|
-
@__gems ||= Utils::Gems.new(**@__gems_opts)
|
36
|
-
# rubocop:enable Naming/MemoizedInstanceVariableName
|
37
|
-
end
|
38
|
-
|
39
|
-
## @private
|
40
|
-
def self.gem(name, *requirements)
|
41
|
-
gems.activate(name, *requirements)
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
28
|
##
|
46
29
|
# A tool-wide instance of {Toys::Utils::Gems}.
|
47
30
|
# @return [Toys::Utils::Gems]
|
@@ -60,6 +43,27 @@ module Toys
|
|
60
43
|
def gem(name, *requirements)
|
61
44
|
self.class.gems.activate(name, *requirements)
|
62
45
|
end
|
46
|
+
|
47
|
+
on_include do |**opts|
|
48
|
+
@__gems_opts = opts
|
49
|
+
|
50
|
+
##
|
51
|
+
# @private
|
52
|
+
#
|
53
|
+
def self.gems
|
54
|
+
require "toys/utils/gems"
|
55
|
+
# rubocop:disable Naming/MemoizedInstanceVariableName
|
56
|
+
@__gems ||= Utils::Gems.new(**@__gems_opts)
|
57
|
+
# rubocop:enable Naming/MemoizedInstanceVariableName
|
58
|
+
end
|
59
|
+
|
60
|
+
##
|
61
|
+
# @private
|
62
|
+
#
|
63
|
+
def self.gem(name, *requirements)
|
64
|
+
gems.activate(name, *requirements)
|
65
|
+
end
|
66
|
+
end
|
63
67
|
end
|
64
68
|
end
|
65
69
|
end
|
@@ -1,7 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "fileutils"
|
4
|
-
|
5
3
|
module Toys
|
6
4
|
module StandardMixins
|
7
5
|
##
|
@@ -30,11 +28,6 @@ module Toys
|
|
30
28
|
#
|
31
29
|
KEY = ::Object.new.freeze
|
32
30
|
|
33
|
-
on_initialize do
|
34
|
-
require "toys/utils/git_cache"
|
35
|
-
self[KEY] = Utils::GitCache.new
|
36
|
-
end
|
37
|
-
|
38
31
|
##
|
39
32
|
# Access the builtin GitCache.
|
40
33
|
#
|
@@ -43,6 +36,11 @@ module Toys
|
|
43
36
|
def git_cache
|
44
37
|
self[KEY]
|
45
38
|
end
|
39
|
+
|
40
|
+
on_initialize do
|
41
|
+
require "toys/utils/git_cache"
|
42
|
+
self[KEY] = Utils::GitCache.new
|
43
|
+
end
|
46
44
|
end
|
47
45
|
end
|
48
46
|
end
|