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