toys-core 0.7.0 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +98 -0
  3. data/LICENSE.md +16 -24
  4. data/README.md +307 -59
  5. data/docs/guide.md +44 -4
  6. data/lib/toys-core.rb +58 -49
  7. data/lib/toys/acceptor.rb +672 -0
  8. data/lib/toys/alias.rb +106 -0
  9. data/lib/toys/arg_parser.rb +624 -0
  10. data/lib/toys/cli.rb +422 -181
  11. data/lib/toys/compat.rb +83 -0
  12. data/lib/toys/completion.rb +442 -0
  13. data/lib/toys/context.rb +354 -0
  14. data/lib/toys/core_version.rb +18 -26
  15. data/lib/toys/dsl/flag.rb +213 -56
  16. data/lib/toys/dsl/flag_group.rb +237 -51
  17. data/lib/toys/dsl/positional_arg.rb +210 -0
  18. data/lib/toys/dsl/tool.rb +968 -317
  19. data/lib/toys/errors.rb +46 -28
  20. data/lib/toys/flag.rb +821 -0
  21. data/lib/toys/flag_group.rb +282 -0
  22. data/lib/toys/input_file.rb +18 -26
  23. data/lib/toys/loader.rb +110 -100
  24. data/lib/toys/middleware.rb +24 -31
  25. data/lib/toys/mixin.rb +90 -59
  26. data/lib/toys/module_lookup.rb +125 -0
  27. data/lib/toys/positional_arg.rb +184 -0
  28. data/lib/toys/source_info.rb +192 -0
  29. data/lib/toys/standard_middleware/add_verbosity_flags.rb +38 -43
  30. data/lib/toys/standard_middleware/handle_usage_errors.rb +39 -40
  31. data/lib/toys/standard_middleware/set_default_descriptions.rb +111 -89
  32. data/lib/toys/standard_middleware/show_help.rb +130 -113
  33. data/lib/toys/standard_middleware/show_root_version.rb +29 -35
  34. data/lib/toys/standard_mixins/exec.rb +116 -78
  35. data/lib/toys/standard_mixins/fileutils.rb +16 -24
  36. data/lib/toys/standard_mixins/gems.rb +29 -30
  37. data/lib/toys/standard_mixins/highline.rb +34 -41
  38. data/lib/toys/standard_mixins/terminal.rb +72 -26
  39. data/lib/toys/template.rb +51 -35
  40. data/lib/toys/tool.rb +1161 -206
  41. data/lib/toys/utils/completion_engine.rb +171 -0
  42. data/lib/toys/utils/exec.rb +279 -182
  43. data/lib/toys/utils/gems.rb +58 -49
  44. data/lib/toys/utils/help_text.rb +117 -111
  45. data/lib/toys/utils/terminal.rb +69 -62
  46. data/lib/toys/wrappable_string.rb +162 -0
  47. metadata +24 -22
  48. data/lib/toys/definition/acceptor.rb +0 -191
  49. data/lib/toys/definition/alias.rb +0 -112
  50. data/lib/toys/definition/arg.rb +0 -140
  51. data/lib/toys/definition/flag.rb +0 -370
  52. data/lib/toys/definition/flag_group.rb +0 -205
  53. data/lib/toys/definition/source_info.rb +0 -190
  54. data/lib/toys/definition/tool.rb +0 -842
  55. data/lib/toys/dsl/arg.rb +0 -132
  56. data/lib/toys/runner.rb +0 -188
  57. data/lib/toys/standard_middleware.rb +0 -47
  58. data/lib/toys/utils/module_lookup.rb +0 -135
  59. data/lib/toys/utils/wrappable_string.rb +0 -165
@@ -1,32 +1,24 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Copyright 2018 Daniel Azuma
3
+ # Copyright 2019 Daniel Azuma
4
4
  #
5
- # All rights reserved.
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
6
11
  #
