toys-core 0.19.0 → 0.19.1
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 +4 -0
- data/docs/guide.md +232 -192
- data/lib/toys/core.rb +1 -1
- metadata +4 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 815f546de5a0da65099cf1fdce70527fb42aafd3793bf8a99e35f63d77c4e66b
|
|
4
|
+
data.tar.gz: 79bd650fb1bdc5d04a2b1e1d235864e39313b4320518b9ac6296a8e1892aa8b1
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e696b9c3921aec0c56796bdd7b93a09d056f6d46347a5936bbf6a0ce9bc7b2811f90d4b9553c54bdf69b62d74289e4608da98473e9b62e34f155accbf665f7a1
|
|
7
|
+
data.tar.gz: 675e01b73df268ceda5cfd5bd62f4a21b164c2fce0b37e88f3397bc12f76ba8baa4b2969df5d82901ffbb78440dd1156374cc6642792d81a4ec9c149a800148a
|
data/CHANGELOG.md
CHANGED
data/docs/guide.md
CHANGED
|
@@ -80,27 +80,29 @@ to ensure that the `toys-core` gem is loaded, and `require "toys-core"`.
|
|
|
80
80
|
|
|
81
81
|
Following is a simple "hello world" example using the CLI:
|
|
82
82
|
|
|
83
|
-
|
|
83
|
+
```ruby
|
|
84
|
+
#!/usr/bin/env ruby
|
|
84
85
|
|
|
85
|
-
|
|
86
|
+
require "toys-core"
|
|
86
87
|
|
|
87
|
-
|
|
88
|
-
|
|
88
|
+
# Instantiate a CLI with the default options
|
|
89
|
+
cli = Toys::CLI.new
|
|
89
90
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
91
|
+
# Define the functionality
|
|
92
|
+
cli.add_config_block do
|
|
93
|
+
desc "My first executable!"
|
|
94
|
+
flag :whom, default: "world"
|
|
95
|
+
def run
|
|
96
|
+
puts "Hello, #{whom}!"
|
|
97
|
+
end
|
|
98
|
+
end
|
|
98
99
|
|
|
99
|
-
|
|
100
|
-
|
|
100
|
+
# Run the CLI, passing the command line arguments
|
|
101
|
+
result = cli.run(*ARGV)
|
|
101
102
|
|
|
102
|
-
|
|
103
|
-
|
|
103
|
+
# Handle the result code.
|
|
104
|
+
exit(result)
|
|
105
|
+
```
|
|
104
106
|
|
|
105
107
|
### CLI execution
|
|
106
108
|
|
|
@@ -141,19 +143,21 @@ when a tool is requested does the block actually execute. Furthermore, if you
|
|
|
141
143
|
have `tool` blocks inside the block, the loader will execute only those that
|
|
142
144
|
are relevant to a tool it wants. Hence:
|
|
143
145
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
146
|
+
```ruby
|
|
147
|
+
cli.add_config_block do
|
|
148
|
+
tool "foo" do
|
|
149
|
+
def run
|
|
150
|
+
puts "foo called"
|
|
151
|
+
end
|
|
152
|
+
end
|
|
150
153
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
end
|
|
155
|
-
end
|
|
154
|
+
tool "bar" do
|
|
155
|
+
def run
|
|
156
|
+
puts "bar called"
|
|
156
157
|
end
|
|
158
|
+
end
|
|
159
|
+
end
|
|
160
|
+
```
|
|
157
161
|
|
|
158
162
|
If only `foo` is requested, the loader will execute the `tool "foo" do` block
|
|
159
163
|
to get that tool definition, but will not execute the `tool "bar" do` block.
|
|
@@ -245,23 +249,25 @@ If you are writing your own command line executable using Toys-Core, often the
|
|
|
245
249
|
easiest way to define your tools is to use a block. The "hello world" example
|
|
246
250
|
at the start of this guide uses this technique:
|
|
247
251
|
|
|
248
|
-
|
|
252
|
+
```ruby
|
|
253
|
+
#!/usr/bin/env ruby
|
|
249
254
|
|
|
250
|
-
|
|
255
|
+
require "toys-core"
|
|
251
256
|
|
|
252
|
-
|
|
257
|
+
cli = Toys::CLI.new
|
|
253
258
|
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
259
|
+
# Define the functionality by passing a block to the CLI
|
|
260
|
+
cli.add_config_block do
|
|
261
|
+
desc "My first executable!"
|
|
262
|
+
flag :whom, default: "world"
|
|
263
|
+
def run
|
|
264
|
+
puts "Hello, #{whom}!"
|
|
265
|
+
end
|
|
266
|
+
end
|
|
262
267
|
|
|
263
|
-
|
|
264
|
-
|
|
268
|
+
result = cli.run(*ARGV)
|
|
269
|
+
exit(result)
|
|
270
|
+
```
|
|
265
271
|
|
|
266
272
|
The block simply contains Toys DSL syntax. The above example configures the
|
|
267
273
|
"root tool", that is, the functionality of the program if you do not pass a
|
|
@@ -282,25 +288,29 @@ messages and documentation, can also be set explicitly.
|
|
|
282
288
|
If you want to define tools in separate files, you can do so and pass the file
|
|
283
289
|
paths to the CLI using {Toys::CLI#add_config_path}.
|
|
284
290
|
|
|
285
|
-
|
|
291
|
+
```ruby
|
|
292
|
+
#!/usr/bin/env ruby
|
|
286
293
|
|
|
287
|
-
|
|
294
|
+
require "toys-core"
|
|
288
295
|
|
|
289
|
-
|
|
296
|
+
cli = Toys::CLI.new
|
|
290
297
|
|
|
291
|
-
|
|
292
|
-
|
|
298
|
+
# Load a file defining the functionality
|
|
299
|
+
cli.add_config_path("/usr/local/share/my_tool.rb")
|
|
293
300
|
|
|
294
|
-
|
|
295
|
-
|
|
301
|
+
result = cli.run(*ARGV)
|
|
302
|
+
exit(result)
|
|
303
|
+
```
|
|
296
304
|
|
|
297
305
|
The contents of `/usr/local/share/my_tool.rb` could then be:
|
|
298
306
|
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
307
|
+
```ruby
|
|
308
|
+
desc "My first executable!"
|
|
309
|
+
flag :whom, default: "world"
|
|
310
|
+
def run
|
|
311
|
+
puts "Hello, #{whom}!"
|
|
312
|
+
end
|
|
313
|
+
```
|
|
304
314
|
|
|
305
315
|
You can point to a specific file to load, or to a Toys directory, whose
|
|
306
316
|
contents will be loaded similarly to how a `.toys` directory is loaded.
|
|
@@ -329,45 +339,49 @@ priority level than previously added sources. Thus, any tools defined in the
|
|
|
329
339
|
new source would be overridden by tools of the same name defined in previously
|
|
330
340
|
added sources.
|
|
331
341
|
|
|
332
|
-
|
|
342
|
+
```ruby
|
|
343
|
+
#!/usr/bin/env ruby
|
|
333
344
|
|
|
334
|
-
|
|
345
|
+
require "toys-core"
|
|
335
346
|
|
|
336
|
-
|
|
347
|
+
cli = Toys::CLI.new
|
|
337
348
|
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
end
|
|
344
|
-
end
|
|
349
|
+
# Add a block defining a tool called "hello"
|
|
350
|
+
cli.add_config_block do
|
|
351
|
+
tool "hello" do
|
|
352
|
+
def run
|
|
353
|
+
puts "Hello from the first config block!"
|
|
345
354
|
end
|
|
355
|
+
end
|
|
356
|
+
end
|
|
346
357
|
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
end
|
|
353
|
-
end
|
|
358
|
+
# Add a lower-priority block defining a tool with the same name
|
|
359
|
+
cli.add_config_block do
|
|
360
|
+
tool "hello" do
|
|
361
|
+
def run
|
|
362
|
+
puts "Hello from the second config block!"
|
|
354
363
|
end
|
|
364
|
+
end
|
|
365
|
+
end
|
|
355
366
|
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
367
|
+
# Runs the tool defined in the first block
|
|
368
|
+
result = cli.run("hello")
|
|
369
|
+
exit(result)
|
|
370
|
+
```
|
|
359
371
|
|
|
360
372
|
When defining tool blocks or loading tools from files, you can also add the new
|
|
361
373
|
source at the *front* of the priority list by passing an argument:
|
|
362
374
|
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
end
|
|
375
|
+
```ruby
|
|
376
|
+
# Add tools with the highest priority
|
|
377
|
+
cli.add_config_block high_priority: true do
|
|
378
|
+
tool "hello" do
|
|
379
|
+
def run
|
|
380
|
+
puts "Hello from the second config block!"
|
|
370
381
|
end
|
|
382
|
+
end
|
|
383
|
+
end
|
|
384
|
+
```
|
|
371
385
|
|
|
372
386
|
Priorities are used by the `toys` gem when loading tools from different
|
|
373
387
|
directories. Any `.toys.rb` file or `.toys` directory is added to the CLI at
|
|
@@ -397,38 +411,42 @@ Suppose, for example, you are writing a gem `my_tools` that uses Toys-Core, and
|
|
|
397
411
|
you have a directory in your gem's `lib` called `my_tools/mixins` where you
|
|
398
412
|
want your standard mixins to live. You could define mixins there:
|
|
399
413
|
|
|
400
|
-
|
|
414
|
+
```ruby
|
|
415
|
+
# This file is my_tools/mixins/foo_mixin.rb
|
|
401
416
|
|
|
402
|
-
|
|
417
|
+
require "toys-core"
|
|
403
418
|
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
419
|
+
module MyTools
|
|
420
|
+
module Mixins
|
|
421
|
+
module FooMixin
|
|
422
|
+
include Toys::Mixin
|
|
408
423
|
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
end
|
|
412
|
-
end
|
|
424
|
+
def foo
|
|
425
|
+
puts "Foo was called"
|
|
413
426
|
end
|
|
414
427
|
end
|
|
428
|
+
end
|
|
429
|
+
end
|
|
430
|
+
```
|
|
415
431
|
|
|
416
432
|
Here is how you could configure a CLI to load standard mixins from that
|
|
417
433
|
directory, and then use the above mixin.
|
|
418
434
|
|
|
419
|
-
|
|
435
|
+
```ruby
|
|
436
|
+
# This file is my_tools.rb
|
|
420
437
|
|
|
421
|
-
|
|
438
|
+
require "toys-core"
|
|
422
439
|
|
|
423
|
-
|
|
424
|
-
|
|
440
|
+
my_mixin_lookup = Toys::ModuleLookup.new.add_path("my_tools/mixins")
|
|
441
|
+
cli = Toys::CLI.new(mixin_lookup: my_mixin_lookup)
|
|
425
442
|
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
443
|
+
cli.add_config_block do
|
|
444
|
+
def run
|
|
445
|
+
include :foo_mixin
|
|
446
|
+
foo
|
|
447
|
+
end
|
|
448
|
+
end
|
|
449
|
+
```
|
|
432
450
|
|
|
433
451
|
When you configure a ModuleLookup, you provide one or more paths, which are
|
|
434
452
|
path prefixes that are used in a `require` statement. In the above example,
|
|
@@ -468,22 +486,24 @@ Toys provides a Logger for each tool execution. Tools can access this Logger by
|
|
|
468
486
|
calling the `logger` method, or by getting the `Toys::Context::Key::LOGGER`
|
|
469
487
|
context object.
|
|
470
488
|
|
|
471
|
-
|
|
489
|
+
```ruby
|
|
490
|
+
#!/usr/bin/env ruby
|
|
472
491
|
|
|
473
|
-
|
|
492
|
+
require "toys-core"
|
|
474
493
|
|
|
475
|
-
|
|
494
|
+
cli = Toys::CLI.new
|
|
476
495
|
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
end
|
|
482
|
-
end
|
|
496
|
+
cli.add_config_block do
|
|
497
|
+
tool "hello" do
|
|
498
|
+
def run
|
|
499
|
+
logger.info "This log entry is displayed in verbose mode."
|
|
483
500
|
end
|
|
501
|
+
end
|
|
502
|
+
end
|
|
484
503
|
|
|
485
|
-
|
|
486
|
-
|
|
504
|
+
result = cli.run(*ARGV)
|
|
505
|
+
exit(result)
|
|
506
|
+
```
|
|
487
507
|
|
|
488
508
|
#### Log level and verbosity
|
|
489
509
|
|
|
@@ -506,15 +526,19 @@ Passing `verbosity: 1` will set the starting verbosity to 1, meaning
|
|
|
506
526
|
the invoker then provides an extra `--verbose` flag, the verbosity will further
|
|
507
527
|
increase to 2, allowing `Logger::DEBUG` entries to appear.
|
|
508
528
|
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
529
|
+
```ruby
|
|
530
|
+
# ...
|
|
531
|
+
result = cli.run(*ARGV, verbosity: 1)
|
|
532
|
+
exit(result)
|
|
533
|
+
```
|
|
512
534
|
|
|
513
535
|
You can also modify the log level that verbosity 0 maps to by passing the
|
|
514
536
|
`base_level` argument to the CLI constructor. The following causes verbosity 0
|
|
515
537
|
to map to `Logger::INFO` rather than `Logger::WARN`.
|
|
516
538
|
|
|
517
|
-
|
|
539
|
+
```ruby
|
|
540
|
+
cli = Toys::CLI.new(base_level: Logger::INFO)
|
|
541
|
+
```
|
|
518
542
|
|
|
519
543
|
#### Customizing the logger
|
|
520
544
|
|
|
@@ -523,8 +547,10 @@ configures it to log to STDERR. If you want to change any of these settings,
|
|
|
523
547
|
you can provide your own logger by passing a `logger` to the CLI constructor
|
|
524
548
|
constructor.
|
|
525
549
|
|
|
526
|
-
|
|
527
|
-
|
|
550
|
+
```ruby
|
|
551
|
+
my_logger = Logger.new("my_logfile.log")
|
|
552
|
+
cli = Toys::CLI.new(logger: my_logger)
|
|
553
|
+
```
|
|
528
554
|
|
|
529
555
|
A logger passed directly to the CLI is *global*. The CLI will attempt to use it
|
|
530
556
|
for every execution, even if multiple executions are happening concurrently. In
|
|
@@ -534,10 +560,12 @@ your CLI might be run multiple times concurrently, we recommend instead passing
|
|
|
534
560
|
a `logger_factory` to the CLI constructor. This is a Proc that will be invoked
|
|
535
561
|
to create a new logger for each execution.
|
|
536
562
|
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
563
|
+
```ruby
|
|
564
|
+
my_logger_factory = Proc.new do
|
|
565
|
+
Logger.new("my_logfile.log")
|
|
566
|
+
end
|
|
567
|
+
cli = Toys::CLI.new(logger_factory: my_logger_factory)
|
|
568
|
+
```
|
|
541
569
|
|
|
542
570
|
#### StandardUI logging
|
|
543
571
|
|
|
@@ -547,8 +575,10 @@ formats log entries with the severity and timestamp using ANSI coloring.
|
|
|
547
575
|
You can use this logger by passing {Toys::Utils::StandardUI#logger_factory} to
|
|
548
576
|
the CLI constructor:
|
|
549
577
|
|
|
550
|
-
|
|
551
|
-
|
|
578
|
+
```ruby
|
|
579
|
+
standard_ui = Toys::Utils::StandardUI.new
|
|
580
|
+
cli = Toys::CLI.new(logger_factory: standard_ui.logger_factory)
|
|
581
|
+
```
|
|
552
582
|
|
|
553
583
|
You can also customize the logger by subclassing StandardUI and overriding its
|
|
554
584
|
methods or adjusting its parameters. In particular, you can alter the
|
|
@@ -574,15 +604,17 @@ final handling of an unhandled exception, such as displaying the error to the
|
|
|
574
604
|
terminal, or reraising the exception. The handler should then return the
|
|
575
605
|
desired result code for the execution.
|
|
576
606
|
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
607
|
+
```ruby
|
|
608
|
+
my_error_handler = Proc.new |wrapped_error| do
|
|
609
|
+
# Propagate signals out and let the Ruby VM handle them.
|
|
610
|
+
raise wrapped_error.cause if wrapped_error.cause.is_a?(SignalException)
|
|
611
|
+
# Handle any other exception types by printing a message.
|
|
612
|
+
$stderr.puts "An error occurred. Please contact your administrator."
|
|
613
|
+
# Return the result code
|
|
614
|
+
255
|
|
615
|
+
end
|
|
616
|
+
cli = Toys::CLI.new(error_handler: my_error_handler)
|
|
617
|
+
```
|
|
586
618
|
|
|
587
619
|
If you do not set an error handler, the exception is raised out of the
|
|
588
620
|
{Toys::CLI#run} call. In the case of signals, the *cause*, represented by a
|
|
@@ -603,8 +635,10 @@ conventional result code of `128 + signo` (e.g. 130 for interrupts).
|
|
|
603
635
|
You can use this error handler by passing
|
|
604
636
|
{Toys::Utils::StandardUI#error_handler} to the CLI constructor:
|
|
605
637
|
|
|
606
|
-
|
|
607
|
-
|
|
638
|
+
```ruby
|
|
639
|
+
standard_ui = Toys::Utils::StandardUI.new
|
|
640
|
+
cli = Toys::CLI.new(error_handler: standard_ui.error_handler)
|
|
641
|
+
```
|
|
608
642
|
|
|
609
643
|
You can also customize the error handler by subclassing StandardUI and
|
|
610
644
|
overriding its methods. In particular, you can alter what is displayed in
|
|
@@ -670,12 +704,14 @@ A useful example can be seen in the default Toys CLI behavior. If you do not
|
|
|
670
704
|
provide a middleware stack when instantiating {Toys::CLI}, the class uses a
|
|
671
705
|
default stack that looks approximately like this:
|
|
672
706
|
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
707
|
+
```ruby
|
|
708
|
+
[
|
|
709
|
+
Toys::Middleware.spec(:set_default_descriptions),
|
|
710
|
+
Toys::Middleware.spec(:show_help, help_flags: true, fallback_execution: true),
|
|
711
|
+
Toys::Middleware.spec(:handle_usage_errors),
|
|
712
|
+
Toys::Middleware.spec(:add_verbosity_flags),
|
|
713
|
+
]
|
|
714
|
+
```
|
|
679
715
|
|
|
680
716
|
Each of the names, e.g. `:set_default_descriptions`, is the name of a Ruby
|
|
681
717
|
file in the `toys-core` gem under `toys/standard_middleware`. You can configure
|
|
@@ -732,51 +768,53 @@ following is a simple middleware that adds the `--show-timing` flag to every
|
|
|
732
768
|
tool. When the flag is set, the middleware displays how long the tool took to
|
|
733
769
|
execute.
|
|
734
770
|
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
771
|
+
```ruby
|
|
772
|
+
class TimingMiddleware
|
|
773
|
+
# This is a context key that will be used to store the "--show-timing"
|
|
774
|
+
# flag state. We can use `Object.new` to ensure that the key is unique
|
|
775
|
+
# across other middlewares and tool definitions.
|
|
776
|
+
KEY = Object.new.freeze
|
|
777
|
+
|
|
778
|
+
# This method intercepts tool configuration. We use it to add a flag that
|
|
779
|
+
# enables timing display.
|
|
780
|
+
def config(tool, _loader)
|
|
781
|
+
# Add a flag to control this functionality. Suppress collisions, i.e.
|
|
782
|
+
# just silently do nothing if the tool has already added a flag called
|
|
783
|
+
# "--show-timing".
|
|
784
|
+
tool.add_flag(KEY, "--show-timing", report_collisions: false)
|
|
785
|
+
|
|
786
|
+
# Calling yield passes control to the rest of the middleware stack.
|
|
787
|
+
# Normally you should call yield, to ensure that the remaining
|
|
788
|
+
# middleware can run. If you omit this, no additional middleware will
|
|
789
|
+
# be able to run tool configuration. Note you can also perform
|
|
790
|
+
# additional processing after the yield call, i.e. after the rest of
|
|
791
|
+
# the middleware stack has run.
|
|
792
|
+
yield
|
|
793
|
+
end
|
|
794
|
+
|
|
795
|
+
# This method intercepts tool execution. We use it to collect timing
|
|
796
|
+
# information, and display it if the flag has been provided in the
|
|
797
|
+
# command line arguments.
|
|
798
|
+
def run(context)
|
|
799
|
+
# Read monotonic time at the start of execution.
|
|
800
|
+
start_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
801
|
+
|
|
802
|
+
# Call yield to run the rest of the middleware stack, including the
|
|
803
|
+
# actual tool execution. If you omit this, you will prevent the rest of
|
|
804
|
+
# the middleware stack, AND the actual tool execution, from running.
|
|
805
|
+
# So you could omit the yield call if your goal is to replace tool
|
|
806
|
+
# execution with your own code.
|
|
807
|
+
yield
|
|
808
|
+
|
|
809
|
+
# Read monotonic time again after execution.
|
|
810
|
+
end_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
811
|
+
|
|
812
|
+
# Display the elapsed time, if the tool was passed the "--show-timing"
|
|
813
|
+
# flag.
|
|
814
|
+
puts "Tool took #{end_time - start_time} secs" if context[KEY]
|
|
815
|
+
end
|
|
816
|
+
end
|
|
817
|
+
```
|
|
780
818
|
|
|
781
819
|
We can now insert our middleware into the stack when we create a CLI. Here
|
|
782
820
|
we'll take that "default" stack we saw earlier and add our timing middleware at
|
|
@@ -785,14 +823,16 @@ other middleware, and thus its timing measurement includes the latency incurred
|
|
|
785
823
|
by other middleware (including middleware that replaces execution such as
|
|
786
824
|
`:show_help`).
|
|
787
825
|
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
826
|
+
```ruby
|
|
827
|
+
my_middleware_stack = [
|
|
828
|
+
Toys::Middleware.spec(TimingMiddleware),
|
|
829
|
+
Toys::Middleware.spec(:set_default_descriptions),
|
|
830
|
+
Toys::Middleware.spec(:show_help, help_flags: true, fallback_execution: true),
|
|
831
|
+
Toys::Middleware.spec(:handle_usage_errors),
|
|
832
|
+
Toys::Middleware.spec(:add_verbosity_flags),
|
|
833
|
+
]
|
|
834
|
+
cli = Toys::CLI.new(middleware_stack: my_middleware_stack)
|
|
835
|
+
```
|
|
796
836
|
|
|
797
837
|
Now, every tool run by this CLI wil have the `--show-timing` flag and
|
|
798
838
|
associated functionality.
|
data/lib/toys/core.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: toys-core
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.19.
|
|
4
|
+
version: 0.19.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Daniel Azuma
|
|
@@ -92,10 +92,10 @@ homepage: https://github.com/dazuma/toys
|
|
|
92
92
|
licenses:
|
|
93
93
|
- MIT
|
|
94
94
|
metadata:
|
|
95
|
-
changelog_uri: https://dazuma.github.io/toys/gems/toys-core/v0.19.
|
|
95
|
+
changelog_uri: https://dazuma.github.io/toys/gems/toys-core/v0.19.1/file.CHANGELOG.html
|
|
96
96
|
source_code_uri: https://github.com/dazuma/toys/tree/main/toys-core
|
|
97
97
|
bug_tracker_uri: https://github.com/dazuma/toys/issues
|
|
98
|
-
documentation_uri: https://dazuma.github.io/toys/gems/toys-core/v0.19.
|
|
98
|
+
documentation_uri: https://dazuma.github.io/toys/gems/toys-core/v0.19.1
|
|
99
99
|
rdoc_options: []
|
|
100
100
|
require_paths:
|
|
101
101
|
- lib
|
|
@@ -110,7 +110,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
110
110
|
- !ruby/object:Gem::Version
|
|
111
111
|
version: '0'
|
|
112
112
|
requirements: []
|
|
113
|
-
rubygems_version:
|
|
113
|
+
rubygems_version: 4.0.3
|
|
114
114
|
specification_version: 4
|
|
115
115
|
summary: Framework for creating command line executables
|
|
116
116
|
test_files: []
|