toys-core 0.12.2 → 0.13.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.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +22 -0
  3. data/LICENSE.md +1 -1
  4. data/README.md +4 -1
  5. data/docs/guide.md +1 -1
  6. data/lib/toys/acceptor.rb +10 -1
  7. data/lib/toys/arg_parser.rb +1 -0
  8. data/lib/toys/cli.rb +127 -107
  9. data/lib/toys/compat.rb +54 -3
  10. data/lib/toys/completion.rb +15 -5
  11. data/lib/toys/context.rb +22 -20
  12. data/lib/toys/core.rb +6 -2
  13. data/lib/toys/dsl/base.rb +2 -0
  14. data/lib/toys/dsl/flag.rb +23 -17
  15. data/lib/toys/dsl/flag_group.rb +11 -7
  16. data/lib/toys/dsl/positional_arg.rb +23 -13
  17. data/lib/toys/dsl/tool.rb +10 -6
  18. data/lib/toys/errors.rb +63 -8
  19. data/lib/toys/flag.rb +660 -651
  20. data/lib/toys/flag_group.rb +19 -6
  21. data/lib/toys/input_file.rb +9 -3
  22. data/lib/toys/loader.rb +129 -115
  23. data/lib/toys/middleware.rb +45 -21
  24. data/lib/toys/mixin.rb +8 -6
  25. data/lib/toys/positional_arg.rb +18 -17
  26. data/lib/toys/settings.rb +81 -67
  27. data/lib/toys/source_info.rb +33 -24
  28. data/lib/toys/standard_middleware/add_verbosity_flags.rb +2 -0
  29. data/lib/toys/standard_middleware/apply_config.rb +1 -0
  30. data/lib/toys/standard_middleware/handle_usage_errors.rb +1 -0
  31. data/lib/toys/standard_middleware/set_default_descriptions.rb +1 -0
  32. data/lib/toys/standard_middleware/show_help.rb +2 -0
  33. data/lib/toys/standard_middleware/show_root_version.rb +2 -0
  34. data/lib/toys/standard_mixins/bundler.rb +22 -14
  35. data/lib/toys/standard_mixins/exec.rb +31 -20
  36. data/lib/toys/standard_mixins/fileutils.rb +3 -1
  37. data/lib/toys/standard_mixins/gems.rb +21 -17
  38. data/lib/toys/standard_mixins/git_cache.rb +5 -7
  39. data/lib/toys/standard_mixins/highline.rb +8 -8
  40. data/lib/toys/standard_mixins/terminal.rb +5 -5
  41. data/lib/toys/standard_mixins/xdg.rb +5 -5
  42. data/lib/toys/template.rb +9 -7
  43. data/lib/toys/tool_definition.rb +209 -202
  44. data/lib/toys/utils/completion_engine.rb +7 -2
  45. data/lib/toys/utils/exec.rb +158 -127
  46. data/lib/toys/utils/gems.rb +81 -57
  47. data/lib/toys/utils/git_cache.rb +674 -45
  48. data/lib/toys/utils/help_text.rb +27 -3
  49. data/lib/toys/utils/terminal.rb +10 -2
  50. data/lib/toys/wrappable_string.rb +9 -2
  51. data/lib/toys-core.rb +14 -5
  52. 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
- # A special value indicating a type check failure.
348
- ILLEGAL_VALUE = ::Object.new.freeze
349
-
350
- # A special type specification indicating infer from the default value.
351
- DEFAULT_TYPE = ::Object.new.freeze
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
  #
@@ -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)
@@ -28,6 +28,7 @@ module Toys
28
28
 
29
29
  ##
30
30
  # Appends the configuration block.
31
+ #
31
32
  # @private
32
33
  #
33
34
  def config(tool, loader)
@@ -33,6 +33,7 @@ module Toys
33
33
 
34
34
  ##
35
35
  # Intercept and handle usage errors during execution.
36
+ #
36
37
  # @private
37
38
  #
38
39
  def run(context)
@@ -90,6 +90,7 @@ module Toys
90
90
 
91
91
  ##
92
92
  # Add default description text to tools.
93
+ #
93
94
  # @private
94
95
  #
95
96
  def config(tool, loader)
@@ -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)
@@ -46,6 +46,7 @@ module Toys
46
46
 
47
47
  ##
48
48
  # Adds the version flag if requested.
49
+ #
49
50
  # @private
50
51
  #
51
52
  def config(tool, _loader)
@@ -58,6 +59,7 @@ module Toys
58
59
 
59
60
  ##
60
61
  # This middleware displays the version.
62
+ #
61
63
  # @private
62
64
  #
63
65
  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
- ## @private
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
- ## @private
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
- ## @private
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
- ## @private
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
- ## @private
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
@@ -16,7 +16,9 @@ module Toys
16
16
  module Fileutils
17
17
  include Mixin
18
18
 
19
- ## @private
19
+ ##
20
+ # @private
21
+ #
20
22
  def self.included(mod)
21
23
  mod.include(::FileUtils)
22
24
  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