7
- # Redistribution and use in source and binary forms, with or without
8
- # modification, are permitted provided that the following conditions are met:
12
+ # The above copyright notice and this permission notice shall be included in
13
+ # all copies or substantial portions of the Software.
9
14
  #
10
- # * Redistributions of source code must retain the above copyright notice,
11
- # this list of conditions and the following disclaimer.
12
- # * Redistributions in binary form must reproduce the above copyright notice,
13
- # this list of conditions and the following disclaimer in the documentation
14
- # and/or other materials provided with the distribution.
15
- # * Neither the name of the copyright holder, nor the names of any other
16
- # contributors to this software, may be used to endorse or promote products
17
- # derived from this software without specific prior written permission.
18
- #
19
- # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20
- # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
- # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22
- # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23
- # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24
- # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25
- # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26
- # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27
- # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28
- # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29
- # POSSIBILITY OF SUCH DAMAGE.
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20
+ # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21
+ # IN THE SOFTWARE.
30
22
  ;
31
23
 
32
24
  module Toys
@@ -52,15 +44,43 @@ module Toys
52
44
  # by `Process#spawn`, and some options supported by {Toys::Utils::Exec}
53
45
  # itself.
54
46
  #
55
- # In addition, this mixin supports one more option,
56
- # `exit_on_nonzero_status`. When set to true, if any subprocess returns a
57
- # nonzero result code, the tool will immediately exit with that same code,
58
- # similar to `set -e` in a bash script.
47
+ # You can set default configuration by passing options to the `include`
48
+ # directive. For example, to log commands at the debug level for all
49
+ # subprocesses spawned by this tool:
50
+ #
51
+ # include :exec, log_level: Logger::DEBUG
52
+ #
53
+ # Two special options are also recognized by the mixin.
54
+ #
55
+ # * A **:result_callback** proc may take a second argument. If it does,
56
+ # the context object is passed as the second argument. This is useful
57
+ # if a `:result_callback` is applied to the entire tool by passing it
58
+ # to the `include` directive. In that case, `self` is not set to the
59
+ # context object as it normally would be in a tool's `run` method, so
60
+ # you cannot access it otherwise. For example, here is how to log the
61
+ # exit code for every subcommand:
62
+ #
63
+ # tool "mytool" do
64
+ # callback = proc do |result, context|
65
+ # context.logger.info "Exit code: #{result.exit_code}"
66
+ # end
67
+ # include :exec, result_callback: callback
68
+ # # ...
69
+ # end
59
70
  #
60
- # You can set initial configuration by passing options to the `include`
61
- # directive. For example:
71
+ # You may also pass a symbol as the `:result_callback`. The method with
72
+ # that name is then called as the callback. The method must take one
73
+ # argument, the result object.
62
74
  #
63
- # include :exec, exit_on_nonzero_status: true
75
+ # * If **:exit_on_nonzero_status** is set to true, a nonzero exit code
76
+ # returned by the subprocess will also cause the tool to exit
77
+ # immediately with that same code.
78
+ #
79
+ # This is particularly useful as an option to the `include` directive,
80
+ # where it causes any subprocess failure to abort the tool, similar to
81
+ # setting `set -e` in a bash script.
82
+ #
83
+ # include :exec, exit_on_nonzero_status: true
64
84
  #
65
85
  module Exec
66
86
  include Mixin
@@ -71,15 +91,16 @@ module Toys
71
91
  #
72
92
  KEY = ::Object.new.freeze
73
93
 
74
- to_initialize do |opts = {}|
75
- tool = self
76
- opts = Exec._setup_exec_opts(opts, tool)
77
- tool[KEY] = Utils::Exec.new(opts) do |k|
94
+ on_initialize do |opts = {}|
95
+ require "toys/utils/exec"
96
+ context = self
97
+ opts = Exec._setup_exec_opts(opts, context)
98
+ context[KEY] = Utils::Exec.new(opts) do |k|
78
99
  case k
79
100
  when :logger
