toys-core 0.11.5 → 0.13.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +62 -0
  3. data/LICENSE.md +1 -1
  4. data/README.md +5 -2
  5. data/docs/guide.md +1 -1
  6. data/lib/toys/acceptor.rb +13 -4
  7. data/lib/toys/arg_parser.rb +7 -7
  8. data/lib/toys/cli.rb +170 -120
  9. data/lib/toys/compat.rb +71 -23
  10. data/lib/toys/completion.rb +18 -6
  11. data/lib/toys/context.rb +24 -15
  12. data/lib/toys/core.rb +6 -2
  13. data/lib/toys/dsl/base.rb +87 -0
  14. data/lib/toys/dsl/flag.rb +26 -20
  15. data/lib/toys/dsl/flag_group.rb +18 -14
  16. data/lib/toys/dsl/internal.rb +206 -0
  17. data/lib/toys/dsl/positional_arg.rb +26 -16
  18. data/lib/toys/dsl/tool.rb +180 -218
  19. data/lib/toys/errors.rb +64 -8
  20. data/lib/toys/flag.rb +662 -656
  21. data/lib/toys/flag_group.rb +24 -10
  22. data/lib/toys/input_file.rb +13 -7
  23. data/lib/toys/loader.rb +293 -140
  24. data/lib/toys/middleware.rb +46 -22
  25. data/lib/toys/mixin.rb +10 -8
  26. data/lib/toys/positional_arg.rb +21 -20
  27. data/lib/toys/settings.rb +914 -0
  28. data/lib/toys/source_info.rb +147 -35
  29. data/lib/toys/standard_middleware/add_verbosity_flags.rb +2 -0
  30. data/lib/toys/standard_middleware/apply_config.rb +6 -4
  31. data/lib/toys/standard_middleware/handle_usage_errors.rb +1 -0
  32. data/lib/toys/standard_middleware/set_default_descriptions.rb +19 -18
  33. data/lib/toys/standard_middleware/show_help.rb +19 -5
  34. data/lib/toys/standard_middleware/show_root_version.rb +2 -0
  35. data/lib/toys/standard_mixins/bundler.rb +24 -15
  36. data/lib/toys/standard_mixins/exec.rb +43 -34
  37. data/lib/toys/standard_mixins/fileutils.rb +3 -1
  38. data/lib/toys/standard_mixins/gems.rb +21 -17
  39. data/lib/toys/standard_mixins/git_cache.rb +46 -0
  40. data/lib/toys/standard_mixins/highline.rb +8 -8
  41. data/lib/toys/standard_mixins/terminal.rb +5 -5
  42. data/lib/toys/standard_mixins/xdg.rb +56 -0
  43. data/lib/toys/template.rb +11 -9
  44. data/lib/toys/{tool.rb → tool_definition.rb} +292 -226
  45. data/lib/toys/utils/completion_engine.rb +7 -2
  46. data/lib/toys/utils/exec.rb +162 -132
  47. data/lib/toys/utils/gems.rb +85 -60
  48. data/lib/toys/utils/git_cache.rb +813 -0
  49. data/lib/toys/utils/help_text.rb +117 -37
  50. data/lib/toys/utils/terminal.rb +11 -3
  51. data/lib/toys/utils/xdg.rb +293 -0
  52. data/lib/toys/wrappable_string.rb +9 -2
  53. data/lib/toys-core.rb +18 -6
  54. metadata +14 -7
@@ -2,28 +2,10 @@
2
2
 
3
3
  module Toys
4
4
  ##
5
- # Information about source toys directories and files.
5
+ # Information about the source of a tool, such as the file, git repository,
6
+ # or block that defined it.
6
7
  #
7
8
  class SourceInfo
