toys-core 0.3.10 → 0.3.11
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 +6 -0
- data/README.md +1 -1
- data/lib/toys-core.rb +2 -0
- data/lib/toys/cli.rb +2 -0
- data/lib/toys/core_version.rb +3 -1
- data/lib/toys/definition/acceptor.rb +2 -0
- data/lib/toys/definition/alias.rb +2 -0
- data/lib/toys/definition/arg.rb +2 -0
- data/lib/toys/definition/flag.rb +2 -0
- data/lib/toys/definition/tool.rb +10 -8
- data/lib/toys/dsl/arg.rb +2 -0
- data/lib/toys/dsl/flag.rb +2 -0
- data/lib/toys/dsl/tool.rb +79 -22
- data/lib/toys/errors.rb +2 -0
- data/lib/toys/input_file.rb +2 -0
- data/lib/toys/loader.rb +4 -4
- data/lib/toys/middleware.rb +2 -0
- data/lib/toys/mixin.rb +9 -2
- data/lib/toys/runner.rb +2 -0
- data/lib/toys/standard_middleware/add_verbosity_flags.rb +2 -0
- data/lib/toys/standard_middleware/handle_usage_errors.rb +3 -1
- data/lib/toys/standard_middleware/set_default_descriptions.rb +5 -3
- data/lib/toys/standard_middleware/show_help.rb +12 -6
- data/lib/toys/standard_middleware/show_root_version.rb +3 -1
- data/lib/toys/standard_mixins/exec.rb +52 -21
- data/lib/toys/standard_mixins/fileutils.rb +2 -0
- data/lib/toys/standard_mixins/highline.rb +20 -1
- data/lib/toys/standard_mixins/terminal.rb +16 -2
- data/lib/toys/template.rb +2 -0
- data/lib/toys/tool.rb +14 -2
- data/lib/toys/utils/exec.rb +2 -0
- data/lib/toys/utils/gems.rb +13 -8
- data/lib/toys/utils/help_text.rb +2 -0
- data/lib/toys/utils/module_lookup.rb +2 -0
- data/lib/toys/utils/terminal.rb +15 -7
- data/lib/toys/utils/wrappable_string.rb +3 -1
- metadata +17 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 170a7493ef1b6d852d4a551b7e6f38d0cf861f6660c8b2b1d710c1eee7b5dd2b
|
4
|
+
data.tar.gz: eb2b614017aff294664306a4a2aa6ce96eda22bf37a375c9bb03641c39eb439d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2e0dc6614370daa927916614b19631dd6b9541d3ed664593b4aeaa6cab2407cb8abf7284afbf13c100fc7b6a783ac261c10e280f7112e6f359bcce90125ab414
|
7
|
+
data.tar.gz: aa7dbaf6c473f233207886fb2b4ce11a7dd551f802dd4e16ad9e8647ee394c8c96f5b6f483e3a775aab08224d4213cce05cf78dbf5fb1000258c4630942e2dc9
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,11 @@
|
|
1
1
|
# Release History
|
2
2
|
|
3
|
+
### 0.3.11 / 2018-07-02
|
4
|
+
|
5
|
+
* CHANGED: Require Ruby 2.3 or later
|
6
|
+
* CHANGED: Renamed "set" directive to "static" to reduce confusion with Tool#set.
|
7
|
+
* ADDED: Convenience methods for getting option values
|
8
|
+
|
3
9
|
### 0.3.10 / 2018-06-30
|
4
10
|
|
5
11
|
* CHANGED: Dropped Tool#option. Use Tool#get instead.
|
data/README.md
CHANGED
@@ -10,7 +10,7 @@ Toys-Core is the command line tool framework underlying Toys. It can be used
|
|
10
10
|
to create command line binaries using the internal Toys APIs.
|
11
11
|
|
12
12
|
To get started using toys-core for your own command line binary, see the
|
13
|
-
|
13
|
+
[Getting Started Guide](https://www.rubydoc.info/gems/toys-core/file/docs/getting-started.md)
|
14
14
|
|
15
15
|
## Contributing
|
16
16
|
|
data/lib/toys-core.rb
CHANGED
data/lib/toys/cli.rb
CHANGED
data/lib/toys/core_version.rb
CHANGED
data/lib/toys/definition/arg.rb
CHANGED
data/lib/toys/definition/flag.rb
CHANGED
data/lib/toys/definition/tool.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# Copyright 2018 Daniel Azuma
|
2
4
|
#
|
3
5
|
# All rights reserved.
|
@@ -465,8 +467,8 @@ module Toys
|
|
465
467
|
# the script may use to obtain the flag value from the context.
|
466
468
|
# You may then provide the flags themselves in `OptionParser` form.
|
467
469
|
#
|
468
|
-
# @param [Symbol] key The key to use to retrieve the value from
|
469
|
-
# execution context.
|
470
|
+
# @param [String,Symbol] key The key to use to retrieve the value from
|
471
|
+
# the execution context.
|
470
472
|
# @param [Array<String>] flags The flags in OptionParser format.
|
471
473
|
# @param [Object] accept An acceptor that validates and/or converts the
|
472
474
|
# value. You may provide either the name of an acceptor you have
|
@@ -529,8 +531,8 @@ module Toys
|
|
529
531
|
# a key which the script may use to obtain the argument value from the
|
530
532
|
# context.
|
531
533
|
#
|
532
|
-
# @param [Symbol] key The key to use to retrieve the value from
|
533
|
-
# execution context.
|
534
|
+
# @param [String,Symbol] key The key to use to retrieve the value from
|
535
|
+
# the execution context.
|
534
536
|
# @param [Object] accept An acceptor that validates and/or converts the
|
535
537
|
# value. You may provide either the name of an acceptor you have
|
536
538
|
# defined, or one of the default acceptors provided by OptionParser.
|
@@ -559,8 +561,8 @@ module Toys
|
|
559
561
|
# context. If an optional argument is not given on the command line, the
|
560
562
|
# value is set to the given default.
|
561
563
|
#
|
562
|
-
# @param [Symbol] key The key to use to retrieve the value from
|
563
|
-
# execution context.
|
564
|
+
# @param [String,Symbol] key The key to use to retrieve the value from
|
565
|
+
# the execution context.
|
564
566
|
# @param [Object] default The default value. This is the value that will
|
565
567
|
# be set in the context if this argument is not provided on the command
|
566
568
|
# line. Defaults to `nil`.
|
@@ -594,8 +596,8 @@ module Toys
|
|
594
596
|
# specify a key which the script may use to obtain the remaining args
|
595
597
|
# from the context.
|
596
598
|
#
|
597
|
-
# @param [Symbol] key The key to use to retrieve the value from
|
598
|
-
# execution context.
|
599
|
+
# @param [String,Symbol] key The key to use to retrieve the value from
|
600
|
+
# the execution context.
|
599
601
|
# @param [Object] default The default value. This is the value that will
|
600
602
|
# be set in the context if no unmatched arguments are provided on the
|
601
603
|
# command line. Defaults to the empty array `[]`.
|
data/lib/toys/dsl/arg.rb
CHANGED
data/lib/toys/dsl/flag.rb
CHANGED
data/lib/toys/dsl/tool.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# Copyright 2018 Daniel Azuma
|
2
4
|
#
|
3
5
|
# All rights reserved.
|
@@ -48,7 +50,7 @@ module Toys
|
|
48
50
|
# optional_arg :recipient, default: "world"
|
49
51
|
#
|
50
52
|
# def run
|
51
|
-
# puts "Hello, #{
|
53
|
+
# puts "Hello, #{recipient}!"
|
52
54
|
# end
|
53
55
|
# end
|
54
56
|
#
|
@@ -294,8 +296,7 @@ module Toys
|
|
294
296
|
# @param [Toys::Utils::WrappableString,String,Array<String>...] strs
|
295
297
|
#
|
296
298
|
def long_desc(*strs)
|
297
|
-
|
298
|
-
cur_tool.append_long_desc(strs) if cur_tool
|
299
|
+
DSL::Tool.current_tool(self, true)&.append_long_desc(strs)
|
299
300
|
self
|
300
301
|
end
|
301
302
|
|
@@ -304,11 +305,17 @@ module Toys
|
|
304
305
|
# the script may use to obtain the flag value from the context.
|
305
306
|
# You may then provide the flags themselves in OptionParser form.
|
306
307
|
#
|
308
|
+
# If the given key is a symbol representing a valid method name, then a
|
309
|
+
# helper method is automatically added to retrieve the value. Otherwise,
|
310
|
+
# if the key is a string or does not represent a valid method name, the
|
311
|
+
# tool can retrieve the value by calling {Toys::Tool#get}.
|
312
|
+
#
|
307
313
|
# Attributes of the flag may be passed in as arguments to this method, or
|
308
|
-
# set in a block passed to this method.
|
314
|
+
# set in a block passed to this method. If you provide a block, you can
|
315
|
+
# use directives in {Toys::DSL::Flag} within the block.
|
309
316
|
#
|
310
|
-
# @param [Symbol] key The key to use to retrieve the value from
|
311
|
-
# execution context.
|
317
|
+
# @param [String,Symbol] key The key to use to retrieve the value from
|
318
|
+
# the execution context.
|
312
319
|
# @param [String...] flags The flags in OptionParser format.
|
313
320
|
# @param [Object] accept An acceptor that validates and/or converts the
|
314
321
|
# value. You may provide either the name of an acceptor you have
|
@@ -343,10 +350,11 @@ module Toys
|
|
343
350
|
&block)
|
344
351
|
cur_tool = DSL::Tool.current_tool(self, true)
|
345
352
|
return self if cur_tool.nil?
|
346
|
-
flag_dsl = DSL::Flag.new(flags, accept, default, handler,
|
347
|
-
desc, long_desc)
|
353
|
+
flag_dsl = DSL::Flag.new(flags, accept, default, handler,
|
354
|
+
report_collisions, desc, long_desc)
|
348
355
|
flag_dsl.instance_exec(flag_dsl, &block) if block
|
349
356
|
flag_dsl._add_to(cur_tool, key)
|
357
|
+
DSL::Tool.maybe_add_getter(self, key)
|
350
358
|
self
|
351
359
|
end
|
352
360
|
|
@@ -355,8 +363,17 @@ module Toys
|
|
355
363
|
# a key which the script may use to obtain the argument value from the
|
356
364
|
# context.
|
357
365
|
#
|
358
|
-
#
|
359
|
-
#
|
366
|
+
# If the given key is a symbol representing a valid method name, then a
|
367
|
+
# helper method is automatically added to retrieve the value. Otherwise,
|
368
|
+
# if the key is a string or does not represent a valid method name, the
|
369
|
+
# tool can retrieve the value by calling {Toys::Tool#get}.
|
370
|
+
#
|
371
|
+
# Attributes of the arg may be passed in as arguments to this method, or
|
372
|
+
# set in a block passed to this method. If you provide a block, you can
|
373
|
+
# use directives in {Toys::DSL::Arg} within the block.
|
374
|
+
#
|
375
|
+
# @param [String,Symbol] key The key to use to retrieve the value from
|
376
|
+
# the execution context.
|
360
377
|
# @param [Object] accept An acceptor that validates and/or converts the
|
361
378
|
# value. You may provide either the name of an acceptor you have
|
362
379
|
# defined, or one of the default acceptors provided by OptionParser.
|
@@ -375,13 +392,15 @@ module Toys
|
|
375
392
|
# this argument in a block.
|
376
393
|
#
|
377
394
|
def required_arg(key,
|
378
|
-
accept: nil, display_name: nil,
|
395
|
+
accept: nil, display_name: nil,
|
396
|
+
desc: nil, long_desc: nil,
|
379
397
|
&block)
|
380
398
|
cur_tool = DSL::Tool.current_tool(self, true)
|
381
399
|
return self if cur_tool.nil?
|
382
400
|
arg_dsl = DSL::Arg.new(accept, nil, display_name, desc, long_desc)
|
383
401
|
arg_dsl.instance_exec(arg_dsl, &block) if block
|
384
402
|
arg_dsl._add_required_to(cur_tool, key)
|
403
|
+
DSL::Tool.maybe_add_getter(self, key)
|
385
404
|
self
|
386
405
|
end
|
387
406
|
alias required required_arg
|
@@ -392,8 +411,17 @@ module Toys
|
|
392
411
|
# context. If an optional argument is not given on the command line, the
|
393
412
|
# value is set to the given default.
|
394
413
|
#
|
395
|
-
#
|
396
|
-
#
|
414
|
+
# If the given key is a symbol representing a valid method name, then a
|
415
|
+
# helper method is automatically added to retrieve the value. Otherwise,
|
416
|
+
# if the key is a string or does not represent a valid method name, the
|
417
|
+
# tool can retrieve the value by calling {Toys::Tool#get}.
|
418
|
+
#
|
419
|
+
# Attributes of the arg may be passed in as arguments to this method, or
|
420
|
+
# set in a block passed to this method. If you provide a block, you can
|
421
|
+
# use directives in {Toys::DSL::Arg} within the block.
|
422
|
+
#
|
423
|
+
# @param [String,Symbol] key The key to use to retrieve the value from
|
424
|
+
# the execution context.
|
397
425
|
# @param [Object] default The default value. This is the value that will
|
398
426
|
# be set in the context if this argument is not provided on the command
|
399
427
|
# line. Defaults to `nil`.
|
@@ -423,6 +451,7 @@ module Toys
|
|
423
451
|
arg_dsl = DSL::Arg.new(accept, default, display_name, desc, long_desc)
|
424
452
|
arg_dsl.instance_exec(arg_dsl, &block) if block
|
425
453
|
arg_dsl._add_optional_to(cur_tool, key)
|
454
|
+
DSL::Tool.maybe_add_getter(self, key)
|
426
455
|
self
|
427
456
|
end
|
428
457
|
alias optional optional_arg
|
@@ -432,8 +461,17 @@ module Toys
|
|
432
461
|
# specify a key which the script may use to obtain the remaining args from
|
433
462
|
# the context.
|
434
463
|
#
|
435
|
-
#
|
436
|
-
#
|
464
|
+
# If the given key is a symbol representing a valid method name, then a
|
465
|
+
# helper method is automatically added to retrieve the value. Otherwise,
|
466
|
+
# if the key is a string or does not represent a valid method name, the
|
467
|
+
# tool can retrieve the value by calling {Toys::Tool#get}.
|
468
|
+
#
|
469
|
+
# Attributes of the arg may be passed in as arguments to this method, or
|
470
|
+
# set in a block passed to this method. If you provide a block, you can
|
471
|
+
# use directives in {Toys::DSL::Arg} within the block.
|
472
|
+
#
|
473
|
+
# @param [String,Symbol] key The key to use to retrieve the value from
|
474
|
+
# the execution context.
|
437
475
|
# @param [Object] default The default value. This is the value that will
|
438
476
|
# be set in the context if no unmatched arguments are provided on the
|
439
477
|
# command line. Defaults to the empty array `[]`.
|
@@ -463,6 +501,7 @@ module Toys
|
|
463
501
|
arg_dsl = DSL::Arg.new(accept, default, display_name, desc, long_desc)
|
464
502
|
arg_dsl.instance_exec(arg_dsl, &block) if block
|
465
503
|
arg_dsl._set_remaining_on(cur_tool, key)
|
504
|
+
DSL::Tool.maybe_add_getter(self, key)
|
466
505
|
self
|
467
506
|
end
|
468
507
|
alias remaining remaining_args
|
@@ -470,17 +509,26 @@ module Toys
|
|
470
509
|
##
|
471
510
|
# Set an option value statically.
|
472
511
|
#
|
473
|
-
#
|
474
|
-
#
|
512
|
+
# If the given key is a symbol representing a valid method name, then a
|
513
|
+
# helper method is automatically added to retrieve the value. Otherwise,
|
514
|
+
# if the key is a string or does not represent a valid method name, the
|
515
|
+
# tool can retrieve the value by calling {Toys::Tool#get}.
|
516
|
+
#
|
517
|
+
# @param [String,Symbol] key The key to use to retrieve the value from
|
518
|
+
# the execution context.
|
475
519
|
# @param [Object] value The value to set.
|
476
520
|
#
|
477
|
-
def
|
521
|
+
def static(key, value = nil)
|
478
522
|
cur_tool = DSL::Tool.current_tool(self, true)
|
479
523
|
return self if cur_tool.nil?
|
480
524
|
if key.is_a?(::Hash)
|
481
525
|
cur_tool.default_data.merge!(key)
|
526
|
+
key.each_key do |k|
|
527
|
+
DSL::Tool.maybe_add_getter(self, k)
|
528
|
+
end
|
482
529
|
else
|
483
530
|
cur_tool.default_data[key] = value
|
531
|
+
DSL::Tool.maybe_add_getter(self, key)
|
484
532
|
end
|
485
533
|
self
|
486
534
|
end
|
@@ -494,8 +542,7 @@ module Toys
|
|
494
542
|
# declare arguments or flags.
|
495
543
|
#
|
496
544
|
def disable_argument_parsing
|
497
|
-
|
498
|
-
cur_tool.disable_argument_parsing unless cur_tool.nil?
|
545
|
+
DSL::Tool.current_tool(self, true)&.disable_argument_parsing
|
499
546
|
self
|
500
547
|
end
|
501
548
|
|
@@ -507,8 +554,7 @@ module Toys
|
|
507
554
|
# @param [String...] flags The flags to disable
|
508
555
|
#
|
509
556
|
def disable_flag(*flags)
|
510
|
-
|
511
|
-
cur_tool.disable_flag(*flags) unless cur_tool.nil?
|
557
|
+
DSL::Tool.current_tool(self, true)&.disable_flag(*flags)
|
512
558
|
self
|
513
559
|
end
|
514
560
|
|
@@ -608,6 +654,17 @@ module Toys
|
|
608
654
|
tool_class.instance_variable_set(:@__remaining_words, nil)
|
609
655
|
tool_class.instance_variable_set(:@__path, nil)
|
610
656
|
end
|
657
|
+
|
658
|
+
## @private
|
659
|
+
def self.maybe_add_getter(tool_class, key)
|
660
|
+
if key.is_a?(::Symbol) && key.to_s =~ /^[_a-zA-Z]\w*[!\?]?$/
|
661
|
+
tool_class.class_eval do
|
662
|
+
define_method(key) do
|
663
|
+
self[key]
|
664
|
+
end
|
665
|
+
end
|
666
|
+
end
|
667
|
+
end
|
611
668
|
end
|
612
669
|
end
|
613
670
|
end
|
data/lib/toys/errors.rb
CHANGED
data/lib/toys/input_file.rb
CHANGED
data/lib/toys/loader.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# Copyright 2018 Daniel Azuma
|
2
4
|
#
|
3
5
|
# All rights reserved.
|
@@ -44,9 +46,6 @@ module Toys
|
|
44
46
|
end
|
45
47
|
end
|
46
48
|
|
47
|
-
## @private
|
48
|
-
LOW_PRIORITY = -999_999
|
49
|
-
|
50
49
|
##
|
51
50
|
# Create a Loader
|
52
51
|
#
|
@@ -86,6 +85,7 @@ module Toys
|
|
86
85
|
@worklist = []
|
87
86
|
@tool_data = {}
|
88
87
|
@max_priority = @min_priority = 0
|
88
|
+
get_tool_definition([], -999_999)
|
89
89
|
end
|
90
90
|
|
91
91
|
##
|
@@ -151,7 +151,7 @@ module Toys
|
|
151
151
|
break if p.empty? || p.length <= cur_prefix.length
|
152
152
|
p = p.slice(0..-2)
|
153
153
|
end
|
154
|
-
|
154
|
+
raise "Unexpected error" if cur_prefix.empty?
|
155
155
|
cur_prefix = cur_prefix.slice(0..-2)
|
156
156
|
end
|
157
157
|
end
|
data/lib/toys/middleware.rb
CHANGED
data/lib/toys/mixin.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# Copyright 2018 Daniel Azuma
|
2
4
|
#
|
3
5
|
# All rights reserved.
|
@@ -66,8 +68,12 @@ module Toys
|
|
66
68
|
#
|
67
69
|
# # Mixin methods are called with self set to the tool and can affect
|
68
70
|
# # the tool state.
|
71
|
+
# def counter_value
|
72
|
+
# get(:counter_value)
|
73
|
+
# end
|
74
|
+
#
|
69
75
|
# def increment
|
70
|
-
#
|
76
|
+
# set(:counter_value, counter_value + 1)
|
71
77
|
# logger.info("Incremented counter")
|
72
78
|
# end
|
73
79
|
# end
|
@@ -79,8 +85,9 @@ module Toys
|
|
79
85
|
# include MyCounterMixin, 1
|
80
86
|
#
|
81
87
|
# def run
|
88
|
+
# # Mixin methods can be called.
|
82
89
|
# 5.times { increment }
|
83
|
-
# puts "Final value is #{
|
90
|
+
# puts "Final value is #{counter_value}"
|
84
91
|
# end
|
85
92
|
# end
|
86
93
|
#
|
data/lib/toys/runner.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# Copyright 2018 Daniel Azuma
|
2
4
|
#
|
3
5
|
# All rights reserved.
|
@@ -62,7 +64,7 @@ module Toys
|
|
62
64
|
@terminal.puts(tool[Tool::Keys::USAGE_ERROR], :bright_red, :bold)
|
63
65
|
@terminal.puts("")
|
64
66
|
@terminal.puts(help_text.usage_string(wrap_width: @terminal.width))
|
65
|
-
|
67
|
+
Tool.exit(@exit_code)
|
66
68
|
else
|
67
69
|
yield
|
68
70
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# Copyright 2018 Daniel Azuma
|
2
4
|
#
|
3
5
|
# All rights reserved.
|
@@ -44,19 +46,19 @@ module Toys
|
|
44
46
|
# The default description for tools.
|
45
47
|
# @return [String]
|
46
48
|
#
|
47
|
-
DEFAULT_TOOL_DESC = "(No tool description available)"
|
49
|
+
DEFAULT_TOOL_DESC = "(No tool description available)"
|
48
50
|
|
49
51
|
##
|
50
52
|
# The default description for namespaces.
|
51
53
|
# @return [String]
|
52
54
|
#
|
53
|
-
DEFAULT_NAMESPACE_DESC = "(A namespace of tools)"
|
55
|
+
DEFAULT_NAMESPACE_DESC = "(A namespace of tools)"
|
54
56
|
|
55
57
|
##
|
56
58
|
# The default description for the root tool.
|
57
59
|
# @return [String]
|
58
60
|
#
|
59
|
-
DEFAULT_ROOT_DESC = "Command line tool built using the toys-core gem."
|
61
|
+
DEFAULT_ROOT_DESC = "Command line tool built using the toys-core gem."
|
60
62
|
|
61
63
|
##
|
62
64
|
# The default long description for the root tool.
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# Copyright 2018 Daniel Azuma
|
2
4
|
#
|
3
5
|
# All rights reserved.
|
@@ -251,15 +253,15 @@ module Toys
|
|
251
253
|
loader = tool[Tool::Keys::LOADER]
|
252
254
|
tool_definition, rest = loader.lookup(tool_name)
|
253
255
|
help_text = Utils::HelpText.new(tool_definition, loader, tool[Tool::Keys::BINARY_NAME])
|
254
|
-
report_usage_error(
|
256
|
+
report_usage_error(tool_name, help_text) unless rest.empty?
|
255
257
|
help_text
|
256
258
|
end
|
257
259
|
|
258
|
-
def report_usage_error(
|
260
|
+
def report_usage_error(tool_name, help_text)
|
259
261
|
terminal.puts("Tool not found: #{tool_name.join(' ')}", :bright_red, :bold)
|
260
262
|
terminal.puts
|
261
263
|
terminal.puts help_text.usage_string(wrap_width: terminal.width)
|
262
|
-
|
264
|
+
Tool.exit(1)
|
263
265
|
end
|
264
266
|
|
265
267
|
def add_help_flags(tool_definition)
|
@@ -289,13 +291,16 @@ module Toys
|
|
289
291
|
def add_recursive_flags(tool_definition)
|
290
292
|
recursive_flags = resolve_flags_spec(@recursive_flags, tool_definition,
|
291
293
|
DEFAULT_RECURSIVE_FLAGS)
|
292
|
-
|
294
|
+
if recursive_flags.empty?
|
295
|
+
tool_definition.default_data[RECURSIVE_SUBTOOLS_KEY] = @default_recursive
|
296
|
+
else
|
293
297
|
tool_definition.add_flag(
|
294
298
|
RECURSIVE_SUBTOOLS_KEY, recursive_flags,
|
295
299
|
report_collisions: false, default: @default_recursive,
|
296
300
|
desc: "Show all subtools recursively (default is #{@default_recursive})"
|
297
301
|
)
|
298
302
|
end
|
303
|
+
recursive_flags
|
299
304
|
end
|
300
305
|
|
301
306
|
def add_search_flags(tool_definition)
|
@@ -307,10 +312,11 @@ module Toys
|
|
307
312
|
desc: "Search subtools for the given regular expression"
|
308
313
|
)
|
309
314
|
end
|
315
|
+
search_flags
|
310
316
|
end
|
311
317
|
|
312
|
-
def resolve_flags_spec(flags,
|
313
|
-
flags = flags.call(
|
318
|
+
def resolve_flags_spec(flags, tool_definition, defaults)
|
319
|
+
flags = flags.call(tool_definition) if flags.respond_to?(:call)
|
314
320
|
case flags
|
315
321
|
when true, :default
|
316
322
|
Array(defaults)
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# Copyright 2018 Daniel Azuma
|
2
4
|
#
|
3
5
|
# All rights reserved.
|
@@ -46,7 +48,7 @@ module Toys
|
|
46
48
|
# Default description for the version flags
|
47
49
|
# @return [String]
|
48
50
|
#
|
49
|
-
DEFAULT_VERSION_FLAG_DESC = "Display the version"
|
51
|
+
DEFAULT_VERSION_FLAG_DESC = "Display the version"
|
50
52
|
|
51
53
|
##
|
52
54
|
# Key set when the version flag is present
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# Copyright 2018 Daniel Azuma
|
2
4
|
#
|
3
5
|
# All rights reserved.
|
@@ -43,6 +45,23 @@ module Toys
|
|
43
45
|
# This is a frontend for {Toys::Utils::Exec}. More information is
|
44
46
|
# available in that class's documentation.
|
45
47
|
#
|
48
|
+
# ## Configuration Options
|
49
|
+
#
|
50
|
+
# Subprocesses may be configured using the options in the
|
51
|
+
# {Toys::Utils::Exec} class. These include a variety of options supported
|
52
|
+
# by `Process#spawn`, and some options supported by {Toys::Utils::Exec}
|
53
|
+
# itself.
|
54
|
+
#
|
55
|
+
# In addition, this mixin supports one more option,
|
56
|
+
# `exit_on_nonzero_status`. When set to true, if any subprocess returns a
|
57
|
+
# nonzero result code, the tool will immediately exit with that same code,
|
58
|
+
# similar to `set -e` in a bash script.
|
59
|
+
#
|
60
|
+
# You can set initial configuration by passing options to the `include`
|
61
|
+
# directive. For example:
|
62
|
+
#
|
63
|
+
# include :exec, exit_on_nonzero_status: true
|
64
|
+
#
|
46
65
|
module Exec
|
47
66
|
include Mixin
|
48
67
|
|
@@ -54,6 +73,7 @@ module Toys
|
|
54
73
|
|
55
74
|
to_initialize do |opts = {}|
|
56
75
|
tool = self
|
76
|
+
opts = Exec._setup_exec_opts(opts, tool)
|
57
77
|
tool[KEY] = Utils::Exec.new(opts) do |k|
|
58
78
|
case k
|
59
79
|
when :logger
|
@@ -67,8 +87,10 @@ module Toys
|
|
67
87
|
##
|
68
88
|
# Set default configuration keys.
|
69
89
|
#
|
70
|
-
#
|
71
|
-
#
|
90
|
+
# All options listed in the {Toys::Utils::Exec} documentation are
|
91
|
+
# supported, plus the `exit_on_nonzero_status` option.
|
92
|
+
#
|
93
|
+
# @param [Hash] opts The default options.
|
72
94
|
#
|
73
95
|
def configure_exec(opts = {})
|
74
96
|
self[KEY].configure_defaults(Exec._setup_exec_opts(opts, self))
|
@@ -82,8 +104,9 @@ module Toys
|
|
82
104
|
# yielded to it, allowing you to interact with the subprocess streams.
|
83
105
|
#
|
84
106
|
# @param [String,Array<String>] cmd The command to execute.
|
85
|
-
# @param [Hash] opts The command options.
|
86
|
-
#
|
107
|
+
# @param [Hash] opts The command options. All options listed in the
|
108
|
+
# {Toys::Utils::Exec} documentation are supported, plus the
|
109
|
+
# `exit_on_nonzero_status` option.
|
87
110
|
# @yieldparam controller [Toys::Utils::Exec::Controller] A controller for
|
88
111
|
# the subprocess streams.
|
89
112
|
#
|
@@ -101,8 +124,9 @@ module Toys
|
|
101
124
|
# yielded to it, allowing you to interact with the subprocess streams.
|
102
125
|
#
|
103
126
|
# @param [String,Array<String>] args The arguments to ruby.
|
104
|
-
# @param [Hash] opts The command options.
|
105
|
-
#
|
127
|
+
# @param [Hash] opts The command options. All options listed in the
|
128
|
+
# {Toys::Utils::Exec} documentation are supported, plus the
|
129
|
+
# `exit_on_nonzero_status` option.
|
106
130
|
# @yieldparam controller [Toys::Utils::Exec::Controller] A controller for
|
107
131
|
# for the subprocess streams.
|
108
132
|
#
|
@@ -121,8 +145,9 @@ module Toys
|
|
121
145
|
# yielded to it, allowing you to interact with the subprocess streams.
|
122
146
|
#
|
123
147
|
# @param [Proc] func The proc to call.
|
124
|
-
# @param [Hash] opts The command options.
|
125
|
-
#
|
148
|
+
# @param [Hash] opts The command options. Most options listed in the
|
149
|
+
# {Toys::Utils::Exec} documentation are supported, plus the
|
150
|
+
# `exit_on_nonzero_status` option.
|
126
151
|
# @yieldparam controller [Toys::Utils::Exec::Controller] A controller
|
127
152
|
# for the subprocess streams.
|
128
153
|
#
|
@@ -141,8 +166,9 @@ module Toys
|
|
141
166
|
# yielded to it, allowing you to interact with the subprocess streams.
|
142
167
|
#
|
143
168
|
# @param [String,Array<String>] cmd The tool to execute.
|
144
|
-
# @param [Hash] opts The command options.
|
145
|
-
#
|
169
|
+
# @param [Hash] opts The command options. Most options listed in the
|
170
|
+
# {Toys::Utils::Exec} documentation are supported, plus the
|
171
|
+
# `exit_on_nonzero_status` option.
|
146
172
|
# @yieldparam controller [Toys::Utils::Exec::Controller] A controller
|
147
173
|
# for the subprocess streams.
|
148
174
|
#
|
@@ -161,8 +187,9 @@ module Toys
|
|
161
187
|
# Captures standard out and returns it as a string.
|
162
188
|
#
|
163
189
|
# @param [String,Array<String>] cmd The command to execute.
|
164
|
-
# @param [Hash] opts The command options.
|
165
|
-
#
|
190
|
+
# @param [Hash] opts The command options. All options listed in the
|
191
|
+
# {Toys::Utils::Exec} documentation are supported, plus the
|
192
|
+
# `exit_on_nonzero_status` option.
|
166
193
|
#
|
167
194
|
# @return [String] What was written to standard out.
|
168
195
|
#
|
@@ -176,8 +203,9 @@ module Toys
|
|
176
203
|
# Captures standard out and returns it as a string.
|
177
204
|
#
|
178
205
|
# @param [String,Array<String>] args The arguments to ruby.
|
179
|
-
# @param [Hash] opts The command options.
|
180
|
-
#
|
206
|
+
# @param [Hash] opts The command options. All options listed in the
|
207
|
+
# {Toys::Utils::Exec} documentation are supported, plus the
|
208
|
+
# `exit_on_nonzero_status` option.
|
181
209
|
#
|
182
210
|
# @return [String] What was written to standard out.
|
183
211
|
#
|
@@ -191,8 +219,9 @@ module Toys
|
|
191
219
|
# Captures standard out and returns it as a string.
|
192
220
|
#
|
193
221
|
# @param [Proc] func The proc to call.
|
194
|
-
# @param [Hash] opts The command options.
|
195
|
-
#
|
222
|
+
# @param [Hash] opts The command options. Most options listed in the
|
223
|
+
# {Toys::Utils::Exec} documentation are supported, plus the
|
224
|
+
# `exit_on_nonzero_status` option.
|
196
225
|
#
|
197
226
|
# @return [String] What was written to standard out.
|
198
227
|
#
|
@@ -207,8 +236,9 @@ module Toys
|
|
207
236
|
# Captures standard out and returns it as a string.
|
208
237
|
#
|
209
238
|
# @param [String,Array<String>] cmd The tool to execute.
|
210
|
-
# @param [Hash] opts The command options.
|
211
|
-
#
|
239
|
+
# @param [Hash] opts The command options. Most options listed in the
|
240
|
+
# {Toys::Utils::Exec} documentation are supported, plus the
|
241
|
+
# `exit_on_nonzero_status` option.
|
212
242
|
#
|
213
243
|
# @return [String] What was written to standard out.
|
214
244
|
#
|
@@ -221,8 +251,9 @@ module Toys
|
|
221
251
|
# Execute the given string in a shell. Returns the exit code.
|
222
252
|
#
|
223
253
|
# @param [String] cmd The shell command to execute.
|
224
|
-
# @param [Hash] opts The command options.
|
225
|
-
#
|
254
|
+
# @param [Hash] opts The command options. All options listed in the
|
255
|
+
# {Toys::Utils::Exec} documentation are supported, plus the
|
256
|
+
# `exit_on_nonzero_status` option.
|
226
257
|
#
|
227
258
|
# @return [Integer] The exit code
|
228
259
|
#
|
@@ -238,7 +269,7 @@ module Toys
|
|
238
269
|
def exit_on_nonzero_status(status)
|
239
270
|
status = status.exit_code if status.respond_to?(:exit_code)
|
240
271
|
status = status.exitstatus if status.respond_to?(:exitstatus)
|
241
|
-
exit(status) unless status.zero?
|
272
|
+
Tool.exit(status) unless status.zero?
|
242
273
|
0
|
243
274
|
end
|
244
275
|
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# Copyright 2018 Daniel Azuma
|
2
4
|
#
|
3
5
|
# All rights reserved.
|
@@ -35,16 +37,33 @@ module Toys
|
|
35
37
|
##
|
36
38
|
# A mixin that provides access to the capabilities of the highline gem.
|
37
39
|
#
|
40
|
+
# This mixin requires the highline gem, version 2.0 or later. It will
|
41
|
+
# attempt to install the gem if it is not available.
|
42
|
+
#
|
38
43
|
# You may make these methods available to your tool by including the
|
39
44
|
# following directive in your tool configuration:
|
40
45
|
#
|
41
46
|
# include :highline
|
42
47
|
#
|
48
|
+
# A HighLine object will then be available by calling the {#highline}
|
49
|
+
# method. For information on using this object, see the
|
50
|
+
# [Highline documentation](https://www.rubydoc.info/gems/highline). Some of
|
51
|
+
# the most common HighLine methods, such as `say`, are also mixed into the
|
52
|
+
# tool and can be called directly.
|
53
|
+
#
|
54
|
+
# You can configure the HighLine object by passing options to the `include`
|
55
|
+
# directive. For example:
|
56
|
+
#
|
57
|
+
# include :highline, my_stdin, my_stdout
|
58
|
+
#
|
59
|
+
# The arguments will be passed on to the
|
60
|
+
# [HighLine constructor](https://www.rubydoc.info/gems/highline/HighLine:initialize).
|
61
|
+
#
|
43
62
|
module Highline
|
44
63
|
include Mixin
|
45
64
|
|
46
65
|
##
|
47
|
-
# Context key for the
|
66
|
+
# Context key for the highline object.
|
48
67
|
# @return [Object]
|
49
68
|
#
|
50
69
|
KEY = ::Object.new.freeze
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# Copyright 2018 Daniel Azuma
|
2
4
|
#
|
3
5
|
# All rights reserved.
|
@@ -41,6 +43,18 @@ module Toys
|
|
41
43
|
#
|
42
44
|
# include :terminal
|
43
45
|
#
|
46
|
+
# A Terminal object will then be available by calling the {#terminal}
|
47
|
+
# method. For information on using this object, see the documentation for
|
48
|
+
# {Toys::Utils::Terminal}. Some of the most useful methods are also mixed
|
49
|
+
# into the tool and can be called directly.
|
50
|
+
#
|
51
|
+
# You can configure the Terminal object by passing options to the `include`
|
52
|
+
# directive. For example:
|
53
|
+
#
|
54
|
+
# include :terminal, styled: true
|
55
|
+
#
|
56
|
+
# The arguments will be passed on to {Toys::Utils::Terminal#initialize}.
|
57
|
+
#
|
44
58
|
module Terminal
|
45
59
|
include Mixin
|
46
60
|
|
@@ -79,8 +93,8 @@ module Toys
|
|
79
93
|
##
|
80
94
|
# @see Toys::Utils::Terminal#confirm
|
81
95
|
#
|
82
|
-
def confirm(prompt = "Proceed?")
|
83
|
-
terminal.confirm(prompt)
|
96
|
+
def confirm(prompt = "Proceed?", default: false)
|
97
|
+
terminal.confirm(prompt, default: default)
|
84
98
|
end
|
85
99
|
|
86
100
|
##
|
data/lib/toys/template.rb
CHANGED
data/lib/toys/tool.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# Copyright 2018 Daniel Azuma
|
2
4
|
#
|
3
5
|
# All rights reserved.
|
@@ -272,9 +274,19 @@ module Toys
|
|
272
274
|
# Exit immediately with the given status code
|
273
275
|
#
|
274
276
|
# @param [Integer] code The status code, which should be 0 for no error,
|
275
|
-
# or nonzero for an error condition.
|
277
|
+
# or nonzero for an error condition. Default is 0.
|
278
|
+
#
|
279
|
+
def exit(code = 0)
|
280
|
+
throw :result, code
|
281
|
+
end
|
282
|
+
|
283
|
+
##
|
284
|
+
# Exit immediately with the given status code
|
285
|
+
#
|
286
|
+
# @param [Integer] code The status code, which should be 0 for no error,
|
287
|
+
# or nonzero for an error condition. Default is 0.
|
276
288
|
#
|
277
|
-
def exit(code)
|
289
|
+
def self.exit(code = 0)
|
278
290
|
throw :result, code
|
279
291
|
end
|
280
292
|
end
|
data/lib/toys/utils/exec.rb
CHANGED
data/lib/toys/utils/gems.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# Copyright 2018 Daniel Azuma
|
2
4
|
#
|
3
5
|
# All rights reserved.
|
@@ -60,16 +62,17 @@ module Toys
|
|
60
62
|
#
|
61
63
|
# @param [String] name Name of the gem
|
62
64
|
# @param [String...] requirements Version requirements
|
65
|
+
# @param [Boolean] default_confirm Default response for the confirmation prompt
|
63
66
|
#
|
64
|
-
def self.activate(name, *requirements)
|
65
|
-
new.activate(name, *requirements)
|
67
|
+
def self.activate(name, *requirements, default_confirm: false)
|
68
|
+
new.activate(name, *requirements, default_confirm: default_confirm)
|
66
69
|
end
|
67
70
|
|
68
71
|
##
|
69
72
|
# Create a new gem activator.
|
70
73
|
#
|
71
|
-
def initialize
|
72
|
-
@terminal = Terminal.new(output:
|
74
|
+
def initialize(input: $stdin, output: $stderr)
|
75
|
+
@terminal = Terminal.new(input: input, output: output)
|
73
76
|
@exec = Exec.new
|
74
77
|
end
|
75
78
|
|
@@ -79,11 +82,12 @@ module Toys
|
|
79
82
|
#
|
80
83
|
# @param [String] name Name of the gem
|
81
84
|
# @param [String...] requirements Version requirements
|
85
|
+
# @param [Boolean] default_confirm Default response for the confirmation prompt
|
82
86
|
#
|
83
|
-
def activate(name, *requirements)
|
87
|
+
def activate(name, *requirements, default_confirm: false)
|
84
88
|
gem(name, *requirements)
|
85
89
|
rescue ::Gem::MissingSpecError
|
86
|
-
install_gem(name, requirements)
|
90
|
+
install_gem(name, requirements, default_confirm: default_confirm)
|
87
91
|
rescue ::Gem::LoadError => e
|
88
92
|
if ::ENV["BUNDLE_GEMFILE"]
|
89
93
|
raise GemfileUpdateNeededError.new(gem_requirements_text(name, requirements),
|
@@ -98,9 +102,10 @@ module Toys
|
|
98
102
|
"#{name.inspect}, #{requirements.map(&:inspect).join(', ')}"
|
99
103
|
end
|
100
104
|
|
101
|
-
def install_gem(name, requirements)
|
105
|
+
def install_gem(name, requirements, default_confirm: false)
|
102
106
|
requirements_text = gem_requirements_text(name, requirements)
|
103
|
-
response = @terminal.confirm("Gem needed: #{requirements_text}. Install?"
|
107
|
+
response = @terminal.confirm("Gem needed: #{requirements_text}. Install?",
|
108
|
+
default: default_confirm)
|
104
109
|
unless response
|
105
110
|
raise InstallFailedError, "Canceled installation of needed gem: #{requirements_text}"
|
106
111
|
end
|
data/lib/toys/utils/help_text.rb
CHANGED
data/lib/toys/utils/terminal.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# Copyright 2018 Daniel Azuma
|
2
4
|
#
|
3
5
|
# All rights reserved.
|
@@ -54,7 +56,7 @@ module Toys
|
|
54
56
|
#
|
55
57
|
class Terminal
|
56
58
|
## ANSI style code to clear styles
|
57
|
-
CLEAR_CODE = "\e[0m"
|
59
|
+
CLEAR_CODE = "\e[0m"
|
58
60
|
|
59
61
|
## Standard ANSI style codes
|
60
62
|
BUILTIN_STYLE_NAMES = {
|
@@ -205,15 +207,21 @@ module Toys
|
|
205
207
|
# Confirm with the user.
|
206
208
|
#
|
207
209
|
# @param [String] prompt Prompt string. Defaults to `"Proceed?"`.
|
210
|
+
# @param [Boolean] default Default value (defaults to false).
|
208
211
|
# @return [Boolean]
|
209
212
|
#
|
210
|
-
def confirm(prompt = "Proceed?")
|
211
|
-
|
212
|
-
|
213
|
-
|
213
|
+
def confirm(prompt = "Proceed?", default: false)
|
214
|
+
y = default ? "Y" : "y"
|
215
|
+
n = default ? "n" : "N"
|
216
|
+
write("#{prompt} (#{y}/#{n}) ")
|
217
|
+
resp = input.gets.to_s.strip
|
218
|
+
case resp
|
219
|
+
when /^y/i
|
214
220
|
true
|
215
|
-
|
221
|
+
when /^n/i
|
216
222
|
false
|
223
|
+
when ""
|
224
|
+
default
|
217
225
|
else
|
218
226
|
confirm("Please answer \"y\" or \"n\"")
|
219
227
|
end
|
@@ -386,7 +394,7 @@ module Toys
|
|
386
394
|
@stopping = true
|
387
395
|
@cond.broadcast
|
388
396
|
end
|
389
|
-
@thread
|
397
|
+
@thread&.join
|
390
398
|
self
|
391
399
|
end
|
392
400
|
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# Copyright 2018 Daniel Azuma
|
2
4
|
#
|
3
5
|
# All rights reserved.
|
@@ -113,7 +115,7 @@ module Toys
|
|
113
115
|
line = "#{line} #{frag}"
|
114
116
|
end
|
115
117
|
end
|
116
|
-
lines << line if line_len
|
118
|
+
lines << line if line_len.positive?
|
117
119
|
lines
|
118
120
|
end
|
119
121
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: toys-core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.11
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Daniel Azuma
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-07-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: minitest
|
@@ -80,6 +80,20 @@ dependencies:
|
|
80
80
|
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0.9'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: highline
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '2.0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '2.0'
|
83
97
|
description: Toys-Core is the command line tool framework underlying Toys. It can
|
84
98
|
be used to create command line binaries using the internal Toys APIs.
|
85
99
|
email:
|
@@ -139,7 +153,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
139
153
|
requirements:
|
140
154
|
- - ">="
|
141
155
|
- !ruby/object:Gem::Version
|
142
|
-
version: 2.
|
156
|
+
version: 2.3.0
|
143
157
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
144
158
|
requirements:
|
145
159
|
- - ">="
|