80
- tool[Tool::Keys::LOGGER]
101
+ context[Context::Key::LOGGER]
81
102
  when :cli
82
- tool[Tool::Keys::CLI]
103
+ context[Context::Key::CLI]
83
104
  end
84
105
  end
85
106
  end
@@ -90,10 +111,12 @@ module Toys
90
111
  # All options listed in the {Toys::Utils::Exec} documentation are
91
112
  # supported, plus the `exit_on_nonzero_status` option.
92
113
  #
93
- # @param [Hash] opts The default options.
114
+ # @param opts [Hash] The default options.
115
+ # @return [self]
94
116
  #
95
117
  def configure_exec(opts = {})
96
118
  self[KEY].configure_defaults(Exec._setup_exec_opts(opts, self))
119
+ self
97
120
  end
98
121
 
99
122
  ##
@@ -103,16 +126,17 @@ module Toys
103
126
  # If the process is not set to run in the background, and a block is
104
127
  # provided, a {Toys::Utils::Exec::Controller} will be yielded to it.
105
128
  #
106
- # @param [String,Array<String>] cmd The command to execute.
107
- # @param [Hash] opts The command options. All options listed in the
129
+ # @param cmd [String,Array<String>] The command to execute.
130
+ # @param opts [Hash] The command options. All options listed in the
108
131
  # {Toys::Utils::Exec} documentation are supported, plus the
109
132
  # `exit_on_nonzero_status` option.
110
133
  # @yieldparam controller [Toys::Utils::Exec::Controller] A controller for
111
134
  # the subprocess streams.
112
135
  #
113
- # @return [Toys::Utils::Exec::Controller,Toys::Utils::Exec::Result] The
114
- # subprocess controller or result, depending on whether the process
115
- # is running in the background or foreground.
136
+ # @return [Toys::Utils::Exec::Controller] The subprocess controller, if
137
+ # the process is running in the background.
138
+ # @return [Toys::Utils::Exec::Result] The result, if the process ran in
139
+ # the foreground.
116
140
  #
117
141
  def exec(cmd, opts = {}, &block)
118
142
  self[KEY].exec(cmd, Exec._setup_exec_opts(opts, self), &block)
@@ -124,16 +148,17 @@ module Toys
124
148
  # If the process is not set to run in the background, and a block is
125
149
  # provided, a {Toys::Utils::Exec::Controller} will be yielded to it.
126
150
  #
127
- # @param [String,Array<String>] args The arguments to ruby.
128
- # @param [Hash] opts The command options. All options listed in the
151
+ # @param args [String,Array<String>] The arguments to ruby.
152
+ # @param opts [Hash] The command options. All options listed in the
129
153
  # {Toys::Utils::Exec} documentation are supported, plus the
130
154
  # `exit_on_nonzero_status` option.
131
155
  # @yieldparam controller [Toys::Utils::Exec::Controller] A controller for
132
156
  # for the subprocess streams.
133
157
  #
134
- # @return [Toys::Utils::Exec::Controller,Toys::Utils::Exec::Result] The
135
- # subprocess controller or result, depending on whether the process
136
- # is running in the background or foreground.
158
+ # @return [Toys::Utils::Exec::Controller] The subprocess controller, if
159
+ # the process is running in the background.
160
+ # @return [Toys::Utils::Exec::Result] The result, if the process ran in
161
+ # the foreground.
137
162
  #
138
163
  def exec_ruby(args, opts = {}, &block)
139
164
  self[KEY].exec_ruby(args, Exec._setup_exec_opts(opts, self), &block)
@@ -146,16 +171,17 @@ module Toys
146
171
  # If the process is not set to run in the background, and a block is
147
172
  # provided, a {Toys::Utils::Exec::Controller} will be yielded to it.
148
173
  #
149
- # @param [Proc] func The proc to call.
150
- # @param [Hash] opts The command options. Most options listed in the
174
+ # @param func [Proc] The proc to call.
175
+ # @param opts [Hash] The command options. Most options listed in the
151
176
  # {Toys::Utils::Exec} documentation are supported, plus the
