toys 0.13.1 → 0.14.2
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 +37 -0
- data/README.md +18 -17
- data/builtins/system/.toys.rb +40 -0
- data/builtins/system/git-cache.rb +15 -10
- data/builtins/system/test.rb +2 -3
- data/builtins/system/tools.rb +145 -0
- data/core-docs/toys/acceptor.rb +50 -8
- data/core-docs/toys/cli.rb +3 -3
- data/core-docs/toys/completion.rb +11 -0
- data/core-docs/toys/context.rb +16 -2
- data/core-docs/toys/core.rb +1 -1
- data/core-docs/toys/dsl/tool.rb +15 -7
- data/core-docs/toys/errors.rb +33 -0
- data/core-docs/toys/flag.rb +11 -0
- data/core-docs/toys/input_file.rb +6 -0
- data/core-docs/toys/loader.rb +146 -5
- data/core-docs/toys/middleware.rb +42 -2
- data/core-docs/toys/settings.rb +17 -0
- data/core-docs/toys/source_info.rb +95 -0
- data/core-docs/toys/standard_mixins/exec.rb +69 -22
- data/core-docs/toys/standard_mixins/pager.rb +46 -0
- data/core-docs/toys/standard_mixins/xdg.rb +7 -7
- data/core-docs/toys/tool_definition.rb +69 -0
- data/core-docs/toys/utils/exec.rb +61 -27
- data/core-docs/toys/utils/pager.rb +104 -0
- data/core-docs/toys/wrappable_string.rb +12 -0
- data/docs/guide.md +92 -67
- data/lib/toys/testing.rb +33 -2
- data/lib/toys/version.rb +1 -1
- metadata +10 -6
data/docs/guide.md
CHANGED
@@ -36,18 +36,18 @@ Toys is a command line *framework*. It provides an executable called `toys`
|
|
36
36
|
with basic functions such as argument parsing and online help. You provide the
|
37
37
|
actual behavior of the Toys executable by writing **Toys files**.
|
38
38
|
|
39
|
-
Toys is a *multi-command* executable. You
|
39
|
+
Toys is a *multi-command* executable. You can define any number of commands,
|
40
40
|
called **tools**, which can be invoked by passing the tool name as an argument
|
41
|
-
to the `toys` executable. Tools are arranged in a hierarchy; you
|
41
|
+
to the `toys` executable. Tools are arranged in a hierarchy; you can define
|
42
42
|
**namespaces** that have **subtools**.
|
43
43
|
|
44
|
-
Tools
|
44
|
+
Tools can recognize command line arguments in the form of **flags** and
|
45
45
|
**positional arguments**. Flags can optionally take **values**, while
|
46
|
-
positional arguments
|
46
|
+
positional arguments can be **required** or **optional**. Flags can be
|
47
47
|
organized into **flag groups** that support marking flags or flag combinations
|
48
48
|
as required.
|
49
49
|
|
50
|
-
The configuration of a tool
|
50
|
+
The configuration of a tool can include **descriptions**, for the tool itself,
|
51
51
|
and for each command line argument. These descriptions are displayed in the
|
52
52
|
tool's **online help** screen. Descriptions come in **long** and **short**
|
53
53
|
forms, which appear in different styles of help.
|
@@ -88,7 +88,7 @@ For example, in the following command:
|
|
88
88
|
|----TOOL----|
|
89
89
|
$ toys system version
|
90
90
|
|
91
|
-
The tool name is `system version`. Notice that the tool name
|
91
|
+
The tool name is `system version`. Notice that the tool name can have multiple
|
92
92
|
words. Tools are arranged hierarchically. In this case, `system` is a
|
93
93
|
**namespace** for tools related to the Toys system, and `version` is one of its
|
94
94
|
**subtools**. It prints the current Toys version.
|
@@ -210,10 +210,10 @@ them.) These standard flags include:
|
|
210
210
|
* `--usage` which displays a shorter usage screen for the tool.
|
211
211
|
* `--verbose` (also `-v`) which increases the verbosity. This affects the
|
212
212
|
tool's logging display, increasing the number of log levels shown. This
|
213
|
-
flag
|
213
|
+
flag can be issued multiple times.
|
214
214
|
* `--quiet` (also `-q`) which decreases the verbosity. This affects the
|
215
215
|
tool's logging display, decreasing the number of log levels shown. This
|
216
|
-
flag
|
216
|
+
flag can also be issued multiple times.
|
217
217
|
|
218
218
|
Namespace tools (tools that have subtools but no explicit functionality of
|
219
219
|
their own) always behave as though `--help` is invoked. (They do recognize the
|
@@ -236,7 +236,7 @@ Finally, the root tool also supports:
|
|
236
236
|
### Positional arguments
|
237
237
|
|
238
238
|
Any arguments not recognized as flags or flag arguments, are interpreted as
|
239
|
-
**positional arguments**. Positional arguments are recognized in order and
|
239
|
+
**positional arguments**. Positional arguments are recognized in order and can
|
240
240
|
be required or optional.
|
241
241
|
|
242
242
|
Each tool recognizes a specific set of positional arguments. If you do not pass
|
@@ -337,7 +337,7 @@ Let's start with an example:
|
|
337
337
|
|
338
338
|
tool "greet" do
|
339
339
|
desc "Print a friendly greeting."
|
340
|
-
long_desc "Prints a friendly greeting. You
|
340
|
+
long_desc "Prints a friendly greeting. You can customize whom to" \
|
341
341
|
" greet, and how friendly it should be.",
|
342
342
|
"",
|
343
343
|
"Example:",
|
@@ -357,12 +357,12 @@ Its results should be mostly self-evident. But let's unpack a few details.
|
|
357
357
|
|
358
358
|
### Tool descriptions
|
359
359
|
|
360
|
-
Each tool
|
360
|
+
Each tool can have a **short description** and/or a **long description**. The
|
361
361
|
short description is a generally a single string that is displayed with the
|
362
362
|
tool name, at the top of its help page or in a subtool list. The long
|
363
363
|
description generally includes multiple strings, which are displayed in
|
364
364
|
multiple lines in the "description" section of the tool's help page. Long
|
365
|
-
descriptions
|
365
|
+
descriptions can include blank lines to separate paragraphs visually.
|
366
366
|
|
367
367
|
By default, each description string/line is word-wrapped when displayed. In the
|
368
368
|
long description example above, the first line is a bit longer than 80
|
@@ -379,9 +379,9 @@ and {Toys::DSL::Tool#long_desc}.
|
|
379
379
|
|
380
380
|
### Positional arguments
|
381
381
|
|
382
|
-
Tools
|
382
|
+
Tools can recognize any number of **positional arguments**. Each argument must
|
383
383
|
have a name, which is a key that the tool can use to obtain the argument's
|
384
|
-
value at execution time. Arguments
|
384
|
+
value at execution time. Arguments can also have various properties controlling
|
385
385
|
how values are validated and expressed.
|
386
386
|
|
387
387
|
The above example uses the directive {Toys::DSL::Tool#optional_arg} to declare
|
@@ -404,8 +404,8 @@ can use to retrieve the value. In the above example, we retrieve the value for
|
|
404
404
|
the option `:whom` by calling the method `whom`. If the option name cannot be
|
405
405
|
made into a method, you can retrieve the value by calling {Toys::Context#get}.
|
406
406
|
|
407
|
-
An argument
|
408
|
-
command line; otherwise the tool will report a usage error. You
|
407
|
+
An argument can also be **required**, which means it must be provided on the
|
408
|
+
command line; otherwise the tool will report a usage error. You can declare a
|
409
409
|
required argument using the directive {Toys::DSL::Tool#required_arg}.
|
410
410
|
|
411
411
|
#### Parsing required and optional arguments
|
@@ -449,7 +449,7 @@ Will produce a usage error, because no value is set for the required argument
|
|
449
449
|
Will also produce an error, since the tool does not define an argument to
|
450
450
|
match `"baz"`.
|
451
451
|
|
452
|
-
Optional arguments
|
452
|
+
Optional arguments can declare a default value to be used if the argument is
|
453
453
|
not provided on the command line. For example:
|
454
454
|
|
455
455
|
tool "args-demo" do
|
@@ -499,7 +499,7 @@ most only one `remaining_args` directive.
|
|
499
499
|
|
500
500
|
#### Descriptions and the args DSL
|
501
501
|
|
502
|
-
Positional arguments
|
502
|
+
Positional arguments can also have short and long descriptions, which are
|
503
503
|
displayed in online help. Set descriptions via the `desc:` and `long_desc:`
|
504
504
|
arguments to the argument directive. The `desc:` argument takes a single string
|
505
505
|
description, while the `long_desc:` argument takes an array of strings. Here is
|
@@ -507,7 +507,7 @@ an example:
|
|
507
507
|
|
508
508
|
required_arg :arg,
|
509
509
|
desc: "This is a short description for the arg",
|
510
|
-
long_desc: ["Long descriptions
|
510
|
+
long_desc: ["Long descriptions can have multiple lines.",
|
511
511
|
"This is the second line."]
|
512
512
|
|
513
513
|
See the [above section on Descriptions](#Tool_descriptions) for more
|
@@ -528,10 +528,10 @@ For detailed info on configuring an argument using a block, see the
|
|
528
528
|
|
529
529
|
#### Argument acceptors
|
530
530
|
|
531
|
-
Finally, positional arguments
|
531
|
+
Finally, positional arguments can use **acceptors** to define how to validate
|
532
532
|
arguments and convert them to Ruby objects for your tool to consume. By
|
533
533
|
default, Toys will accept any argument string, and expose it to your tool as a
|
534
|
-
raw string. However, you
|
534
|
+
raw string. However, you can provide an acceptor to change this behavior.
|
535
535
|
|
536
536
|
Acceptors are part of the OptionParser interface, and are described under the
|
537
537
|
[type coercion](http://ruby-doc.org/stdlib/libdoc/optparse/rdoc/OptionParser.html#class-OptionParser-label-Type+Coercion)
|
@@ -548,13 +548,13 @@ integer during parsing:
|
|
548
548
|
|
549
549
|
If you pass a non-integer for this argument, Toys will report a usage error.
|
550
550
|
|
551
|
-
You
|
551
|
+
You can use any of the ready-to-use coercion types provided by OptionParser,
|
552
552
|
including the special types such as
|
553
553
|
[OptionParser::DecimalInteger](http://ruby-doc.org/stdlib/libdoc/optparse/rdoc/OptionParser.html#DecimalInteger)
|
554
554
|
and
|
555
555
|
[OptionParser::OctalInteger](http://ruby-doc.org/stdlib/libdoc/optparse/rdoc/OptionParser.html#OctalInteger).
|
556
556
|
|
557
|
-
You
|
557
|
+
You can also create **custom acceptors**. See the
|
558
558
|
[section below on Custom Acceptors](#Custom_acceptors) for more information.
|
559
559
|
|
560
560
|
#### Argument completions
|
@@ -583,7 +583,7 @@ argument parsing, whereas completions affect tab completion in the shell.
|
|
583
583
|
|
584
584
|
### Flags
|
585
585
|
|
586
|
-
Tools
|
586
|
+
Tools can also recognize **flags** on the command line. In our "greet" example,
|
587
587
|
we declared a flag named `:shout`:
|
588
588
|
|
589
589
|
flag :shout, "-s", "--shout", desc: "Greet loudly."
|
@@ -592,7 +592,7 @@ Like a positional argument, a flag sets an option based on the command line
|
|
592
592
|
arguments passed to the tool. In the case above, the `:shout` option is set to
|
593
593
|
`true` if either `-s` or `--shout` is provided on the command line; otherwise
|
594
594
|
it remains falsy. The two flags `-s` and `--shout` are effectively synonyms and
|
595
|
-
have the same effect. A flag declaration
|
595
|
+
have the same effect. A flag declaration can include any number of synonyms.
|
596
596
|
|
597
597
|
As with arguments, Toys will provide a method that you can call to retrieve the
|
598
598
|
option value set by a flag. In this case, a method called `shout` will be
|
@@ -738,10 +738,10 @@ Here is the behavior:
|
|
738
738
|
|
739
739
|
#### Flag acceptors
|
740
740
|
|
741
|
-
Flags
|
741
|
+
Flags can use **acceptors** to define how to validate values and convert them
|
742
742
|
to Ruby objects for your tool to consume. By default, Toys will accept a flag
|
743
743
|
value string in any form, and expose it to your tool as a raw string. However,
|
744
|
-
you
|
744
|
+
you can provide an acceptor to change this behavior.
|
745
745
|
|
746
746
|
Acceptors are part of the OptionParser interface, and are described under the
|
747
747
|
[type coercion](http://ruby-doc.org/stdlib/libdoc/optparse/rdoc/OptionParser.html#class-OptionParser-label-Type+Coercion)
|
@@ -758,13 +758,13 @@ integer during parsing:
|
|
758
758
|
|
759
759
|
If you pass a non-integer for this flag value, Toys will report a usage error.
|
760
760
|
|
761
|
-
You
|
761
|
+
You can use any of the ready-to-use coercion types provided by OptionParser,
|
762
762
|
including the special types such as
|
763
763
|
[OptionParser::DecimalInteger](http://ruby-doc.org/stdlib/libdoc/optparse/rdoc/OptionParser.html#DecimalInteger)
|
764
764
|
and
|
765
765
|
[OptionParser::OctalInteger](http://ruby-doc.org/stdlib/libdoc/optparse/rdoc/OptionParser.html#OctalInteger).
|
766
766
|
|
767
|
-
You
|
767
|
+
You can also create **custom acceptors**. See the
|
768
768
|
[section below on Custom Acceptors](#Custom_acceptors) for more information.
|
769
769
|
|
770
770
|
#### Defaults and handlers
|
@@ -773,7 +773,7 @@ Flags are usually optional; a flag can appear in a command line zero, one, or
|
|
773
773
|
any number of times.
|
774
774
|
|
775
775
|
If a flag is not passed in the command line arguments for a tool, by default
|
776
|
-
its corresponding option value will be `nil`. You
|
776
|
+
its corresponding option value will be `nil`. You can change this by providing
|
777
777
|
a default value for a flag:
|
778
778
|
|
779
779
|
flag :age, accept: Integer, default: 21
|
@@ -805,7 +805,7 @@ equivalent to:
|
|
805
805
|
|
806
806
|
The `--verbose` flag, provided automatically by Toys for most tools, shows an
|
807
807
|
example of an alternate handler. Verbosity is represented by an integer value,
|
808
|
-
defaulting to 0. The `--verbose` flag
|
808
|
+
defaulting to 0. The `--verbose` flag can appear any number of times, and
|
809
809
|
*each* appearance increases the verbosity. Its implementation is internal to
|
810
810
|
Toys, but looks something like this:
|
811
811
|
|
@@ -841,14 +841,14 @@ The `:push` handler is equivalent to
|
|
841
841
|
|
842
842
|
#### Descriptions and the flags DSL
|
843
843
|
|
844
|
-
Flags
|
844
|
+
Flags can also have short and long descriptions, which are displayed in online
|
845
845
|
help. Set descriptions via the `desc:` and `long_desc:` arguments to the flag
|
846
846
|
directive. The `desc:` argument takes a single string description, while the
|
847
847
|
`long_desc:` argument takes an array of strings. Here is an example:
|
848
848
|
|
849
849
|
flag :my_flag, "--my-flag",
|
850
850
|
desc: "This is a short description for the arg",
|
851
|
-
long_desc: ["Long descriptions
|
851
|
+
long_desc: ["Long descriptions can have multiple lines.",
|
852
852
|
"This is the second line."]
|
853
853
|
|
854
854
|
See the [above section on Descriptions](#Tool_descriptions) for more information on
|
@@ -894,13 +894,13 @@ option parsing, whereas completions affect tab completion in the shell.
|
|
894
894
|
|
895
895
|
#### Flag groups
|
896
896
|
|
897
|
-
Flags
|
897
|
+
Flags can be organized into groups. This serves two functions:
|
898
898
|
|
899
899
|
* Grouping related flags in the help and usage screens
|
900
900
|
* Implementing required flags and other constraints
|
901
901
|
|
902
902
|
To create a simple flag group, use the `flag_group` directive, and provide a
|
903
|
-
block that defines the group's flags. You
|
903
|
+
block that defines the group's flags. You can also provide a group description
|
904
904
|
that appears in the help screen.
|
905
905
|
|
906
906
|
flag_group desc: "Debug flags" do
|
@@ -908,9 +908,9 @@ that appears in the help screen.
|
|
908
908
|
flag :warnings, "-W[VAL]", desc: "Enable warnings"
|
909
909
|
end
|
910
910
|
|
911
|
-
Flag groups
|
911
|
+
Flag groups can have a "type" that specifies constraints on the flags contained
|
912
912
|
in the group. Flags in a simple group like the above are ordinary optional
|
913
|
-
flags. However, you
|
913
|
+
flags. However, you can specify that flags in the group are required using the
|
914
914
|
`all_required` directive:
|
915
915
|
|
916
916
|
all_required desc: "Login flags (all required)" do
|
@@ -1017,7 +1017,7 @@ a valid method name, you can still get the value by calling
|
|
1017
1017
|
end
|
1018
1018
|
|
1019
1019
|
If a tool's `run` method finishes normally, Toys will exit with a result code
|
1020
|
-
of 0, indicating success. You
|
1020
|
+
of 0, indicating success. You can exit immediately and/or provide a nonzero
|
1021
1021
|
result by calling {Toys::Context#exit}:
|
1022
1022
|
|
1023
1023
|
def run
|
@@ -1029,7 +1029,7 @@ result by calling {Toys::Context#exit}:
|
|
1029
1029
|
If your `run` method raises an exception, Toys will display the exception and
|
1030
1030
|
exit with a nonzero code.
|
1031
1031
|
|
1032
|
-
Finally, you
|
1032
|
+
Finally, you can also define additional methods within the tool. These are
|
1033
1033
|
available to be called by your `run` method, and can be used to decompose your
|
1034
1034
|
tool implementation. Indeed, a tool is actually a class under the hood, and
|
1035
1035
|
you can define methods as with any other class. Here's a contrived example:
|
@@ -1059,7 +1059,7 @@ discussed further below. But first we will cover a few important topics.
|
|
1059
1059
|
|
1060
1060
|
### Namespaces and subtools
|
1061
1061
|
|
1062
|
-
Like many command line frameworks, Toys supports **subtools**. You
|
1062
|
+
Like many command line frameworks, Toys supports **subtools**. You can, for
|
1063
1063
|
example create a tool called "test" that runs your tests for a particular
|
1064
1064
|
project, but you might also want "test unit" and "test integration" tools to
|
1065
1065
|
run specific subsets of the test suite. One way to do this, of course, is for
|
@@ -1483,7 +1483,7 @@ execute, and return a process status code (i.e. 0 for success, and nonzero for
|
|
1483
1483
|
error). Make sure you handle the exit status. For example, in most cases, you
|
1484
1484
|
should probably exit if the tool you are calling returns a nonzero code.
|
1485
1485
|
|
1486
|
-
You
|
1486
|
+
You can also use the `exec` mixin [described below](#Executing_subprocesses) to
|
1487
1487
|
run a tool in a separate process. This is particularly useful if you need to
|
1488
1488
|
capture or manipulate that tool's input or output stream.
|
1489
1489
|
|
@@ -1503,7 +1503,7 @@ helper methods. Include a mixin using the `include` directive:
|
|
1503
1503
|
end
|
1504
1504
|
end
|
1505
1505
|
|
1506
|
-
A mixin
|
1506
|
+
A mixin can be specified by providing a module itself, or by providing a
|
1507
1507
|
**mixin name**. In the above example, we used `:terminal`, which is the name
|
1508
1508
|
of a built-in mixin that Toys provides. Among other things, it defines a
|
1509
1509
|
special `puts` method that lets you include style information such as `:bold`,
|
@@ -1563,10 +1563,16 @@ as styled output and simple spinners. For information, see the
|
|
1563
1563
|
|
1564
1564
|
If you prefer the venerable Highline library interface, Toys provides a mixin
|
1565
1565
|
called `:highline` that automatically installs the highline gem (version 2.x)
|
1566
|
-
if it is not available, and makes a highline object available to the
|
1567
|
-
more information, see the {Toys::StandardMixins::Highline} mixin
|
1566
|
+
if it is not already available, and makes a highline object available to the
|
1567
|
+
tool. For more information, see the {Toys::StandardMixins::Highline} mixin
|
1568
|
+
module.
|
1568
1569
|
|
1569
|
-
|
1570
|
+
The `:pager` mixin provides a convenient interface to pager utilities such as
|
1571
|
+
`less`, which let your users interactively page through long output. For more
|
1572
|
+
information, see the {Toys::StandardMixins::Pager} mixin module and the
|
1573
|
+
underlying library {Toys::Utils::Pager}.
|
1574
|
+
|
1575
|
+
You can also use other third-party gems such as
|
1570
1576
|
[tty](https://github.com/piotrmurach/tty). The section below on
|
1571
1577
|
[useful gems](#Useful_gems) provides some examples.
|
1572
1578
|
|
@@ -1828,7 +1834,7 @@ arguments to the `expand` directive, such as:
|
|
1828
1834
|
|
1829
1835
|
expand :minitest, name: "unit-test", warnings: true
|
1830
1836
|
|
1831
|
-
Alternatively, you
|
1837
|
+
Alternatively, you can provide a block to `expand`. It will yield the template
|
1832
1838
|
to your block, letting you modify its properties:
|
1833
1839
|
|
1834
1840
|
expand :minitest do |t|
|
@@ -1843,7 +1849,7 @@ templates. Like built-in mixins, built-in template names are always symbols.
|
|
1843
1849
|
You can read more about them in the next section on using
|
1844
1850
|
[Toys as a Rake replacement](#Toys_as_a_Rake_replacement).
|
1845
1851
|
|
1846
|
-
You
|
1852
|
+
You can also write your own templates. Here's how...
|
1847
1853
|
|
1848
1854
|
#### Defining templates
|
1849
1855
|
|
@@ -2038,7 +2044,7 @@ by how close they are to the tool being executed. For example:
|
|
2038
2044
|
|
2039
2045
|
### Preloading Ruby files
|
2040
2046
|
|
2041
|
-
You
|
2047
|
+
You can also provide Ruby files that are "preloaded" before tools are defined.
|
2042
2048
|
This is useful if those Ruby files are required by the tool definitions
|
2043
2049
|
themselves. Like files in the `.lib` directory, preloaded files can define Ruby
|
2044
2050
|
classes, modules, and other code. But preloaded files *automatically* loaded
|
@@ -2086,7 +2092,7 @@ Furthermore, Toys will also execute
|
|
2086
2092
|
first before loading any of the tools in the `test` subdirectory. Thus, any
|
2087
2093
|
additional classes needed by `test unit` can be defined in these files.
|
2088
2094
|
|
2089
|
-
Either a single `.preload.rb` file or a `.preload` directory, or both,
|
2095
|
+
Either a single `.preload.rb` file or a `.preload` directory, or both, can be
|
2090
2096
|
used. If both are present in the same directory, the `.preload.rb` file is
|
2091
2097
|
loaded first before the `.preload` directory contents.
|
2092
2098
|
|
@@ -2178,7 +2184,7 @@ takes an optional argument and a `--shout` flag:
|
|
2178
2184
|
# greet.rb
|
2179
2185
|
|
2180
2186
|
desc "Print a friendly greeting."
|
2181
|
-
long_desc "Prints a friendly greeting. You
|
2187
|
+
long_desc "Prints a friendly greeting. You can customize whom to" \
|
2182
2188
|
" greet, and how friendly it should be.",
|
2183
2189
|
"",
|
2184
2190
|
"Example:",
|
@@ -2319,7 +2325,7 @@ individual methods without running the entire tool. This can be useful for
|
|
2319
2325
|
writing unit tests for tools that are large, complex, or otherwise should not
|
2320
2326
|
be executed in their entirety during testing.
|
2321
2327
|
|
2322
|
-
To test individual methods, pass a block to {Toys::Testing#
|
2328
|
+
To test individual methods, pass a block to {Toys::Testing#toys_load_tool}.
|
2323
2329
|
This method loads the tool associated with the given command line, parses the
|
2324
2330
|
command line arguments, and prepares the tool for execution, but does not
|
2325
2331
|
invoke the `run` method. The tool's context is passed to the block, and you can
|
@@ -2804,7 +2810,7 @@ A variety of other useful gems can also be found in
|
|
2804
2810
|
|
2805
2811
|
## Toys as a Rake replacement
|
2806
2812
|
|
2807
|
-
Toys was designed to organize scripts that
|
2813
|
+
Toys was designed to organize scripts that can be "scoped" to a project or
|
2808
2814
|
directory. Rake is also commonly used for this purpose: you can write a
|
2809
2815
|
"Rakefile" that defines rake tasks scoped to a directory. In many cases, Toys
|
2810
2816
|
can be used as a replacement for Rake. Indeed, the Toys repository itself
|
@@ -2906,7 +2912,7 @@ pass an explicit path to it when expanding the template:
|
|
2906
2912
|
# In .toys.rb
|
2907
2913
|
expand :rake, rakefile_path: "path/to/my_rakefile"
|
2908
2914
|
|
2909
|
-
You
|
2915
|
+
You can also choose to pass arguments as named flags rather than command line
|
2910
2916
|
arguments. Set `:use_flags` when expanding the template:
|
2911
2917
|
|
2912
2918
|
# In .toys.rb
|
@@ -2988,7 +2994,7 @@ The `:gem_build` template by default looks for a gemspec file in the current
|
|
2988
2994
|
directory, and builds that gem into a `pkg` directory. You can also build a
|
2989
2995
|
specific gem if you have multiple gemspec files.
|
2990
2996
|
|
2991
|
-
You
|
2997
|
+
You can also configure the template so it also releases the gem to Rubygems
|
2992
2998
|
(using your stored Rubygems credentials), by setting the `push_gem` option.
|
2993
2999
|
For example, here is how to generate a "release" tool that builds and releases
|
2994
3000
|
your gem:
|
@@ -3113,7 +3119,7 @@ regularly.
|
|
3113
3119
|
|
3114
3120
|
### Delegating tools
|
3115
3121
|
|
3116
|
-
A tool
|
3122
|
+
A tool can **delegate** to another tool, which means it uses the other tool's
|
3117
3123
|
flags, arguments, and execution. Effectively, it becomes an "alias"---that is,
|
3118
3124
|
an alternate name---for the target tool.
|
3119
3125
|
|
@@ -3165,6 +3171,10 @@ a namespace to delegate to one of its subtools:
|
|
3165
3171
|
|
3166
3172
|
Now `toys test` delegates to, and thus has the same effect as `toys test unit`.
|
3167
3173
|
|
3174
|
+
It is also possible to specify the delegate via _relative_ name, using the
|
3175
|
+
`:delegate_relative` keyword argument. This can be helpful if you have a set of
|
3176
|
+
tools and delegates that are meant to be reused under different namespaces.
|
3177
|
+
|
3168
3178
|
### Applying directives to multiple tools
|
3169
3179
|
|
3170
3180
|
Sometimes a group of tools are set up similarly or share a set of flags,
|
@@ -3213,27 +3223,27 @@ to use a different configuration:
|
|
3213
3223
|
### Custom acceptors
|
3214
3224
|
|
3215
3225
|
We saw earlier that flags and positional arguments can have acceptors, which
|
3216
|
-
control the allowed format, and
|
3226
|
+
control the allowed format, and can also convert the string argument to a Ruby
|
3217
3227
|
object. By default, Toys supports the same acceptors recognized by Ruby's
|
3218
3228
|
OptionParser library. And like OptionParser, Toys also lets you define your own
|
3219
3229
|
acceptors.
|
3220
3230
|
|
3221
3231
|
Define an acceptor using the `acceptor` directive. You provide a name for the
|
3222
3232
|
acceptor, and specify how to validate input strings and how to convert input
|
3223
|
-
strings to Ruby objects. You
|
3233
|
+
strings to Ruby objects. You can then reference the acceptor in that tool or
|
3224
3234
|
any of its subtools or their subtools, recursively.
|
3225
3235
|
|
3226
3236
|
There are several ways to define an acceptor.
|
3227
3237
|
|
3228
|
-
You
|
3229
|
-
regex to the `acceptor` directive. You
|
3238
|
+
You can validate input strings against a regular expression, by passing the
|
3239
|
+
regex to the `acceptor` directive. You can also optionally provide a block to
|
3230
3240
|
convert input strings to objects (or omit the block to use the original string
|
3231
3241
|
as the option value.) For example, a simple hexadecimal input acceptor might
|
3232
3242
|
look like this:
|
3233
3243
|
|
3234
3244
|
acceptor("hex", /^[0-9a-fA-F]+$/) { |input| input.to_i(16) }
|
3235
3245
|
|
3236
|
-
You
|
3246
|
+
You can also accept enum values by passing an array of valid values to the
|
3237
3247
|
`acceptor` directive. Inputs will be matched against the `to_s` form of the
|
3238
3248
|
given values, and will be converted to the value itself. For example, one way
|
3239
3249
|
to accept integers from 1 to 5 is:
|
@@ -3272,7 +3282,7 @@ still be present to decrease verbosity.
|
|
3272
3282
|
# Repurposes -q to set the "quick" option instead of "quiet"
|
3273
3283
|
flag :quick, "-q"
|
3274
3284
|
|
3275
|
-
You
|
3285
|
+
You can also completely disable a flag, and *not* repurpose it, using the
|
3276
3286
|
`disable_flag` directive. It lets you mark one or more flags as "never use".
|
3277
3287
|
|
3278
3288
|
For example, if you disable the `-q` flag, then `-q` will no longer be a
|
@@ -3296,7 +3306,7 @@ first, followed by positional arguments. In such a tool, once a non-flag
|
|
3296
3306
|
argument appears on the command line, all remaining arguments are treated as
|
3297
3307
|
positional, even if they look like a flag and start with a hyphen.
|
3298
3308
|
|
3299
|
-
You
|
3309
|
+
You can configure a tool to follow this alternate parsing strategy using the
|
3300
3310
|
`enforce_flags_before_args` directive.
|
3301
3311
|
|
3302
3312
|
The built-in tool `toys do` is an example of a tool that does this. It
|
@@ -3405,9 +3415,9 @@ interrupts as follows:
|
|
3405
3415
|
2. Toys will call the interrupt handler. If this method or block takes an
|
3406
3416
|
argument, Toys will pass it the `Interrupt` exception object.
|
3407
3417
|
3. The interrupt handler is then responsible for tool execution from that
|
3408
|
-
point. It
|
3418
|
+
point. It can terminate execution by returning or calling `exit`, or it can
|
3409
3419
|
restart or resume processing (perhaps by calling the `run` method again).
|
3410
|
-
Or it
|
3420
|
+
Or it can invoke the normal Toys interrupt handling (i.e. terminating
|
3411
3421
|
execution, displaying the message `INTERRUPTED`) by re-raising *the same*
|
3412
3422
|
interrupt exception object.
|
3413
3423
|
4. If another interrupt takes place during the execution of the interrupt
|
@@ -3496,14 +3506,14 @@ To use data files, you must define your tools inside a
|
|
3496
3506
|
[Toys directory](#Toys_directories). Within the Toys directory, create a
|
3497
3507
|
directory named `.data` and copy your data files there.
|
3498
3508
|
|
3499
|
-
You
|
3509
|
+
You mcanay then "find" a data file by providing the relative path to the file from
|
3500
3510
|
the `.data` directory. When defining a tool, use the
|
3501
3511
|
{Toys::DSL::Tool#find_data} directive in a Toys file. Or, at tool execution
|
3502
3512
|
time, call {Toys::Context#find_data} (which is a convenience method for getting
|
3503
3513
|
the tool source object using the `TOOL_SOURCE` key, and calling
|
3504
3514
|
{Toys::SourceInfo#find_data} on it). In either case, `find_data` locates a
|
3505
3515
|
matching file (or directory) among the data files, and returns the full path to
|
3506
|
-
that file system object. You
|
3516
|
+
that file system object. You can then read the file or perform any other
|
3507
3517
|
operation on it.
|
3508
3518
|
|
3509
3519
|
For example, take the following directory structure:
|
@@ -3714,7 +3724,7 @@ context directory to `my-repo/gem1`. Here's what that could look like:
|
|
3714
3724
|
|
3715
3725
|
Tools whose name begins with an underscore (e.g. `_foo`) are called "hidden"
|
3716
3726
|
tools. They can be executed the same as any other tool, but are normally
|
3717
|
-
omitted from the subtool list displayed in help and usage screens. You
|
3727
|
+
omitted from the subtool list displayed in help and usage screens. You can use
|
3718
3728
|
hidden tools as "internal" tools that are meant to be called only as part of
|
3719
3729
|
the implementation of other tools.
|
3720
3730
|
|
@@ -3780,6 +3790,21 @@ using zsh, however, you can use the `bashcompinit` function to load the toys
|
|
3780
3790
|
bash completion (as well as other bash-based completions). This *mostly* works,
|
3781
3791
|
with a few caveats. Native zsh completion is on the future roadmap.
|
3782
3792
|
|
3793
|
+
### Getting information about tools
|
3794
|
+
|
3795
|
+
Sometimes you need to introspect the list of defined tools. For example, you
|
3796
|
+
might have a CI job that runs a Toys tool if available, but falls back to a
|
3797
|
+
Rake task if no Toys tools are defined. To determine whether a tool exists, you
|
3798
|
+
could use the status code returned from `system tools show`.
|
3799
|
+
|
3800
|
+
Two operations are available under the `system tools` namespace, one to search
|
3801
|
+
and list tools, and another to get information about a specific tool. In both
|
3802
|
+
cases, you can view results as either YAML or JSON. For more information, see
|
3803
|
+
the help screens:
|
3804
|
+
|
3805
|
+
toys system tools list --help
|
3806
|
+
toys system tools show --help
|
3807
|
+
|
3783
3808
|
### Managing the Git cache
|
3784
3809
|
|
3785
3810
|
Toys manages a cache of files downloaded from remote Git repositories. This is
|
data/lib/toys/testing.rb
CHANGED
@@ -94,6 +94,37 @@ module Toys
|
|
94
94
|
# @param cmd [String,Array<String>] The command to execute.
|
95
95
|
# @return [Integer] The integer result code (i.e. 0 for success).
|
96
96
|
#
|
97
|
+
# @example
|
98
|
+
# # Given the following tool:
|
99
|
+
#
|
100
|
+
# tool "hello" do
|
101
|
+
# flag :shout
|
102
|
+
# def run
|
103
|
+
# puts message
|
104
|
+
# end
|
105
|
+
# def message
|
106
|
+
# shout ? "HELLO" : "hello"
|
107
|
+
# end
|
108
|
+
# end
|
109
|
+
#
|
110
|
+
# # You can test the tool's output as follows:
|
111
|
+
#
|
112
|
+
# class MyTest < Minitest::Test
|
113
|
+
# include Toys::Testing
|
114
|
+
# def test_output_without_shout
|
115
|
+
# assert_output("hello\n") do
|
116
|
+
# result = toys_run_tool(["hello"])
|
117
|
+
# assert_equal(0, result)
|
118
|
+
# end
|
119
|
+
# end
|
120
|
+
# def test_with_shout
|
121
|
+
# assert_output("HELLO\n") do
|
122
|
+
# result = toys_run_tool(["hello", "--shout"])
|
123
|
+
# assert_equal(0, result)
|
124
|
+
# end
|
125
|
+
# end
|
126
|
+
# end
|
127
|
+
#
|
97
128
|
def toys_run_tool(cmd, cli: nil)
|
98
129
|
cli ||= toys_cli
|
99
130
|
cmd = ::Shellwords.split(cmd) if cmd.is_a?(::String)
|
@@ -146,11 +177,11 @@ module Toys
|
|
146
177
|
# include Toys::Testing
|
147
178
|
# def test_output_without_shout
|
148
179
|
# result = toys_exec_tool(["hello"])
|
149
|
-
# assert_equal("hello
|
180
|
+
# assert_equal("hello\n", result.captured_out)
|
150
181
|
# end
|
151
182
|
# def test_with_shout
|
152
183
|
# result = toys_exec_tool(["hello", "--shout"])
|
153
|
-
# assert_equal("HELLO
|
184
|
+
# assert_equal("HELLO\n", result.captured_out)
|
154
185
|
# end
|
155
186
|
# end
|
156
187
|
#
|
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.14.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Daniel Azuma
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-10-09 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.14.2
|
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.14.2
|
27
27
|
description: Toys is a configurable command line tool. Write commands in Ruby using
|
28
28
|
a simple DSL, and Toys will provide the command line executable and take care of
|
29
29
|
all the details such as argument parsing, online help, and error reporting. Toys
|
@@ -44,9 +44,11 @@ files:
|
|
44
44
|
- README.md
|
45
45
|
- bin/toys
|
46
46
|
- builtins/do.rb
|
47
|
+
- builtins/system/.toys.rb
|
47
48
|
- builtins/system/bash-completion.rb
|
48
49
|
- builtins/system/git-cache.rb
|
49
50
|
- builtins/system/test.rb
|
51
|
+
- builtins/system/tools.rb
|
50
52
|
- builtins/system/update.rb
|
51
53
|
- core-docs/toys-core.rb
|
52
54
|
- core-docs/toys/acceptor.rb
|
@@ -85,6 +87,7 @@ files:
|
|
85
87
|
- core-docs/toys/standard_mixins/gems.rb
|
86
88
|
- core-docs/toys/standard_mixins/git_cache.rb
|
87
89
|
- core-docs/toys/standard_mixins/highline.rb
|
90
|
+
- core-docs/toys/standard_mixins/pager.rb
|
88
91
|
- core-docs/toys/standard_mixins/terminal.rb
|
89
92
|
- core-docs/toys/standard_mixins/xdg.rb
|
90
93
|
- core-docs/toys/template.rb
|
@@ -94,6 +97,7 @@ files:
|
|
94
97
|
- core-docs/toys/utils/gems.rb
|
95
98
|
- core-docs/toys/utils/git_cache.rb
|
96
99
|
- core-docs/toys/utils/help_text.rb
|
100
|
+
- core-docs/toys/utils/pager.rb
|
97
101
|
- core-docs/toys/utils/terminal.rb
|
98
102
|
- core-docs/toys/utils/xdg.rb
|
99
103
|
- core-docs/toys/wrappable_string.rb
|
@@ -116,10 +120,10 @@ homepage: https://github.com/dazuma/toys
|
|
116
120
|
licenses:
|
117
121
|
- MIT
|
118
122
|
metadata:
|
119
|
-
changelog_uri: https://dazuma.github.io/toys/gems/toys/v0.
|
123
|
+
changelog_uri: https://dazuma.github.io/toys/gems/toys/v0.14.2/file.CHANGELOG.html
|
120
124
|
source_code_uri: https://github.com/dazuma/toys/tree/main/toys
|
121
125
|
bug_tracker_uri: https://github.com/dazuma/toys/issues
|
122
|
-
documentation_uri: https://dazuma.github.io/toys/gems/toys/v0.
|
126
|
+
documentation_uri: https://dazuma.github.io/toys/gems/toys/v0.14.2
|
123
127
|
post_install_message:
|
124
128
|
rdoc_options: []
|
125
129
|
require_paths:
|