toys-core 0.14.7 → 0.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +28 -0
- data/LICENSE.md +1 -1
- data/README.md +10 -5
- data/docs/guide.md +534 -39
- data/lib/toys/cli.rb +76 -172
- data/lib/toys/compat.rb +15 -30
- data/lib/toys/context.rb +51 -0
- data/lib/toys/core.rb +1 -1
- data/lib/toys/dsl/flag.rb +40 -2
- data/lib/toys/dsl/flag_group.rb +15 -5
- data/lib/toys/dsl/internal.rb +23 -8
- data/lib/toys/dsl/positional_arg.rb +32 -1
- data/lib/toys/dsl/tool.rb +174 -68
- data/lib/toys/errors.rb +2 -2
- data/lib/toys/middleware.rb +3 -2
- data/lib/toys/settings.rb +1 -1
- data/lib/toys/standard_mixins/bundler.rb +16 -1
- data/lib/toys/standard_mixins/exec.rb +29 -8
- data/lib/toys/standard_mixins/gems.rb +17 -3
- data/lib/toys/standard_mixins/highline.rb +12 -12
- data/lib/toys/standard_mixins/terminal.rb +7 -7
- data/lib/toys/tool_definition.rb +153 -50
- data/lib/toys/utils/exec.rb +22 -1
- data/lib/toys/utils/gems.rb +3 -0
- data/lib/toys/utils/standard_ui.rb +261 -0
- data/lib/toys-core.rb +51 -3
- metadata +6 -5
data/lib/toys/cli.rb
CHANGED
@@ -72,7 +72,7 @@ module Toys
|
|
72
72
|
# * `preload_dir_name`: Name of preload directories in tool directories
|
73
73
|
# * `data_dir_name`: Name of data directories in tool directories
|
74
74
|
#
|
75
|
-
# @param logger [Logger] A global logger to use for all tools. This
|
75
|
+
# @param logger [Logger] A global logger to use for all tools. This can be
|
76
76
|
# set if the CLI will call at most one tool at a time. However, it will
|
77
77
|
# behave incorrectly if CLI might run multiple tools at the same time
|
78
78
|
# with different verbosity settings (since the logger cannot have
|
@@ -80,19 +80,21 @@ module Toys
|
|
80
80
|
# global logger, but use the `logger_factory` parameter instead.
|
81
81
|
# @param logger_factory [Proc] A proc that takes a {Toys::ToolDefinition}
|
82
82
|
# as an argument, and returns a `Logger` to use when running that tool.
|
83
|
-
# Optional. If not provided (and no global logger is set),
|
84
|
-
#
|
85
|
-
# output to `STDERR`, as defined by {Toys::CLI.default_logger_factory}.
|
83
|
+
# Optional. If not provided (and no global logger is set),
|
84
|
+
# {Toys::CLI.default_logger_factory} is called to get a basic default.
|
86
85
|
# @param base_level [Integer] The logger level that should correspond
|
87
86
|
# to zero verbosity.
|
88
87
|
# Optional. If not provided, defaults to the current level of the
|
89
88
|
# logger (which is often `Logger::WARN`).
|
90
|
-
# @param error_handler [Proc,nil] A proc that is called when an
|
91
|
-
#
|
92
|
-
#
|
93
|
-
#
|
94
|
-
# {Toys::
|
95
|
-
#
|
89
|
+
# @param error_handler [Proc,nil] A proc that is called when an unhandled
|
90
|
+
# exception (a normal exception subclassing `StandardError`, an error
|
91
|
+
# loading a toys config file subclassing `SyntaxError`, or an unhandled
|
92
|
+
# signal subclassing `SignalException`) is detected. The proc should
|
93
|
+
# take a {Toys::ContextualError}, whose cause is the unhandled
|
94
|
+
# exception, as the sole argument, and report the error. It should
|
95
|
+
# return an exit code (normally nonzero) appropriate to the error.
|
96
|
+
# Optional. If not provided, {Toys::CLI.default_error_handler} is
|
97
|
+
# called to get a basic default handler.
|
96
98
|
# @param executable_name [String] The executable name displayed in help
|
97
99
|
# text. Optional. Defaults to the ruby program name.
|
98
100
|
#
|
@@ -101,9 +103,8 @@ module Toys
|
|
101
103
|
# characters are period, colon, and slash.
|
102
104
|
# @param completion [Toys::Completion::Base] A specifier for shell tab
|
103
105
|
# completion for the CLI as a whole.
|
104
|
-
# Optional. If not provided,
|
105
|
-
#
|
106
|
-
# relevant tool.
|
106
|
+
# Optional. If not provided, {Toys::CLI.default_completion} is called
|
107
|
+
# to get a default completion that delegates to the tool.
|
107
108
|
#
|
108
109
|
# @param middleware_stack [Array<Toys::Middleware::Spec>] An array of
|
109
110
|
# middleware that will be used by default for all tools.
|
@@ -198,8 +199,8 @@ module Toys
|
|
198
199
|
@mixin_lookup = mixin_lookup || CLI.default_mixin_lookup
|
199
200
|
@middleware_lookup = middleware_lookup || CLI.default_middleware_lookup
|
200
201
|
@template_lookup = template_lookup || CLI.default_template_lookup
|
201
|
-
@error_handler = error_handler ||
|
202
|
-
@completion = completion ||
|
202
|
+
@error_handler = error_handler || CLI.default_error_handler
|
203
|
+
@completion = completion || CLI.default_completion
|
203
204
|
@logger = logger
|
204
205
|
@logger_factory = logger ? proc { logger } : logger_factory || CLI.default_logger_factory
|
205
206
|
@base_level = base_level
|
@@ -461,9 +462,10 @@ module Toys
|
|
461
462
|
context = build_context(tool, remaining,
|
462
463
|
verbosity: verbosity,
|
463
464
|
delegated_from: delegated_from)
|
464
|
-
|
465
|
+
run_handler = make_run_handler(tool)
|
466
|
+
execute_tool(tool, context, &run_handler)
|
465
467
|
end
|
466
|
-
rescue ContextualError
|
468
|
+
rescue ContextualError => e
|
467
469
|
@error_handler.call(e).to_i
|
468
470
|
end
|
469
471
|
|
@@ -487,102 +489,6 @@ module Toys
|
|
487
489
|
end
|
488
490
|
end
|
489
491
|
|
490
|
-
##
|
491
|
-
# A basic error handler that prints out captured errors to a stream or
|
492
|
-
# a logger.
|
493
|
-
#
|
494
|
-
class DefaultErrorHandler
|
495
|
-
##
|
496
|
-
# Create an error handler.
|
497
|
-
#
|
498
|
-
# @param output [IO,nil] Where to write errors. Default is `$stderr`.
|
499
|
-
#
|
500
|
-
def initialize(output: $stderr)
|
501
|
-
require "toys/utils/terminal"
|
502
|
-
@terminal = Utils::Terminal.new(output: output)
|
503
|
-
end
|
504
|
-
|
505
|
-
##
|
506
|
-
# The error handler routine. Prints out the error message and backtrace,
|
507
|
-
# and returns the correct result code.
|
508
|
-
#
|
509
|
-
# @param error [Exception] The error that occurred.
|
510
|
-
# @return [Integer] The result code for the execution.
|
511
|
-
#
|
512
|
-
def call(error)
|
513
|
-
cause = error
|
514
|
-
case error
|
515
|
-
when ContextualError
|
516
|
-
cause = error.cause
|
517
|
-
@terminal.puts(cause_string(cause))
|
518
|
-
@terminal.puts(context_string(error), :bold)
|
519
|
-
when ::Interrupt
|
520
|
-
@terminal.puts
|
521
|
-
@terminal.puts("INTERRUPTED", :bold)
|
522
|
-
else
|
523
|
-
@terminal.puts(cause_string(error))
|
524
|
-
end
|
525
|
-
exit_code_for(cause)
|
526
|
-
end
|
527
|
-
|
528
|
-
private
|
529
|
-
|
530
|
-
def exit_code_for(error)
|
531
|
-
case error
|
532
|
-
when ArgParsingError
|
533
|
-
2
|
534
|
-
when NotRunnableError
|
535
|
-
126
|
536
|
-
when ::Interrupt
|
537
|
-
130
|
538
|
-
else
|
539
|
-
1
|
540
|
-
end
|
541
|
-
end
|
542
|
-
|
543
|
-
def cause_string(cause)
|
544
|
-
lines = ["#{cause.class}: #{cause.message}"]
|
545
|
-
cause.backtrace.each_with_index.reverse_each do |bt, i|
|
546
|
-
lines << " #{(i + 1).to_s.rjust(3)}: #{bt}"
|
547
|
-
end
|
548
|
-
lines.join("\n")
|
549
|
-
end
|
550
|
-
|
551
|
-
def context_string(error)
|
552
|
-
lines = [
|
553
|
-
error.banner || "Unexpected error!",
|
554
|
-
" #{error.cause.class}: #{error.cause.message}",
|
555
|
-
]
|
556
|
-
if error.config_path
|
557
|
-
lines << " in config file: #{error.config_path}:#{error.config_line}"
|
558
|
-
end
|
559
|
-
if error.tool_name
|
560
|
-
lines << " while executing tool: #{error.tool_name.join(' ').inspect}"
|
561
|
-
if error.tool_args
|
562
|
-
lines << " with arguments: #{error.tool_args.inspect}"
|
563
|
-
end
|
564
|
-
end
|
565
|
-
lines.join("\n")
|
566
|
-
end
|
567
|
-
end
|
568
|
-
|
569
|
-
##
|
570
|
-
# A Completion that implements the default algorithm for a CLI. This
|
571
|
-
# algorithm simply determines the tool and uses its completion.
|
572
|
-
#
|
573
|
-
class DefaultCompletion < Completion::Base
|
574
|
-
##
|
575
|
-
# Returns candidates for the current completion.
|
576
|
-
#
|
577
|
-
# @param context [Toys::Completion::Context] the current completion
|
578
|
-
# context including the string fragment.
|
579
|
-
# @return [Array<Toys::Completion::Candidate>] an array of candidates
|
580
|
-
#
|
581
|
-
def call(context)
|
582
|
-
context.tool.completion.call(context)
|
583
|
-
end
|
584
|
-
end
|
585
|
-
|
586
492
|
class << self
|
587
493
|
##
|
588
494
|
# Returns a default set of middleware that may be used as a starting
|
@@ -637,56 +543,43 @@ module Toys
|
|
637
543
|
end
|
638
544
|
|
639
545
|
##
|
640
|
-
# Returns a
|
641
|
-
#
|
642
|
-
#
|
643
|
-
#
|
546
|
+
# Returns a bare-bones error handler that takes simply reraises the
|
547
|
+
# error. If the original error (the cause of the {Toys::ContextualError})
|
548
|
+
# was a `SignalException` (or a subclass such as `Interrupted`), that
|
549
|
+
# `SignalException` itself is reraised so that the Ruby VM has a chance
|
550
|
+
# to handle it. Otherwise, for any other error, the
|
551
|
+
# {Toys::ContextualError} is reraised.
|
552
|
+
#
|
553
|
+
# @return [Proc]
|
554
|
+
#
|
555
|
+
def default_error_handler
|
556
|
+
proc do |error|
|
557
|
+
cause = error.cause
|
558
|
+
raise cause.is_a?(::SignalException) ? cause : error
|
559
|
+
end
|
560
|
+
end
|
561
|
+
|
562
|
+
##
|
563
|
+
# Returns a default logger factory that generates simple loggers that
|
564
|
+
# write to STDERR.
|
644
565
|
#
|
645
566
|
# @return [Proc]
|
646
567
|
#
|
647
568
|
def default_logger_factory
|
648
|
-
require "toys/utils/terminal"
|
649
|
-
shared_terminal = Utils::Terminal.new(output: $stderr)
|
650
569
|
proc do
|
651
|
-
logger = ::Logger.new(
|
652
|
-
logger.formatter = proc do |severity, time, _progname, msg|
|
653
|
-
msg_str =
|
654
|
-
case msg
|
655
|
-
when ::String
|
656
|
-
msg
|
657
|
-
when ::Exception
|
658
|
-
"#{msg.message} (#{msg.class})\n" << (msg.backtrace || []).join("\n")
|
659
|
-
else
|
660
|
-
msg.inspect
|
661
|
-
end
|
662
|
-
format_log(shared_terminal, time, severity, msg_str)
|
663
|
-
end
|
570
|
+
logger = ::Logger.new($stderr)
|
664
571
|
logger.level = ::Logger::WARN
|
665
572
|
logger
|
666
573
|
end
|
667
574
|
end
|
668
575
|
|
669
|
-
|
670
|
-
|
671
|
-
|
672
|
-
|
673
|
-
|
674
|
-
|
675
|
-
|
676
|
-
when "FATAL"
|
677
|
-
terminal.apply_styles(header, :bright_magenta, :bold, :underline)
|
678
|
-
when "ERROR"
|
679
|
-
terminal.apply_styles(header, :bright_red, :bold)
|
680
|
-
when "WARN"
|
681
|
-
terminal.apply_styles(header, :bright_yellow)
|
682
|
-
when "INFO"
|
683
|
-
terminal.apply_styles(header, :bright_cyan)
|
684
|
-
when "DEBUG"
|
685
|
-
terminal.apply_styles(header, :white)
|
686
|
-
else
|
687
|
-
header
|
688
|
-
end
|
689
|
-
"#{styled_header} #{msg}\n"
|
576
|
+
##
|
577
|
+
# Returns a default Completion that simply uses the tool's completion.
|
578
|
+
#
|
579
|
+
def default_completion
|
580
|
+
proc do |context|
|
581
|
+
context.tool.completion.call(context)
|
582
|
+
end
|
690
583
|
end
|
691
584
|
end
|
692
585
|
|
@@ -704,7 +597,20 @@ module Toys
|
|
704
597
|
tool.tool_class.new(arg_parser.data)
|
705
598
|
end
|
706
599
|
|
707
|
-
def
|
600
|
+
def make_run_handler(tool)
|
601
|
+
run_handler = tool.run_handler
|
602
|
+
if run_handler.is_a?(::Symbol)
|
603
|
+
proc do |context|
|
604
|
+
context.send(run_handler)
|
605
|
+
end
|
606
|
+
else
|
607
|
+
proc do |context|
|
608
|
+
context.instance_exec(&run_handler)
|
609
|
+
end
|
610
|
+
end
|
611
|
+
end
|
612
|
+
|
613
|
+
def execute_tool(tool, context, &block)
|
708
614
|
tool.source_info&.apply_lib_paths
|
709
615
|
tool.run_initializers(context)
|
710
616
|
cur_logger = context[Context::Key::LOGGER]
|
@@ -713,9 +619,7 @@ module Toys
|
|
713
619
|
cur_logger.level = (base_level || original_level) - context[Context::Key::VERBOSITY].to_i
|
714
620
|
end
|
715
621
|
begin
|
716
|
-
executor = build_executor(tool, context)
|
717
|
-
yield context
|
718
|
-
end
|
622
|
+
executor = build_executor(tool, context, &block)
|
719
623
|
catch(:result) do
|
720
624
|
executor.call
|
721
625
|
0
|
@@ -733,11 +637,10 @@ module Toys
|
|
733
637
|
elsif !tool.runnable?
|
734
638
|
raise NotRunnableError, "No implementation for tool #{tool.display_name.inspect}"
|
735
639
|
else
|
736
|
-
yield
|
640
|
+
yield context
|
737
641
|
end
|
738
|
-
rescue ::
|
739
|
-
|
740
|
-
handle_interrupt(context, tool.interrupt_handler, e)
|
642
|
+
rescue ::SignalException => e
|
643
|
+
handle_signal_by_tool(context, tool, e)
|
741
644
|
end
|
742
645
|
end
|
743
646
|
tool.built_middleware.reverse_each do |middleware|
|
@@ -750,24 +653,25 @@ module Toys
|
|
750
653
|
usage_errors = context[Context::Key::USAGE_ERRORS]
|
751
654
|
handler = tool.usage_error_handler
|
752
655
|
raise ArgParsingError, usage_errors if handler.nil?
|
753
|
-
|
754
|
-
if handler.arity.zero?
|
755
|
-
context.instance_exec(&handler)
|
756
|
-
else
|
757
|
-
context.instance_exec(usage_errors, &handler)
|
758
|
-
end
|
656
|
+
call_handler(context, handler, usage_errors)
|
759
657
|
end
|
760
658
|
|
761
|
-
def
|
659
|
+
def handle_signal_by_tool(context, tool, exception)
|
660
|
+
handler = tool.signal_handler(exception.signo)
|
661
|
+
raise exception unless handler
|
662
|
+
call_handler(context, handler, exception)
|
663
|
+
rescue ::SignalException => e
|
664
|
+
raise e if e.equal?(exception)
|
665
|
+
handle_signal_by_tool(context, tool, e)
|
666
|
+
end
|
667
|
+
|
668
|
+
def call_handler(context, handler, argument)
|
762
669
|
handler = context.method(handler).to_proc if handler.is_a?(::Symbol)
|
763
670
|
if handler.arity.zero?
|
764
671
|
context.instance_exec(&handler)
|
765
672
|
else
|
766
|
-
context.instance_exec(
|
673
|
+
context.instance_exec(argument, &handler)
|
767
674
|
end
|
768
|
-
rescue ::Interrupt => e
|
769
|
-
raise e if e.equal?(exception)
|
770
|
-
handle_interrupt(context, handler, e)
|
771
675
|
end
|
772
676
|
|
773
677
|
def make_executor(middleware, context, next_executor)
|
data/lib/toys/compat.rb
CHANGED
@@ -12,37 +12,27 @@ module Toys
|
|
12
12
|
parts = ::RUBY_VERSION.split(".")
|
13
13
|
ruby_version = parts[0].to_i * 10000 + parts[1].to_i * 100 + parts[2].to_i
|
14
14
|
|
15
|
-
##
|
16
15
|
# @private
|
17
|
-
#
|
18
16
|
def self.jruby?
|
19
17
|
::RUBY_ENGINE == "jruby"
|
20
18
|
end
|
21
19
|
|
22
|
-
##
|
23
20
|
# @private
|
24
|
-
#
|
25
21
|
def self.truffleruby?
|
26
22
|
::RUBY_ENGINE == "truffleruby"
|
27
23
|
end
|
28
24
|
|
29
|
-
##
|
30
25
|
# @private
|
31
|
-
#
|
32
26
|
def self.windows?
|
33
27
|
::RbConfig::CONFIG["host_os"] =~ /mswin|msys|mingw|cygwin|bccwin|wince|emc/
|
34
28
|
end
|
35
29
|
|
36
|
-
##
|
37
30
|
# @private
|
38
|
-
#
|
39
31
|
def self.allow_fork?
|
40
32
|
!jruby? && !truffleruby? && !windows?
|
41
33
|
end
|
42
34
|
|
43
|
-
##
|
44
35
|
# @private
|
45
|
-
#
|
46
36
|
def self.supports_suggestions?
|
47
37
|
unless defined?(@supports_suggestions)
|
48
38
|
begin
|
@@ -60,9 +50,7 @@ module Toys
|
|
60
50
|
@supports_suggestions
|
61
51
|
end
|
62
52
|
|
63
|
-
##
|
64
53
|
# @private
|
65
|
-
#
|
66
54
|
def self.suggestions(word, list)
|
67
55
|
if supports_suggestions?
|
68
56
|
::DidYouMean::SpellChecker.new(dictionary: list).correct(word)
|
@@ -73,16 +61,12 @@ module Toys
|
|
73
61
|
|
74
62
|
# The :base argument to Dir.glob requires Ruby 2.5 or later.
|
75
63
|
if ruby_version >= 20500
|
76
|
-
##
|
77
64
|
# @private
|
78
|
-
#
|
79
65
|
def self.glob_in_dir(glob, dir)
|
80
66
|
::Dir.glob(glob, base: dir)
|
81
67
|
end
|
82
68
|
else
|
83
|
-
##
|
84
69
|
# @private
|
85
|
-
#
|
86
70
|
def self.glob_in_dir(glob, dir)
|
87
71
|
::Dir.chdir(dir) { ::Dir.glob(glob) }
|
88
72
|
end
|
@@ -90,16 +74,12 @@ module Toys
|
|
90
74
|
|
91
75
|
# Dir.children requires Ruby 2.5 or later.
|
92
76
|
if ruby_version >= 20500
|
93
|
-
##
|
94
77
|
# @private
|
95
|
-
#
|
96
78
|
def self.dir_children(dir)
|
97
79
|
::Dir.children(dir)
|
98
80
|
end
|
99
81
|
else
|
100
|
-
##
|
101
82
|
# @private
|
102
|
-
#
|
103
83
|
def self.dir_children(dir)
|
104
84
|
::Dir.entries(dir) - [".", ".."]
|
105
85
|
end
|
@@ -110,16 +90,12 @@ module Toys
|
|
110
90
|
# This also hits TruffleRuby
|
111
91
|
# (see https://github.com/oracle/truffleruby/issues/2567)
|
112
92
|
if ruby_version >= 20700 && !truffleruby?
|
113
|
-
##
|
114
93
|
# @private
|
115
|
-
#
|
116
94
|
def self.instantiate(klass, args, kwargs, block)
|
117
95
|
klass.new(*args, **kwargs, &block)
|
118
96
|
end
|
119
97
|
else
|
120
|
-
##
|
121
98
|
# @private
|
122
|
-
#
|
123
99
|
def self.instantiate(klass, args, kwargs, block)
|
124
100
|
formals = klass.instance_method(:initialize).parameters
|
125
101
|
if kwargs.empty? && formals.all? { |arg| arg.first != :key && arg.first != :keyrest }
|
@@ -133,26 +109,35 @@ module Toys
|
|
133
109
|
# File.absolute_path? requires Ruby 2.7 or later. For earlier Rubies, use
|
134
110
|
# an ad-hoc mechanism.
|
135
111
|
if ruby_version >= 20700
|
136
|
-
##
|
137
112
|
# @private
|
138
|
-
#
|
139
113
|
def self.absolute_path?(path)
|
140
114
|
::File.absolute_path?(path)
|
141
115
|
end
|
142
116
|
elsif ::Dir.getwd =~ /^[a-zA-Z]:/
|
143
|
-
##
|
144
117
|
# @private
|
145
|
-
#
|
146
118
|
def self.absolute_path?(path)
|
147
119
|
/^[a-zA-Z]:/.match?(path)
|
148
120
|
end
|
149
121
|
else
|
150
|
-
##
|
151
122
|
# @private
|
152
|
-
#
|
153
123
|
def self.absolute_path?(path)
|
154
124
|
path.start_with?("/")
|
155
125
|
end
|
156
126
|
end
|
127
|
+
|
128
|
+
# The second argument to method_defined? and private_method_defined?
|
129
|
+
# requires Ruby 2.6 or later.
|
130
|
+
if ruby_version >= 20600
|
131
|
+
# @private
|
132
|
+
def self.method_defined_without_ancestors?(klass, name)
|
133
|
+
klass.method_defined?(name, false) || klass.private_method_defined?(name, false)
|
134
|
+
end
|
135
|
+
else
|
136
|
+
# @private
|
137
|
+
def self.method_defined_without_ancestors?(klass, name)
|
138
|
+
klass.instance_methods(false).include?(name) ||
|
139
|
+
klass.private_instance_methods(false).include?(name)
|
140
|
+
end
|
141
|
+
end
|
157
142
|
end
|
158
143
|
end
|
data/lib/toys/context.rb
CHANGED
@@ -139,22 +139,30 @@ module Toys
|
|
139
139
|
#
|
140
140
|
# This is a convenience getter for {Toys::Context::Key::ARGS}.
|
141
141
|
#
|
142
|
+
# If the `args` method is overridden by the tool, you can still access it
|
143
|
+
# using the name `__args`.
|
144
|
+
#
|
142
145
|
# @return [Array<String>]
|
143
146
|
#
|
144
147
|
def args
|
145
148
|
@__data[Key::ARGS]
|
146
149
|
end
|
150
|
+
alias __args args
|
147
151
|
|
148
152
|
##
|
149
153
|
# The currently running CLI.
|
150
154
|
#
|
151
155
|
# This is a convenience getter for {Toys::Context::Key::CLI}.
|
152
156
|
#
|
157
|
+
# If the `cli` method is overridden by the tool, you can still access it
|
158
|
+
# using the name `__cli`.
|
159
|
+
#
|
153
160
|
# @return [Toys::CLI]
|
154
161
|
#
|
155
162
|
def cli
|
156
163
|
@__data[Key::CLI]
|
157
164
|
end
|
165
|
+
alias __cli cli
|
158
166
|
|
159
167
|
##
|
160
168
|
# Return the context directory for this tool. Generally, this defaults
|
@@ -164,71 +172,98 @@ module Toys
|
|
164
172
|
#
|
165
173
|
# This is a convenience getter for {Toys::Context::Key::CONTEXT_DIRECTORY}.
|
166
174
|
#
|
175
|
+
# If the `context_directory` method is overridden by the tool, you can
|
176
|
+
# still access it using the name `__context_directory`.
|
177
|
+
#
|
167
178
|
# @return [String] Context directory path
|
168
179
|
# @return [nil] if there is no context.
|
169
180
|
#
|
170
181
|
def context_directory
|
171
182
|
@__data[Key::CONTEXT_DIRECTORY]
|
172
183
|
end
|
184
|
+
alias __context_directory context_directory
|
173
185
|
|
174
186
|
##
|
175
187
|
# The logger for this execution.
|
176
188
|
#
|
177
189
|
# This is a convenience getter for {Toys::Context::Key::LOGGER}.
|
178
190
|
#
|
191
|
+
# If the `logger` method is overridden by the tool, you can still access it
|
192
|
+
# using the name `__logger`.
|
193
|
+
#
|
179
194
|
# @return [Logger]
|
180
195
|
#
|
181
196
|
def logger
|
182
197
|
@__data[Key::LOGGER]
|
183
198
|
end
|
199
|
+
alias __logger logger
|
184
200
|
|
185
201
|
##
|
186
202
|
# The full name of the tool being executed, as an array of strings.
|
187
203
|
#
|
188
204
|
# This is a convenience getter for {Toys::Context::Key::TOOL_NAME}.
|
189
205
|
#
|
206
|
+
# If the `tool_name` method is overridden by the tool, you can still access
|
207
|
+
# it using the name `__tool_name`.
|
208
|
+
#
|
190
209
|
# @return [Array<String>]
|
191
210
|
#
|
192
211
|
def tool_name
|
193
212
|
@__data[Key::TOOL_NAME]
|
194
213
|
end
|
214
|
+
alias __tool_name tool_name
|
195
215
|
|
196
216
|
##
|
197
217
|
# The source of the tool being executed.
|
198
218
|
#
|
199
219
|
# This is a convenience getter for {Toys::Context::Key::TOOL_SOURCE}.
|
200
220
|
#
|
221
|
+
# If the `tool_source` method is overridden by the tool, you can still
|
222
|
+
# access it using the name `__tool_source`.
|
223
|
+
#
|
201
224
|
# @return [Toys::SourceInfo]
|
202
225
|
#
|
203
226
|
def tool_source
|
204
227
|
@__data[Key::TOOL_SOURCE]
|
205
228
|
end
|
229
|
+
alias __tool_source tool_source
|
206
230
|
|
207
231
|
##
|
208
232
|
# The (possibly empty) array of errors detected during argument parsing.
|
209
233
|
#
|
210
234
|
# This is a convenience getter for {Toys::Context::Key::USAGE_ERRORS}.
|
211
235
|
#
|
236
|
+
# If the `usage_errors` method is overridden by the tool, you can still
|
237
|
+
# access it using the name `__usage_errors`.
|
238
|
+
#
|
212
239
|
# @return [Array<Toys::ArgParser::UsageError>]
|
213
240
|
#
|
214
241
|
def usage_errors
|
215
242
|
@__data[Key::USAGE_ERRORS]
|
216
243
|
end
|
244
|
+
alias __usage_errors usage_errors
|
217
245
|
|
218
246
|
##
|
219
247
|
# The current verbosity setting as an integer.
|
220
248
|
#
|
221
249
|
# This is a convenience getter for {Toys::Context::Key::VERBOSITY}.
|
222
250
|
#
|
251
|
+
# If the `verbosity` method is overridden by the tool, you can still access
|
252
|
+
# it using the name `__verbosity`.
|
253
|
+
#
|
223
254
|
# @return [Integer]
|
224
255
|
#
|
225
256
|
def verbosity
|
226
257
|
@__data[Key::VERBOSITY]
|
227
258
|
end
|
259
|
+
alias __verbosity verbosity
|
228
260
|
|
229
261
|
##
|
230
262
|
# Fetch an option or other piece of data by key.
|
231
263
|
#
|
264
|
+
# If the `get` method is overridden by the tool, you can still access it
|
265
|
+
# using the name `__get` or the `[]` operator.
|
266
|
+
#
|
232
267
|
# @param key [Symbol]
|
233
268
|
# @return [Object]
|
234
269
|
#
|
@@ -251,6 +286,9 @@ module Toys
|
|
251
286
|
##
|
252
287
|
# Set one or more options or other context data by key.
|
253
288
|
#
|
289
|
+
# If the `set` method is overridden by the tool, you can still access it
|
290
|
+
# using the name `__set`.
|
291
|
+
#
|
254
292
|
# @return [self]
|
255
293
|
#
|
256
294
|
# @overload set(key, value)
|
@@ -272,6 +310,7 @@ module Toys
|
|
272
310
|
end
|
273
311
|
self
|
274
312
|
end
|
313
|
+
alias __set set
|
275
314
|
|
276
315
|
##
|
277
316
|
# The subset of the context that uses string or symbol keys. By convention,
|
@@ -279,6 +318,9 @@ module Toys
|
|
279
318
|
# include well-known context values such as verbosity or private context
|
280
319
|
# values used by middleware or mixins.
|
281
320
|
#
|
321
|
+
# If the `options` method is overridden by the tool, you can still access
|
322
|
+
# it using the name `__options`.
|
323
|
+
#
|
282
324
|
# @return [Hash]
|
283
325
|
#
|
284
326
|
def options
|
@@ -286,10 +328,14 @@ module Toys
|
|
286
328
|
k.is_a?(::Symbol) || k.is_a?(::String)
|
287
329
|
end
|
288
330
|
end
|
331
|
+
alias __options options
|
289
332
|
|
290
333
|
##
|
291
334
|
# Find the given data file or directory in this tool's search path.
|
292
335
|
#
|
336
|
+
# If the `find_data` method is overridden by the tool, you can still access
|
337
|
+
# it using the name `__find_data`.
|
338
|
+
#
|
293
339
|
# @param path [String] The path to find
|
294
340
|
# @param type [nil,:file,:directory] Type of file system object to find,
|
295
341
|
# or nil to return any type.
|
@@ -300,10 +346,14 @@ module Toys
|
|
300
346
|
def find_data(path, type: nil)
|
301
347
|
@__data[Key::TOOL_SOURCE].find_data(path, type: type)
|
302
348
|
end
|
349
|
+
alias __find_data find_data
|
303
350
|
|
304
351
|
##
|
305
352
|
# Exit immediately with the given status code.
|
306
353
|
#
|
354
|
+
# If the `exit` method is overridden by the tool, you can still access it
|
355
|
+
# using the name `__exit` or by calling {Context.exit}.
|
356
|
+
#
|
307
357
|
# @param code [Integer] The status code, which should be 0 for no error,
|
308
358
|
# or nonzero for an error condition. Default is 0.
|
309
359
|
# @return [void]
|
@@ -311,6 +361,7 @@ module Toys
|
|
311
361
|
def exit(code = 0)
|
312
362
|
Context.exit(code)
|
313
363
|
end
|
364
|
+
alias __exit exit
|
314
365
|
|
315
366
|
##
|
316
367
|
# Exit immediately with the given status code. This class method can be
|