8
- ##
9
- # Create a SourceInfo.
10
- # @private
11
- #
12
- def initialize(parent, context_directory, source_type, source_path, source_proc,
13
- source_name, data_dir_name, lib_dir_name)
14
- @parent = parent
15
- @context_directory = context_directory
16
- @source_type = source_type
17
- @source = source_type == :proc ? source_proc : source_path
18
- @source_path = source_path
19
- @source_proc = source_proc
20
- @source_name = source_name
21
- @data_dir_name = data_dir_name
22
- @lib_dir_name = lib_dir_name
23
- @data_dir = find_special_dir(data_dir_name)
24
- @lib_dir = find_special_dir(lib_dir_name)
25
- end
26
-
27
9
  ##
28
10
  # The parent of this SourceInfo.
29
11
  #
@@ -32,6 +14,21 @@ module Toys
32
14
  #
33
15
  attr_reader :parent
34
16
 
17
+ ##
18
+ # The root ancestor of this SourceInfo.
19
+ #
20
+ # @return [Toys::SourceInfo] The root ancestor.
21
+ #
22
+ attr_reader :root
23
+
24
+ ##
25
+ # The priority of tools defined by this source. Higher values indicate a
26
+ # higher priority. Lower priority values could be negative.
27
+ #
28
+ # @return [Integer] The priority.
29
+ #
30
+ attr_reader :priority
31
+
35
32
  ##
36
33
  # The context directory path (normally the directory containing the
37
34
  # toplevel toys file or directory).
@@ -73,6 +70,30 @@ module Toys
73
70
  #
74
71
  attr_reader :source_proc
75
72
 
73
+ ##
74
+ # The git remote.
75
+ #
76
+ # @return [String] The git remote
77
+ # @return [nil] if this source is not fron git.
78
+ #
79
+ attr_reader :git_remote
80
+
81
+ ##
82
+ # The git path.
83
+ #
84
+ # @return [String] The git path. This could be the empty string.
85
+ # @return [nil] if this source is not fron git.
86
+ #
87
+ attr_reader :git_path
88
+
89
+ ##
90
+ # The git commit.
91
+ #
92
+ # @return [String] The git commit.
93
+ # @return [nil] if this source is not fron git.
94
+ #
95
+ attr_reader :git_commit
96
+
76
97
  ##
77
98
  # The user-visible name of this source.
78
99
  #
@@ -116,59 +137,150 @@ module Toys
116
137
  self
117
138
  end
118
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
+
119
165
  ##
120
166
  # Create a child SourceInfo relative to the parent path.
167
+ #
121
168
  # @private
122
169
  #
123
- def relative_child(filename)
124
- raise "relative_child is valid only on a directory source" unless source_type == :directory
170
+ def relative_child(filename, source_name: nil)
171
+ unless source_type == :directory
172
+ raise LoaderError, "relative_child is valid only on a directory source"
173
+ end
125
174
  child_path = ::File.join(source_path, filename)
126
175
  child_path, type = SourceInfo.check_path(child_path, true)
127
176
  return nil unless child_path
128
- SourceInfo.new(self, context_directory, type, child_path, nil, child_path,
129
- @data_dir_name, @lib_dir_name)
177
+ child_git_path = ::File.join(git_path, filename) if git_path
178
+ source_name ||=
179
+ if git_path
180
+ "git(remote=#{git_remote} path=#{child_git_path} commit=#{git_commit})"
181
+ else
182
+ child_path
183
+ end
184
+ SourceInfo.new(self, priority, context_directory, type, child_path, nil,
185
+ git_remote, child_git_path, git_commit,
186
+ source_name, @data_dir_name, @lib_dir_name)
130
187
  end
131
188
 
132
189
  ##
133
190
  # Create a child SourceInfo with an absolute path.
191
+ #
134
192
  # @private
135
193
  #
136
- def absolute_child(child_path)
194
+ def absolute_child(child_path, source_name: nil)
137
195
  child_path, type = SourceInfo.check_path(child_path, false)