152
177
  # `exit_on_nonzero_status` option.
153
178
  # @yieldparam controller [Toys::Utils::Exec::Controller] A controller
154
179
  # for the subprocess streams.
155
180
  #
156
- # @return [Toys::Utils::Exec::Controller,Toys::Utils::Exec::Result] The
157
- # subprocess controller or result, depending on whether the process
158
- # is running in the background or foreground.
181
+ # @return [Toys::Utils::Exec::Controller] The subprocess controller, if
182
+ # the process is running in the background.
183
+ # @return [Toys::Utils::Exec::Result] The result, if the process ran in
184
+ # the foreground.
159
185
  #
160
186
  def exec_proc(func, opts = {}, &block)
161
187
  self[KEY].exec_proc(func, Exec._setup_exec_opts(opts, self), &block)
@@ -168,16 +194,17 @@ module Toys
168
194
  # If the process is not set to run in the background, and a block is
169
195
  # provided, a {Toys::Utils::Exec::Controller} will be yielded to it.
170
196
  #
171
- # @param [String,Array<String>] cmd The tool to execute.
172
- # @param [Hash] opts The command options. Most options listed in the
197
+ # @param cmd [String,Array<String>] The tool to execute.
198
+ # @param opts [Hash] The command options. Most options listed in the
173
199
  # {Toys::Utils::Exec} documentation are supported, plus the
174
200
  # `exit_on_nonzero_status` option.
175
201
  # @yieldparam controller [Toys::Utils::Exec::Controller] A controller
176
202
  # for the subprocess streams.
177
203
  #
178
- # @return [Toys::Utils::Exec::Controller,Toys::Utils::Exec::Result] The
179
- # subprocess controller or result, depending on whether the process
180
- # is running in the background or foreground.
204
+ # @return [Toys::Utils::Exec::Controller] The subprocess controller, if
205
+ # the process is running in the background.
206
+ # @return [Toys::Utils::Exec::Result] The result, if the process ran in
207
+ # the foreground.
181
208
  #
182
209
  def exec_tool(cmd, opts = {}, &block)
183
210
  func = Exec._make_tool_caller(cmd)
@@ -194,8 +221,8 @@ module Toys
194
221
  # If a block is provided, a {Toys::Utils::Exec::Controller} will be
195
222
  # yielded to it.
196
223
  #
197
- # @param [String,Array<String>] cmd The command to execute.
198
- # @param [Hash] opts The command options. All options listed in the
224
+ # @param cmd [String,Array<String>] The command to execute.
225
+ # @param opts [Hash] The command options. All options listed in the
199
226
  # {Toys::Utils::Exec} documentation are supported, plus the
200
227
  # `exit_on_nonzero_status` option.
201
228
  # @yieldparam controller [Toys::Utils::Exec::Controller] A controller
@@ -216,8 +243,8 @@ module Toys
216
243
  # If a block is provided, a {Toys::Utils::Exec::Controller} will be
217
244
  # yielded to it.
218
245
  #
219
- # @param [String,Array<String>] args The arguments to ruby.
220
- # @param [Hash] opts The command options. All options listed in the
246
+ # @param args [String,Array<String>] The arguments to ruby.
247
+ # @param opts [Hash] The command options. All options listed in the
221
248
  # {Toys::Utils::Exec} documentation are supported, plus the
222
249
  # `exit_on_nonzero_status` option.
223
250
  # @yieldparam controller [Toys::Utils::Exec::Controller] A controller
@@ -238,8 +265,8 @@ module Toys
238
265
  # If a block is provided, a {Toys::Utils::Exec::Controller} will be
239
266
  # yielded to it.
240
267
  #
241
- # @param [Proc] func The proc to call.
242
- # @param [Hash] opts The command options. Most options listed in the
268
+ # @param func [Proc] The proc to call.
269
+ # @param opts [Hash] The command options. Most options listed in the
243
270
  # {Toys::Utils::Exec} documentation are supported, plus the
