toys 0.11.5 → 0.12.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +27 -0
- data/README.md +1 -1
- data/builtins/system/bash-completion.rb +89 -0
- data/builtins/system/test.rb +96 -0
- data/builtins/system/update.rb +48 -0
- data/docs/guide.md +91 -3
- data/lib/toys/standard_cli.rb +2 -5
- data/lib/toys/templates/clean.rb +17 -1
- data/lib/toys/templates/gem_build.rb +22 -4
- data/lib/toys/templates/minitest.rb +17 -1
- data/lib/toys/templates/rake.rb +18 -2
- data/lib/toys/templates/rdoc.rb +22 -3
- data/lib/toys/templates/rspec.rb +17 -1
- data/lib/toys/templates/rubocop.rb +22 -3
- data/lib/toys/templates/yardoc.rb +30 -10
- data/lib/toys/testing.rb +197 -0
- data/lib/toys/version.rb +1 -1
- metadata +12 -9
- data/builtins/system.rb +0 -152
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '091a51c34d19b918c203d88f0bbae74432343aae63a0ee7d62799fa30a1c8097'
|
4
|
+
data.tar.gz: 00e1a389cf5de2d5a85133a7ca148480e6885f2c80822fcfc4e9838d36d724a3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 93b41a0886856f9665f3650596dba6fa4cb9a13c0a1c3fa040aed3b669382b86373e38d57bf3ac8bc0f90ed33a5094e2bcd4c89ea974ff98fc7dd5aebff5cb88
|
7
|
+
data.tar.gz: c83a1aa39ba8e3be2246aaa4bd8f6003b6c10d52e91beeb04ecc9082403b19e64fd5af7c0a04a8bd10c21d0f731bd63a0d8f3c0649163027fdc78429760553ef
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,32 @@
|
|
1
1
|
# Release History
|
2
2
|
|
3
|
+
### v0.12.0 / 2021-08-05
|
4
|
+
|
5
|
+
Toys 0.12.0 is a major release with significant new features and bug fixes, and a few minor breaking changes. Additionally, this release now requires Ruby 2.4 or later.
|
6
|
+
|
7
|
+
Breaking changes:
|
8
|
+
|
9
|
+
* Defining a tool with whitespace, control characters, or certain punctuation in the name, now raises ToolDefinitionError.
|
10
|
+
* The Toys::Tool class (for the object returned by the Toys::Context::Key::TOOL attribute) has been renamed to Toys::ToolDefinition so that the old name can be used for class-based tool definition.
|
11
|
+
|
12
|
+
New functionality:
|
13
|
+
|
14
|
+
* The DSL now supports a class-based tool definition syntax (in addition to the existing block-based syntax). Some users may prefer this new class-based style as more Ruby-like.
|
15
|
+
* The subtool list on help screens is now split into sections by source directory
|
16
|
+
* You can now load tools from a remote git repository using the load_git directive.
|
17
|
+
* Whitespace is now automatically considered a name delimiter when defining tools.
|
18
|
+
* There is experimental support for providing tests for tools.
|
19
|
+
* There is now an extensible settings mechanism to activate less-common tool behavior. Currently there is one setting, which causes subtools to inherit their parent's methods by default.
|
20
|
+
* The load directive can load into a new tool.
|
21
|
+
* You can now set the context directory individually for the standard build tools.
|
22
|
+
* Added a new standard mixin that provides XDG Base Directory information.
|
23
|
+
* Added a new standard mixin that provides cached access to remote git repos.
|
24
|
+
|
25
|
+
Fixes:
|
26
|
+
|
27
|
+
* Fixed some bundler integration issues that occurred when the bundle is being installed in a separate path such as a vendor directory.
|
28
|
+
* Exceptions raised from internal classes now include the full backtrace.
|
29
|
+
|
3
30
|
### v0.11.5 / 2021-03-28
|
4
31
|
|
5
32
|
* BREAKING CHANGE: The exit_on_nonzero_status option to exec now exits on signals and failures to spawn, in addition to error codes.
|
data/README.md
CHANGED
@@ -50,7 +50,7 @@ Toys does not yet specially implement tab completion for zsh or other shells.
|
|
50
50
|
However, if you are using zsh, installing bash completion using `bashcompinit`
|
51
51
|
*mostly* works.
|
52
52
|
|
53
|
-
Toys requires Ruby 2.
|
53
|
+
Toys requires Ruby 2.4 or later.
|
54
54
|
|
55
55
|
Most parts of Toys work on JRuby. However, JRuby is not recommended because of
|
56
56
|
JVM boot latency, lack of support for Kernel#fork, and other issues.
|
@@ -0,0 +1,89 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
desc "Bash tab completion for Toys"
|
4
|
+
|
5
|
+
long_desc \
|
6
|
+
"Tools that manage tab completion for Toys in the bash shell.",
|
7
|
+
"",
|
8
|
+
"To install tab completion for Toys, execute the following line in a bash shell, or" \
|
9
|
+
" include it in an init file such as your .bashrc:",
|
10
|
+
[" $(toys system bash-completion install)"],
|
11
|
+
"",
|
12
|
+
"To remove tab completion, execute:",
|
13
|
+
[" $(toys system bash-completion remove)"],
|
14
|
+
"",
|
15
|
+
"It is also possible to install completions for different executable names if you have" \
|
16
|
+
" aliases for Toys. See the help for the \"install\" and \"remove\" tools for details.",
|
17
|
+
"",
|
18
|
+
"The \"eval\" tool is the actual completion command invoked by bash when it needs to" \
|
19
|
+
" complete a toys command line. You shouldn't need to invoke it directly."
|
20
|
+
|
21
|
+
tool "eval" do
|
22
|
+
desc "Tab completion command (executed by bash)"
|
23
|
+
|
24
|
+
long_desc \
|
25
|
+
"Completion command invoked by bash to compete a toys command line. Generally you do not" \
|
26
|
+
" need to invoke this directly. It reads the command line context from the COMP_LINE" \
|
27
|
+
" and COMP_POINT environment variables, and outputs completion candidates to stdout."
|
28
|
+
|
29
|
+
disable_argument_parsing
|
30
|
+
|
31
|
+
def run
|
32
|
+
require "toys/utils/completion_engine"
|
33
|
+
result = ::Toys::Utils::CompletionEngine::Bash.new(cli).run
|
34
|
+
if result > 1
|
35
|
+
logger.fatal("This tool must be invoked as a bash completion command.")
|
36
|
+
end
|
37
|
+
exit(result)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
tool "install" do
|
42
|
+
desc "Install bash tab completion"
|
43
|
+
|
44
|
+
long_desc \
|
45
|
+
"Outputs a command to set up Toys tab completion in the current bash shell.",
|
46
|
+
"",
|
47
|
+
"To use, execute the following line in a bash shell, or include it in an init file" \
|
48
|
+
" such as your .bashrc:",
|
49
|
+
[" $(toys system bash-completion install)"],
|
50
|
+
"",
|
51
|
+
"This will associate the toys tab completion logic with the `toys` executable by default." \
|
52
|
+
" If you have aliases for the toys executable, pass them as arguments. e.g.",
|
53
|
+
[" $(toys system bash-completion install my-toys-alias another-alias)"]
|
54
|
+
|
55
|
+
remaining_args :executable_names,
|
56
|
+
desc: "Names of executables for which to set up tab completion" \
|
57
|
+
" (default: #{::Toys::StandardCLI::EXECUTABLE_NAME})"
|
58
|
+
|
59
|
+
def run
|
60
|
+
require "shellwords"
|
61
|
+
path = ::File.join(::File.dirname(::File.dirname(__dir__)), "share", "bash-completion.sh")
|
62
|
+
exes = executable_names.empty? ? [::Toys::StandardCLI::EXECUTABLE_NAME] : executable_names
|
63
|
+
puts Shellwords.join(["source", path] + exes)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
tool "remove" do
|
68
|
+
desc "Remove bash tab completion"
|
69
|
+
|
70
|
+
long_desc \
|
71
|
+
"Outputs a command to remove Toys tab completion from the current bash shell.",
|
72
|
+
"",
|
73
|
+
"To use, execute the following line in a bash shell:",
|
74
|
+
[" $(toys system bash-completion remove)"],
|
75
|
+
"",
|
76
|
+
"If you have other names or aliases for the toys executable, pass them as arguments. e.g.",
|
77
|
+
[" $(toys system bash-completion remove my-toys-alias another-alias)"]
|
78
|
+
|
79
|
+
remaining_args :executable_names,
|
80
|
+
desc: "Names of executables for which to set up tab completion" \
|
81
|
+
" (default: #{::Toys::StandardCLI::EXECUTABLE_NAME})"
|
82
|
+
|
83
|
+
def run
|
84
|
+
require "shellwords"
|
85
|
+
path = ::File.join(::File.dirname(::File.dirname(__dir__)), "share", "bash-completion-remove.sh")
|
86
|
+
exes = executable_names.empty? ? [::Toys::StandardCLI::EXECUTABLE_NAME] : executable_names
|
87
|
+
puts Shellwords.join(["source", path] + exes)
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
desc "Run tool tests"
|
4
|
+
|
5
|
+
flag :directory, "-d", "--directory PATH",
|
6
|
+
desc: "Run tests from the given directory"
|
7
|
+
flag :seed, "-s", "--seed SEED",
|
8
|
+
desc: "Sets random seed."
|
9
|
+
flag :warnings, "-w", "--[no-]warnings",
|
10
|
+
default: true,
|
11
|
+
desc: "Turn on Ruby warnings (defaults to true)"
|
12
|
+
flag :name, "-n", "--name PATTERN",
|
13
|
+
desc: "Filter run on /regexp/ or string."
|
14
|
+
flag :exclude, "-e", "--exclude PATTERN",
|
15
|
+
desc: "Exclude /regexp/ or string from run."
|
16
|
+
flag :recursive, "--[no-]recursive", default: true,
|
17
|
+
desc: "Recursively test subtools (default is true)"
|
18
|
+
flag :tool, "-t TOOL", "--tool TOOL", default: "",
|
19
|
+
desc: "Run tests only for tools under the given path"
|
20
|
+
|
21
|
+
include :exec
|
22
|
+
include :gems
|
23
|
+
include :terminal
|
24
|
+
|
25
|
+
def run
|
26
|
+
gem "minitest", "~> 5.0"
|
27
|
+
::Dir.chdir(tool_dir)
|
28
|
+
test_files = find_test_files
|
29
|
+
result = exec_ruby(ruby_args, in: :controller, log_cmd: "Starting minitest...") do |controller|
|
30
|
+
controller.in.puts("gem 'minitest', '~> 5.0'")
|
31
|
+
controller.in.puts("require 'minitest/autorun'")
|
32
|
+
controller.in.puts("require 'toys'")
|
33
|
+
controller.in.puts("require 'toys/testing'")
|
34
|
+
test_files.each do |file|
|
35
|
+
controller.in.puts("load '#{file}'")
|
36
|
+
end
|
37
|
+
end
|
38
|
+
if result.error?
|
39
|
+
logger.error("Minitest failed!")
|
40
|
+
exit(result.exit_code)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def find_test_files
|
45
|
+
glob = ".test/**/test_*.rb"
|
46
|
+
glob = "**/#{glob}" if recursive
|
47
|
+
test_files = ::Dir.glob(glob)
|
48
|
+
if test_files.empty?
|
49
|
+
logger.warn("No test files found")
|
50
|
+
exit
|
51
|
+
end
|
52
|
+
test_files.each do |file|
|
53
|
+
logger.info("Loading: #{file}")
|
54
|
+
end
|
55
|
+
test_files
|
56
|
+
end
|
57
|
+
|
58
|
+
def tool_dir
|
59
|
+
words = cli.loader.split_path(tool)
|
60
|
+
dir = base_dir
|
61
|
+
unless words.empty?
|
62
|
+
dir = ::File.join(dir, *words)
|
63
|
+
unless ::File.directory?(dir)
|
64
|
+
logger.warn("No such directory: #{dir}")
|
65
|
+
exit
|
66
|
+
end
|
67
|
+
end
|
68
|
+
dir
|
69
|
+
end
|
70
|
+
|
71
|
+
def base_dir
|
72
|
+
return ::File.absolute_path(directory) if directory
|
73
|
+
dir = ::Dir.getwd
|
74
|
+
loop do
|
75
|
+
candidate = ::File.join(dir, ::Toys::StandardCLI::CONFIG_DIR_NAME)
|
76
|
+
return candidate if ::File.directory?(candidate)
|
77
|
+
parent = ::File.dirname(dir)
|
78
|
+
if parent == dir
|
79
|
+
logger.error("Unable to find a Toys directory")
|
80
|
+
exit(1)
|
81
|
+
end
|
82
|
+
dir = parent
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def ruby_args
|
87
|
+
args = []
|
88
|
+
args << "-w" if warnings
|
89
|
+
args << "-I#{::Toys::CORE_LIB_PATH}#{::File::PATH_SEPARATOR}#{::Toys::LIB_PATH}"
|
90
|
+
args << "-"
|
91
|
+
args << "--seed" << seed if seed
|
92
|
+
args << "--verbose" if verbosity.positive?
|
93
|
+
args << "--name" << name if name
|
94
|
+
args << "--exclude" << exclude if exclude
|
95
|
+
args
|
96
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
desc "Update Toys if a newer version is available"
|
4
|
+
|
5
|
+
long_desc "Checks rubygems for a newer version of Toys. If one is available, downloads" \
|
6
|
+
" and installs it."
|
7
|
+
|
8
|
+
flag :yes, "-y", "--yes", desc: "Do not ask for interactive confirmation"
|
9
|
+
|
10
|
+
include :exec
|
11
|
+
include :terminal
|
12
|
+
|
13
|
+
def run
|
14
|
+
require "rubygems"
|
15
|
+
configure_exec(exit_on_nonzero_status: true)
|
16
|
+
version_info = spinner(leading_text: "Checking rubygems for the latest release... ",
|
17
|
+
final_text: "Done.\n") do
|
18
|
+
capture(["gem", "list", "-q", "-r", "-e", "toys"])
|
19
|
+
end
|
20
|
+
if version_info =~ /toys\s\((.+)\)/
|
21
|
+
latest_version = ::Gem::Version.new(::Regexp.last_match(1))
|
22
|
+
cur_version = ::Gem::Version.new(::Toys::VERSION)
|
23
|
+
if latest_version > cur_version
|
24
|
+
prompt = "Update Toys from #{cur_version} to #{latest_version}? "
|
25
|
+
exit(1) unless yes || confirm(prompt, default: true)
|
26
|
+
result = spinner(leading_text: "Installing Toys version #{latest_version}... ",
|
27
|
+
final_text: "Done.\n") do
|
28
|
+
exec(["gem", "install", "toys", "--version", latest_version.to_s],
|
29
|
+
out: :capture, err: :capture)
|
30
|
+
end
|
31
|
+
if result.error?
|
32
|
+
puts(result.captured_out + result.captured_err)
|
33
|
+
puts("Toys failed to install version #{latest_version}", :red, :bold)
|
34
|
+
exit(1)
|
35
|
+
end
|
36
|
+
puts("Toys successfully installed version #{latest_version}", :green, :bold)
|
37
|
+
elsif latest_version < cur_version
|
38
|
+
puts("Toys is already at experimental version #{cur_version}, which is later than" \
|
39
|
+
" the latest released version #{latest_version}",
|
40
|
+
:yellow, :bold)
|
41
|
+
else
|
42
|
+
puts("Toys is already at the latest version: #{latest_version}", :green, :bold)
|
43
|
+
end
|
44
|
+
else
|
45
|
+
puts("Could not get latest Toys version", :red, :bold)
|
46
|
+
exit(1)
|
47
|
+
end
|
48
|
+
end
|
data/docs/guide.md
CHANGED
@@ -1118,8 +1118,8 @@ run Toys with no arguments:
|
|
1118
1118
|
|
1119
1119
|
The root tool will display the overall help screen for Toys.
|
1120
1120
|
|
1121
|
-
Although it is a less common pattern, it is possible for a tool
|
1122
|
-
|
1121
|
+
Although it is a less common pattern, it is possible for a tool to have its own
|
1122
|
+
`run` method even if it has subtools:
|
1123
1123
|
|
1124
1124
|
tool "test" do
|
1125
1125
|
def run
|
@@ -1142,12 +1142,100 @@ subtools to have its own `run` method:
|
|
1142
1142
|
Now running `toys test` will run its own implementation.
|
1143
1143
|
|
1144
1144
|
(Yes, it is even possible to write a `run` method for the root tool. I don't
|
1145
|
-
recommend doing so, because
|
1145
|
+
recommend doing so, because you would lose the root tool's useful default
|
1146
1146
|
implementation that lists all your tools.)
|
1147
1147
|
|
1148
1148
|
Toys allows subtools to be nested arbitrarily deep. In practice, however, more
|
1149
1149
|
than two or three levels of hierarchy can be confusing to use.
|
1150
1150
|
|
1151
|
+
### Defining subtools using classes
|
1152
|
+
|
1153
|
+
It is also possible to define subtools by subclassing `Toys::Tool`. The class
|
1154
|
+
will support the same DSL as a `tool` block would. For example, this is what
|
1155
|
+
our greet tool would look like as a class:
|
1156
|
+
|
1157
|
+
class Greet < Toys::Tool
|
1158
|
+
optional_arg :whom, default: "world"
|
1159
|
+
flag :shout, "-s", "--shout"
|
1160
|
+
|
1161
|
+
def run
|
1162
|
+
greeting = "Hello, #{whom}!"
|
1163
|
+
greeting = greeting.upcase if shout
|
1164
|
+
puts greeting
|
1165
|
+
end
|
1166
|
+
end
|
1167
|
+
|
1168
|
+
Defining tools as clases is useful if you want your Toys files to look a bit
|
1169
|
+
more like normal Ruby or you want to avoid long blocks. Additionally, they can
|
1170
|
+
be useful to scope constants, which otherwise would be visible throughout the
|
1171
|
+
entire file, as noted in the [section on using constants](#Using_constants).
|
1172
|
+
|
1173
|
+
When you define a tool as a class, Toys infers the tool name by converting the
|
1174
|
+
class name to "kebab-case". For example, the `Greet` class above would define a
|
1175
|
+
tool called `greet`. If the class were called `GreetMany`, the tool would be
|
1176
|
+
called `greet-many`. If you need to override this behavior or set a tool name
|
1177
|
+
that is not possible from legal class names, pass the desired tool name to the
|
1178
|
+
`Toys.Tool` method like this:
|
1179
|
+
|
1180
|
+
class Greet < Toys.Tool("_my_greet")
|
1181
|
+
optional_arg :whom, default: "world"
|
1182
|
+
flag :shout, "-s", "--shout"
|
1183
|
+
|
1184
|
+
def run
|
1185
|
+
greeting = "Hello, #{whom}!"
|
1186
|
+
greeting = greeting.upcase if shout
|
1187
|
+
puts greeting
|
1188
|
+
end
|
1189
|
+
end
|
1190
|
+
|
1191
|
+
You can create subtools by nesting classes:
|
1192
|
+
|
1193
|
+
class Test < Toys::Tool
|
1194
|
+
class Unit < Toys::Tool
|
1195
|
+
def run
|
1196
|
+
puts "run only unit tests here..."
|
1197
|
+
end
|
1198
|
+
end
|
1199
|
+
|
1200
|
+
class Integration < Toys::Tool
|
1201
|
+
def run
|
1202
|
+
puts "run only integration tests here..."
|
1203
|
+
end
|
1204
|
+
end
|
1205
|
+
end
|
1206
|
+
|
1207
|
+
The above defines `test unit` and `test integration` tools as expected.
|
1208
|
+
|
1209
|
+
Finally, you may not nest a class-based tool inside a block-based tool. (This
|
1210
|
+
is because Ruby's constant definition rules would put such a class in an
|
1211
|
+
unexpected namespace, leading to potential clashes that would be difficult to
|
1212
|
+
diagnose.) It is, however, permissible to nest a block-based tool inside a
|
1213
|
+
class-based tool.
|
1214
|
+
|
1215
|
+
Hence, this is not allowed, and will result in an exception:
|
1216
|
+
|
1217
|
+
tool "test" do
|
1218
|
+
# This will raise Toys::ToolDefinitionError...
|
1219
|
+
class Unit < Toys::Tool
|
1220
|
+
def run
|
1221
|
+
puts "run unit tests..."
|
1222
|
+
end
|
1223
|
+
end
|
1224
|
+
end
|
1225
|
+
|
1226
|
+
But this is legal:
|
1227
|
+
|
1228
|
+
class Test < Toys::Tool
|
1229
|
+
tool "unit" do
|
1230
|
+
def run
|
1231
|
+
puts "run unit tests..."
|
1232
|
+
end
|
1233
|
+
end
|
1234
|
+
end
|
1235
|
+
|
1236
|
+
In general, though, as a best practice, I recommend against mixing the two
|
1237
|
+
styles. Define tools either as classes or as blocks, not both.
|
1238
|
+
|
1151
1239
|
## Understanding Toys files
|
1152
1240
|
|
1153
1241
|
Toys commands are defined in Toys files. We covered the basic syntax for these
|
data/lib/toys/standard_cli.rb
CHANGED
@@ -139,7 +139,7 @@ module Toys
|
|
139
139
|
add_search_path_hierarchy(start: cur_dir, terminate: global_dirs)
|
140
140
|
global_dirs.each { |path| add_search_path(path) }
|
141
141
|
builtins_path = ::File.join(::File.dirname(::File.dirname(__dir__)), "builtins")
|
142
|
-
add_config_path(builtins_path)
|
142
|
+
add_config_path(builtins_path, source_name: "(builtin tools)", context_directory: nil)
|
143
143
|
self
|
144
144
|
end
|
145
145
|
|
@@ -157,8 +157,6 @@ module Toys
|
|
157
157
|
end
|
158
158
|
end
|
159
159
|
|
160
|
-
# rubocop:disable Metrics/MethodLength
|
161
|
-
|
162
160
|
##
|
163
161
|
# Returns the middleware for the standard Toys CLI.
|
164
162
|
#
|
@@ -179,6 +177,7 @@ module Toys
|
|
179
177
|
default_recursive: true,
|
180
178
|
allow_root_args: true,
|
181
179
|
show_source_path: true,
|
180
|
+
separate_sources: true,
|
182
181
|
use_less: true,
|
183
182
|
fallback_execution: true),
|
184
183
|
Middleware.spec(:show_root_version,
|
@@ -189,8 +188,6 @@ module Toys
|
|
189
188
|
]
|
190
189
|
end
|
191
190
|
|
192
|
-
# rubocop:enable Metrics/MethodLength
|
193
|
-
|
194
191
|
##
|
195
192
|
# Returns the default set of global config directories.
|
196
193
|
#
|
data/lib/toys/templates/clean.rb
CHANGED
@@ -23,10 +23,13 @@ module Toys
|
|
23
23
|
# to clean. You can also include the symbol `:gitignore` which will
|
24
24
|
# clean all items covered by `.gitignore` files, if contained in a
|
25
25
|
# git working tree.
|
26
|
+
# @param context_directory [String] A custom context directory to use
|
27
|
+
# when executing this tool.
|
26
28
|
#
|
27
|
-
def initialize(name: nil, paths: [])
|
29
|
+
def initialize(name: nil, paths: [], context_directory: nil)
|
28
30
|
@name = name
|
29
31
|
@paths = paths
|
32
|
+
@context_directory = context_directory
|
30
33
|
end
|
31
34
|
|
32
35
|
##
|
@@ -45,6 +48,17 @@ module Toys
|
|
45
48
|
#
|
46
49
|
attr_writer :paths
|
47
50
|
|
51
|
+
##
|
52
|
+
# Custom context directory for this tool.
|
53
|
+
#
|
54
|
+
# @param value [String]
|
55
|
+
# @return [String]
|
56
|
+
#
|
57
|
+
attr_writer :context_directory
|
58
|
+
|
59
|
+
# @private
|
60
|
+
attr_reader :context_directory
|
61
|
+
|
48
62
|
# @private
|
49
63
|
def paths
|
50
64
|
Array(@paths)
|
@@ -59,6 +73,8 @@ module Toys
|
|
59
73
|
tool(template.name) do
|
60
74
|
desc "Clean built files and directories."
|
61
75
|
|
76
|
+
set_context_directory template.context_directory if template.context_directory
|
77
|
+
|
62
78
|
static :template_paths, template.paths
|
63
79
|
|
64
80
|
include :fileutils
|