138
- SourceInfo.new(self, context_directory, type, child_path, nil, child_path,
139
- @data_dir_name, @lib_dir_name)
196
+ source_name ||= child_path
197
+ SourceInfo.new(self, priority, context_directory, type, child_path, nil, nil, nil, nil,
198
+ source_name, @data_dir_name, @lib_dir_name)
199
+ end
200
+
201
+ ##
202
+ # Create a child SourceInfo with a git source.
203
+ #
204
+ # @private
205
+ #
206
+ def git_child(child_git_remote, child_git_path, child_git_commit, child_path,
207
+ source_name: nil)
208
+ child_path, type = SourceInfo.check_path(child_path, false)
209
+ source_name ||=
210
+ "git(remote=#{child_git_remote} path=#{child_git_path} commit=#{child_git_commit})"
211
+ SourceInfo.new(self, priority, context_directory, type, child_path, nil,
212
+ child_git_remote, child_git_path, child_git_commit,
213
+ source_name, @data_dir_name, @lib_dir_name)
140
214
  end
141
215
 
142
216
  ##
143
217
  # Create a proc child SourceInfo
218
+ #
144
219
  # @private
145
220
  #
146
- def proc_child(child_proc, source_name = nil)
221
+ def proc_child(child_proc, source_name: nil)
147
222
  source_name ||= self.source_name
148
- SourceInfo.new(self, context_directory, :proc, source_path, child_proc, source_name,
149
- @data_dir_name, @lib_dir_name)
223
+ SourceInfo.new(self, priority, context_directory, :proc, source_path, child_proc,
224
+ git_remote, git_path, git_commit,
225
+ source_name, @data_dir_name, @lib_dir_name)
150
226
  end
151
227
 
152
228
  ##
153
229
  # Create a root source info for a file path.
230
+ #
154
231
  # @private
155
232
  #
156
- def self.create_path_root(source_path, data_dir_name, lib_dir_name)
233
+ def self.create_path_root(source_path, priority,
234
+ context_directory: nil,
235
+ data_dir_name: nil,
236
+ lib_dir_name: nil,
237
+ source_name: nil)
157
238
  source_path, type = check_path(source_path, false)
158
- context_directory = ::File.dirname(source_path)
159
- new(nil, context_directory, type, source_path, nil, source_path, data_dir_name, lib_dir_name)
239
+ case context_directory
240
+ when :parent
241
+ context_directory = ::File.dirname(source_path)
242
+ when :path
243
+ context_directory = source_path
244
+ end
245
+ source_name ||= source_path
246
+ new(nil, priority, context_directory, type, source_path, nil, nil, nil, nil,
247
+ source_name, data_dir_name, lib_dir_name)
248
+ end
249
+
250
+ ##
251
+ # Create a root source info for a cached git repo.
252
+ #
253
+ # @private
254
+ #
255
+ def self.create_git_root(git_remote, git_path, git_commit, source_path, priority,
256
+ context_directory: nil,
257
+ data_dir_name: nil,
258
+ lib_dir_name: nil,
259
+ source_name: nil)
260
+ source_path, type = check_path(source_path, false)
261
+ source_name ||= "git(remote=#{git_remote} path=#{git_path} commit=#{git_commit})"
262
+ new(nil, priority, context_directory, type, source_path, nil, git_remote,
263
+ git_path, git_commit, source_name, data_dir_name, lib_dir_name)
160
264
  end
161
265
 
162
266
  ##
163
267
  # Create a root source info for a proc.
268
+ #
164
269
  # @private
165
270
  #
166
- def self.create_proc_root(source_proc, source_name, data_dir_name, lib_dir_name)
167
- new(nil, nil, :proc, nil, source_proc, source_name, data_dir_name, lib_dir_name)
271
+ def self.create_proc_root(source_proc, priority,
272
+ context_directory: nil,
273
+ data_dir_name: nil,
274
+ lib_dir_name: nil,
275
+ source_name: nil)
276
+ source_name ||= "(code block #{source_proc.object_id})"
277
+ new(nil, priority, context_directory, :proc, nil, source_proc, nil, nil,
278
+ nil, source_name, data_dir_name, lib_dir_name)
168
279
  end
169
280
 
170
281
  ##
171
282
  # Check a path and determine the canonical path and type.