244
271
  # `exit_on_nonzero_status` option.
245
272
  # @yieldparam controller [Toys::Utils::Exec::Controller] A controller
@@ -261,8 +288,8 @@ module Toys
261
288
  # If a block is provided, a {Toys::Utils::Exec::Controller} will be
262
289
  # yielded to it.
263
290
  #
264
- # @param [String,Array<String>] cmd The tool to execute.
265
- # @param [Hash] opts The command options. Most options listed in the
291
+ # @param cmd [String,Array<String>] The tool to execute.
292
+ # @param opts [Hash] The command options. Most options listed in the
266
293
  # {Toys::Utils::Exec} documentation are supported, plus the
267
294
  # `exit_on_nonzero_status` option.
268
295
  # @yieldparam controller [Toys::Utils::Exec::Controller] A controller
@@ -282,8 +309,8 @@ module Toys
282
309
  # If a block is provided, a {Toys::Utils::Exec::Controller} will be
283
310
  # yielded to it.
284
311
  #
285
- # @param [String] cmd The shell command to execute.
286
- # @param [Hash] opts The command options. All options listed in the
312
+ # @param cmd [String] The shell command to execute.
313
+ # @param opts [Hash] The command options. All options listed in the
287
314
  # {Toys::Utils::Exec} documentation are supported, plus the
288
315
  # `exit_on_nonzero_status` option.
289
316
  # @yieldparam controller [Toys::Utils::Exec::Controller] A controller
@@ -298,12 +325,13 @@ module Toys
298
325
  ##
299
326
  # Exit if the given status code is nonzero. Otherwise, returns 0.
300
327
  #
301
- # @param [Integer,Process::Status,Toys::Utils::Exec::Result] status
328
+ # @param status [Integer,Process::Status,Toys::Utils::Exec::Result]
329
+ # @return [Integer]
302
330
  #
303
331
  def exit_on_nonzero_status(status)
304
332
  status = status.exit_code if status.respond_to?(:exit_code)
305
333
  status = status.exitstatus if status.respond_to?(:exitstatus)
306
- Tool.exit(status) unless status.zero?
334
+ Context.exit(status) unless status.zero?
307
335
  0
308
336
  end
309
337
 
@@ -314,14 +342,24 @@ module Toys
314
342
  end
315
343
 
316
344
  ## @private
317
- def self._setup_exec_opts(opts, tool)
318
- return opts unless opts.key?(:exit_on_nonzero_status)
319
- nonzero_status_handler =
320
- if opts[:exit_on_nonzero_status]
321
- proc { |s| tool.exit(s.exitstatus) }
322
- end
323
- opts = opts.merge(nonzero_status_handler: nonzero_status_handler)
324
- opts.delete(:exit_on_nonzero_status)
345
+ def self._setup_exec_opts(opts, context)
346
+ if opts.key?(:exit_on_nonzero_status)
347
+ result_callback =
348
+ if opts[:exit_on_nonzero_status]
349
+ proc { |r| context.exit(r.exit_code) if r.error? }
350
+ end
351
+ opts = opts.merge(result_callback: result_callback)
352
+ opts.delete(:exit_on_nonzero_status)
353
+ elsif opts.key?(:result_callback)
354
+ orig_callback = opts[:result_callback]
355
+ result_callback =
356
+ if orig_callback.is_a?(::Symbol)
357
+ context.method(orig_callback)
358
+ elsif orig_callback.respond_to?(:call)
359
+ proc { |r| orig_callback.call(r, context) }
360
+ end
361
+ opts = opts.merge(result_callback: result_callback)
362
+ end
325
363
  opts
326
364
  end
327
365
  end
@@ -1,32 +1,24 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Copyright 2018 Daniel Azuma
3
+ # Copyright 2019 Daniel Azuma
4
4
  #
