toys-core 0.3.10 → 0.3.11
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
- - ">="
|