283
+ #
172
284
  # @private
173
285
  #
174
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)
@@ -19,20 +19,22 @@ module Toys
19
19
  def initialize(parent_source: nil, source_name: nil, &block)
20
20
  @source_info =
21
21
  if parent_source
22
- parent_source.proc_child(block, source_name)
22
+ parent_source.proc_child(block, source_name: source_name)
23
23
  else
24
- SourceInfo.create_proc_root(block, source_name)
24
+ SourceInfo.create_proc_root(block, source_name: source_name)
25
25
  end
26
26
  @block = block
27
27
  end
28
28
 
29
29
  ##
30
30
  # Appends the configuration block.
31
+ #
31
32
  # @private
32
33
  #
33
- def config(tool, _loader)
34
+ def config(tool, loader)
34
35
  tool_class = tool.tool_class
35
- DSL::Tool.prepare(tool_class, nil, @source_info) do
36
+ DSL::Internal.prepare(tool_class, tool.full_name, tool.priority, nil, @source_info,
37
+ loader) do
36
38
  tool_class.class_eval(&@block)
37
39
  end
38
40
  yield
@@ -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)
@@ -115,12 +116,12 @@ module Toys
115
116
  # By default, it uses the parameters given to the middleware object.
116
117
  # Override this method to provide different logic.
117
118
  #
118
- # @param tool [Toys::Tool] The tool to document.
119
+ # @param tool [Toys::ToolDefinition] The tool to document.
119
120
  # @param data [Hash] Additional data that might be useful. Currently,
120
121
  # the {Toys::Loader} is passed with key `:loader`. Future versions
121
122
  # of Toys may provide additional information.
122
123
  # @return [String,Array<String>,Toys::WrappableString] The default
123
- # description. See {Toys::Tool#desc=} for info on the format.
124
+ # description. See {Toys::DSL::Tool#desc} for info on the format.
124
125
  # @return [nil] if this middleware should not set the description.
125
126
  #
126
127
  def generate_tool_desc(tool, data)
@@ -141,12 +142,12 @@ module Toys
141
142
  # By default, it uses the parameters given to the middleware object.
142
143
  # Override this method to provide different logic.
143
144
  #
144
- # @param tool [Toys::Tool] The tool to document
145
+ # @param tool [Toys::ToolDefinition] The tool to document
145
146
  # @param data [Hash] Additional data that might be useful. Currently,
146
147
  # the {Toys::Loader} is passed with key `:loader`. Future versions of
147
148
  # Toys may provide additional information.
148
149
  # @return [Array<Toys::WrappableString,String,Array<String>>] The default
149
- # long description. See {Toys::Tool#long_desc=} for info on the
150
+ # long description. See {Toys::DSL::Tool#long_desc} for info on the
150
151
  # format.
151
152
  # @return [nil] if this middleware should not set the long description.
152
153
  #
@@ -166,10 +167,10 @@ module Toys
166
167
  #
167
168
  # @param flag [Toys::Flag] The flag to document
168
169
  # @param data [Hash] Additional data that might be useful. Currently,
169
- # the {Toys::Tool} is passed with key `:tool`. Future
170
+ # the {Toys::ToolDefinition} is passed with key `:tool`. Future
170
171
  # versions of Toys may provide additional information.
171
172
  # @return [String,Array<String>,Toys::WrappableString] The default
172
- # description. See {Toys::Tool#desc=} for info on the format.
173
+ # description. See {Toys::DSL::Tool#desc} for info on the format.
173
174
  # @return [nil] if this middleware should not set the description.
174
175
  #
175
176
  def generate_flag_desc(flag, data) # rubocop:disable Lint/UnusedMethodArgument
@@ -185,10 +186,10 @@ module Toys
185
186
  #
186
187
  # @param flag [Toys::Flag] The flag to document
187
188
  # @param data [Hash] Additional data that might be useful. Currently,
188
- # the {Toys::Tool} is passed with key `:tool`. Future versions of
189
+ # the {Toys::ToolDefinition} is passed with key `:tool`. Future
189
190
  # versions of Toys may provide additional information.
