toys 0.16.0 → 0.17.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 +17 -0
- data/docs/guide.md +264 -44
- data/lib/toys/version.rb +1 -1
- metadata +5 -5
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e3835e01039a57776c3ae00091c53153166a723210e73e098b6af38d901c3066
|
|
4
|
+
data.tar.gz: e1efc2f269501b0a218522d929ce1d1ea50662045ab4ca03c9b4d63c8e68cdd9
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 8b64f1f36da5faeebeee80456ab33247f90311f5e98bdd8ba7a68a2da8e83326e02aff9f8be877c076739c96127501b07208cec8009b4bf85bd170a328c19aa4
|
|
7
|
+
data.tar.gz: 5a178132d475dff414a6c134313412a484f6700cb5900394e5d3fe3f7ec7e6c00005d6f4471173d74b3a9a989bdacf9723934ec83b08c760ab21ee90a8f9e572
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,22 @@
|
|
|
1
1
|
# Release History
|
|
2
2
|
|
|
3
|
+
### v0.17.0 / 2025-11-07
|
|
4
|
+
|
|
5
|
+
Toys 0.17 includes several significant new pieces of functionality:
|
|
6
|
+
|
|
7
|
+
* Support for loading tools from Rubygems. The load_gem directive loads tools from the "toys" directory in a gem, installing the gem if necessary. This makes it easy to distribute tools, securely and versioned, as gems.
|
|
8
|
+
* Flag handlers can now take an optional third argument, the entire options hash. This enables significantly more powerful behavior during flag parsing, such as letting flags affect the behavior of other flags.
|
|
9
|
+
|
|
10
|
+
Additional new features:
|
|
11
|
+
|
|
12
|
+
* When using the :gems mixin, you can now specify installation options such as on_missing not only when you include the mixin, but also when you declare the gem.
|
|
13
|
+
* Added support for an environment variable `TOYS_GIT_CACHE_WRITABLE` to disable the read-only behavior of git cache sources. This improves compatibility with environments that want to delete caches.
|
|
14
|
+
|
|
15
|
+
Other fixes and documentation:
|
|
16
|
+
|
|
17
|
+
* Added the standard logger gem to the toys-core dependencies to silence Ruby 3.5 warnings.
|
|
18
|
+
* Updated the user guide to cover new features and fix some internal links
|
|
19
|
+
|
|
3
20
|
### v0.16.0 / 2025-10-31
|
|
4
21
|
|
|
5
22
|
* ADDED: Updated minimum Ruby version to 2.7
|
data/docs/guide.md
CHANGED
|
@@ -54,7 +54,8 @@ forms, which appear in different styles of help.
|
|
|
54
54
|
|
|
55
55
|
Toys searches for tools in specifically-named **Toys files** and **Toys
|
|
56
56
|
directories**. It searches for these in the current directory, in parent
|
|
57
|
-
directories, and in the Toys **search path**.
|
|
57
|
+
directories, and in the Toys **search path**. You can also distribute tools in
|
|
58
|
+
gems or via git.
|
|
58
59
|
|
|
59
60
|
Toys provides various features to help you write tools. This includes providing
|
|
60
61
|
a **logger** for each tool, **mixins** that provide common functions a tool can
|
|
@@ -221,7 +222,7 @@ flag, but it has no additional effect.) Namespaces also support the following
|
|
|
221
222
|
additional flags:
|
|
222
223
|
|
|
223
224
|
* `--all` which displays all subtools, including
|
|
224
|
-
[hidden subtools](#
|
|
225
|
+
[hidden subtools](#hidden-tools) and namespaces.
|
|
225
226
|
* `--no-recursive` which displays only immediate subtools, instead of the
|
|
226
227
|
default behavior of showing all subtools recursively.
|
|
227
228
|
* `--search=TERM` which displays only subtools whose name or description
|
|
@@ -267,7 +268,7 @@ you could do this:
|
|
|
267
268
|
$ toys do build --staging , test --help
|
|
268
269
|
|
|
269
270
|
Each tool can choose which behavior it will support, whether or not to enforce
|
|
270
|
-
[flags before positional args](#
|
|
271
|
+
[flags before positional args](#enforcing-flags-before-args).
|
|
271
272
|
|
|
272
273
|
You can also, of course, stop recognizing flags on the command line by passing
|
|
273
274
|
`--` as an argument.
|
|
@@ -275,7 +276,7 @@ You can also, of course, stop recognizing flags on the command line by passing
|
|
|
275
276
|
### Tab completion
|
|
276
277
|
|
|
277
278
|
If you are using the Bash shell, Toys provides custom tab completion. See
|
|
278
|
-
[this section](#
|
|
279
|
+
[this section](#installing-tab-completion-for-bash) for instructions on
|
|
279
280
|
installing tab completion.
|
|
280
281
|
|
|
281
282
|
Toys will complete tool and subtool names, flags, values passed to flags, and
|
|
@@ -511,7 +512,7 @@ an example:
|
|
|
511
512
|
long_desc: ["Long descriptions can have multiple lines.",
|
|
512
513
|
"This is the second line."]
|
|
513
514
|
|
|
514
|
-
See the [above section on Descriptions](#
|
|
515
|
+
See the [above section on Descriptions](#tool-descriptions) for more
|
|
515
516
|
information on how descriptions are rendered and word wrapped.
|
|
516
517
|
|
|
517
518
|
Because long descriptions may be unwieldly to write as a hash argument in this
|
|
@@ -556,7 +557,7 @@ and
|
|
|
556
557
|
[OptionParser::OctalInteger](http://ruby-doc.org/stdlib/libdoc/optparse/rdoc/OptionParser.html#OctalInteger).
|
|
557
558
|
|
|
558
559
|
You can also create **custom acceptors**. See the
|
|
559
|
-
[section below on Custom Acceptors](#
|
|
560
|
+
[section below on Custom Acceptors](#custom-acceptors) for more information.
|
|
560
561
|
|
|
561
562
|
#### Argument completions
|
|
562
563
|
|
|
@@ -768,7 +769,7 @@ and
|
|
|
768
769
|
[OptionParser::OctalInteger](http://ruby-doc.org/stdlib/libdoc/optparse/rdoc/OptionParser.html#OctalInteger).
|
|
769
770
|
|
|
770
771
|
You can also create **custom acceptors**. See the
|
|
771
|
-
[section below on Custom Acceptors](#
|
|
772
|
+
[section below on Custom Acceptors](#custom-acceptors) for more information.
|
|
772
773
|
|
|
773
774
|
#### Defaults and handlers
|
|
774
775
|
|
|
@@ -791,15 +792,25 @@ will be `false`, i.e. the last value set on the command line. This is because a
|
|
|
791
792
|
flag normally *sets* its option value, replacing any previously set value.
|
|
792
793
|
|
|
793
794
|
You can, however, change this behavior by providing a **handler**. A handler is
|
|
794
|
-
a Ruby Proc that defines what a flag does to its option value. It takes
|
|
795
|
-
arguments
|
|
796
|
-
|
|
797
|
-
new value
|
|
795
|
+
a Ruby Proc that defines what a flag does to its option value. It takes up to
|
|
796
|
+
three arguments:
|
|
797
|
+
|
|
798
|
+
1. The new value given
|
|
799
|
+
2. The previously set value (which might be the default value if this is the
|
|
800
|
+
first appearance of the flag)
|
|
801
|
+
3. A hash containing all the options set so far
|
|
802
|
+
|
|
803
|
+
The proc must then return the new value for the option.
|
|
804
|
+
|
|
805
|
+
If the proc takes three arguments, it can use the third argument to read and/or
|
|
806
|
+
modify any other option. This enables powerful abilities such as flags that
|
|
807
|
+
affect the behavior of other flags.
|
|
798
808
|
|
|
799
809
|
Effectively, the default behavior (setting the value and ignoring the previous
|
|
800
|
-
value) is equivalent to the following handler
|
|
810
|
+
value) is equivalent to the following handler that takes only the first
|
|
811
|
+
argument:
|
|
801
812
|
|
|
802
|
-
flag :shout, "--[no-]shout", handler: proc { | val
|
|
813
|
+
flag :shout, "--[no-]shout", handler: proc { | val| val }
|
|
803
814
|
|
|
804
815
|
Toys gives the default handler the special name `:set`. So the above is also
|
|
805
816
|
equivalent to:
|
|
@@ -827,7 +838,7 @@ Note that both flags affect the same option name,
|
|
|
827
838
|
{Toys::Context::Key::VERBOSITY}. The first increments it each time it appears,
|
|
828
839
|
and the second decrements it. A tool can query this option and get an integer
|
|
829
840
|
telling the requested verbosity level, as you will see
|
|
830
|
-
[below](#
|
|
841
|
+
[below](#logging-and-verbosity).
|
|
831
842
|
|
|
832
843
|
Toys provides a few built-in handlers that can be specified by name. We already
|
|
833
844
|
discussed the default handler that can be specified by its name `:set` or by
|
|
@@ -855,7 +866,7 @@ directive. The `desc:` argument takes a single string description, while the
|
|
|
855
866
|
long_desc: ["Long descriptions can have multiple lines.",
|
|
856
867
|
"This is the second line."]
|
|
857
868
|
|
|
858
|
-
See the [above section on Descriptions](#
|
|
869
|
+
See the [above section on Descriptions](#tool-descriptions) for more information on
|
|
859
870
|
how descriptions are rendered and word wrapped.
|
|
860
871
|
|
|
861
872
|
Because long descriptions may be unwieldly to write as a hash argument in this
|
|
@@ -978,7 +989,7 @@ your tools.
|
|
|
978
989
|
|
|
979
990
|
Note: If you do not define the `run` method for a tool, Toys provides a default
|
|
980
991
|
implementation that displays the tool's help screen. This is typically used for
|
|
981
|
-
namespaces, as we shall see [below](#
|
|
992
|
+
namespaces, as we shall see [below](#namespaces-and-subtools). Most tools,
|
|
982
993
|
however, should define `run`.
|
|
983
994
|
|
|
984
995
|
Let's revisit the "greet" example we covered earlier.
|
|
@@ -1160,7 +1171,7 @@ our greet tool would look like as a class:
|
|
|
1160
1171
|
Defining tools as clases is useful if you want your Toys files to look a bit
|
|
1161
1172
|
more like normal Ruby or you want to avoid long blocks. Additionally, they can
|
|
1162
1173
|
be useful to scope constants, which otherwise would be visible throughout the
|
|
1163
|
-
entire file, as noted in the [section on using constants](#
|
|
1174
|
+
entire file, as noted in the [section on using constants](#using-constants).
|
|
1164
1175
|
|
|
1165
1176
|
When you define a tool as a class, Toys infers the tool name by converting the
|
|
1166
1177
|
class name to "kebab-case". For example, the `Greet` class above would define a
|
|
@@ -1231,7 +1242,7 @@ styles. Define tools either as classes or as blocks, not both.
|
|
|
1231
1242
|
## Understanding Toys files
|
|
1232
1243
|
|
|
1233
1244
|
Toys commands are defined in Toys files. We covered the basic syntax for these
|
|
1234
|
-
files in the [above section on defining tools](#
|
|
1245
|
+
files in the [above section on defining tools](#defining-tools). In this
|
|
1235
1246
|
section, we will take a deeper look at what you can do with Toys files.
|
|
1236
1247
|
|
|
1237
1248
|
### Toys directories
|
|
@@ -1336,7 +1347,7 @@ in the separate file `.toys/test/unit.rb`.
|
|
|
1336
1347
|
Toys also loads the index file in a directory *before* any other files in that
|
|
1337
1348
|
directory. This means they are convenient places to define shared code that can
|
|
1338
1349
|
be used by all the subtools defined in that directory, as we shall see later in
|
|
1339
|
-
the [section on sharing code](#
|
|
1350
|
+
the [section on sharing code](#sharing-code).
|
|
1340
1351
|
|
|
1341
1352
|
### The Toys search path
|
|
1342
1353
|
|
|
@@ -1393,7 +1404,7 @@ so, use the directive {Toys::DSL::Tool#truncate_load_path!}. This directive
|
|
|
1393
1404
|
removes all directories further down the search path. It can be used, for
|
|
1394
1405
|
example, to disable global tools when you run Toys from the current directory.
|
|
1395
1406
|
It can also be useful if you are using
|
|
1396
|
-
[Bundler integration](#
|
|
1407
|
+
[Bundler integration](#using-bundler-with-a-tool) to prevent bundle conflicts
|
|
1397
1408
|
with parent directories, by disabling tools from parent directories.
|
|
1398
1409
|
|
|
1399
1410
|
The `truncate_load_path!` directive works only if no tools from further down
|
|
@@ -1402,11 +1413,216 @@ if it fails to truncate the load path. In most cases, Toys is very smart about
|
|
|
1402
1413
|
loading tools only when needed, but there are exceptions. To minimize the
|
|
1403
1414
|
chance of problems, if you need to use `truncate_load_path!`, locate it as
|
|
1404
1415
|
early as possible in your Toys files, typically at the top of the
|
|
1405
|
-
[index file](#
|
|
1416
|
+
[index file](#index-files).
|
|
1417
|
+
|
|
1418
|
+
### Sharing tool definitions
|
|
1419
|
+
|
|
1420
|
+
It is a common practice to "share" tools across projects, that is, to implement
|
|
1421
|
+
tools in a central place and reference them from potentially multiple toys
|
|
1422
|
+
files. You can do this by "loading" remote tools from a toys file. You can load
|
|
1423
|
+
tools from a file path on your local file system, from a git repository, or
|
|
1424
|
+
even from a Ruby gem.
|
|
1425
|
+
|
|
1426
|
+
#### Loading from the file system
|
|
1427
|
+
|
|
1428
|
+
To load a tool from the file system, use the `load` directive, providing a path
|
|
1429
|
+
to a file or directory. This will behave as though the file or directory's
|
|
1430
|
+
contents were inserted in the current location.
|
|
1431
|
+
|
|
1432
|
+
As an example, if you had a shared file `/var/share/mytools.rb` as follows:
|
|
1433
|
+
|
|
1434
|
+
# /var/share/mytools.rb
|
|
1435
|
+
tool "foo" do
|
|
1436
|
+
def run
|
|
1437
|
+
puts "Running foo"
|
|
1438
|
+
end
|
|
1439
|
+
end
|
|
1440
|
+
tool "bar" do
|
|
1441
|
+
def run
|
|
1442
|
+
puts "Running bar"
|
|
1443
|
+
end
|
|
1444
|
+
end
|
|
1445
|
+
|
|
1446
|
+
You could instantiate it in your toys file as follows:
|
|
1447
|
+
|
|
1448
|
+
# .toys.rb
|
|
1449
|
+
load "/var/share/mytools.rb"
|
|
1450
|
+
|
|
1451
|
+
This has the effect of copying the _contents_ of `mytools.rb` into where it is
|
|
1452
|
+
being referenced. In this case, it defines the two tools "foo" and "bar" at the
|
|
1453
|
+
top level of your toys file.
|
|
1454
|
+
|
|
1455
|
+
Note that when you load a file, the name of the file does not define a tool or
|
|
1456
|
+
a tool namespace. In the above case, the tools "foo" and "bar" are defined,
|
|
1457
|
+
_not_ "mytools foo" or "mytools bar". Avoid the common mistake of referencing a
|
|
1458
|
+
file that defines at the top level and not loading it inside a tool. For
|
|
1459
|
+
example, consider a shared file `/var/share/single-tool.rb`:
|
|
1460
|
+
|
|
1461
|
+
# /var/share/single-tool.rb
|
|
1462
|
+
desc "This file defines a tool at the top level"
|
|
1463
|
+
def run
|
|
1464
|
+
puts "Running the top level of single-tool.rb"
|
|
1465
|
+
end
|
|
1466
|
+
|
|
1467
|
+
If you load it like follows:
|
|
1468
|
+
|
|
1469
|
+
# .toys.rb
|
|
1470
|
+
load "/var/share/single-tool.rb"
|
|
1471
|
+
|
|
1472
|
+
You will define the run method of the _root tool_. Instead, what you probably
|
|
1473
|
+
want is:
|
|
1474
|
+
|
|
1475
|
+
# .toys.rb
|
|
1476
|
+
tool "my-single-tool" do
|
|
1477
|
+
load "/var/share/single-tool.rb"
|
|
1478
|
+
end
|
|
1479
|
+
|
|
1480
|
+
Equivalently, you can say:
|
|
1481
|
+
|
|
1482
|
+
# .toys.rb
|
|
1483
|
+
load "/var/share/single-tool.rb", as: "my-single-tool"
|
|
1484
|
+
|
|
1485
|
+
You can also use the `load` directive to load an entire directory. Again, this
|
|
1486
|
+
will be have as though the directory's contents are inserted at the load point.
|
|
1487
|
+
The contents of any `.toys.rb` index file will be defined at the load point
|
|
1488
|
+
itself, and other files within the directory and subdirectories will be
|
|
1489
|
+
namespaced accordingly.
|
|
1490
|
+
|
|
1491
|
+
As an example, consider this shared directory:
|
|
1492
|
+
|
|
1493
|
+
/var/share/mytools
|
|
1494
|
+
|
|
|
1495
|
+
+- .toys.rb
|
|
1496
|
+
|
|
|
1497
|
+
+- greet.rb
|
|
1498
|
+
|
|
1499
|
+
Here's the contents of `.toys.rb` above:
|
|
1500
|
+
|
|
1501
|
+
# /var/share/mytools/.toys.rb
|
|
1502
|
+
tool "foo" do
|
|
1503
|
+
def run
|
|
1504
|
+
puts "Running foo"
|
|
1505
|
+
end
|
|
1506
|
+
end
|
|
1507
|
+
|
|
1508
|
+
Here's the contents of `greet.rb`:
|
|
1509
|
+
|
|
1510
|
+
# /var/share/mytools/greet.rb
|
|
1511
|
+
optional_arg :whom, default: "world"
|
|
1512
|
+
def run
|
|
1513
|
+
puts "Hello, #{whom}"
|
|
1514
|
+
end
|
|
1515
|
+
|
|
1516
|
+
You can then define the tools "foo" and "greet" by loading this directory:
|
|
1517
|
+
|
|
1518
|
+
# .toys.rb
|
|
1519
|
+
load "/var/share/mytools"
|
|
1520
|
+
|
|
1521
|
+
#### Loading from a git repository
|
|
1522
|
+
|
|
1523
|
+
You can also load tools over a network using git, by defining the tools in a
|
|
1524
|
+
git repository (e.g. on GitHub) and referencing it via the `load_git`
|
|
1525
|
+
directive. This is a simple way to distribute tools across an organization or
|
|
1526
|
+
over the internet.
|
|
1527
|
+
|
|
1528
|
+
The `load_git` directive takes a repository URL, and optionally a path within
|
|
1529
|
+
the repository and a commit. If you do not specify the path, the entire
|
|
1530
|
+
repository is loaded as if you were loading a directory. (See the discussion
|
|
1531
|
+
above on loading from the file system.) Otherwise, if you specify a path, it
|
|
1532
|
+
should be a file or a directory within the repository. A commit can be a SHA,
|
|
1533
|
+
a branch, or a tag. If it is omitted, the default HEAD of the repository is
|
|
1534
|
+
used.
|
|
1535
|
+
|
|
1536
|
+
As an example, suppose you have a repository `https://github.com/dazuma/example`
|
|
1537
|
+
(not a real repo...), with the file `greet.rb` at the top level. You can then
|
|
1538
|
+
reference that tool as follows:
|
|
1539
|
+
|
|
1540
|
+
# .toys.rb
|
|
1541
|
+
load_git remote: "https://github.com/dazuma/example",
|
|
1542
|
+
path: "greet.rb",
|
|
1543
|
+
as: "greet"
|
|
1544
|
+
|
|
1545
|
+
As discussed earlier, if you are loading a file that includes definitions at
|
|
1546
|
+
the top level, make sure you load it inside a tool, or use the `as:` parameter.
|
|
1547
|
+
|
|
1548
|
+
The `load_git` directive uses the Git Cache to download and reference files in
|
|
1549
|
+
git repositories. This means if you omit the commit or set it to a reference
|
|
1550
|
+
that can float such as a branch or HEAD, it is possible you might get a stale
|
|
1551
|
+
commit, if the repository was previously pulled into the cache, and then
|
|
1552
|
+
additional commits were subsequently pushed to the remote repo. To ensure you
|
|
1553
|
+
get the latest data from `load_git`, you can set the `update:` parameter. If
|
|
1554
|
+
set to true, this forces the cache to refresh (i.e. git pull). You can also set
|
|
1555
|
+
it to an integer, representing a cache lifetime in seconds; the cache will
|
|
1556
|
+
refresh only if it has been at least that long since the last refresh.
|
|
1406
1557
|
|
|
1407
|
-
|
|
1558
|
+
# .toys.rb
|
|
1559
|
+
load_git remote: "https://github.com/dazuma/example",
|
|
1560
|
+
path: "greet.rb",
|
|
1561
|
+
as: "greet",
|
|
1562
|
+
update: 3600 # Pull the latest HEAD if the cache is an hour old
|
|
1408
1563
|
|
|
1409
|
-
|
|
1564
|
+
#### Loading from a Ruby gem
|
|
1565
|
+
|
|
1566
|
+
Finally, you can define and distribute tools in a Ruby gem, and load them from
|
|
1567
|
+
the gem. This can be more involved as it requires creating and publishing a
|
|
1568
|
+
gem, but it is useful for versioning and public distribution of tools.
|
|
1569
|
+
|
|
1570
|
+
A Ruby gem is basically just a zip file with some metadata. By convention, it
|
|
1571
|
+
contains Ruby classes (usually in a top level `lib` directory), and sometimes
|
|
1572
|
+
executables (often in a top level `bin` directory), and sometimes a few
|
|
1573
|
+
documentation files. However, it's just a zip file and you can put anything in
|
|
1574
|
+
it, including toys files.
|
|
1575
|
+
|
|
1576
|
+
By convention, toys tools live in the top level `toys` directory in a gem. For
|
|
1577
|
+
example, you could publish a gem called "my-tools" and include `toys/greet.rb`.
|
|
1578
|
+
Then, to reference the tool:
|
|
1579
|
+
|
|
1580
|
+
# .toys.rb
|
|
1581
|
+
load_gem "my-tools"
|
|
1582
|
+
|
|
1583
|
+
This will define the tool "greet". In the process, it will ensure the gem is
|
|
1584
|
+
installed and loaded (prompting you to confirm the install from rubygems.org if
|
|
1585
|
+
necessary).
|
|
1586
|
+
|
|
1587
|
+
You can specify gem version requirements by providing the `version:` parameter.
|
|
1588
|
+
For example:
|
|
1589
|
+
|
|
1590
|
+
# .toys.rb
|
|
1591
|
+
load_gem "my-tools", version: ["~> 1.5", ">= 1.5.2"]
|
|
1592
|
+
|
|
1593
|
+
It takes version requirements in the format used by Rubygems and Bundler. You
|
|
1594
|
+
can pass a single requirement, multiple requirements as an array, or none.
|
|
1595
|
+
|
|
1596
|
+
You can also specify a subpath within the gem to load. The subpath is relative
|
|
1597
|
+
to the "toys" root directory in the gem. For example:
|
|
1598
|
+
|
|
1599
|
+
# .toys.rb
|
|
1600
|
+
load_gem "my-tools", path: "greet.rb", as: "greet"
|
|
1601
|
+
|
|
1602
|
+
As before, if you are loading a file that includes definitions at the top
|
|
1603
|
+
level, make sure you load it inside a tool, or use the `as:` parameter.
|
|
1604
|
+
|
|
1605
|
+
By default, `load_gem` looks inside the `toys` top level directory of a gem.
|
|
1606
|
+
Although this is not recommended, if you need to change this default, you can
|
|
1607
|
+
set the gem's `"toys_dir"` metadata to a different directory name. If this
|
|
1608
|
+
metadata is set, `load_gem` will use it as the toys top level directory for
|
|
1609
|
+
that gem.
|
|
1610
|
+
|
|
1611
|
+
Additionally, you can pass a top level directory name in the `load_gem`
|
|
1612
|
+
directive itself. This can be useful if a gem has multiple toys directories:
|
|
1613
|
+
|
|
1614
|
+
# .toys.rb
|
|
1615
|
+
load_gem "my-tools", toys_dir: "uncommon-tools"
|
|
1616
|
+
|
|
1617
|
+
#### Publishing a tools Ruby gem
|
|
1618
|
+
|
|
1619
|
+
Publishing a Ruby gem that includes tools is as simple as publishing a gem with
|
|
1620
|
+
the tool files in an extra `toys` directory.
|
|
1621
|
+
|
|
1622
|
+
Another benefit of distributing tools via Ruby gem is that the gem's library
|
|
1623
|
+
files can be used in the tools' implementations. When `load_gem` is run, the
|
|
1624
|
+
gem is activated so its library directory is made available in the require
|
|
1625
|
+
path. This may be simpler than using `.lib` directories as described later.
|
|
1410
1626
|
|
|
1411
1627
|
## The execution environment
|
|
1412
1628
|
|
|
@@ -1465,7 +1681,7 @@ integer context value that you can retrieve using the `VERBOSITY` context key
|
|
|
1465
1681
|
or {Toys::Context#verbosity}. The verbosity is set to 0 by default. This
|
|
1466
1682
|
corresponds to a logger level of `WARN`. That is, warnings, errors, and fatals
|
|
1467
1683
|
are displayed, while infos and debugs are not. However,
|
|
1468
|
-
[as we saw earlier](#
|
|
1684
|
+
[as we saw earlier](#standard-flags), most tools automatically respond to the
|
|
1469
1685
|
`--verbose` and `--quiet` flags, (or `-v` and `-q`), which increment and
|
|
1470
1686
|
decrement the verbosity value, respectively. If you pass `-v` to a tool, the
|
|
1471
1687
|
verbosity is incremented to 1, and the logger level is set to `INFO`. If you
|
|
@@ -1491,14 +1707,14 @@ execute, and return a process status code (i.e. 0 for success, and nonzero for
|
|
|
1491
1707
|
error). Make sure you handle the exit status. For example, in most cases, you
|
|
1492
1708
|
should probably exit if the tool you are calling returns a nonzero code.
|
|
1493
1709
|
|
|
1494
|
-
You can also use the `exec` mixin [described below](#
|
|
1710
|
+
You can also use the `exec` mixin [described below](#executing-subprocesses) to
|
|
1495
1711
|
run a tool in a separate process. This is particularly useful if you need to
|
|
1496
1712
|
capture or manipulate that tool's input or output stream.
|
|
1497
1713
|
|
|
1498
1714
|
### Helper methods and mixins
|
|
1499
1715
|
|
|
1500
1716
|
The methods of {Toys::Context} are not the only methods available for your tool
|
|
1501
|
-
to call. We [saw earlier](#
|
|
1717
|
+
to call. We [saw earlier](#tool-execution-basics) that a tool can define
|
|
1502
1718
|
additional methods that you can use as helpers.
|
|
1503
1719
|
|
|
1504
1720
|
You can also include **mixins**, which are modules that bring in a whole set of
|
|
@@ -1522,7 +1738,7 @@ For details on the built-in mixins provided by Toys, see the modules under
|
|
|
1522
1738
|
mixins below. Built-in mixins have names that are symbols.
|
|
1523
1739
|
|
|
1524
1740
|
You can also define your own mixins, as we will see in the
|
|
1525
|
-
[upcoming section on defining mixins](#
|
|
1741
|
+
[upcoming section on defining mixins](#defining-mixins).
|
|
1526
1742
|
|
|
1527
1743
|
### Executing subprocesses
|
|
1528
1744
|
|
|
@@ -1582,7 +1798,7 @@ underlying library {Toys::Utils::Pager}.
|
|
|
1582
1798
|
|
|
1583
1799
|
You can also use other third-party gems such as
|
|
1584
1800
|
[tty](https://github.com/piotrmurach/tty). The section below on
|
|
1585
|
-
[useful gems](#
|
|
1801
|
+
[useful gems](#useful-gems) provides some examples.
|
|
1586
1802
|
|
|
1587
1803
|
### Standard base directories
|
|
1588
1804
|
|
|
@@ -1621,7 +1837,7 @@ classes, and constants, that you might define in your tools.
|
|
|
1621
1837
|
|
|
1622
1838
|
### Defining mixins
|
|
1623
1839
|
|
|
1624
|
-
We [saw earlier](#
|
|
1840
|
+
We [saw earlier](#helper-methods-and-mixins) that you can mix a module (with
|
|
1625
1841
|
all its methods) into your tool using the `include` directive. You can specify
|
|
1626
1842
|
a module itself, or the name of a built-in mixin such as `:exec` or
|
|
1627
1843
|
`:terminal`. But you can also define your own mixin using the `mixin`
|
|
@@ -1636,7 +1852,7 @@ includes the mixin, in the same way that you can include a Ruby module.
|
|
|
1636
1852
|
|
|
1637
1853
|
(Note that, unlike full modules, mixins allow only methods to be shared. Mixins
|
|
1638
1854
|
do not support constants. See the next section on
|
|
1639
|
-
[using constants](#
|
|
1855
|
+
[using constants](#using-constants) to learn how Toys handles constants.)
|
|
1640
1856
|
|
|
1641
1857
|
Here's an example. Suppose you had common setup code that you wanted to share
|
|
1642
1858
|
among your testing tools.
|
|
@@ -1675,7 +1891,7 @@ descendant tools defined in that same directory, but not in a different `.toys`
|
|
|
1675
1891
|
directory.
|
|
1676
1892
|
|
|
1677
1893
|
A common technique, for example, would be to define a mixin in the
|
|
1678
|
-
[index file](#
|
|
1894
|
+
[index file](#index-files) in a Toys directory. You can then include it from
|
|
1679
1895
|
any subtools defined in other files in that same directory.
|
|
1680
1896
|
|
|
1681
1897
|
#### Mixin initializers
|
|
@@ -1855,7 +2071,7 @@ development, including templates that generate build, test, and documentation
|
|
|
1855
2071
|
tools. The `:minitest` template illustrated above is one of these built-in
|
|
1856
2072
|
templates. Like built-in mixins, built-in template names are always symbols.
|
|
1857
2073
|
You can read more about them in the next section on using
|
|
1858
|
-
[Toys as a Rake replacement](#
|
|
2074
|
+
[Toys as a Rake replacement](#toys-as-a-rake-replacement).
|
|
1859
2075
|
|
|
1860
2076
|
You can also write your own templates. Here's how...
|
|
1861
2077
|
|
|
@@ -1968,8 +2184,12 @@ For more complicated tools, you might want to write normal Ruby modules and
|
|
|
1968
2184
|
classes as helpers. Toys provides a way to write Ruby code outside of its DSL
|
|
1969
2185
|
and `require` the code from your tool, using `.lib` directories.
|
|
1970
2186
|
|
|
2187
|
+
Note: If you are writing tools for distribution in a Ruby gem as described
|
|
2188
|
+
[earlier](#publishing-a-tools-ruby-gem), consider simply defining your Ruby
|
|
2189
|
+
modules and classes in the gem's lib directory instead of using this mechanism.
|
|
2190
|
+
|
|
1971
2191
|
To use `.lib` directories, you must define your tools inside a
|
|
1972
|
-
[Toys directory](#
|
|
2192
|
+
[Toys directory](#toys-directories). When a tool is executed, it looks for
|
|
1973
2193
|
directories called `.lib` in the Toys directory, and adds them to the Ruby load
|
|
1974
2194
|
path. Your tool can thus call `require` to load helpers from any Ruby files in
|
|
1975
2195
|
a `.lib` directory.
|
|
@@ -2060,7 +2280,7 @@ classes, modules, and other code. But preloaded files *automatically* loaded
|
|
|
2060
2280
|
(i.e. you do not `require` them explicitly) *before* your tools are defined.
|
|
2061
2281
|
|
|
2062
2282
|
To use preloaded files, you must define your tools inside a
|
|
2063
|
-
[Toys directory](#
|
|
2283
|
+
[Toys directory](#toys-directories). Before any tools inside a directory are
|
|
2064
2284
|
loaded, any file named `.preload.rb` in the directory is automatically
|
|
2065
2285
|
required. Next, any Ruby files inside a subdirectory called `.preload` are also
|
|
2066
2286
|
automatically required.
|
|
@@ -2116,7 +2336,7 @@ tests, and a set of helpers that make it easy to test tools and parts of tools.
|
|
|
2116
2336
|
|
|
2117
2337
|
Toys integrates with [Minitest](https://github.com/seattlerb/minitest) to
|
|
2118
2338
|
provide a testing framework for your tools. To write tests, you must define
|
|
2119
|
-
your tools inside a [Toys directory](#
|
|
2339
|
+
your tools inside a [Toys directory](#toys-directories). Create a directory
|
|
2120
2340
|
called `.test` inside that directory. You can then write Minitest tests in
|
|
2121
2341
|
files within that directory with names matching `test_*.rb`. You can also
|
|
2122
2342
|
provide other files that do not match that name pattern, as fixture data or
|
|
@@ -2482,7 +2702,7 @@ flexible tool than Rake, and it covers two cases that are not well served by
|
|
|
2482
2702
|
|
|
2483
2703
|
First, Toys lets you define *global tools* that are defined in your home
|
|
2484
2704
|
directory or system config directory. (See the previous section on
|
|
2485
|
-
[the Toys search path](#
|
|
2705
|
+
[the Toys search path](#the-toys-search-path).) These tools are global, and can
|
|
2486
2706
|
be called from anywhere. But if they have gem dependencies, it might not be
|
|
2487
2707
|
feasible for their Gemfiles to be present in every directory from which you
|
|
2488
2708
|
might want to run them.
|
|
@@ -2520,7 +2740,7 @@ Simply `include :bundler` in your tool definition:
|
|
|
2520
2740
|
end
|
|
2521
2741
|
|
|
2522
2742
|
When the `:bundler` mixin is included in a tool, it installs a
|
|
2523
|
-
[mixin initializer](#
|
|
2743
|
+
[mixin initializer](#mixin-initializers) that calls `Bundler.setup` when the
|
|
2524
2744
|
tool is *executed*. This assumes the bundle is already installed, and brings
|
|
2525
2745
|
the appropriate gems into the Ruby load path. That is, it's basically the same
|
|
2526
2746
|
as `bundle exec`, but it applies only to the running tool.
|
|
@@ -2548,14 +2768,14 @@ your tools. For example:
|
|
|
2548
2768
|
end
|
|
2549
2769
|
|
|
2550
2770
|
See the section on
|
|
2551
|
-
[applying directives to multiple tools](#
|
|
2771
|
+
[applying directives to multiple tools](#applying-directives-to-multiple-tools)
|
|
2552
2772
|
for more information on `subtool_apply`.
|
|
2553
2773
|
|
|
2554
2774
|
#### Bundler options
|
|
2555
2775
|
|
|
2556
2776
|
By default, the `:bundler` mixin will look for a `Gemfile` within the `.toys`
|
|
2557
2777
|
directory (if your tool is defined in one), and if one is not found there,
|
|
2558
|
-
within the [context directory](#
|
|
2778
|
+
within the [context directory](#the-context-directory) (the directory
|
|
2559
2779
|
containing your `.toys` directory or `.toys.rb` file), and if one still is not
|
|
2560
2780
|
found, in the current working directory. You can change this behavior by
|
|
2561
2781
|
passing an option to the `:bundler` mixin. For example, you can search only the
|
|
@@ -2651,7 +2871,7 @@ tools:
|
|
|
2651
2871
|
There is a big caveat to using `static: true`, which is that you are setting up
|
|
2652
2872
|
a bundle immediately, and as a result any subsequent attempt to set up or use a
|
|
2653
2873
|
different bundle will fail. (See the section on
|
|
2654
|
-
[bundle conflicts](#
|
|
2874
|
+
[bundle conflicts](#solving-bundle-conflicts) for a discussion of other reasons
|
|
2655
2875
|
this can happen.) As a result, it's best not to use `static: true` unless you
|
|
2656
2876
|
*really* need it to define tools. If you do run into this problem, here are two
|
|
2657
2877
|
things you could try:
|
|
@@ -2664,7 +2884,7 @@ things you could try:
|
|
|
2664
2884
|
2. Failing that, if you need a particular gem in order to define a tool, you
|
|
2665
2885
|
could consider activating the gem directly rather than as part of a bundle.
|
|
2666
2886
|
See the following section on
|
|
2667
|
-
[Activating gems directly](#
|
|
2887
|
+
[Activating gems directly](#activating-gems-directly) for details on this
|
|
2668
2888
|
technique.
|
|
2669
2889
|
|
|
2670
2890
|
### Activating gems directly
|
|
@@ -3573,7 +3793,7 @@ like we did with the test tool above.
|
|
|
3573
3793
|
|
|
3574
3794
|
If you need to access information from enclosing scopes, consider instead
|
|
3575
3795
|
setting options using the {Toys::DSL::Tool#static} directive, as illustrated
|
|
3576
|
-
earlier when we discussed [defining templates](#
|
|
3796
|
+
earlier when we discussed [defining templates](#defining-templates).
|
|
3577
3797
|
|
|
3578
3798
|
tool "def-time" do
|
|
3579
3799
|
# Grab the time during tool definition and set it as a static option.
|
|
@@ -3592,7 +3812,7 @@ provides a convenient place to put data files that can be looked up by tools
|
|
|
3592
3812
|
either during definition or runtime.
|
|
3593
3813
|
|
|
3594
3814
|
To use data files, you must define your tools inside a
|
|
3595
|
-
[Toys directory](#
|
|
3815
|
+
[Toys directory](#toys-directories). Within the Toys directory, create a
|
|
3596
3816
|
directory named `.data` and copy your data files there.
|
|
3597
3817
|
|
|
3598
3818
|
You mcanay then "find" a data file by providing the relative path to the file from
|
|
@@ -3747,7 +3967,7 @@ the entire toys directory structure. So if your tool definition is inside a
|
|
|
3747
3967
|
|
|
3748
3968
|
This technique is particularly useful for build tools. Indeed, all the build
|
|
3749
3969
|
tools described in the section on
|
|
3750
|
-
[Toys as a Rake Replacement](#
|
|
3970
|
+
[Toys as a Rake Replacement](#toys-as-a-rake-replacement) automatically move
|
|
3751
3971
|
into the context directory when they execute.
|
|
3752
3972
|
|
|
3753
3973
|
#### Changing the context directory
|
data/lib/toys/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: toys
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.17.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Daniel Azuma
|
|
@@ -15,14 +15,14 @@ dependencies:
|
|
|
15
15
|
requirements:
|
|
16
16
|
- - '='
|
|
17
17
|
- !ruby/object:Gem::Version
|
|
18
|
-
version: 0.
|
|
18
|
+
version: 0.17.0
|
|
19
19
|
type: :runtime
|
|
20
20
|
prerelease: false
|
|
21
21
|
version_requirements: !ruby/object:Gem::Requirement
|
|
22
22
|
requirements:
|
|
23
23
|
- - '='
|
|
24
24
|
- !ruby/object:Gem::Version
|
|
25
|
-
version: 0.
|
|
25
|
+
version: 0.17.0
|
|
26
26
|
description: Toys is a configurable command line tool. Write commands in Ruby using
|
|
27
27
|
a simple DSL, and Toys will provide the command line executable and take care of
|
|
28
28
|
all the details such as argument parsing, online help, and error reporting. Toys
|
|
@@ -68,10 +68,10 @@ homepage: https://github.com/dazuma/toys
|
|
|
68
68
|
licenses:
|
|
69
69
|
- MIT
|
|
70
70
|
metadata:
|
|
71
|
-
changelog_uri: https://dazuma.github.io/toys/gems/toys/v0.
|
|
71
|
+
changelog_uri: https://dazuma.github.io/toys/gems/toys/v0.17.0/file.CHANGELOG.html
|
|
72
72
|
source_code_uri: https://github.com/dazuma/toys/tree/main/toys
|
|
73
73
|
bug_tracker_uri: https://github.com/dazuma/toys/issues
|
|
74
|
-
documentation_uri: https://dazuma.github.io/toys/gems/toys/v0.
|
|
74
|
+
documentation_uri: https://dazuma.github.io/toys/gems/toys/v0.17.0
|
|
75
75
|
rdoc_options: []
|
|
76
76
|
require_paths:
|
|
77
77
|
- lib
|