toys 0.14.6 → 0.15.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.
data/docs/guide.md CHANGED
@@ -399,10 +399,11 @@ argument is omitted, e.g.
399
399
 
400
400
  Then the option `:whom` is set to the default value `"world"`.
401
401
 
402
- If the option name is a valid method name, Toys will provide a method that you
403
- can use to retrieve the value. In the above example, we retrieve the value for
404
- the option `:whom` by calling the method `whom`. If the option name cannot be
405
- made into a method, you can retrieve the value by calling {Toys::Context#get}.
402
+ If the option name is symbol representing a valid method name (that doesn't
403
+ collide with a method already present), Toys will provide a method that you can
404
+ use to retrieve the value. In the above example, we retrieve the value for the
405
+ option `:whom` by calling the method `whom`. If the option name cannot be made
406
+ into a method, you can retrieve the value by calling {Toys::Context#get}.
406
407
 
407
408
  An argument can also be **required**, which means it must be provided on the
408
409
  command line; otherwise the tool will report a usage error. You can declare a
@@ -418,7 +419,7 @@ first, in order, followed by the optional arguments. For example:
418
419
  required_arg :arg1
419
420
 
420
421
  def run
421
- puts "options data is #{options.inspect}"
422
+ puts "Options data is #{options.inspect}"
422
423
  end
423
424
  end
424
425
 
@@ -457,7 +458,7 @@ not provided on the command line. For example:
457
458
  optional_arg :arg2, default: "the-default"
458
459
 
459
460
  def run
460
- puts "options data is #{options.inspect}"
461
+ puts "Options data is #{options.inspect}"
461
462
  end
462
463
  end
463
464
 
@@ -594,10 +595,12 @@ arguments passed to the tool. In the case above, the `:shout` option is set to
594
595
  it remains falsy. The two flags `-s` and `--shout` are effectively synonyms and
595
596
  have the same effect. A flag declaration can include any number of synonyms.
596
597
 
597
- As with arguments, Toys will provide a method that you can call to retrieve the
598
- option value set by a flag. In this case, a method called `shout` will be
599
- available, and will return either true or false. If the option name cannot be
600
- made into a method, you can retrieve the value by calling {Toys::Context#get}.
598
+ As with arguments, Toys can provide a method that you can call to retrieve the
599
+ option value set by a flag. This method is provided if the flag name is a
600
+ symbol representing a valid method name that does not collide with a method
601
+ already present. In our example, Toys provides a method called `shout` that
602
+ returns either true or false. If the option name cannot be made into a method,
603
+ you can retrieve the value by calling {Toys::Context#get}.
601
604
 
602
605
  #### Flag types
603
606
 
@@ -820,10 +823,11 @@ like this:
820
823
  default: 0,
821
824
  handler: proc { |_val, prev| prev - 1 }
822
825
 
823
- Note that both flags affect the same option name, `VERBOSITY`. The first
824
- increments it each time it appears, and the second decrements it. A tool can
825
- query this option and get an integer telling the requested verbosity level, as
826
- you will see [below](#Logging_and_verbosity).
826
+ Note that both flags affect the same option name,
827
+ {Toys::Context::Key::VERBOSITY}. The first increments it each time it appears,
828
+ and the second decrements it. A tool can query this option and get an integer
829
+ telling the requested verbosity level, as you will see
830
+ [below](#Logging_and_verbosity).
827
831
 
828
832
  Toys provides a few built-in handlers that can be specified by name. We already
829
833
  discussed the default handler that can be specified by its name `:set` or by
@@ -1400,6 +1404,10 @@ chance of problems, if you need to use `truncate_load_path!`, locate it as
1400
1404
  early as possible in your Toys files, typically at the top of the
1401
1405
  [index file](#Index_files).
1402
1406
 
1407
+ ### Loading remote files
1408
+
1409
+ (TODO)
1410
+
1403
1411
  ## The execution environment
1404
1412
 
1405
1413
  This section describes the context and resources available to your tool when it
@@ -1871,8 +1879,11 @@ Following is a simple template example:
1871
1879
  on_expand do |template|
1872
1880
  tool template.name do
1873
1881
  desc "A greeting tool generated from a template"
1874
- to_run do
1875
- puts "Hello, #{template.whom}!"
1882
+
1883
+ static :whom, template.whom
1884
+
1885
+ def run
1886
+ puts "Hello, #{whom}!"
1876
1887
  end
1877
1888
  end
1878
1889
  end
@@ -1893,15 +1904,12 @@ passed to the block, so it can access the template configuration when
1893
1904
  generating directives. The "greet" template in the above example generates a
1894
1905
  tool whose name is set by the template's `name` property.
1895
1906
 
1896
- Notice that in the above example, we used `to_run do`, providing a *block* for
1897
- the tool's execution, rather than `def run`, providing a method. Both forms are
1898
- valid and will work in a template (as well as in a normal Toys file), but the
1899
- block form is often useful in a template because you can access the `template`
1900
- variable inside the block, whereas it would not be accessible if you defined a
1901
- method. Similarly, if your template generates helper methods, and the body of
1902
- those methods need access to the `template` variable, you can use
1903
- [Module#define_method](http://ruby-doc.org/core/Module.html#method-i-define_method)
1904
- instead of `def`.
1907
+ Notice in the above example, we used the {Toys::DSL::Tool#static} directive to
1908
+ create a "static" option for `template.whom`. A "static" option is an option
1909
+ whose value is set directly in code rather than via a flag or argument. We use
1910
+ it here because we can't access the `template` local variable from within the
1911
+ `run` method. Static options are a common technique for accessing template
1912
+ configuration properties from inside tool methods.
1905
1913
 
1906
1914
  By convention, it is a good idea for configuration options for your template to
1907
1915
  be settable *both* as arguments to the constructor, *and* as `attr_accessor`
@@ -1927,8 +1935,9 @@ class by including the {Toys::Template} module in your class definition.
1927
1935
  on_expand do |template|
1928
1936
  tool template.name do
1929
1937
  desc "A greeting tool generated from a template"
1930
- to_run do
1931
- puts "Hello, #{template.whom}!"
1938
+ static :whom, template.whom
1939
+ def run
1940
+ puts "Hello, #{whom}!"
1932
1941
  end
1933
1942
  end
1934
1943
  end
@@ -3045,9 +3054,9 @@ themselves.
3045
3054
 
3046
3055
  # This file is .toys.rb
3047
3056
 
3048
- # A "clean" tool that cleans out gem builds (from the pkg directory), and
3049
- # documentation builds (from doc and .yardoc)
3050
- expand :clean, paths: ["pkg", "doc", ".yardoc"]
3057
+ # A "clean" tool that cleans out anything matched by the gitignore. You can
3058
+ # also configure it to clean specific files and directories.
3059
+ expand :clean, paths: :gitignore
3051
3060
 
3052
3061
  # This is the "test" tool.
3053
3062
  expand :minitest, libs: ["lib", "test"]
@@ -3397,44 +3406,49 @@ Here is an example that wraps calls to git:
3397
3406
  end
3398
3407
  end
3399
3408
 
3400
- ### Handling interrupts
3409
+ ### Handling signals
3401
3410
 
3402
- If you interrupt a running tool, say, by hitting `CTRL`-`C`, Toys will normally
3403
- terminate execution and display the message `INTERRUPTED` on the standard error
3404
- stream.
3411
+ If you interrupt a running tool by hitting `CTRL`-`C` or sending it a signal,
3412
+ Toys will normally terminate execution and display the message `INTERRUPTED` on
3413
+ the standard error stream.
3405
3414
 
3406
- If your tool needs to handle interrupts itself, you have several options. You
3407
- can rescue the `Interrupt` exception or call `Signal.trap`. Or you can provide
3408
- an *interrupt handler* in your tool using the `on_interrupt` directive. This
3409
- directive either provides a block to handle interrupts, or designates a named
3410
- method as the handler. If an interrupt handler is present, Toys will handle
3411
- interrupts as follows:
3415
+ If your tool needs to handle signals or inerrupts itself, you have several
3416
+ options. You can rescue the `SignalException` or call `Signal.trap`. Or you can
3417
+ provide a *signal handler* in your tool using the `on_signal` or `on_interrupt`
3418
+ directive. These directives either provide a block or designate a named method
3419
+ to handle a given signal received by the process. A separate handler must be
3420
+ provided for each signal type. (The `on_interrupt` directive is simply
3421
+ shorthand for registering a handler for `SIGINT`.)
3412
3422
 
3413
- 1. Toys will terminate the tool's `run` method by raising an `Interrupt`
3414
- exception. Any `ensure` blocks will be called.
3415
- 2. Toys will call the interrupt handler. If this method or block takes an
3416
- argument, Toys will pass it the `Interrupt` exception object.
3417
- 3. The interrupt handler is then responsible for tool execution from that
3423
+ If a signal or interrupt is received and is not caught via `Signal.trap`, the
3424
+ following takes place:
3425
+
3426
+ 1. Ruby will terminate the tool's `run` method by raising a `SignalException`
3427
+ Any `ensure` blocks in the tool will be called.
3428
+ 2. Toys will call the signal handler, either a method or a block. If the
3429
+ handler takes an argument, Toys will pass it the `SignalException` object.
3430
+ 3. The signal handler is then responsible for tool execution from that
3418
3431
  point. It can terminate execution by returning or calling `exit`, or it can
3419
3432
  restart or resume processing (perhaps by calling the `run` method again).
3420
- Or it can invoke the normal Toys interrupt handling (i.e. terminating
3421
- execution, displaying the message `INTERRUPTED`) by re-raising *the same*
3422
- interrupt exception object.
3423
- 4. If another interrupt takes place during the execution of the interrupt
3424
- handler, Toys will terminate it by raising a *second* `Interrupt` exception
3425
- (calling any `ensure` blocks). Then, the interrupt handler will be called
3426
- *again* and passed the new exception. Any additional interrupts will be
3427
- handled similarly.
3428
-
3429
- Because the interrupt handler is called again even if it is itself interrupted,
3430
- you might consider detecting this case if your interrupt handler might be
3431
- long-running. You can tell how many interrupts have taken place by looking at
3432
- the `Exception#cause` property of the exception. The first interrupt will have
3433
- a cause of `nil`. The second interrupt (i.e. the interrupt raised the first
3434
- time the interrupt handler is itself interrupted) will have its cause point to
3435
- the first interrupt (which in turn has a `nil` cause.) The third interrupt's
3436
- cause will point to the second interrupt, and so on. So you can determine the
3437
- interrupt "depth" by counting the length of the cause chain.
3433
+ Or it can invoke the normal Toys signal handling (i.e. terminating
3434
+ execution and displaying the message `INTERRUPTED` or `SIGNAL RECEIVED`) by
3435
+ re-raising *the same* `SignalException` object.
3436
+ 4. If another signal is received or interrupt takes place during the execution
3437
+ of the handler, Toys will terminate the handler by raising a *second*
3438
+ `SignalException` (again calling any `ensure` blocks). Then, any matching
3439
+ signal handler will be called *again* for the new signal and passed the new
3440
+ exception. Any further signals will be handled similarly.
3441
+
3442
+ It is possible for a signal handler itself to receive signals. For example, if
3443
+ you have a long-running `CTRL`-`C` interrupt handler, it itself could get
3444
+ interrupted. You can tell how many signals have taken place by looking at the
3445
+ `Exception#cause` property of the `SignalException`. The first signal will have
3446
+ a cause of `nil`. The second signal (i.e. the first time a signal handler
3447
+ itself receives a signal) will have a cause pointing to the first
3448
+ `SignalException` (which in turn has a `nil` cause). The third signal's cause
3449
+ points at the second, and so forth. Hence, you can determine the signal "depth"
3450
+ by counting the length of the cause chain, which could be important to prevent
3451
+ "infinite" signals.
3438
3452
 
3439
3453
  Here is an example that performs a long-running task. The first two times the
3440
3454
  task is interrupted, it is restarted. The third time, it is terminated.
@@ -3496,6 +3510,81 @@ failed.
3496
3510
  end
3497
3511
  end
3498
3512
 
3513
+ ### Changing the entrypoint
3514
+
3515
+ The normal entrypoint for a tool is the `run` method. However, you can change
3516
+ it using the {Toys::DSL::Tool#to_run} directive, providing either a different
3517
+ method name as a symbol, or a block that will be called instead of a method to
3518
+ run the tool.
3519
+
3520
+ One reason to change which method is called, is if you need to modify a tool
3521
+ that was already defined by some other means (like a template expansion). For
3522
+ example, the tests for the Toys gems include a number of longer-running
3523
+ "integration" tests that run only when the `TOYS_TEST_INTEGRATION` environment
3524
+ variable is set. The Toys gems provide standard `test` tools using the
3525
+ `:minitest` template, but then modify those tools to add an `--integration`
3526
+ flag. When this flag is set, the `TOYS_TEST_INTEGRATION` environment variable
3527
+ gets set, causing the integration tests to run. Here's what that looks like:
3528
+
3529
+ # Use the minitest template to generate the normal test tool with the
3530
+ # normal "run" method as the entrypoint
3531
+ expand :minitest, libs: ["lib", "test"], bundler: true
3532
+
3533
+ # Reopen the "test" tool generated above
3534
+ tool "test" do
3535
+ # Add a flag to the tool
3536
+ flag :integration
3537
+
3538
+ # Create a new run method that "wraps" the existing one
3539
+ def run_with_integration
3540
+ # First set the environment variable to activate integration tests
3541
+ # if requested
3542
+ ENV["TOYS_TEST_INTEGRATION"] = "true" if integration
3543
+
3544
+ # Invoke the original run method that was defined in the template
3545
+ run
3546
+ end
3547
+
3548
+ # Now set the entrypoint to our new method
3549
+ to_run :run_with_integration
3550
+ end
3551
+
3552
+ Passing a block to {Toys::DSL::Tool#to_run} is less common. One reason you
3553
+ might do it is if you need to access variables from an outer scope. (Normally,
3554
+ defining a method isolates your variables from any enclosing scopes.) Here is
3555
+ an example that prints out the time that the tool was *defined* (rather than
3556
+ executed).
3557
+
3558
+ tool "def-time" do
3559
+ # Grab the time during tool definition
3560
+ time = Time.now
3561
+
3562
+ # Define the entrypoint using a block rather than a method.
3563
+ # The block is still called in the same object context, but now has
3564
+ # access to variables from enclosing scopes.
3565
+ to_run do
3566
+ puts "Defined at #{time}"
3567
+ end
3568
+ end
3569
+
3570
+ The downside of this technique is that the entrypoint is not a method, and
3571
+ can't be called like one. Which means, among other things, you can't "wrap" it
3572
+ like we did with the test tool above.
3573
+
3574
+ If you need to access information from enclosing scopes, consider instead
3575
+ setting options using the {Toys::DSL::Tool#static} directive, as illustrated
3576
+ earlier when we discussed [defining templates](#Defining_templates).
3577
+
3578
+ tool "def-time" do
3579
+ # Grab the time during tool definition and set it as a static option.
3580
+ static :time, Time.now
3581
+
3582
+ # Now you can access it from a run method like any other option
3583
+ def run
3584
+ puts "Defined at #{time}"
3585
+ end
3586
+ end
3587
+
3499
3588
  ### Data files
3500
3589
 
3501
3590
  If your tools require images, archives, keys, or other such static data, Toys
@@ -3,7 +3,19 @@
3
3
  module Toys
4
4
  ##
5
5
  # Subclass of `Toys::CLI` configured for the behavior of the standard Toys
6
- # executable.
6
+ # executable. Specifically, this subclass:
7
+ #
8
+ # * Configures the standard names of files and directories, such as the
9
+ # `.toys.rb` file for an "index" tool, and the `.data` and `.lib` directory
10
+ # names.
11
+ # * Configures default descriptions for the root tool.
12
+ # * Configures a default error handler and logger that provide ANSI-colored
13
+ # formatted output.
14
+ # * Configures a set of middleware that implement online help, verbosity
15
+ # flags, and other features.
16
+ # * Provides a set of standard templates for typical project build and
17
+ # maintenance scripts (suh as clean, test, and rubocop).
18
+ # * Finds tool definitions in the standard Toys search path.
7
19
  #
8
20
  class StandardCLI < CLI
9
21
  ##
@@ -103,6 +115,8 @@ module Toys
103
115
  def initialize(custom_paths: nil,
104
116
  include_builtins: true,
105
117
  cur_dir: nil)
118
+ require "toys/utils/standard_ui"
119
+ ui = Toys::Utils::StandardUI.new
106
120
  super(
107
121
  executable_name: EXECUTABLE_NAME,
108
122
  config_dir_name: CONFIG_DIR_NAME,
@@ -114,7 +128,8 @@ module Toys
114
128
  lib_dir_name: LIB_DIR_NAME,
115
129
  extra_delimiters: EXTRA_DELIMITERS,
116
130
  middleware_stack: default_middleware_stack,
117
- template_lookup: default_template_lookup
131
+ template_lookup: default_template_lookup,
132
+ **ui.cli_args
118
133
  )
119
134
  if custom_paths
120
135
  Array(custom_paths).each { |path| add_config_path(path) }
@@ -237,15 +237,21 @@ module Toys
237
237
  end
238
238
  end
239
239
 
240
+ static :gem_name, template.gem_name(context_directory || ::Dir.getwd)
241
+ static :install_gem, template.install_gem
242
+ static :push_gem, template.push_gem
243
+ static :tag, template.tag
244
+ static :push_tag, template.push_tag
245
+
240
246
  include :exec, exit_on_nonzero_status: true
241
247
  include :fileutils
242
248
  include :terminal
243
249
 
244
- to_run do
250
+ # @private
251
+ def run # rubocop:disable all
245
252
  require "rubygems"
246
253
  require "rubygems/package"
247
254
  ::Dir.chdir(context_directory || ::Dir.getwd) do
248
- gem_name = template.gem_name
249
255
  gemspec = ::Gem::Specification.load("#{gem_name}.gemspec")
250
256
  ::Gem::Package.build(gemspec)
251
257
  version = gemspec.version
@@ -255,21 +261,21 @@ module Toys
255
261
  mkdir_p(::File.dirname(archive_path))
256
262
  mv(archive_name, archive_path)
257
263
  end
258
- if template.install_gem
264
+ if install_gem
259
265
  exit(1) unless yes || confirm("Install #{gem_name} #{version}? ", default: true)
260
266
  exec ["gem", "install", archive_path]
261
267
  end
262
- if template.push_gem
268
+ if push_gem
263
269
  if ::File.directory?(".git") && capture("git status -s").strip != ""
264
270
  logger.error "Cannot push the gem when there are uncommited changes"
265
271
  exit(1)
266
272
  end
267
273
  exit(1) unless yes || confirm("Release #{gem_name} #{version}? ", default: true)
268
274
  exec(["gem", "push", archive_path])
269
- if template.tag
275
+ if tag
270
276
  exec(["git", "tag", "v#{version}"])
271
- if template.push_tag
272
- exec(["git", "push", template.push_tag, "v#{version}"])
277
+ if push_tag
278
+ exec(["git", "push", push_tag, "v#{version}"])
273
279
  end
274
280
  end
275
281
  end
@@ -55,6 +55,10 @@ module Toys
55
55
  # enabled. See the documentation for the
56
56
  # [bundler mixin](https://dazuma.github.io/toys/gems/toys-core/latest/Toys/StandardMixins/Bundler)
57
57
  # for information on available options.
58
+ # @param mt_compat [boolean] If set to `true` or `false`, sets the
59
+ # `MT_COMPAT` environment variable accordingly. This may be required
60
+ # for certain older Minitest plugins. Optional. If not present, keeps
61
+ # any current setting.
58
62
  # @param context_directory [String] A custom context directory to use
59
63
  # when executing this tool.
60
64
  #
@@ -66,6 +70,7 @@ module Toys
66
70
  verbose: false,
67
71
  warnings: true,
68
72
  bundler: false,
73
+ mt_compat: nil,
69
74
  context_directory: nil)
70
75
  @name = name
71
76
  @gem_version = gem_version
@@ -75,6 +80,7 @@ module Toys
75
80
  @verbose = verbose
76
81
  @warnings = warnings
77
82
  @bundler = bundler
83
+ @mt_compat = mt_compat
78
84
  @context_directory = context_directory
79
85
  end
80
86
 
@@ -160,6 +166,18 @@ module Toys
160
166
  #
161
167
  attr_writer :bundler
162
168
 
169
+ ##
170
+ # Adjust the `MT_COMPAT` environment variable when running tests. This
171
+ # setting may be necessary for certain older Minitest plugins.
172
+ #
173
+ # Pass `true` to enable compat mode, `false` to disable it, or `nil` to
174
+ # use any ambient setting from the current environment.
175
+ #
176
+ # @param value [true,false,nil]
177
+ # @return [true,false,nil]
178
+ #
179
+ attr_writer :mt_compat
180
+
163
181
  ##
164
182
  # Use bundler for this tool.
165
183
  #
@@ -195,6 +213,11 @@ module Toys
195
213
  #
196
214
  attr_reader :context_directory
197
215
 
216
+ ##
217
+ # @private
218
+ #
219
+ attr_reader :mt_compat
220
+
198
221
  ##
199
222
  # @private
200
223
  #
@@ -261,35 +284,42 @@ module Toys
261
284
  complete: :file_system,
262
285
  desc: "Paths to the tests to run (defaults to all tests)"
263
286
 
264
- to_run do
265
- gem "minitest", *template.gem_version
287
+ static :gem_version, template.gem_version
288
+ static :libs, template.libs
289
+ static :files, template.files
290
+ static :template_verbose, template.verbose
291
+ static :mt_compat, template.mt_compat
292
+
293
+ # @private
294
+ def run # rubocop:disable all
295
+ gem "minitest", *gem_version
266
296
 
267
297
  ::Dir.chdir(context_directory || ::Dir.getwd) do
268
298
  ruby_args = []
269
- libs = Array(template.libs)
270
299
  ruby_args << "-I#{libs.join(::File::PATH_SEPARATOR)}" unless libs.empty?
271
300
  ruby_args << "-w" if warnings
272
- ruby_args << "-"
273
- ruby_args << "--seed" << seed if seed
274
- vv = verbosity
275
- vv += 1 if template.verbose
276
- ruby_args << "--verbose" if vv.positive?
277
- ruby_args << "--name" << name if name
278
- ruby_args << "--exclude" << exclude if exclude
279
301
 
280
302
  if tests.empty?
281
- Array(template.files).each do |pattern|
303
+ files.each do |pattern|
282
304
  tests.concat(::Dir.glob(pattern))
283
305
  end
284
306
  tests.uniq!
285
307
  end
308
+ code = ["require 'minitest/autorun'"] + tests.map { |file| "load '#{file}'" }
309
+ ruby_args << "-e" << code.join("\n")
286
310
 
287
- result = exec_ruby(ruby_args, in: :controller) do |controller|
288
- controller.in.puts("require 'minitest/autorun'")
289
- tests.each do |file|
290
- controller.in.puts("load '#{file}'")
291
- end
292
- end
311
+ ruby_args << "--"
312
+ ruby_args << "--seed" << seed if seed
313
+ vv = verbosity
314
+ vv += 1 if template_verbose
315
+ ruby_args << "--verbose" if vv.positive?
316
+ ruby_args << "--name" << name if name
317
+ ruby_args << "--exclude" << exclude if exclude
318
+
319
+ env = {}
320
+ env["MT_COMPAT"] = mt_compat ? "true" : nil unless mt_compat.nil?
321
+
322
+ result = exec_ruby(ruby_args, env: env)
293
323
  if result.error?
294
324
  logger.error("Minitest failed!")
295
325
  exit(result.exit_code)
@@ -163,31 +163,41 @@ module Toys
163
163
  on_expand do |template|
164
164
  gem "rake", *template.gem_version
165
165
  require "rake"
166
+
166
167
  rakefile_path = Templates::Rake.find_rakefile(
167
168
  template.rakefile_path, template.context_directory || context_directory
168
169
  )
169
170
  raise "Cannot find #{template.rakefile_path}" unless rakefile_path
170
- context_dir = ::File.dirname(rakefile_path)
171
- rake = Templates::Rake.prepare_rake(rakefile_path, context_dir)
171
+ rake_context_dir = ::File.dirname(rakefile_path)
172
+ rake = Templates::Rake.prepare_rake(rakefile_path, rake_context_dir)
173
+
172
174
  rake.tasks.each do |task|
173
175
  comments = task.full_comment.to_s.split("\n")
174
176
  next if comments.empty? && template.only_described
177
+
175
178
  tool(task.name.split(":"), if_defined: :ignore) do
179
+ static :task, task
180
+ static :rake_context_dir, rake_context_dir
181
+
176
182
  bundler_settings = template.bundler_settings
177
183
  include :bundler, **bundler_settings if bundler_settings
184
+
178
185
  unless comments.empty?
179
186
  desc(comments.first)
180
187
  comments << "" << "Defined as a Rake task in #{rakefile_path}"
181
188
  long_desc(*comments)
182
189
  end
190
+
183
191
  if template.use_flags
184
192
  task.arg_names.each do |arg|
185
193
  specs = Templates::Rake.flag_specs(arg)
186
194
  flag(arg, *specs) unless specs.empty?
187
195
  end
188
- to_run do
196
+
197
+ # @private
198
+ def run
189
199
  args = task.arg_names.map { |arg| self[arg] }
190
- ::Dir.chdir(context_dir) do
200
+ ::Dir.chdir(rake_context_dir) do
191
201
  task.invoke(*args)
192
202
  end
193
203
  end
@@ -195,8 +205,10 @@ module Toys
195
205
  task.arg_names.each do |arg|
196
206
  optional_arg(arg)
197
207
  end
198
- to_run do
199
- ::Dir.chdir(context_dir) do
208
+
209
+ # @private
210
+ def run
211
+ ::Dir.chdir(rake_context_dir) do
200
212
  task.invoke(*args)
201
213
  end
202
214
  end
@@ -297,36 +297,47 @@ module Toys
297
297
 
298
298
  set_context_directory template.context_directory if template.context_directory
299
299
 
300
+ static :gem_version, template.gem_version
301
+ static :template_files, template.files
302
+ static :rdoc_options, template.options
303
+ static :output_dir, template.output_dir
304
+ static :rdoc_markup, template.markup
305
+ static :rdoc_main, template.main
306
+ static :rdoc_title, template.title
307
+ static :rdoc_template, template.template
308
+ static :rdoc_generator, template.generator
309
+
300
310
  include :exec, exit_on_nonzero_status: true
301
311
  include :gems
302
312
 
303
313
  bundler_settings = template.bundler_settings
304
314
  include :bundler, **bundler_settings if bundler_settings
305
315
 
306
- to_run do
307
- gem_requirements = template.gem_version
308
- gem "rdoc", *gem_requirements
316
+ # @private
317
+ def run # rubocop:disable all
318
+ gem "rdoc", *gem_version
309
319
 
310
320
  ::Dir.chdir(context_directory || ::Dir.getwd) do
311
321
  files = []
312
- template.files.each do |pattern|
322
+ template_files.each do |pattern|
313
323
  files.concat(::Dir.glob(pattern))
314
324
  end
315
325
  files.uniq!
316
326
 
317
- args = template.options.dup
318
- args << "-o" << template.output_dir
319
- args << "--markup" << template.markup if template.markup
320
- args << "--main" << template.main if template.main
321
- args << "--title" << template.title if template.title
322
- args << "-T" << template.template if template.template
323
- args << "-f" << template.generator if template.generator
324
-
325
- exec_ruby([], in: :controller) do |controller|
326
- controller.in.puts("gem 'rdoc', *#{gem_requirements.inspect}")
327
- controller.in.puts("require 'rdoc'")
328
- controller.in.puts("::RDoc::RDoc.new.document(#{(args + files).inspect})")
329
- end
327
+ args = rdoc_options.dup
328
+ args << "-o" << output_dir
329
+ args << "--markup" << rdoc_markup if rdoc_markup
330
+ args << "--main" << rdoc_main if rdoc_main
331
+ args << "--title" << rdoc_title if rdoc_title
332
+ args << "-T" << rdoc_template if rdoc_template
333
+ args << "-f" << rdoc_generator if rdoc_generator
334
+
335
+ code = <<~CODE
336
+ gem 'rdoc', *#{gem_version.inspect}
337
+ require 'rdoc'
338
+ ::RDoc::RDoc.new.document(#{(args + files).inspect})
339
+ CODE
340
+ exec_ruby(["-e", code])
330
341
  end
331
342
  end
332
343
  end