190
191
  # @return [Array<Toys::WrappableString,String,Array<String>>] The default
191
- # long description. See {Toys::Tool#long_desc=} for info on the
192
+ # long description. See {Toys::DSL::Tool#long_desc} for info on the
192
193
  # format.
193
194
  # @return [nil] if this middleware should not set the long description.
194
195
  #
@@ -202,10 +203,10 @@ module Toys
202
203
  #
203
204
  # @param arg [Toys::PositionalArg] The arg to document
204
205
  # @param data [Hash] Additional data that might be useful. Currently,
205
- # the {Toys::Tool} is passed with key `:tool`. Future versions of
206
- # Toys may provide additional information.
206
+ # the {Toys::ToolDefinition} is passed with key `:tool`. Future
207
+ # versions of Toys may provide additional information.
207
208
  # @return [String,Array<String>,Toys::WrappableString] The default
208
- # description. See {Toys::Tool#desc=} for info on the format.
209
+ # description. See {Toys::DSL::Tool#desc} for info on the format.
209
210
  # @return [nil] if this middleware should not set the description.
210
211
  #
211
212
  def generate_arg_desc(arg, data) # rubocop:disable Lint/UnusedMethodArgument
@@ -227,10 +228,10 @@ module Toys
227
228
  #
228
229
  # @param arg [Toys::PositionalArg] The arg to document
229
230
  # @param data [Hash] Additional data that might be useful. Currently,
230
- # the {Toys::Tool} is passed with key `:tool`. Future versions of
231
- # Toys may provide additional information.
231
+ # the {Toys::ToolDefinition} is passed with key `:tool`. Future
232
+ # versions of Toys may provide additional information.
232
233
  # @return [Array<Toys::WrappableString,String,Array<String>>] The default
233
- # long description. See {Toys::Tool#long_desc=} for info on the
234
+ # long description. See {Toys::DSL::Tool#long_desc} for info on the
234
235
  # format.
235
236
  # @return [nil] if this middleware should not set the long description.
236
237
  #
@@ -244,10 +245,10 @@ module Toys
244
245
  #
245
246
  # @param group [Toys::FlagGroup] The flag group to document
246
247
  # @param data [Hash] Additional data that might be useful. Currently,
247
- # the {Toys::Tool} is passed with key `:tool`. Future
248
+ # the {Toys::ToolDefinition} is passed with key `:tool`. Future
248
249
  # versions of Toys may provide additional information.
249
250
  # @return [String,Array<String>,Toys::WrappableString] The default
250
- # description. See {Toys::Tool#desc=} for info on the format.
251
+ # description. See {Toys::DSL::Tool#desc} for info on the format.
251
252
  # @return [nil] if this middleware should not set the description.
252
253
  #
253
254
  def generate_flag_group_desc(group, data) # rubocop:disable Lint/UnusedMethodArgument
@@ -264,10 +265,10 @@ module Toys
264
265
  #
265
266
  # @param group [Toys::FlagGroup] The flag group to document
266
267
  # @param data [Hash] Additional data that might be useful. Currently,
267
- # the {Toys::Tool} is passed with key `:tool`. Future
268
+ # the {Toys::ToolDefinition} is passed with key `:tool`. Future
268
269
  # versions of Toys may provide additional information.
269
270
  # @return [Array<Toys::WrappableString,String,Array<String>>] The default
270
- # long description. See {Toys::Tool#long_desc=} for info on the
271
+ # long description. See {Toys::DSL::Tool#long_desc} for info on the
271
272
  # format.
272
273
  # @return [nil] if this middleware should not set the long description.
273
274
  #
@@ -159,6 +159,8 @@ module Toys
159
159
  # that tool.
160
160
  # @param show_source_path [Boolean] Show the source path section. Default
161
161
  # is `false`.
162
+ # @param separate_sources [Boolean] Split up tool list by source root.
163
+ # Defaults to false.
162
164
  # @param use_less [Boolean] If the `less` tool is available, and the
