toys-core 0.3.3 → 0.3.4
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 +23 -1
- data/lib/toys-core.rb +2 -0
- data/lib/toys/cli.rb +108 -15
- data/lib/toys/config_dsl.rb +101 -55
- data/lib/toys/context.rb +3 -3
- data/lib/toys/core_version.rb +1 -1
- data/lib/toys/errors.rb +76 -0
- data/lib/toys/helpers/highline.rb +0 -2
- data/lib/toys/helpers/spinner.rb +17 -11
- data/lib/toys/loader.rb +43 -18
- data/lib/toys/middleware.rb +14 -14
- data/lib/toys/middleware/add_verbosity_flags.rb +113 -0
- data/lib/toys/middleware/base.rb +1 -1
- data/lib/toys/middleware/handle_usage_errors.rb +15 -9
- data/lib/toys/middleware/set_default_descriptions.rb +114 -37
- data/lib/toys/middleware/show_help.rb +245 -0
- data/lib/toys/middleware/show_version.rb +20 -16
- data/lib/toys/templates/clean.rb +4 -1
- data/lib/toys/templates/gem_build.rb +3 -1
- data/lib/toys/templates/minitest.rb +5 -6
- data/lib/toys/tool.rb +418 -213
- data/lib/toys/utils/help_text.rb +487 -0
- data/lib/toys/utils/line_output.rb +105 -0
- data/lib/toys/utils/wrappable_string.rb +67 -19
- metadata +6 -5
- data/lib/toys/middleware/add_verbosity_switches.rb +0 -99
- data/lib/toys/middleware/show_usage.rb +0 -174
- data/lib/toys/utils/usage.rb +0 -250
data/lib/toys/middleware/base.rb
CHANGED
@@ -30,15 +30,16 @@
|
|
30
30
|
require "highline"
|
31
31
|
|
32
32
|
require "toys/middleware/base"
|
33
|
-
require "toys/utils/
|
33
|
+
require "toys/utils/help_text"
|
34
|
+
require "toys/utils/line_output"
|
34
35
|
|
35
36
|
module Toys
|
36
37
|
module Middleware
|
37
38
|
##
|
38
39
|
# This middleware handles the case of a usage error. If a usage error, such
|
39
|
-
# as an unrecognized
|
40
|
-
#
|
41
|
-
#
|
40
|
+
# as an unrecognized flag or an unfulfilled required argument, is detected,
|
41
|
+
# this middleware intercepts execution and displays the error along with
|
42
|
+
# the short help string, and terminates execution with an error code.
|
42
43
|
#
|
43
44
|
class HandleUsageErrors < Base
|
44
45
|
##
|
@@ -46,9 +47,14 @@ module Toys
|
|
46
47
|
#
|
47
48
|
# @param [Intgeer] exit_code The exit code to return if a usage error
|
48
49
|
# occurs. Default is -1.
|
50
|
+
# @param [IO] stream Output stream to write to. Default is stderr.
|
51
|
+
# @param [Boolean,nil] styled_output Cause the tool to display help text
|
52
|
+
# with ansi styles. If `nil`, display styles if the output stream is
|
53
|
+
# a tty. Default is `nil`.
|
49
54
|
#
|
50
|
-
def initialize(exit_code: -1)
|
55
|
+
def initialize(exit_code: -1, stream: $stderr, styled_output: nil)
|
51
56
|
@exit_code = exit_code
|
57
|
+
@output = Utils::LineOutput.new(stream, styled: styled_output)
|
52
58
|
end
|
53
59
|
|
54
60
|
##
|
@@ -57,10 +63,10 @@ module Toys
|
|
57
63
|
def execute(context)
|
58
64
|
if context[Context::USAGE_ERROR]
|
59
65
|
width = ::HighLine.new.output_cols
|
60
|
-
|
61
|
-
puts(context[Context::USAGE_ERROR])
|
62
|
-
puts("")
|
63
|
-
puts(
|
66
|
+
help_text = Utils::HelpText.from_context(context)
|
67
|
+
@output.puts(context[Context::USAGE_ERROR], :bright_red, :bold)
|
68
|
+
@output.puts("")
|
69
|
+
@output.puts(help_text.usage_string(wrap_width: width))
|
64
70
|
context.exit(@exit_code)
|
65
71
|
else
|
66
72
|
yield
|
@@ -41,89 +41,166 @@ module Toys
|
|
41
41
|
# The default description for tools.
|
42
42
|
# @return [String]
|
43
43
|
#
|
44
|
-
DEFAULT_TOOL_DESC = "(No description available)".freeze
|
44
|
+
DEFAULT_TOOL_DESC = "(No tool description available)".freeze
|
45
45
|
|
46
46
|
##
|
47
47
|
# The default description for groups.
|
48
48
|
# @return [String]
|
49
49
|
#
|
50
|
-
DEFAULT_GROUP_DESC = "(A group of
|
50
|
+
DEFAULT_GROUP_DESC = "(A group of tools)".freeze
|
51
51
|
|
52
52
|
##
|
53
53
|
# The default description for the root tool.
|
54
54
|
# @return [String]
|
55
55
|
#
|
56
|
-
DEFAULT_ROOT_DESC =
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
56
|
+
DEFAULT_ROOT_DESC = "Command line tool built using the toys-core gem.".freeze
|
57
|
+
|
58
|
+
##
|
59
|
+
# The default long description for the root tool.
|
60
|
+
# @return [String]
|
61
|
+
#
|
62
|
+
DEFAULT_ROOT_LONG_DESC =
|
63
|
+
"This command line tool was built using the toys-core gem. See" \
|
64
|
+
" https://www.rubydoc.info/gems/toys-core for more info. To replace this message," \
|
65
|
+
" configure the SetDefaultDescriptions middleware.".freeze
|
66
|
+
|
67
|
+
##
|
68
|
+
# The default description for flags.
|
69
|
+
# @return [String]
|
70
|
+
#
|
71
|
+
DEFAULT_FLAG_DESC = "(No flag description available)".freeze
|
72
|
+
|
73
|
+
##
|
74
|
+
# The default description for required args.
|
75
|
+
# @return [String]
|
76
|
+
#
|
77
|
+
DEFAULT_REQUIRED_ARG_DESC = "(Required argument - no description available)".freeze
|
78
|
+
|
79
|
+
##
|
80
|
+
# The default description for optional args.
|
81
|
+
# @return [String]
|
82
|
+
#
|
83
|
+
DEFAULT_OPTIONAL_ARG_DESC = "(Optional argument - no description available)".freeze
|
84
|
+
|
85
|
+
##
|
86
|
+
# The default description for remaining args.
|
87
|
+
# @return [String]
|
88
|
+
#
|
89
|
+
DEFAULT_REMAINING_ARG_DESC = "(Remaining arguments - no description available)".freeze
|
61
90
|
|
62
91
|
##
|
63
92
|
# Create a SetDefaultDescriptions middleware given default descriptions.
|
64
93
|
#
|
65
|
-
# @param [String] default_tool_desc The default short description for
|
66
|
-
# tools with an
|
94
|
+
# @param [String,nil] default_tool_desc The default short description for
|
95
|
+
# tools with an executor, or `nil` not to set one. Defaults to
|
96
|
+
# {DEFAULT_TOOL_DESC}.
|
67
97
|
# @param [String,nil] default_tool_long_desc The default long description
|
68
|
-
# for tools with an
|
69
|
-
#
|
70
|
-
# @param [String] default_group_desc The default short description
|
71
|
-
# tools with no
|
98
|
+
# for tools with an executor, or `nil` not to set one. Defaults to
|
99
|
+
# `nil`.
|
100
|
+
# @param [String,nil] default_group_desc The default short description
|
101
|
+
# for tools with no executor, or `nil` not to set one. Defaults to
|
102
|
+
# {DEFAULT_TOOL_DESC}.
|
72
103
|
# @param [String,nil] default_group_long_desc The default long
|
73
|
-
# description for tools with no
|
74
|
-
#
|
75
|
-
# @param [String] default_root_desc The default
|
76
|
-
# root tool. Defaults to
|
104
|
+
# description for tools with no executor, or `nil` not to set one.
|
105
|
+
# Defaults to `nil`.
|
106
|
+
# @param [String,nil] default_root_desc The default short description for
|
107
|
+
# the root tool, or `nil` not to set one. Defaults to
|
108
|
+
# {DEFAULT_ROOT_DESC}.
|
109
|
+
# @param [String,nil] default_root_long_desc The default long description
|
110
|
+
# for the root tool, or `nil` not to set one. Defaults to
|
111
|
+
# {DEFAULT_ROOT_LONG_DESC}.
|
112
|
+
# @param [String,nil] default_flag_desc The default short description for
|
113
|
+
# flags, or `nil` not to set one. Defaults to {DEFAULT_FLAG_DESC}.
|
114
|
+
# @param [String,nil] default_flag_long_desc The default long description
|
115
|
+
# for flags, or `nil` not to set one. Defaults to `nil`.
|
116
|
+
# @param [String,nil] default_required_arg_desc The default short
|
117
|
+
# description for required args, or `nil` not to set one. Defaults to
|
118
|
+
# {DEFAULT_REQUIRED_ARG_DESC}.
|
119
|
+
# @param [String,nil] default_required_arg_long_desc The default long
|
120
|
+
# description for required args, or `nil` not to set one. Defaults to
|
121
|
+
# `nil`.
|
122
|
+
# @param [String,nil] default_optional_arg_desc The default short
|
123
|
+
# description for optional args, or `nil` not to set one. Defaults to
|
124
|
+
# {DEFAULT_OPTIONAL_ARG_DESC}.
|
125
|
+
# @param [String,nil] default_optional_arg_long_desc The default long
|
126
|
+
# description for optional args, or `nil` not to set one. Defaults to
|
127
|
+
# `nil`.
|
128
|
+
# @param [String,nil] default_remaining_arg_desc The default short
|
129
|
+
# description for remaining args, or `nil` not to set one. Defaults
|
130
|
+
# to {DEFAULT_REMAINING_ARG_DESC}.
|
131
|
+
# @param [String,nil] default_remaining_arg_long_desc The default long
|
132
|
+
# description for remaining args, or `nil` not to set one. Defaults
|
133
|
+
# to `nil`.
|
77
134
|
#
|
78
135
|
def initialize(default_tool_desc: DEFAULT_TOOL_DESC,
|
79
136
|
default_tool_long_desc: nil,
|
80
137
|
default_group_desc: DEFAULT_GROUP_DESC,
|
81
138
|
default_group_long_desc: nil,
|
82
|
-
default_root_desc: DEFAULT_ROOT_DESC
|
139
|
+
default_root_desc: DEFAULT_ROOT_DESC,
|
140
|
+
default_root_long_desc: DEFAULT_ROOT_LONG_DESC,
|
141
|
+
default_flag_desc: DEFAULT_FLAG_DESC,
|
142
|
+
default_flag_long_desc: nil,
|
143
|
+
default_required_arg_desc: DEFAULT_REQUIRED_ARG_DESC,
|
144
|
+
default_required_arg_long_desc: nil,
|
145
|
+
default_optional_arg_desc: DEFAULT_OPTIONAL_ARG_DESC,
|
146
|
+
default_optional_arg_long_desc: nil,
|
147
|
+
default_remaining_arg_desc: DEFAULT_REMAINING_ARG_DESC,
|
148
|
+
default_remaining_arg_long_desc: nil)
|
83
149
|
@default_tool_desc = default_tool_desc
|
84
150
|
@default_tool_long_desc = default_tool_long_desc
|
85
151
|
@default_group_desc = default_group_desc
|
86
152
|
@default_group_long_desc = default_group_long_desc
|
87
153
|
@default_root_desc = default_root_desc
|
154
|
+
@default_root_long_desc = default_root_long_desc
|
155
|
+
@default_flag_desc = default_flag_desc
|
156
|
+
@default_flag_long_desc = default_flag_long_desc
|
157
|
+
@default_required_arg_desc = default_required_arg_desc
|
158
|
+
@default_required_arg_long_desc = default_required_arg_long_desc
|
159
|
+
@default_optional_arg_desc = default_optional_arg_desc
|
160
|
+
@default_optional_arg_long_desc = default_optional_arg_long_desc
|
161
|
+
@default_remaining_arg_desc = default_remaining_arg_desc
|
162
|
+
@default_remaining_arg_long_desc = default_remaining_arg_long_desc
|
88
163
|
end
|
89
164
|
|
90
165
|
##
|
91
166
|
# Add default description text to tools.
|
92
167
|
#
|
93
|
-
def config(tool)
|
168
|
+
def config(tool, _loader)
|
94
169
|
if tool.root?
|
95
|
-
|
170
|
+
config_descs(tool, @default_root_desc, @default_root_long_desc)
|
96
171
|
elsif tool.includes_executor?
|
97
|
-
|
172
|
+
config_descs(tool, @default_tool_desc, @default_tool_long_desc)
|
98
173
|
else
|
99
|
-
|
174
|
+
config_descs(tool, @default_group_desc, @default_group_long_desc)
|
175
|
+
end
|
176
|
+
tool.flag_definitions.each do |flag|
|
177
|
+
config_descs(flag, @default_flag_desc, @default_flag_long_desc)
|
100
178
|
end
|
179
|
+
config_args(tool)
|
101
180
|
yield
|
102
181
|
end
|
103
182
|
|
104
183
|
private
|
105
184
|
|
106
|
-
def
|
107
|
-
|
108
|
-
|
185
|
+
def config_args(tool)
|
186
|
+
tool.required_arg_definitions.each do |arg|
|
187
|
+
config_descs(arg, @default_required_arg_desc, @default_required_arg_long_desc)
|
109
188
|
end
|
110
|
-
|
111
|
-
|
112
|
-
def config_tool_desc(tool)
|
113
|
-
if @default_tool_long_desc && tool.effective_long_desc.empty?
|
114
|
-
tool.long_desc = @default_tool_long_desc
|
189
|
+
tool.optional_arg_definitions.each do |arg|
|
190
|
+
config_descs(arg, @default_optional_arg_desc, @default_optional_arg_long_desc)
|
115
191
|
end
|
116
|
-
if
|
117
|
-
tool.
|
192
|
+
if tool.remaining_args_definition
|
193
|
+
config_descs(tool.remaining_args_definition,
|
194
|
+
@default_remaining_arg_desc, @default_remaining_arg_long_desc)
|
118
195
|
end
|
119
196
|
end
|
120
197
|
|
121
|
-
def
|
122
|
-
if
|
123
|
-
|
198
|
+
def config_descs(object, default_desc, default_long_desc)
|
199
|
+
if default_desc && object.desc.empty?
|
200
|
+
object.desc = default_desc
|
124
201
|
end
|
125
|
-
if
|
126
|
-
|
202
|
+
if default_long_desc && object.long_desc.empty?
|
203
|
+
object.long_desc = default_long_desc
|
127
204
|
end
|
128
205
|
end
|
129
206
|
end
|
@@ -0,0 +1,245 @@
|
|
1
|
+
# Copyright 2018 Daniel Azuma
|
2
|
+
#
|
3
|
+
# All rights reserved.
|
4
|
+
#
|
5
|
+
# Redistribution and use in source and binary forms, with or without
|
6
|
+
# modification, are permitted provided that the following conditions are met:
|
7
|
+
#
|
8
|
+
# * Redistributions of source code must retain the above copyright notice,
|
9
|
+
# this list of conditions and the following disclaimer.
|
10
|
+
# * Redistributions in binary form must reproduce the above copyright notice,
|
11
|
+
# this list of conditions and the following disclaimer in the documentation
|
12
|
+
# and/or other materials provided with the distribution.
|
13
|
+
# * Neither the name of the copyright holder, nor the names of any other
|
14
|
+
# contributors to this software, may be used to endorse or promote products
|
15
|
+
# derived from this software without specific prior written permission.
|
16
|
+
#
|
17
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
18
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
19
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
20
|
+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
21
|
+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
22
|
+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
23
|
+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
24
|
+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
25
|
+
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
26
|
+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
27
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
28
|
+
;
|
29
|
+
|
30
|
+
require "highline"
|
31
|
+
|
32
|
+
require "toys/middleware/base"
|
33
|
+
require "toys/utils/help_text"
|
34
|
+
require "toys/utils/line_output"
|
35
|
+
|
36
|
+
module Toys
|
37
|
+
module Middleware
|
38
|
+
##
|
39
|
+
# A middleware that shows help text for the tool when a flag (typically
|
40
|
+
# `--help`) is provided. It can also be configured to show help by
|
41
|
+
# default if the tool is a group with no executor.
|
42
|
+
#
|
43
|
+
# If a tool has no executor, this middleware can also add a
|
44
|
+
# `--[no-]recursive` flag, which, when set to `true` (the default), shows
|
45
|
+
# all subtools recursively rather than only immediate subtools. This
|
46
|
+
# middleware can also search for keywords in its subtools.
|
47
|
+
#
|
48
|
+
class ShowHelp < Base
|
49
|
+
##
|
50
|
+
# Default help flags
|
51
|
+
# @return [Array<String>]
|
52
|
+
#
|
53
|
+
DEFAULT_HELP_FLAGS = ["-?", "--help"].freeze
|
54
|
+
|
55
|
+
##
|
56
|
+
# Default usage flags
|
57
|
+
# @return [Array<String>]
|
58
|
+
#
|
59
|
+
DEFAULT_USAGE_FLAGS = ["--usage"].freeze
|
60
|
+
|
61
|
+
##
|
62
|
+
# Default recursive flags
|
63
|
+
# @return [Array<String>]
|
64
|
+
#
|
65
|
+
DEFAULT_RECURSIVE_FLAGS = ["-r", "--[no-]recursive"].freeze
|
66
|
+
|
67
|
+
##
|
68
|
+
# Default search flags
|
69
|
+
# @return [Array<String>]
|
70
|
+
#
|
71
|
+
DEFAULT_SEARCH_FLAGS = ["-s WORD", "--search=WORD"].freeze
|
72
|
+
|
73
|
+
##
|
74
|
+
# Create a ShowHelp middleware.
|
75
|
+
#
|
76
|
+
# @param [Boolean,Array<String>,Proc] help_flags Specify flags to
|
77
|
+
# display help. The value may be any of the following:
|
78
|
+
# * An array of flags.
|
79
|
+
# * The `true` value to use {DEFAULT_HELP_FLAGS}.
|
80
|
+
# * The `false` value for no flags. (Default)
|
81
|
+
# * A proc that takes a tool and returns any of the above.
|
82
|
+
# @param [Boolean,Array<String>,Proc] usage_flags Specify flags to
|
83
|
+
# display usage. The value may be any of the following:
|
84
|
+
# * An array of flags.
|
85
|
+
# * The `true` value to use {DEFAULT_USAGE_FLAGS}.
|
86
|
+
# * The `false` value for no flags. (Default)
|
87
|
+
# * A proc that takes a tool and returns any of the above.
|
88
|
+
# @param [Boolean,Array<String>,Proc] recursive_flags Specify flags
|
89
|
+
# to control recursive subtool search. The value may be any of the
|
90
|
+
# following:
|
91
|
+
# * An array of flags.
|
92
|
+
# * The `true` value to use {DEFAULT_RECURSIVE_FLAGS}.
|
93
|
+
# * The `false` value for no flags. (Default)
|
94
|
+
# * A proc that takes a tool and returns any of the above.
|
95
|
+
# @param [Boolean,Array<String>,Proc] search_flags Specify flags
|
96
|
+
# to search subtools for a search term. The value may be any of
|
97
|
+
# the following:
|
98
|
+
# * An array of flags.
|
99
|
+
# * The `true` value to use {DEFAULT_SEARCH_FLAGS}.
|
100
|
+
# * The `false` value for no flags. (Default)
|
101
|
+
# * A proc that takes a tool and returns any of the above.
|
102
|
+
# @param [Boolean] default_recursive Whether to search recursively for
|
103
|
+
# subtools by default. Default is `false`.
|
104
|
+
# @param [Boolean] fallback_execution Cause the tool to display its own
|
105
|
+
# help text if it does not otherwise have an executor. This is
|
106
|
+
# mostly useful for groups, which have children but no executor.
|
107
|
+
# Default is `false`.
|
108
|
+
# @param [Boolean] allow_root_args If the root tool includes flags for
|
109
|
+
# help or usage, and doesn't otherwise use positional arguments,
|
110
|
+
# then a tool name can be passed as arguments to display help for
|
111
|
+
# that tool.
|
112
|
+
# @param [IO] stream Output stream to write to. Default is stdout.
|
113
|
+
# @param [Boolean,nil] styled_output Cause the tool to display help text
|
114
|
+
# with ansi styles. If `nil`, display styles if the output stream is
|
115
|
+
# a tty. Default is `nil`.
|
116
|
+
#
|
117
|
+
def initialize(help_flags: false,
|
118
|
+
usage_flags: false,
|
119
|
+
recursive_flags: false,
|
120
|
+
search_flags: false,
|
121
|
+
default_recursive: false,
|
122
|
+
fallback_execution: false,
|
123
|
+
allow_root_args: false,
|
124
|
+
stream: $stdout,
|
125
|
+
styled_output: nil)
|
126
|
+
@help_flags = help_flags
|
127
|
+
@usage_flags = usage_flags
|
128
|
+
@recursive_flags = recursive_flags
|
129
|
+
@search_flags = search_flags
|
130
|
+
@default_recursive = default_recursive ? true : false
|
131
|
+
@fallback_execution = fallback_execution
|
132
|
+
@allow_root_args = allow_root_args
|
133
|
+
@stream = stream
|
134
|
+
@styled_output = styled_output
|
135
|
+
end
|
136
|
+
|
137
|
+
##
|
138
|
+
# Configure flags and default data.
|
139
|
+
#
|
140
|
+
def config(tool, loader)
|
141
|
+
help_flags = add_help_flags(tool)
|
142
|
+
usage_flags = add_usage_flags(tool)
|
143
|
+
if @allow_root_args && (!help_flags.empty? || !usage_flags.empty?)
|
144
|
+
if tool.root? && tool.arg_definitions.empty?
|
145
|
+
tool.set_remaining_args(:_tool_name, display_name: "TOOL_NAME",
|
146
|
+
desc: "The tool for which to display help")
|
147
|
+
end
|
148
|
+
end
|
149
|
+
if (!help_flags.empty? || @fallback_execution) && loader.has_subtools?(tool.full_name)
|
150
|
+
add_recursive_flags(tool)
|
151
|
+
add_search_flags(tool)
|
152
|
+
end
|
153
|
+
yield
|
154
|
+
end
|
155
|
+
|
156
|
+
##
|
157
|
+
# Display help text if requested.
|
158
|
+
#
|
159
|
+
def execute(context)
|
160
|
+
if context[:_show_usage]
|
161
|
+
help_text = get_help_text(context)
|
162
|
+
str = help_text.usage_string(wrap_width: output_cols)
|
163
|
+
output.puts(str)
|
164
|
+
elsif @fallback_execution && !context[Context::TOOL].includes_executor? ||
|
165
|
+
context[:_show_help]
|
166
|
+
help_text = get_help_text(context)
|
167
|
+
str = help_text.help_string(recursive: context[:_recursive_subtools],
|
168
|
+
search: context[:_search_subtools],
|
169
|
+
wrap_width: output_cols)
|
170
|
+
output.puts(str)
|
171
|
+
else
|
172
|
+
yield
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
private
|
177
|
+
|
178
|
+
def output_cols
|
179
|
+
@output_cols ||= ::HighLine.new(nil, @stream).output_cols
|
180
|
+
end
|
181
|
+
|
182
|
+
def output
|
183
|
+
@output ||= Utils::LineOutput.new(@stream, styled: @styled_output)
|
184
|
+
end
|
185
|
+
|
186
|
+
def get_help_text(context)
|
187
|
+
tool_name = context[:_tool_name]
|
188
|
+
return Utils::HelpText.from_context(context) if tool_name.nil? || tool_name.empty?
|
189
|
+
loader = context[Context::LOADER]
|
190
|
+
tool, rest = loader.lookup(tool_name)
|
191
|
+
help_text = Utils::HelpText.new(tool, loader, context[Context::BINARY_NAME])
|
192
|
+
report_usage_error(context, tool_name, help_text) unless rest.empty?
|
193
|
+
help_text
|
194
|
+
end
|
195
|
+
|
196
|
+
def report_usage_error(context, tool_name, help_text)
|
197
|
+
output.puts("Tool not found: #{tool_name.join(' ')}", :bright_red, :bold)
|
198
|
+
output.puts
|
199
|
+
output.puts help_text.usage_string(wrap_width: output_cols)
|
200
|
+
context.exit(1)
|
201
|
+
end
|
202
|
+
|
203
|
+
def add_help_flags(tool)
|
204
|
+
help_flags = Middleware.resolve_flags_spec(@help_flags, tool,
|
205
|
+
DEFAULT_HELP_FLAGS)
|
206
|
+
unless help_flags.empty?
|
207
|
+
tool.add_flag(:_show_help, *help_flags,
|
208
|
+
desc: "Display help for this tool", only_unique: true)
|
209
|
+
end
|
210
|
+
help_flags
|
211
|
+
end
|
212
|
+
|
213
|
+
def add_usage_flags(tool)
|
214
|
+
usage_flags = Middleware.resolve_flags_spec(@usage_flags, tool,
|
215
|
+
DEFAULT_USAGE_FLAGS)
|
216
|
+
unless usage_flags.empty?
|
217
|
+
tool.add_flag(:_show_usage, *usage_flags,
|
218
|
+
desc: "Display a brief usage string for this tool", only_unique: true)
|
219
|
+
end
|
220
|
+
usage_flags
|
221
|
+
end
|
222
|
+
|
223
|
+
def add_recursive_flags(tool)
|
224
|
+
recursive_flags = Middleware.resolve_flags_spec(@recursive_flags, tool,
|
225
|
+
DEFAULT_RECURSIVE_FLAGS)
|
226
|
+
unless recursive_flags.empty?
|
227
|
+
tool.add_flag(:_recursive_subtools, *recursive_flags,
|
228
|
+
default: @default_recursive,
|
229
|
+
desc: "Show all subtools recursively (default is #{@default_recursive})",
|
230
|
+
only_unique: true)
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
234
|
+
def add_search_flags(tool)
|
235
|
+
search_flags = Middleware.resolve_flags_spec(@search_flags, tool,
|
236
|
+
DEFAULT_SEARCH_FLAGS)
|
237
|
+
unless search_flags.empty?
|
238
|
+
tool.add_flag(:_search_subtools, *search_flags,
|
239
|
+
desc: "Search subtools for the given regular expression",
|
240
|
+
only_unique: true)
|
241
|
+
end
|
242
|
+
end
|
243
|
+
end
|
244
|
+
end
|
245
|
+
end
|