claide 0.5.0 → 0.6.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/README.markdown +4 -3
- data/lib/claide.rb +4 -3
- data/lib/claide/ansi.rb +126 -0
- data/lib/claide/ansi/cursor.rb +69 -0
- data/lib/claide/ansi/graphics.rb +72 -0
- data/lib/claide/ansi/string_escaper.rb +81 -0
- data/lib/claide/argv.rb +63 -108
- data/lib/claide/argv/parser.rb +83 -0
- data/lib/claide/command.rb +245 -300
- data/lib/claide/command/banner.rb +133 -117
- data/lib/claide/command/banner/prettifier.rb +59 -0
- data/lib/claide/command/options.rb +87 -0
- data/lib/claide/command/parser.rb +47 -0
- data/lib/claide/command/plugins_helper.rb +112 -0
- data/lib/claide/command/shell_completion_helper.rb +39 -0
- data/lib/claide/command/shell_completion_helper/zsh_completion_generator.rb +191 -0
- data/lib/claide/command/validation_helper.rb +82 -0
- data/lib/claide/help.rb +2 -18
- data/lib/claide/helper.rb +113 -0
- data/lib/claide/informative_error.rb +0 -2
- data/lib/claide/mixins.rb +25 -0
- metadata +16 -2
@@ -0,0 +1,83 @@
|
|
1
|
+
module CLAide
|
2
|
+
class ARGV
|
3
|
+
module Parser
|
4
|
+
# @return [Array<Array<Symbol, String, Array>>] A list of tuples for each
|
5
|
+
# parameter, where the first entry is the `type` and the second
|
6
|
+
# entry the actual parsed parameter.
|
7
|
+
#
|
8
|
+
# @example
|
9
|
+
#
|
10
|
+
# list = parse(['tea', '--no-milk', '--sweetner=honey'])
|
11
|
+
# list # => [[:arg, "tea"],
|
12
|
+
# [:flag, ["milk", false]],
|
13
|
+
# [:option, ["sweetner", "honey"]]]
|
14
|
+
#
|
15
|
+
def self.parse(argv)
|
16
|
+
entries = []
|
17
|
+
copy = argv.map(&:to_s)
|
18
|
+
while argument = copy.shift
|
19
|
+
type = argument_type(argument)
|
20
|
+
parameter = argument_parameter(type, argument)
|
21
|
+
entries << [type, parameter]
|
22
|
+
end
|
23
|
+
entries
|
24
|
+
end
|
25
|
+
|
26
|
+
# @return [Symbol] Returns the type of an argument. The types can be
|
27
|
+
# either: `:arg`, `:flag`, `:option`.
|
28
|
+
#
|
29
|
+
# @param [String] argument
|
30
|
+
# The argument to check.
|
31
|
+
#
|
32
|
+
def self.argument_type(argument)
|
33
|
+
if argument.start_with?('--')
|
34
|
+
if argument.include?('=')
|
35
|
+
:option
|
36
|
+
else
|
37
|
+
:flag
|
38
|
+
end
|
39
|
+
else
|
40
|
+
:arg
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
# @return [String, Array<String, String>] Returns argument itself for
|
45
|
+
# normal arguments (like commands) and a tuple with they key and
|
46
|
+
# the value for options and flags.
|
47
|
+
#
|
48
|
+
# @param [Symbol] type
|
49
|
+
# The type of the argument.
|
50
|
+
#
|
51
|
+
# @param [String] argument
|
52
|
+
# The argument to check.
|
53
|
+
#
|
54
|
+
def self.argument_parameter(type, argument)
|
55
|
+
case type
|
56
|
+
when :arg
|
57
|
+
return argument
|
58
|
+
when :flag
|
59
|
+
return flag_paramenter(argument)
|
60
|
+
when :option
|
61
|
+
return argument[2..-1].split('=', 2)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
# @return [String, Array<String, String>] Returns the parameter
|
66
|
+
# describing a flag arguments.
|
67
|
+
#
|
68
|
+
# @param [String] argument
|
69
|
+
# The flag argument to check.
|
70
|
+
#
|
71
|
+
def self.flag_paramenter(argument)
|
72
|
+
if argument.start_with?('--no-')
|
73
|
+
key = argument[5..-1]
|
74
|
+
value = false
|
75
|
+
else
|
76
|
+
key = argument[2..-1]
|
77
|
+
value = true
|
78
|
+
end
|
79
|
+
[key, value]
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
data/lib/claide/command.rb
CHANGED
@@ -1,9 +1,13 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
3
|
require 'claide/command/banner'
|
4
|
+
require 'claide/command/parser'
|
5
|
+
require 'claide/command/plugins_helper'
|
6
|
+
require 'claide/command/options'
|
7
|
+
require 'claide/command/shell_completion_helper'
|
8
|
+
require 'claide/command/validation_helper'
|
4
9
|
|
5
10
|
module CLAide
|
6
|
-
|
7
11
|
# This class is used to build a command-line interface
|
8
12
|
#
|
9
13
|
# Each command is represented by a subclass of this class, which may be
|
@@ -44,11 +48,7 @@ module CLAide
|
|
44
48
|
# defaults to {Command.summary}.
|
45
49
|
#
|
46
50
|
class Command
|
47
|
-
|
48
|
-
#-------------------------------------------------------------------------#
|
49
|
-
|
50
51
|
class << self
|
51
|
-
|
52
52
|
# @return [Boolean] Indicates whether or not this command can actually
|
53
53
|
# perform work of itself, or that it only contains subcommands.
|
54
54
|
#
|
@@ -60,6 +60,7 @@ module CLAide
|
|
60
60
|
# help banner or to show its subcommands instead.
|
61
61
|
#
|
62
62
|
# Setting this to `true` implies it’s an abstract command.
|
63
|
+
#
|
63
64
|
attr_reader :ignore_in_command_lookup
|
64
65
|
alias_method :ignore_in_command_lookup?, :ignore_in_command_lookup
|
65
66
|
def ignore_in_command_lookup=(flag)
|
@@ -88,10 +89,43 @@ module CLAide
|
|
88
89
|
#
|
89
90
|
attr_accessor :plugin_prefix
|
90
91
|
|
91
|
-
# @return [
|
92
|
-
# in the usage section of the command’s help banner.
|
92
|
+
# @return [Array<Tuple>] A list of arguments the command handles. This
|
93
|
+
# is shown in the usage section of the command’s help banner.
|
94
|
+
# Each tuple in the array represents an argument using
|
95
|
+
# [name, type] where:
|
96
|
+
# - name is a String containing the argument
|
97
|
+
# - type is either :optional or :required
|
93
98
|
#
|
99
|
+
# @TODO Remove deprecation
|
100
|
+
#
|
101
|
+
# rubocop:disable all
|
94
102
|
attr_accessor :arguments
|
103
|
+
def arguments
|
104
|
+
@arguments ||= []
|
105
|
+
end
|
106
|
+
|
107
|
+
# @param [Array<Tuple>] arguments
|
108
|
+
# An array containing arguments, each described by a tuple of
|
109
|
+
# the form [name, type], where:
|
110
|
+
# - name is a String containing the argument
|
111
|
+
# - type is either :optional or :required
|
112
|
+
#
|
113
|
+
def arguments=(arguments)
|
114
|
+
if arguments.is_a?(Array)
|
115
|
+
@arguments = arguments
|
116
|
+
else
|
117
|
+
warn '[!] The specification of arguments as a string has been' \
|
118
|
+
" deprecated #{self}: `#{arguments}`".ansi.yellow
|
119
|
+
@arguments = arguments.split(' ').map do |argument|
|
120
|
+
if argument.start_with?('[')
|
121
|
+
[argument.sub(/\[(.*)\]/, '\1'), :optional]
|
122
|
+
else
|
123
|
+
[argument, :required]
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
# rubocop:enable all
|
95
129
|
|
96
130
|
# @return [Boolean] The default value for {Command#ansi_output}. This
|
97
131
|
# defaults to `true` if `STDOUT` is connected to a TTY and
|
@@ -101,31 +135,13 @@ module CLAide
|
|
101
135
|
#
|
102
136
|
def ansi_output
|
103
137
|
if @ansi_output.nil?
|
104
|
-
@ansi_output = STDOUT.tty?
|
105
|
-
String.method_defined?(:red) &&
|
106
|
-
String.method_defined?(:green) &&
|
107
|
-
String.method_defined?(:yellow)
|
138
|
+
@ansi_output = STDOUT.tty?
|
108
139
|
end
|
109
140
|
@ansi_output
|
110
141
|
end
|
111
142
|
attr_writer :ansi_output
|
112
143
|
alias_method :ansi_output?, :ansi_output
|
113
144
|
|
114
|
-
def colorize_output
|
115
|
-
warn "[!] The use of `CLAide::Command.colorize_output` has been " \
|
116
|
-
"deprecated. Use `CLAide::Command.ansi_output` instead. " \
|
117
|
-
"(Called from: #{caller.first})"
|
118
|
-
ansi_output
|
119
|
-
end
|
120
|
-
alias_method :colorize_output?, :colorize_output
|
121
|
-
|
122
|
-
def colorize_output=(flag)
|
123
|
-
warn "[!] The use of `CLAide::Command.colorize_output=` has been " \
|
124
|
-
"deprecated. Use `CLAide::Command.ansi_output=` instead. " \
|
125
|
-
"(Called from: #{caller.first})"
|
126
|
-
self.ansi_output = flag
|
127
|
-
end
|
128
|
-
|
129
145
|
# @return [String] The name of the command. Defaults to a snake-cased
|
130
146
|
# version of the class’ name.
|
131
147
|
#
|
@@ -136,265 +152,215 @@ module CLAide
|
|
136
152
|
end
|
137
153
|
attr_writer :command
|
138
154
|
|
139
|
-
# @return [String] The
|
140
|
-
#
|
141
|
-
#
|
142
|
-
# @note (see #ignore_in_command_lookup)
|
143
|
-
#
|
144
|
-
# @example
|
155
|
+
# @return [String] The version of the command. This value will be printed
|
156
|
+
# by the `--version` flag if used for the root command.
|
145
157
|
#
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
158
|
+
attr_accessor :version
|
159
|
+
end
|
160
|
+
|
161
|
+
#-------------------------------------------------------------------------#
|
162
|
+
|
163
|
+
# @return [String] The full command up-to this command, as it would be
|
164
|
+
# looked up during parsing.
|
165
|
+
#
|
166
|
+
# @note (see #ignore_in_command_lookup)
|
167
|
+
#
|
168
|
+
# @example
|
169
|
+
#
|
170
|
+
# BevarageMaker::Tea.full_command # => "beverage-maker tea"
|
171
|
+
#
|
172
|
+
def self.full_command
|
173
|
+
if superclass == Command
|
174
|
+
ignore_in_command_lookup? ? '' : command
|
175
|
+
else
|
176
|
+
if ignore_in_command_lookup?
|
177
|
+
superclass.full_command
|
151
178
|
else
|
152
|
-
|
153
|
-
superclass.full_command
|
154
|
-
else
|
155
|
-
"#{superclass.full_command} #{command}"
|
156
|
-
end
|
179
|
+
"#{superclass.full_command} #{command}"
|
157
180
|
end
|
158
181
|
end
|
182
|
+
end
|
159
183
|
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
end
|
184
|
+
# @return [Bool] Whether this is the root command class
|
185
|
+
#
|
186
|
+
def self.root_command?
|
187
|
+
superclass == CLAide::Command
|
188
|
+
end
|
166
189
|
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
if subcommand.ignore_in_command_lookup?
|
174
|
-
subcommand.subcommands_for_command_lookup
|
175
|
-
else
|
176
|
-
subcommand
|
177
|
-
end
|
178
|
-
end.flatten
|
179
|
-
end
|
190
|
+
# @return [Array<Class>] A list of all command classes that are nested
|
191
|
+
# under this command.
|
192
|
+
#
|
193
|
+
def self.subcommands
|
194
|
+
@subcommands ||= []
|
195
|
+
end
|
180
196
|
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
197
|
+
# @return [Array<Class>] A list of command classes that are nested under
|
198
|
+
# this command _or_ the subcommands of those command classes in
|
199
|
+
# case the command class should be ignored in command lookup.
|
200
|
+
#
|
201
|
+
def self.subcommands_for_command_lookup
|
202
|
+
subcommands.map do |subcommand|
|
203
|
+
if subcommand.ignore_in_command_lookup?
|
204
|
+
subcommand.subcommands_for_command_lookup
|
205
|
+
else
|
206
|
+
subcommand
|
207
|
+
end
|
208
|
+
end.flatten
|
209
|
+
end
|
192
210
|
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
211
|
+
# Searches the list of subcommands that should not be ignored for command
|
212
|
+
# lookup for a subcommand with the given `name`.
|
213
|
+
#
|
214
|
+
# @param [String] name
|
215
|
+
# The name of the subcommand to be found.
|
216
|
+
#
|
217
|
+
# @return [CLAide::Command, nil] The subcommand, if found.
|
218
|
+
#
|
219
|
+
def self.find_subcommand(name)
|
220
|
+
subcommands_for_command_lookup.find { |sc| sc.command == name }
|
221
|
+
end
|
200
222
|
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
#
|
209
|
-
# A list of option name and description tuples.
|
210
|
-
#
|
211
|
-
# @example
|
212
|
-
#
|
213
|
-
# def self.options
|
214
|
-
# [
|
215
|
-
# ['--verbose', 'Print more info'],
|
216
|
-
# ['--help', 'Print help banner'],
|
217
|
-
# ].concat(super)
|
218
|
-
# end
|
219
|
-
#
|
220
|
-
def options
|
221
|
-
options = [
|
222
|
-
['--verbose', 'Show more debugging information'],
|
223
|
-
['--help', 'Show help banner of specified command'],
|
224
|
-
]
|
225
|
-
if Command.ansi_output?
|
226
|
-
options.unshift(['--no-ansi', 'Show output without ANSI codes'])
|
227
|
-
end
|
228
|
-
options
|
229
|
-
end
|
223
|
+
# @visibility private
|
224
|
+
#
|
225
|
+
# Automatically registers a subclass as a subcommand.
|
226
|
+
#
|
227
|
+
def self.inherited(subcommand)
|
228
|
+
subcommands << subcommand
|
229
|
+
end
|
230
230
|
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
else
|
254
|
-
new(argv)
|
255
|
-
end
|
256
|
-
end
|
231
|
+
# Should be overridden by a subclass if it handles any options.
|
232
|
+
#
|
233
|
+
# The subclass has to combine the result of calling `super` and its own
|
234
|
+
# list of options. The recommended way of doing this is by concatenating
|
235
|
+
# concatenating to this classes’ own options.
|
236
|
+
#
|
237
|
+
# @return [Array<Array>]
|
238
|
+
#
|
239
|
+
# A list of option name and description tuples.
|
240
|
+
#
|
241
|
+
# @example
|
242
|
+
#
|
243
|
+
# def self.options
|
244
|
+
# [
|
245
|
+
# ['--verbose', 'Print more info'],
|
246
|
+
# ['--help', 'Print help banner'],
|
247
|
+
# ].concat(super)
|
248
|
+
# end
|
249
|
+
#
|
250
|
+
def self.options
|
251
|
+
Options.default_options(self)
|
252
|
+
end
|
257
253
|
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
254
|
+
# Instantiates the command class matching the parameters through
|
255
|
+
# {Command.parse}, validates it through {Command#validate!}, and runs it
|
256
|
+
# through {Command#run}.
|
257
|
+
#
|
258
|
+
# @note You should normally call this on
|
259
|
+
#
|
260
|
+
# @note The ANSI support is configured before running a command to allow
|
261
|
+
# the same process to run multiple commands with different
|
262
|
+
# settings. For example a process with ANSI output enabled might
|
263
|
+
# want to programmatically invoke another command with the output
|
264
|
+
# enabled.
|
265
|
+
#
|
266
|
+
# @param [Array, ARGV] argv
|
267
|
+
# A list of parameters. For instance, the standard `ARGV` constant,
|
268
|
+
# which contains the parameters passed to the program.
|
269
|
+
#
|
270
|
+
# @return [void]
|
271
|
+
#
|
272
|
+
def self.run(argv = [])
|
273
|
+
argv = ARGV.coherce(argv)
|
274
|
+
PluginsHelper.load_plugins(plugin_prefix)
|
275
|
+
command = parse(argv)
|
276
|
+
|
277
|
+
unless Options.handle_root_option(command, argv)
|
278
|
+
ANSI.disabled = !ansi_output?
|
276
279
|
command.validate!
|
277
280
|
command.run
|
278
|
-
rescue Exception => exception
|
279
|
-
if exception.is_a?(InformativeError)
|
280
|
-
puts exception.message
|
281
|
-
if command.verbose?
|
282
|
-
puts
|
283
|
-
puts(*exception.backtrace)
|
284
|
-
end
|
285
|
-
exit exception.exit_status
|
286
|
-
else
|
287
|
-
report_error(exception)
|
288
|
-
end
|
289
|
-
end
|
290
|
-
|
291
|
-
# Allows the application to perform custom error reporting, by overriding
|
292
|
-
# this method.
|
293
|
-
#
|
294
|
-
# @param [Exception] exception
|
295
|
-
#
|
296
|
-
# An exception that occurred while running a command through
|
297
|
-
# {Command.run}.
|
298
|
-
#
|
299
|
-
# @raise
|
300
|
-
#
|
301
|
-
# By default re-raises the specified exception.
|
302
|
-
#
|
303
|
-
# @return [void]
|
304
|
-
#
|
305
|
-
def report_error(exception)
|
306
|
-
raise exception
|
307
281
|
end
|
282
|
+
rescue Object => exception
|
283
|
+
handle_exception(command, exception)
|
284
|
+
end
|
308
285
|
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
# The error message to show to the user.
|
313
|
-
#
|
314
|
-
# @param [Boolean] ansi_output
|
315
|
-
# Whether or not to use ANSI codes to prettify output.
|
316
|
-
#
|
317
|
-
# @param [Class] help_class
|
318
|
-
# The class to use to raise a ‘help’ error.
|
319
|
-
#
|
320
|
-
# @raise [Help]
|
321
|
-
#
|
322
|
-
# Signals CLAide that a help banner for this command should be shown,
|
323
|
-
# with an optional error message.
|
324
|
-
#
|
325
|
-
# @return [void]
|
326
|
-
#
|
327
|
-
def help!(error_message = nil, ansi_output = false, help_class = Help)
|
328
|
-
raise help_class.new(banner(ansi_output), error_message, ansi_output)
|
329
|
-
end
|
286
|
+
def self.parse(argv)
|
287
|
+
Parser.parse(self, argv)
|
288
|
+
end
|
330
289
|
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
290
|
+
# Presents an exception to the user according to class of the .
|
291
|
+
#
|
292
|
+
# @param [Command] command
|
293
|
+
# The command which originated the exception.
|
294
|
+
#
|
295
|
+
# @param [Object] exception
|
296
|
+
# The exception to present.
|
297
|
+
#
|
298
|
+
# @return [void]
|
299
|
+
#
|
300
|
+
def self.handle_exception(command, exception)
|
301
|
+
if exception.is_a?(InformativeError)
|
302
|
+
puts exception.message
|
303
|
+
if command.verbose?
|
304
|
+
puts
|
305
|
+
puts(*exception.backtrace)
|
306
|
+
end
|
307
|
+
exit exception.exit_status
|
308
|
+
else
|
309
|
+
report_error(exception)
|
345
310
|
end
|
311
|
+
end
|
346
312
|
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
else
|
365
|
-
Gem.find_files("#{plugin_prefix}_plugin")
|
366
|
-
end
|
367
|
-
files_to_require.each { |path| require_plugin_path(path) }
|
368
|
-
end
|
313
|
+
# Allows the application to perform custom error reporting, by overriding
|
314
|
+
# this method.
|
315
|
+
#
|
316
|
+
# @param [Exception] exception
|
317
|
+
#
|
318
|
+
# An exception that occurred while running a command through
|
319
|
+
# {Command.run}.
|
320
|
+
#
|
321
|
+
# @raise
|
322
|
+
#
|
323
|
+
# By default re-raises the specified exception.
|
324
|
+
#
|
325
|
+
# @return [void]
|
326
|
+
#
|
327
|
+
def self.report_error(exception)
|
328
|
+
raise exception
|
329
|
+
end
|
369
330
|
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
331
|
+
# @visibility private
|
332
|
+
#
|
333
|
+
# @param [String] error_message
|
334
|
+
# The error message to show to the user.
|
335
|
+
#
|
336
|
+
# @param [Class] help_class
|
337
|
+
# The class to use to raise a ‘help’ error.
|
338
|
+
#
|
339
|
+
# @raise [Help]
|
340
|
+
#
|
341
|
+
# Signals CLAide that a help banner for this command should be shown,
|
342
|
+
# with an optional error message.
|
343
|
+
#
|
344
|
+
# @return [void]
|
345
|
+
#
|
346
|
+
def self.help!(error_message = nil, help_class = Help)
|
347
|
+
raise help_class.new(banner, error_message)
|
348
|
+
end
|
385
349
|
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
350
|
+
# @visibility private
|
351
|
+
#
|
352
|
+
# Returns the banner for the command.
|
353
|
+
#
|
354
|
+
# @param [Boolean] ansi
|
355
|
+
# Whether the banner should use ANSI codes to prettify output.
|
356
|
+
#
|
357
|
+
# @param [Class] banner_class
|
358
|
+
# The class to use to format help banners.
|
359
|
+
#
|
360
|
+
# @return [String] The banner for the command.
|
361
|
+
#
|
362
|
+
def self.banner(banner_class = Banner)
|
363
|
+
banner_class.new(self).formatted_banner
|
398
364
|
end
|
399
365
|
|
400
366
|
#-------------------------------------------------------------------------#
|
@@ -429,27 +395,6 @@ module CLAide
|
|
429
395
|
attr_accessor :ansi_output
|
430
396
|
alias_method :ansi_output?, :ansi_output
|
431
397
|
|
432
|
-
def colorize_output
|
433
|
-
warn "[!] The use of `CLAide::Command#colorize_output` has been " \
|
434
|
-
"deprecated. Use `CLAide::Command#ansi_output` instead. " \
|
435
|
-
"(Called from: #{caller.first})"
|
436
|
-
ansi_output
|
437
|
-
end
|
438
|
-
alias_method :colorize_output?, :colorize_output
|
439
|
-
|
440
|
-
def colorize_output=(flag)
|
441
|
-
warn "[!] The use of `CLAide::Command#colorize_output=` has been " \
|
442
|
-
"deprecated. Use `CLAide::Command#ansi_output=` instead. " \
|
443
|
-
"(Called from: #{caller.first})"
|
444
|
-
self.ansi_output = flag
|
445
|
-
end
|
446
|
-
|
447
|
-
# @return [Bool] Whether the command was invoked by an abstract command by
|
448
|
-
# default.
|
449
|
-
#
|
450
|
-
attr_accessor :invoked_as_default
|
451
|
-
alias_method :invoked_as_default?, :invoked_as_default
|
452
|
-
|
453
398
|
# Subclasses should override this method to remove the arguments/options
|
454
399
|
# they support from `argv` _before_ calling `super`.
|
455
400
|
#
|
@@ -466,17 +411,15 @@ module CLAide
|
|
466
411
|
argv = ARGV.new(argv) unless argv.is_a?(ARGV)
|
467
412
|
@verbose = argv.flag?('verbose')
|
468
413
|
@ansi_output = argv.flag?('ansi', Command.ansi_output?)
|
469
|
-
|
470
|
-
color = argv.flag?('color')
|
471
|
-
unless color.nil?
|
472
|
-
warn "[!] The use of the `--color`/`--no-color` flag has been " \
|
473
|
-
"deprecated. Use `--ansi`/`--no-ansi` instead."
|
474
|
-
@ansi_output = color
|
475
|
-
end
|
476
|
-
|
477
414
|
@argv = argv
|
478
415
|
end
|
479
416
|
|
417
|
+
# @return [Bool] Whether the command was invoked by an abstract command by
|
418
|
+
# default.
|
419
|
+
#
|
420
|
+
attr_accessor :invoked_as_default
|
421
|
+
alias_method :invoked_as_default?, :invoked_as_default
|
422
|
+
|
480
423
|
# Raises a Help exception if the `--help` option is specified, if `argv`
|
481
424
|
# still contains remaining arguments/options by the time it reaches this
|
482
425
|
# implementation, or when called on an ‘abstract command’.
|
@@ -491,17 +434,20 @@ module CLAide
|
|
491
434
|
#
|
492
435
|
def validate!
|
493
436
|
help! if @argv.flag?('help')
|
494
|
-
|
437
|
+
unless @argv.empty?
|
438
|
+
help! ValidationHelper.argument_suggestion(@argv.remainder, self.class)
|
439
|
+
end
|
495
440
|
help! if self.class.abstract_command?
|
496
441
|
end
|
497
442
|
|
498
|
-
# This method should be overridden by the command class to perform its
|
443
|
+
# This method should be overridden by the command class to perform its
|
444
|
+
# work.
|
499
445
|
#
|
500
446
|
# @return [void
|
501
447
|
#
|
502
448
|
def run
|
503
|
-
raise
|
504
|
-
|
449
|
+
raise 'A subclass should override the `CLAide::Command#run` method to ' \
|
450
|
+
'actually perform some work.'
|
505
451
|
end
|
506
452
|
|
507
453
|
protected
|
@@ -519,10 +465,9 @@ module CLAide
|
|
519
465
|
else
|
520
466
|
command = self.class
|
521
467
|
end
|
522
|
-
command
|
468
|
+
command.help!(error_message)
|
523
469
|
end
|
524
470
|
|
525
471
|
#-------------------------------------------------------------------------#
|
526
|
-
|
527
472
|
end
|
528
473
|
end
|