toys 0.5.0 → 0.6.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +12 -0
- data/docs/guide.md +253 -115
- data/lib/toys/standard_cli.rb +1 -0
- data/lib/toys/templates/clean.rb +11 -11
- data/lib/toys/templates/gem_build.rb +24 -21
- data/lib/toys/templates/minitest.rb +20 -18
- data/lib/toys/templates/rake.rb +41 -8
- data/lib/toys/templates/rdoc.rb +17 -15
- data/lib/toys/templates/rubocop.rb +8 -6
- data/lib/toys/templates/yardoc.rb +43 -41
- data/lib/toys/version.rb +1 -1
- metadata +20 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1af0f4b8108ed4bf39da40bffa62fd4cc601df712b0b2e0a5a8d7ff9eb7cb160
|
4
|
+
data.tar.gz: 6c8f02f7f0e5a84c13e3ef7048febbab744f89fc14ca950221d6c56130eb8fc6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7976bb5dd0d9619f44b6c4e88ef63f417ccf88a72fb2f89aa6d5528eb70270c0dead339419b4339a184f7ef8d7fe7d6a2161f9119a3aa03af425831d54ceed22
|
7
|
+
data.tar.gz: 59e8a779fddedfa0b38245d36002b8e5626be6f9740d2e2090c5fe65ef225dd3278461a20d7e3928a6ce9b6a798f943d818cb3916aeda5562f89e1e7fdc7d8f9
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,17 @@
|
|
1
1
|
# Release History
|
2
2
|
|
3
|
+
### 0.6.0 / 2018-10-22
|
4
|
+
|
5
|
+
* FIXED: Build tools cd into the context directory when running.
|
6
|
+
* FIXED: Rakefiles are evaluated and tasks are run in the Rakefile's directory.
|
7
|
+
* ADDED: Context directory is available in the DSL and the tool runtime.
|
8
|
+
* IMPROVED: Rake template searches parent directories for Rakefile.
|
9
|
+
* IMPROVED: Rake tasks show the Rakefile path in the long description.
|
10
|
+
* IMPROVED: Subtools whose names begin with underscore are no longer listed in help
|
11
|
+
screens unless the `--all` flag is given.
|
12
|
+
* IMPROVED: Non-runnable namespaces are no longer displayed in recursive subtool
|
13
|
+
lists if their children are already displayed.
|
14
|
+
|
3
15
|
### 0.5.0 / 2018-10-07
|
4
16
|
|
5
17
|
* ADDED: Period and colon are recognized as tool path delimiters.
|
data/docs/guide.md
CHANGED
@@ -1079,13 +1079,13 @@ which can be used to call another tool:
|
|
1079
1079
|
end
|
1080
1080
|
|
1081
1081
|
Pass the tool name and arguments as arguments to the run method. It will
|
1082
|
-
execute, and return a process status
|
1083
|
-
|
1084
|
-
|
1082
|
+
execute, and return a process status code (i.e. 0 for success, and nonzero for
|
1083
|
+
error). Make sure you handle the exit status. For example, in most cases, you
|
1084
|
+
should probably exit if the tool you are calling returns a nonzero code.
|
1085
1085
|
|
1086
1086
|
You may also use the `exec` mixin [described below](#Executing_Subprocesses) to
|
1087
1087
|
run a tool in a separate process. This is particularly useful if you need to
|
1088
|
-
capture or manipulate that tool's input or output.
|
1088
|
+
capture or manipulate that tool's input or output stream.
|
1089
1089
|
|
1090
1090
|
### Helper Methods and Mixins
|
1091
1091
|
|
@@ -1572,96 +1572,6 @@ Either a single `.preload.rb` file or a `.preload` directory, or both, may be
|
|
1572
1572
|
used. If both are present, the `.preload.rb` file is loaded first before the
|
1573
1573
|
`.preload` directory contents.
|
1574
1574
|
|
1575
|
-
### Data Files
|
1576
|
-
|
1577
|
-
If your tools require images, archives, keys, or other such static data, Toys
|
1578
|
-
provides a convenient place to put data files that can be looked up by tools
|
1579
|
-
either during definition or runtime.
|
1580
|
-
|
1581
|
-
To use data files, you must define your tools inside a
|
1582
|
-
[Toys directory](#Toys_Directories). Within the Toys directory, create a
|
1583
|
-
directory named `.data` and copy your data files there. You may "find" a data
|
1584
|
-
file using the `find_data` directive in a Toys file, or by calling the
|
1585
|
-
`find_data` method in a tool. The `find_data` mechanism takes a relative path
|
1586
|
-
to a file, locates a matching file (or directory) among the data files, and
|
1587
|
-
returns the full path to that file system object. You may then read the file
|
1588
|
-
or perform any other operation on it.
|
1589
|
-
|
1590
|
-
For example, take the following directory structure:
|
1591
|
-
|
1592
|
-
(current directory)
|
1593
|
-
|
|
1594
|
-
+- .toys/
|
1595
|
-
|
|
1596
|
-
+- .data
|
1597
|
-
| |
|
1598
|
-
| +- greeting.txt
|
1599
|
-
| |
|
1600
|
-
| +- desc/
|
1601
|
-
| |
|
1602
|
-
| +- short.txt
|
1603
|
-
|
|
1604
|
-
+- greet.rb <-- defines "greet" (and subtools)
|
1605
|
-
|
1606
|
-
The data files in `.toys/.data` are available to any tool in the `.toys`
|
1607
|
-
directory or any of its subdirectories. For example, suppose we want our
|
1608
|
-
"greet" tool to use the contents of `greeting.txt`. We can call `find_data` to
|
1609
|
-
read those contents when the tool is executed:
|
1610
|
-
|
1611
|
-
# greet.rb
|
1612
|
-
desc "Print a friendly greeting."
|
1613
|
-
optional_arg :whom, default: "world", desc: "Whom to greet."
|
1614
|
-
def run
|
1615
|
-
greeting = IO.read(find_data("greeting.txt")).strip
|
1616
|
-
puts "#{greeting}, #{whom}!"
|
1617
|
-
end
|
1618
|
-
|
1619
|
-
You can include directories in the argument to `find_data`. For example, here
|
1620
|
-
is how to use the `find_data` directive to read the short description from the
|
1621
|
-
file "desc/short.txt":
|
1622
|
-
|
1623
|
-
# greet.rb
|
1624
|
-
desc IO.read(find_data("desc/short.txt")).strip
|
1625
|
-
optional_arg :whom, default: "world", desc: "Whom to greet."
|
1626
|
-
def run
|
1627
|
-
greeting = IO.read(find_data("greeting.txt")).strip
|
1628
|
-
puts "#{greeting}, #{whom}!"
|
1629
|
-
end
|
1630
|
-
|
1631
|
-
The `find_data` mechanism will return the "closest" file or directory found.
|
1632
|
-
In the example below, there is a `desc/short.txt` file in the `.data` directory
|
1633
|
-
at the top level, but there is also a `desc/short.txt` file in the `.data`
|
1634
|
-
directory under `test`. Tools under the `test` directory will find the more
|
1635
|
-
specific data file, while other tools will find the more general file.
|
1636
|
-
|
1637
|
-
(current directory)
|
1638
|
-
|
|
1639
|
-
+- .toys/
|
1640
|
-
|
|
1641
|
-
+- .data
|
1642
|
-
| |
|
1643
|
-
| +- greeting.txt
|
1644
|
-
| |
|
1645
|
-
| +- desc/
|
1646
|
-
| |
|
1647
|
-
| +- short.txt <-- default description for all tools
|
1648
|
-
|
|
1649
|
-
+- greet.rb <-- defines "greet" (and subtools)
|
1650
|
-
|
|
1651
|
-
+- test/
|
1652
|
-
|
|
1653
|
-
+- .data
|
1654
|
-
| |
|
1655
|
-
| +- desc/
|
1656
|
-
| |
|
1657
|
-
| +- short.txt <-- override description for test tools
|
1658
|
-
|
|
1659
|
-
+- unit.rb <-- defines "test unit" (and its subtools)
|
1660
|
-
|
1661
|
-
If, however, you find `greeting.txt` from a tool under `test`, it will still
|
1662
|
-
find the more general `.toys/.data/greeting.txt` file because there is no
|
1663
|
-
overriding file under `.toys/test/.data`.
|
1664
|
-
|
1665
1575
|
## Using Third-Party Gems
|
1666
1576
|
|
1667
1577
|
The Ruby community has developed many resources for building command line
|
@@ -1814,8 +1724,8 @@ Toys was designed to organize scripts that may be "scoped" to a project or
|
|
1814
1724
|
directory. Rake is also commonly used for this purpose: you can write a
|
1815
1725
|
"Rakefile" that defines rake tasks scoped to a directory. In many cases, Toys
|
1816
1726
|
can be used as a replacement for Rake. Indeed, the Toys repository itself
|
1817
|
-
contains a `.toys.rb` file
|
1818
|
-
forth
|
1727
|
+
contains a `.toys.rb` file instead of a Rakefile for running tests, builds, and
|
1728
|
+
so forth.
|
1819
1729
|
|
1820
1730
|
This section will explore the differences between Toys and Rake, and describe
|
1821
1731
|
how to use Toys for some of the things traditionally done with Rake.
|
@@ -1859,7 +1769,7 @@ it focuses on making it easy to define imperative tasks.
|
|
1859
1769
|
All told, this boils down to the principle of using the best tool for the job.
|
1860
1770
|
There will be times when you need to express file-based dependencies in some of
|
1861
1771
|
your build tasks. Rake will continue to be your friend in those cases. However,
|
1862
|
-
for
|
1772
|
+
for imperative tasks such as "run my tests", "build my YARD documentation", or
|
1863
1773
|
"release my gem", you may find Toys easier to use.
|
1864
1774
|
|
1865
1775
|
### Using Toys to Invoke Rake Tasks
|
@@ -1955,17 +1865,18 @@ can use either or both tools, depending on your needs.
|
|
1955
1865
|
|
1956
1866
|
Toys provides a built-in template for minitest, called `:minitest`. It is
|
1957
1867
|
implemented by the template class {Toys::Templates::Minitest}, and it uses the
|
1958
|
-
minitest gem
|
1959
|
-
|
1868
|
+
[minitest gem](https://rubygems.org/gems/minitest). The following directive
|
1869
|
+
uses the minitest template to create a tool called `test`:
|
1960
1870
|
|
1961
1871
|
expand :minitest, files: ["test/test*.rb"], libs: ["lib", "ext"]
|
1962
1872
|
|
1963
1873
|
See the {Toys::Templates::Minitest} documentation for details on the various
|
1964
1874
|
options.
|
1965
1875
|
|
1966
|
-
If you want to enforce code style using the
|
1967
|
-
|
1968
|
-
|
1876
|
+
If you want to enforce code style using the
|
1877
|
+
[rubocop gem](https://rubygems.org/gems/rubocop), you can use the built-in
|
1878
|
+
`:rubocop` template. The following directive uses this template to create a
|
1879
|
+
tool called `rubocop`:
|
1969
1880
|
|
1970
1881
|
expand :rubocop
|
1971
1882
|
|
@@ -2020,13 +1931,13 @@ Here's an example for YARD, creating a tool called `yardoc`:
|
|
2020
1931
|
Let's look at a complete example that combines the techniques above to provide
|
2021
1932
|
all the basic tools for a Ruby gem. It includes:
|
2022
1933
|
|
2023
|
-
* A testing tool that can be
|
2024
|
-
* Code style checking using Rubocop,
|
2025
|
-
* Documentation building using Yardoc,
|
2026
|
-
* Gem building,
|
2027
|
-
* Gem build and release to Rubygems.org,
|
2028
|
-
* A full CI tool,
|
2029
|
-
system. It runs the tests and style checks, and checks (but does not
|
1934
|
+
* A testing tool that can be invoked using `toys test`
|
1935
|
+
* Code style checking using Rubocop, invoked using `toys rubocop`
|
1936
|
+
* Documentation building using Yardoc, invoked using `toys yardoc`
|
1937
|
+
* Gem building, invoked using `toys build`
|
1938
|
+
* Gem build and release to Rubygems.org, invoked using `toys release`
|
1939
|
+
* A full CI tool, invoked using `toys ci`, that can be run from your favorite
|
1940
|
+
CI system. It runs the tests and style checks, and checks (but does not
|
2030
1941
|
actually build) the documentation for warnings and completeness.
|
2031
1942
|
|
2032
1943
|
Below is the full annotated `.toys.rb` file. For many gems, you could drop this
|
@@ -2211,10 +2122,10 @@ completely disable decreasing the verbosity, disable both `-q` and `--quiet`.
|
|
2211
2122
|
|
2212
2123
|
Normally Toys handles parsing command line arguments for you. This makes
|
2213
2124
|
writing tools easier, and also allows Toys to generate documentation
|
2214
|
-
automatically for flags and arguments. However, occasionally you'll
|
2215
|
-
|
2125
|
+
automatically for flags and arguments. However, occasionally you'll want Toys
|
2126
|
+
not to perform any parsing, but just to give you the command line arguments
|
2216
2127
|
raw. One common case is if your tool turns around and passes its arguments
|
2217
|
-
verbatim to
|
2128
|
+
verbatim to a subprocess.
|
2218
2129
|
|
2219
2130
|
To disable argument parsing, use the `disable_argument_parsing` directive. This
|
2220
2131
|
directive disables parsing and validation of flags and positional arguments.
|
@@ -2233,6 +2144,232 @@ Here is an example that wraps calls to git:
|
|
2233
2144
|
end
|
2234
2145
|
end
|
2235
2146
|
|
2147
|
+
### Data Files
|
2148
|
+
|
2149
|
+
If your tools require images, archives, keys, or other such static data, Toys
|
2150
|
+
provides a convenient place to put data files that can be looked up by tools
|
2151
|
+
either during definition or runtime.
|
2152
|
+
|
2153
|
+
To use data files, you must define your tools inside a
|
2154
|
+
[Toys directory](#Toys_Directories). Within the Toys directory, create a
|
2155
|
+
directory named `.data` and copy your data files there.
|
2156
|
+
|
2157
|
+
You may then "find" a data file by providing the relative path to the file from
|
2158
|
+
the `.data` directory. When defining a tool, use the
|
2159
|
+
[Toys::DSL::Tool#find_data](https://www.rubydoc.info/gems/toys-core/Toys%2FDSL%2FTool:find_data)
|
2160
|
+
directive in a Toys file. Or, at tool execution time, call
|
2161
|
+
[Toys::Tool#find_data](https://www.rubydoc.info/gems/toys-core/Toys%2FTool:find_data)
|
2162
|
+
(which is a convenience method for getting the tool source object using the
|
2163
|
+
`TOOL_SOURCE` key, and calling
|
2164
|
+
[Toys::Definition::SourceInfo#find_data](https://www.rubydoc.info/gems/toys-core/Toys%2FDefinition%2FSourceInfo:find_data)
|
2165
|
+
on it). In either case, `find_data` locates a matching file (or directory)
|
2166
|
+
among the data files, and returns the full path to that file system object. You
|
2167
|
+
may then read the file or perform any other operation on it.
|
2168
|
+
|
2169
|
+
For example, take the following directory structure:
|
2170
|
+
|
2171
|
+
(current directory)
|
2172
|
+
|
|
2173
|
+
+- .toys/
|
2174
|
+
|
|
2175
|
+
+- .data/
|
2176
|
+
| |
|
2177
|
+
| +- greeting.txt
|
2178
|
+
| |
|
2179
|
+
| +- desc/
|
2180
|
+
| |
|
2181
|
+
| +- short.txt
|
2182
|
+
|
|
2183
|
+
+- greet.rb <-- defines "greet" (and subtools)
|
2184
|
+
|
2185
|
+
The data files in `.toys/.data` are available to any tool in the `.toys`
|
2186
|
+
directory or any of its subdirectories. For example, suppose we want our
|
2187
|
+
"greet" tool to use the contents of `greeting.txt`. We can call `find_data` to
|
2188
|
+
read those contents when the tool is executed:
|
2189
|
+
|
2190
|
+
# greet.rb
|
2191
|
+
desc "Print a friendly greeting."
|
2192
|
+
optional_arg :whom, default: "world", desc: "Whom to greet."
|
2193
|
+
def run
|
2194
|
+
greeting = IO.read(find_data("greeting.txt")).strip
|
2195
|
+
puts "#{greeting}, #{whom}!"
|
2196
|
+
end
|
2197
|
+
|
2198
|
+
You can include directories in the argument to `find_data`. For example, here
|
2199
|
+
is how to use the `find_data` directive to read the short description from the
|
2200
|
+
file "desc/short.txt":
|
2201
|
+
|
2202
|
+
# greet.rb
|
2203
|
+
desc IO.read(find_data("desc/short.txt")).strip
|
2204
|
+
optional_arg :whom, default: "world", desc: "Whom to greet."
|
2205
|
+
def run
|
2206
|
+
greeting = IO.read(find_data("greeting.txt")).strip
|
2207
|
+
puts "#{greeting}, #{whom}!"
|
2208
|
+
end
|
2209
|
+
|
2210
|
+
The `find_data` mechanism will return the "closest" file or directory found.
|
2211
|
+
In the example below, there is a `desc/short.txt` file in the `.data` directory
|
2212
|
+
at the top level, but there is also a `desc/short.txt` file in the `.data`
|
2213
|
+
directory under `test`. Tools under the `test` directory will find the more
|
2214
|
+
specific data file, while other tools will find the more general file.
|
2215
|
+
|
2216
|
+
(current directory)
|
2217
|
+
|
|
2218
|
+
+- .toys/
|
2219
|
+
|
|
2220
|
+
+- .data/
|
2221
|
+
| |
|
2222
|
+
| +- greeting.txt
|
2223
|
+
| |
|
2224
|
+
| +- desc/
|
2225
|
+
| |
|
2226
|
+
| +- short.txt <-- default description for all tools
|
2227
|
+
|
|
2228
|
+
+- greet.rb <-- defines "greet" (and subtools)
|
2229
|
+
|
|
2230
|
+
+- test/
|
2231
|
+
|
|
2232
|
+
+- .data/
|
2233
|
+
| |
|
2234
|
+
| +- desc/
|
2235
|
+
| |
|
2236
|
+
| +- short.txt <-- override description for test tools
|
2237
|
+
|
|
2238
|
+
+- unit.rb <-- defines "test unit" (and its subtools)
|
2239
|
+
|
2240
|
+
If, however, you find `greeting.txt` from a tool under `test`, it will still
|
2241
|
+
find the more general `.toys/.data/greeting.txt` file because there is no
|
2242
|
+
overriding file under `.toys/test/.data`.
|
2243
|
+
|
2244
|
+
### The Context Directory
|
2245
|
+
|
2246
|
+
The **context directory** for a tool is the directory containing the toplevel
|
2247
|
+
`.toys.rb` file or the `.toys` directory within which the tool is defined. It
|
2248
|
+
is sometimes useful for tools that expect to be run from a specific working
|
2249
|
+
directory.
|
2250
|
+
|
2251
|
+
For example, suppose you have a Ruby project directory:
|
2252
|
+
|
2253
|
+
my-project/
|
2254
|
+
|
|
2255
|
+
+- .toys.rb <-- project tools defined here
|
2256
|
+
|
|
2257
|
+
+- lib/
|
2258
|
+
|
|
2259
|
+
+- test/
|
2260
|
+
|
|
2261
|
+
etc...
|
2262
|
+
|
2263
|
+
Now suppose you defined a tool that lists the tests:
|
2264
|
+
|
2265
|
+
tool "list-tests" do
|
2266
|
+
def run
|
2267
|
+
puts Dir.glob("test/**/*.rb").join("\n")
|
2268
|
+
end
|
2269
|
+
end
|
2270
|
+
|
2271
|
+
This tool assumes it will be run from the main project directory (`my-project`
|
2272
|
+
in the above case). However, Toys lets you invoke tools even if you are in a
|
2273
|
+
subdirectory:
|
2274
|
+
|
2275
|
+
cd lib
|
2276
|
+
toys list-tests # Does not work
|
2277
|
+
|
2278
|
+
Rake handles this by actually changing the current working directory to the
|
2279
|
+
directory containing the active Rakefile. Toys, however, does not change the
|
2280
|
+
working directory unless you tell it. You can make the `list-tests` tool work
|
2281
|
+
correctly by changing the directory to the context directory (which is the
|
2282
|
+
directory containing the `.toys.rb` file, i.e. the `my-project` directory.)
|
2283
|
+
|
2284
|
+
tool "list-tests" do
|
2285
|
+
def run
|
2286
|
+
Dir.chdir context_directory do
|
2287
|
+
puts Dir.glob("test/**/*.rb").join("\n")
|
2288
|
+
end
|
2289
|
+
end
|
2290
|
+
end
|
2291
|
+
|
2292
|
+
Note the context directory is different from `__dir__`. It is not necessarily
|
2293
|
+
the directory containing the file being executed, but the directory containing
|
2294
|
+
the entire toys directory structure. So if your tool definition is inside a
|
2295
|
+
`.toys` directory, it will still work:
|
2296
|
+
|
2297
|
+
my-project/ <-- context_directory still points here
|
2298
|
+
|
|
2299
|
+
+- .toys/
|
2300
|
+
| |
|
2301
|
+
| +- list-tests.rb <-- tool defined here
|
2302
|
+
|
|
2303
|
+
+- lib/
|
2304
|
+
|
|
2305
|
+
+- test/
|
2306
|
+
|
|
2307
|
+
etc...
|
2308
|
+
|
2309
|
+
This behavior is particularly useful for build tools. Indeed, all the build
|
2310
|
+
tools described in the section on
|
2311
|
+
[Toys as a Rake Replacement](#Toys_as_a_Rake_Replacement) automatically move
|
2312
|
+
into the context directory when they execute.
|
2313
|
+
|
2314
|
+
#### Changing the Context Directory
|
2315
|
+
|
2316
|
+
It is even possible to modify the context directory, causing tools that use the
|
2317
|
+
context directory (such as the standard build tools) to run in a different
|
2318
|
+
directory. Here is an example:
|
2319
|
+
|
2320
|
+
Suppose you have a repository with multiple gems, each in its own directory:
|
2321
|
+
|
2322
|
+
my-repo/
|
2323
|
+
|
|
2324
|
+
+- .toys.rb <-- all project tools defined here
|
2325
|
+
|
|
2326
|
+
+- gem1/
|
2327
|
+
| |
|
2328
|
+
| +- lib/
|
2329
|
+
| |
|
2330
|
+
| +- test/
|
2331
|
+
|
|
2332
|
+
+- gem2/
|
2333
|
+
| |
|
2334
|
+
| +- lib/
|
2335
|
+
| |
|
2336
|
+
| +- test/
|
2337
|
+
|
|
2338
|
+
etc...
|
2339
|
+
|
2340
|
+
Assuming all the gems use the same set of build tools, it is possible to define
|
2341
|
+
those tools once in a single `.toys.rb` file and have it run in a particular
|
2342
|
+
gem directory depending on your current location. For example, you can cd into
|
2343
|
+
`gem1` or even `gem1/lib` to have the tools run on `gem1`. Because the standard
|
2344
|
+
build tools execute within the context directory, you can accomplish this by
|
2345
|
+
setting the context directory to the gem directory corresponding to the current
|
2346
|
+
location. That is, if the working directory is `my-repo/gem1/lib`, set the
|
2347
|
+
context directory to `my-repo/gem1`. Here's what that could look like:
|
2348
|
+
|
2349
|
+
# .toys.rb content
|
2350
|
+
|
2351
|
+
require "pathname"
|
2352
|
+
base_dir = Pathname.new context_directory
|
2353
|
+
cur_dir = Pathname.new Dir.getwd
|
2354
|
+
|
2355
|
+
# The gem name is the first segment of the relative path from the context
|
2356
|
+
# directory to the current directory.
|
2357
|
+
relative_path = cur_dir.relative_path_from(base_dir).to_s
|
2358
|
+
gem_name = relative_path.split("/").first
|
2359
|
+
|
2360
|
+
# Only proceed if we're truly in a subdirectory
|
2361
|
+
if gem_name && gem_name != "." && gem_name != ".."
|
2362
|
+
|
2363
|
+
# Now set the context directory to the gem directory.
|
2364
|
+
set_context_directory base_dir.join(gem_name).to_s
|
2365
|
+
|
2366
|
+
# Define the build tools. Each of these uses the custom context directory
|
2367
|
+
# set above, and thus runs for the selected gem.
|
2368
|
+
expand :minitest
|
2369
|
+
expand :gem_build
|
2370
|
+
# etc.
|
2371
|
+
end
|
2372
|
+
|
2236
2373
|
## Toys Administration Using the System Tools
|
2237
2374
|
|
2238
2375
|
Toys comes with a few built-in tools, including some that let you administer
|
@@ -2265,8 +2402,8 @@ A similar effect can of course be obtained simply by `gem install toys`.
|
|
2265
2402
|
|
2266
2403
|
## Writing Your Own CLI Using Toys
|
2267
2404
|
|
2268
|
-
Toys is not primarily designed to help you write a custom command-line
|
2269
|
-
|
2405
|
+
Although Toys is not primarily designed to help you write a custom command-line
|
2406
|
+
binary, you can use it in that way. Toys is factored into two gems:
|
2270
2407
|
**toys-core**, which includes all the underlying machinery for creating
|
2271
2408
|
command-line binaries, and **toys**, which is really just a wrapper that
|
2272
2409
|
provides the `toys` binary itself and its built-in commands and behavior. To
|
@@ -2284,7 +2421,8 @@ line binary. For example:
|
|
2284
2421
|
Toys-Core lets you provide an alternate default run method for your own
|
2285
2422
|
command line binary.
|
2286
2423
|
* Toys itself provides several built-in tools, such as `do`, and `system`.
|
2287
|
-
Toys-Core lets your own command line binary
|
2424
|
+
Toys-Core lets you write your own command line binary with its own built-in
|
2425
|
+
tools.
|
2288
2426
|
* Toys itself implements a particular search path for user-provided Toys
|
2289
2427
|
files, and looks for specific file and directory names such as `.toys.rb`.
|
2290
2428
|
Toys-Core lets you change the search path, the file/directory names, or
|
data/lib/toys/standard_cli.rb
CHANGED
data/lib/toys/templates/clean.rb
CHANGED
@@ -66,17 +66,17 @@ module Toys
|
|
66
66
|
include :fileutils
|
67
67
|
|
68
68
|
to_run do
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
69
|
+
::Dir.chdir(context_directory || ::Dir.getwd) do
|
70
|
+
files = []
|
71
|
+
patterns = Array(template.paths)
|
72
|
+
patterns.each do |pattern|
|
73
|
+
files.concat(::Dir.glob(pattern))
|
74
|
+
end
|
75
|
+
files.uniq.each do |file|
|
76
|
+
if ::File.exist?(file)
|
77
|
+
rm_rf(file)
|
78
|
+
puts "Cleaned: #{file}"
|
79
|
+
end
|
80
80
|
end
|
81
81
|
end
|
82
82
|
end
|
@@ -77,7 +77,9 @@ module Toys
|
|
77
77
|
|
78
78
|
to_expand do |template|
|
79
79
|
unless template.gem_name
|
80
|
-
candidates = ::Dir.
|
80
|
+
candidates = ::Dir.chdir(context_directory || ::Dir.getwd) do
|
81
|
+
::Dir.glob("*.gemspec")
|
82
|
+
end
|
81
83
|
if candidates.empty?
|
82
84
|
raise ToolDefinitionError, "Could not find a gemspec"
|
83
85
|
end
|
@@ -90,31 +92,32 @@ module Toys
|
|
90
92
|
|
91
93
|
flag :yes, "-y", "--yes", desc: "Do not ask for interactive confirmation"
|
92
94
|
|
93
|
-
include :exec
|
95
|
+
include :exec, exit_on_nonzero_status: true
|
94
96
|
include :fileutils
|
95
97
|
include :terminal
|
96
98
|
|
97
99
|
to_run do
|
98
100
|
require "rubygems/package"
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
101
|
+
::Dir.chdir(context_directory || ::Dir.getwd) do
|
102
|
+
gemspec = ::Gem::Specification.load("#{template.gem_name}.gemspec")
|
103
|
+
version = gemspec.version
|
104
|
+
gemfile = "#{template.gem_name}-#{version}.gem"
|
105
|
+
::Gem::Package.build(gemspec)
|
106
|
+
mkdir_p("pkg")
|
107
|
+
mv(gemfile, "pkg")
|
108
|
+
if template.push_gem
|
109
|
+
if ::File.directory?(".git") && capture("git status -s").strip != ""
|
110
|
+
logger.error "Cannot push the gem when there are uncommited changes"
|
111
|
+
exit(1)
|
112
|
+
end
|
113
|
+
exit(1) unless yes || confirm("Release #{gemfile}?", default: true)
|
114
|
+
exec(["gem", "push", "pkg/#{gemfile}"])
|
115
|
+
if template.tag
|
116
|
+
exec(["git", "tag", "v#{version}"])
|
117
|
+
if template.push_tag
|
118
|
+
template.push_tag = "origin" if template.push_tag == true
|
119
|
+
exec(["git", "push", template.push_tag, "v#{version}"])
|
120
|
+
end
|
118
121
|
end
|
119
122
|
end
|
120
123
|
end
|
@@ -109,28 +109,30 @@ module Toys
|
|
109
109
|
to_run do
|
110
110
|
gem "minitest", *Array(template.gem_version)
|
111
111
|
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
112
|
+
::Dir.chdir(context_directory || ::Dir.getwd) do
|
113
|
+
ruby_args = []
|
114
|
+
unless template.libs.empty?
|
115
|
+
lib_path = template.libs.join(::File::PATH_SEPARATOR)
|
116
|
+
ruby_args << "-I#{lib_path}"
|
117
|
+
end
|
118
|
+
ruby_args << "-w" if warnings
|
118
119
|
|
119
|
-
|
120
|
-
|
121
|
-
|
120
|
+
if tests.empty?
|
121
|
+
Array(template.files).each do |pattern|
|
122
|
+
tests.concat(::Dir.glob(pattern))
|
123
|
+
end
|
124
|
+
tests.uniq!
|
122
125
|
end
|
123
|
-
tests.uniq!
|
124
|
-
end
|
125
126
|
|
126
|
-
|
127
|
-
|
128
|
-
|
127
|
+
result = ruby(ruby_args, in: :controller) do |controller|
|
128
|
+
tests.each do |file|
|
129
|
+
controller.in.puts("load '#{file}'")
|
130
|
+
end
|
131
|
+
end
|
132
|
+
if result.error?
|
133
|
+
logger.error("Minitest failed!")
|
134
|
+
exit(result.exit_code)
|
129
135
|
end
|
130
|
-
end
|
131
|
-
if result.error?
|
132
|
-
logger.error("Minitest failed!")
|
133
|
-
exit(result.exit_code)
|
134
136
|
end
|
135
137
|
end
|
136
138
|
end
|
data/lib/toys/templates/rake.rb
CHANGED
@@ -50,8 +50,8 @@ module Toys
|
|
50
50
|
# the rake gem. Defaults to nil, indicating no version requirement.
|
51
51
|
# @param [String] rakefile_path Path to the Rakefile. Defaults to
|
52
52
|
# {DEFAULT_RAKEFILE_PATH}.
|
53
|
-
# @param [Boolean] only_described
|
54
|
-
# with descriptions. Default is false.
|
53
|
+
# @param [Boolean] only_described If true, tools are generated only for
|
54
|
+
# rake tasks with descriptions. Default is false.
|
55
55
|
# @param [Boolean] use_flags Generated tools use flags instead of
|
56
56
|
# positional arguments to pass arguments to rake tasks. Default is
|
57
57
|
# false.
|
@@ -74,16 +74,17 @@ module Toys
|
|
74
74
|
to_expand do |template|
|
75
75
|
gem "rake", *Array(template.gem_version)
|
76
76
|
require "rake"
|
77
|
-
::Rake
|
78
|
-
|
79
|
-
|
80
|
-
::Rake.
|
77
|
+
rakefile_path = Templates::Rake.find_rakefile(template.rakefile_path, context_directory)
|
78
|
+
raise "Cannot find #{template.rakefile_path}" unless rakefile_path
|
79
|
+
context_dir = ::File.dirname(rakefile_path)
|
80
|
+
rake = Templates::Rake.prepare_rake(rakefile_path, context_dir)
|
81
81
|
rake.tasks.each do |task|
|
82
82
|
comments = task.full_comment.to_s.split("\n")
|
83
83
|
next if comments.empty? && template.only_described
|
84
84
|
tool(task.name.split(":"), if_defined: :ignore) do
|
85
85
|
unless comments.empty?
|
86
86
|
desc(comments.first)
|
87
|
+
comments << "" << "Defined as a Rake task in #{rakefile_path}"
|
87
88
|
long_desc(*comments)
|
88
89
|
end
|
89
90
|
if template.use_flags
|
@@ -93,14 +94,18 @@ module Toys
|
|
93
94
|
end
|
94
95
|
to_run do
|
95
96
|
args = task.arg_names.map { |arg| self[arg] }
|
96
|
-
|
97
|
+
::Dir.chdir(context_dir) do
|
98
|
+
task.invoke(*args)
|
99
|
+
end
|
97
100
|
end
|
98
101
|
else
|
99
102
|
task.arg_names.each do |arg|
|
100
103
|
optional_arg(arg)
|
101
104
|
end
|
102
105
|
to_run do
|
103
|
-
|
106
|
+
::Dir.chdir(context_dir) do
|
107
|
+
task.invoke(*args)
|
108
|
+
end
|
104
109
|
end
|
105
110
|
end
|
106
111
|
end
|
@@ -118,6 +123,34 @@ module Toys
|
|
118
123
|
end
|
119
124
|
specs
|
120
125
|
end
|
126
|
+
|
127
|
+
## @private
|
128
|
+
def self.find_rakefile(path, context_dir)
|
129
|
+
if path == ::File.absolute_path(path)
|
130
|
+
return ::File.file?(path) && ::File.readable?(path) ? path : nil
|
131
|
+
end
|
132
|
+
dir = ::Dir.getwd
|
133
|
+
50.times do
|
134
|
+
rakefile_path = ::File.expand_path(path, dir)
|
135
|
+
return rakefile_path if ::File.file?(rakefile_path) && ::File.readable?(rakefile_path)
|
136
|
+
break if dir == context_dir
|
137
|
+
next_dir = ::File.dirname(dir)
|
138
|
+
break if dir == next_dir
|
139
|
+
dir = next_dir
|
140
|
+
end
|
141
|
+
nil
|
142
|
+
end
|
143
|
+
|
144
|
+
## @private
|
145
|
+
def self.prepare_rake(rakefile_path, context_dir)
|
146
|
+
::Rake::TaskManager.record_task_metadata = true
|
147
|
+
rake = ::Rake::Application.new
|
148
|
+
::Rake.application = rake
|
149
|
+
::Dir.chdir(context_dir) do
|
150
|
+
::Rake.load_rakefile(rakefile_path)
|
151
|
+
end
|
152
|
+
rake
|
153
|
+
end
|
121
154
|
end
|
122
155
|
end
|
123
156
|
end
|
data/lib/toys/templates/rdoc.rb
CHANGED
@@ -122,23 +122,25 @@ module Toys
|
|
122
122
|
gem "rdoc", *Array(template.gem_version)
|
123
123
|
require "rdoc"
|
124
124
|
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
125
|
+
::Dir.chdir(context_directory || ::Dir.getwd) do
|
126
|
+
files = []
|
127
|
+
patterns = Array(template.files)
|
128
|
+
patterns = ["lib/**/*.rb"] if patterns.empty?
|
129
|
+
patterns.each do |pattern|
|
130
|
+
files.concat(::Dir.glob(pattern))
|
131
|
+
end
|
132
|
+
files.uniq!
|
132
133
|
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
134
|
+
args = template.options.dup
|
135
|
+
args << "-o" << template.output_dir
|
136
|
+
args << "--markup" << template.markup if template.markup
|
137
|
+
args << "--main" << template.main if template.main
|
138
|
+
args << "--title" << template.title if template.title
|
139
|
+
args << "-T" << template.template if template.template
|
140
|
+
args << "-f" << template.generator if template.generator
|
140
141
|
|
141
|
-
|
142
|
+
exec_proc(proc { RDoc::RDoc.new.document(args + files) })
|
143
|
+
end
|
142
144
|
end
|
143
145
|
end
|
144
146
|
end
|
@@ -86,12 +86,14 @@ module Toys
|
|
86
86
|
gem "rubocop", *Array(template.gem_version)
|
87
87
|
require "rubocop"
|
88
88
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
89
|
+
::Dir.chdir(context_directory || ::Dir.getwd) do
|
90
|
+
cli = ::RuboCop::CLI.new
|
91
|
+
logger.info "Running RuboCop..."
|
92
|
+
result = cli.run(template.options)
|
93
|
+
if result.nonzero?
|
94
|
+
logger.error "RuboCop failed!"
|
95
|
+
exit(1) if template.fail_on_error
|
96
|
+
end
|
95
97
|
end
|
96
98
|
end
|
97
99
|
end
|
@@ -169,55 +169,57 @@ module Toys
|
|
169
169
|
gem "yard", *Array(template.gem_version)
|
170
170
|
require "yard"
|
171
171
|
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
172
|
+
::Dir.chdir(context_directory || ::Dir.getwd) do
|
173
|
+
files = []
|
174
|
+
patterns = Array(template.files)
|
175
|
+
patterns = ["lib/**/*.rb"] if patterns.empty?
|
176
|
+
patterns.each do |pattern|
|
177
|
+
files.concat(::Dir.glob(pattern))
|
178
|
+
end
|
179
|
+
files.uniq!
|
179
180
|
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
181
|
+
run_options = template.options.dup
|
182
|
+
stats_options = template.stats_options.dup
|
183
|
+
stats_options << "--list-undoc" if template.fail_on_undocumented_objects
|
184
|
+
run_options << "--fail-on-warning" if template.fail_on_warning
|
185
|
+
run_options << "--no-output" unless generate_output
|
186
|
+
run_options << "--output-dir" << template.output_dir if template.output_dir
|
187
|
+
run_options << "--no-public" unless template.show_public
|
188
|
+
run_options << "--protected" if template.show_protected
|
189
|
+
run_options << "--private" if template.show_private
|
190
|
+
run_options << "--no-private" if template.hide_private_tag
|
191
|
+
run_options << "-r" << template.readme if template.readme
|
192
|
+
run_options << "-m" << template.markup if template.markup
|
193
|
+
run_options << "-t" << template.template if template.template
|
194
|
+
run_options << "-p" << template.template_path if template.template_path
|
195
|
+
run_options << "-f" << template.format if template.format
|
196
|
+
unless stats_options.empty?
|
197
|
+
run_options << "--no-stats"
|
198
|
+
stats_options << "--use-cache"
|
199
|
+
end
|
200
|
+
run_options.concat(files)
|
200
201
|
|
201
|
-
|
202
|
-
if result.error?
|
203
|
-
puts("Yardoc encountered errors", :red, :bold) unless verbosity.negative?
|
204
|
-
exit(1)
|
205
|
-
end
|
206
|
-
unless stats_options.empty?
|
207
|
-
result = exec_proc(proc { ::YARD::CLI::Stats.run(*stats_options) }, out: :capture)
|
208
|
-
puts result.captured_out
|
202
|
+
result = exec_proc(proc { ::YARD::CLI::Yardoc.run(*run_options) })
|
209
203
|
if result.error?
|
210
204
|
puts("Yardoc encountered errors", :red, :bold) unless verbosity.negative?
|
211
205
|
exit(1)
|
212
206
|
end
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
end
|
207
|
+
unless stats_options.empty?
|
208
|
+
result = exec_proc(proc { ::YARD::CLI::Stats.run(*stats_options) }, out: :capture)
|
209
|
+
puts result.captured_out
|
210
|
+
if result.error?
|
211
|
+
puts("Yardoc encountered errors", :red, :bold) unless verbosity.negative?
|
219
212
|
exit(1)
|
220
213
|
end
|
214
|
+
exit_on_nonzero_status(result)
|
215
|
+
if template.fail_on_undocumented_objects
|
216
|
+
if result.captured_out =~ /Undocumented\sObjects:/
|
217
|
+
unless verbosity.negative?
|
218
|
+
puts("Yardoc encountered undocumented objects", :red, :bold)
|
219
|
+
end
|
220
|
+
exit(1)
|
221
|
+
end
|
222
|
+
end
|
221
223
|
end
|
222
224
|
end
|
223
225
|
end
|
data/lib/toys/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: toys
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Daniel Azuma
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-10-
|
11
|
+
date: 2018-10-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: toys-core
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - '='
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 0.
|
19
|
+
version: 0.6.0
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - '='
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 0.
|
26
|
+
version: 0.6.0
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: highline
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -80,6 +80,20 @@ dependencies:
|
|
80
80
|
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '5.2'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rake
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '12.0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '12.0'
|
83
97
|
- !ruby/object:Gem::Dependency
|
84
98
|
name: redcarpet
|
85
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -100,14 +114,14 @@ dependencies:
|
|
100
114
|
requirements:
|
101
115
|
- - "~>"
|
102
116
|
- !ruby/object:Gem::Version
|
103
|
-
version: 0.59.
|
117
|
+
version: 0.59.2
|
104
118
|
type: :development
|
105
119
|
prerelease: false
|
106
120
|
version_requirements: !ruby/object:Gem::Requirement
|
107
121
|
requirements:
|
108
122
|
- - "~>"
|
109
123
|
- !ruby/object:Gem::Version
|
110
|
-
version: 0.59.
|
124
|
+
version: 0.59.2
|
111
125
|
- !ruby/object:Gem::Dependency
|
112
126
|
name: yard
|
113
127
|
requirement: !ruby/object:Gem::Requirement
|