5
- # All rights reserved.
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
6
11
  #
7
- # Redistribution and use in source and binary forms, with or without
8
- # modification, are permitted provided that the following conditions are met:
12
+ # The above copyright notice and this permission notice shall be included in
13
+ # all copies or substantial portions of the Software.
9
14
  #
10
- # * Redistributions of source code must retain the above copyright notice,
11
- # this list of conditions and the following disclaimer.
12
- # * Redistributions in binary form must reproduce the above copyright notice,
13
- # this list of conditions and the following disclaimer in the documentation
14
- # and/or other materials provided with the distribution.
15
- # * Neither the name of the copyright holder, nor the names of any other
16
- # contributors to this software, may be used to endorse or promote products
17
- # derived from this software without specific prior written permission.
18
- #
19
- # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20
- # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
- # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22
- # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23
- # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24
- # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25
- # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26
- # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27
- # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28
- # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29
- # POSSIBILITY OF SUCH DAMAGE.
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20
+ # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21
+ # IN THE SOFTWARE.
30
22
  ;
31
23
 
32
24
  require "fileutils"
@@ -1,32 +1,24 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Copyright 2018 Daniel Azuma
3
+ # Copyright 2019 Daniel Azuma
4
4
  #
5
- # All rights reserved.
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
6
11
  #
7
- # Redistribution and use in source and binary forms, with or without
8
- # modification, are permitted provided that the following conditions are met:
12
+ # The above copyright notice and this permission notice shall be included in
13
+ # all copies or substantial portions of the Software.
9
14
  #
10
- # * Redistributions of source code must retain the above copyright notice,
11
- # this list of conditions and the following disclaimer.
12
- # * Redistributions in binary form must reproduce the above copyright notice,
13
- # this list of conditions and the following disclaimer in the documentation
14
- # and/or other materials provided with the distribution.
15
- # * Neither the name of the copyright holder, nor the names of any other
16
- # contributors to this software, may be used to endorse or promote products
17
- # derived from this software without specific prior written permission.
18
- #
19
- # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20
- # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
- # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22
- # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23
- # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24
- # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25
- # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26
- # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27
- # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28
- # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29
- # POSSIBILITY OF SUCH DAMAGE.
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20
+ # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21
+ # IN THE SOFTWARE.
30
22
  ;
31
23
 
32
24
  module Toys
@@ -55,20 +47,26 @@ module Toys
55
47
  module Gems
56
48
  include Mixin
57
49
 
58
- to_include do |opts = {}|
59
- @__gems = Utils::Gems.new(opts)
50
+ on_include do |opts = {}|
51
+ @__gems_opts = opts
60
52
 
53
+ ## @private
61
54
  def self.gems
62
- @__gems
55
+ require "toys/utils/gems"
56
+ # rubocop:disable Naming/MemoizedInstanceVariableName
57
+ @__gems ||= Utils::Gems.new(@__gems_opts)
58
+ # rubocop:enable Naming/MemoizedInstanceVariableName
63
59
  end
64
60
 
61
+ ## @private
65
62
  def self.gem(name, *requirements)
66
63
  gems.activate(name, *requirements)
67
64
  end
68
65
  end
69
66
 
70
67
  ##
71
- # Returns a tool-wide instance of {Toys::Utils::Gems}.
68
+ # A tool-wide instance of {Toys::Utils::Gems}.
69
+ # @return [Toys::Utils::Gems]
72
70
  #
73
71
  def gems
74
72
  self.class.gems
@@ -77,8 +75,9 @@ module Toys
77
75
  ##
78
76
  # Activate the given gem.
79
77
  #
80
- # @param [String] name Name of the gem
81
- # @param [String...] requirements Version requirements
78
+ # @param name [String] Name of the gem
79
+ # @param requirements [String...] Version requirements
80
+ # @return [void]
82
81
  #
83
82
  def gem(name, *requirements)
84
83
  self.class.gems.activate(name, *requirements)