163
165
  # output stream is a tty, then use `less` to display help text.
164
166
  # @param stream [IO] Output stream to write to. Default is stdout.
@@ -177,6 +179,7 @@ module Toys
177
179
  fallback_execution: false,
178
180
  allow_root_args: false,
179
181
  show_source_path: false,
182
+ separate_sources: false,
180
183
  use_less: false,
181
184
  stream: $stdout,
182
185
  styled_output: nil)
@@ -191,6 +194,7 @@ module Toys
191
194
  @fallback_execution = fallback_execution
192
195
  @allow_root_args = allow_root_args
193
196
  @show_source_path = show_source_path
197
+ @separate_sources = separate_sources
194
198
  @stream = stream
195
199
  @styled_output = styled_output
196
200
  @use_less = use_less && !Compat.jruby?
@@ -198,6 +202,7 @@ module Toys
198
202
 
199
203
  ##
200
204
  # Configure flags and default data.
205
+ #
201
206
  # @private
202
207
  #
203
208
  def config(tool, loader)
@@ -220,6 +225,7 @@ module Toys
220
225
 
221
226
  ##
222
227
  # Display help text if requested.
228
+ #
223
229
  # @private
224
230
  #
225
231
  def run(context)
@@ -250,7 +256,9 @@ module Toys
250
256
  help_text = get_help_text(context, true)
251
257
  str = help_text.usage_string(
252
258
  recursive: context[RECURSIVE_SUBTOOLS_KEY],
253
- include_hidden: context[SHOW_ALL_SUBTOOLS_KEY], wrap_width: terminal.width
259
+ include_hidden: context[SHOW_ALL_SUBTOOLS_KEY],
260
+ separate_sources: @separate_sources,
261
+ wrap_width: terminal.width
254
262
  )
255
263
  terminal.puts(str)
256
264
  end
@@ -258,8 +266,11 @@ module Toys
258
266
  def show_list(context)
259
267
  help_text = get_help_text(context, true)
260
268
  str = help_text.list_string(
261
- recursive: context[RECURSIVE_SUBTOOLS_KEY], search: context[SEARCH_STRING_KEY],
262
- include_hidden: context[SHOW_ALL_SUBTOOLS_KEY], wrap_width: terminal.width
269
+ recursive: context[RECURSIVE_SUBTOOLS_KEY],
270
+ search: context[SEARCH_STRING_KEY],
271
+ include_hidden: context[SHOW_ALL_SUBTOOLS_KEY],
272
+ separate_sources: @separate_sources,
273
+ wrap_width: terminal.width
263
274
  )
264
275
  terminal.puts(str)
265
276
  end
@@ -267,8 +278,11 @@ module Toys
267
278
  def show_help(context, use_extra_args)
268
279
  help_text = get_help_text(context, use_extra_args)
269
280
  str = help_text.help_string(
270
- recursive: context[RECURSIVE_SUBTOOLS_KEY], search: context[SEARCH_STRING_KEY],
271
- include_hidden: context[SHOW_ALL_SUBTOOLS_KEY], show_source_path: @show_source_path,
281
+ recursive: context[RECURSIVE_SUBTOOLS_KEY],
282
+ search: context[SEARCH_STRING_KEY],
283
+ include_hidden: context[SHOW_ALL_SUBTOOLS_KEY],
284
+ show_source_path: @show_source_path,
285
+ separate_sources: @separate_sources,
272
286
  wrap_width: terminal.width
273
287
  )
274
288
  if less_path
@@ -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
@@ -159,7 +167,8 @@ module Toys
159
167
  def search_toys
160
168
  source_info = @source_info
161
169
  while source_info
162
- if source_info.source_type == :directory
170
+ if source_info.source_type == :directory &&
171
+ source_info.source_path != source_info.context_directory
163
172
  result = ::Toys::Utils::Gems.find_gemfile(source_info.source_path,
164
173
  gemfile_names: @toys_gemfile_names)
165
174
  return result if result