toys 0.5.0 → 0.6.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 +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
|