atli 0.1.4 → 0.1.5
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/lib/thor.rb +23 -3
- data/lib/thor/base.rb +15 -611
- data/lib/thor/base/class_methods.rb +730 -0
- data/lib/thor/command.rb +146 -28
- data/lib/thor/group.rb +61 -54
- data/lib/thor/parser/argument.rb +9 -2
- data/lib/thor/parser/arguments.rb +142 -110
- data/lib/thor/parser/options.rb +218 -102
- data/lib/thor/version.rb +2 -2
- metadata +3 -2
data/lib/thor/command.rb
CHANGED
@@ -23,39 +23,102 @@ class Thor
|
|
23
23
|
def hidden?
|
24
24
|
false
|
25
25
|
end
|
26
|
-
|
26
|
+
|
27
|
+
|
28
|
+
# Run a command by calling the actual method on the {Thor::Base} instance.
|
29
|
+
#
|
27
30
|
# By default, a command invokes a method in the thor class. You can change
|
28
31
|
# this implementation to create custom commands.
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
32
|
+
#
|
33
|
+
# @param [Thor::Base] instance
|
34
|
+
# Thor class instance the command is being run for.
|
35
|
+
#
|
36
|
+
# @param [Array<?>] args
|
37
|
+
# Arguments for the command.
|
38
|
+
#
|
39
|
+
# @return
|
40
|
+
# The return value of the command method on `instance`.
|
41
|
+
#
|
42
|
+
# @raise [Thor::InvocationError]
|
43
|
+
# 1. When we find a suitable method on `instance` to call, but it
|
44
|
+
# raised and {ArgumentError} **and** {#handle_argument_error?}
|
45
|
+
# returned `true`.
|
46
|
+
#
|
47
|
+
def run instance, args = []
|
48
|
+
logger.debug "Command#run",
|
49
|
+
name: self.name,
|
33
50
|
args: args
|
34
51
|
|
52
|
+
# raise "BAD!!!" unless args.include? '--'
|
53
|
+
|
54
|
+
# Declaration for arity of the method, which is set in (2) below and
|
55
|
+
# used when handling raised {ArgumentError}
|
35
56
|
arity = nil
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
57
|
+
|
58
|
+
# Method invocation switch - figure out how to make the method call to
|
59
|
+
# `instance`, or error out.
|
60
|
+
#
|
61
|
+
# Cases:
|
62
|
+
#
|
63
|
+
# 1. Protect from calling private methods by error'ing out if {#name}
|
64
|
+
# is the name of a private method of `instance`.
|
65
|
+
#
|
66
|
+
if private_method? instance
|
67
|
+
instance.class.handle_no_command_error name
|
68
|
+
|
69
|
+
# 2. The success case - if {#name} is a public method of `instance`
|
70
|
+
# than call it with `args`.
|
71
|
+
#
|
72
|
+
elsif public_method? instance
|
73
|
+
# Save the arity to use when handling {ArgumentError} below
|
74
|
+
#
|
75
|
+
# TODO Why does it fetch the {Method} *then* use {#__send__} instead
|
76
|
+
# of just `#call` it?
|
77
|
+
#
|
78
|
+
arity = instance.method( name ).arity
|
79
|
+
|
80
|
+
# Unless the method is a subcommand, remove any '--' separators
|
81
|
+
# since we know we're done option parsin'
|
82
|
+
unless subcommand? instance, name
|
83
|
+
args = args.reject { |arg| arg == '--' }
|
84
|
+
end
|
85
|
+
|
86
|
+
# Do that call
|
87
|
+
instance.__send__ name, *args
|
88
|
+
|
89
|
+
# 3. If the {Thor} instance has a `#method_missing` defined in *itself*
|
90
|
+
# (not any super class) than call that.
|
91
|
+
#
|
92
|
+
elsif local_method? instance, :method_missing
|
93
|
+
instance.__send__ :method_missing, name.to_sym, *args
|
94
|
+
|
95
|
+
# 4. We got nothing... pass of to
|
96
|
+
# {Thor::Base::ClassMethods.handle_no_command_error}
|
97
|
+
# which will raise.
|
98
|
+
#
|
44
99
|
else
|
45
|
-
instance.class.handle_no_command_error
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
100
|
+
instance.class.handle_no_command_error name
|
101
|
+
|
102
|
+
end # Method invocation switch
|
103
|
+
|
104
|
+
rescue ArgumentError => error
|
105
|
+
if handle_argument_error? instance, error, caller
|
106
|
+
# NOTE I *believe* `arity` could still be `nil`, assuming that
|
107
|
+
# (3) could raise {ArgumentError} and end up here.
|
108
|
+
#
|
109
|
+
# However...
|
110
|
+
instance.class.handle_argument_error self, error, args, arity
|
50
111
|
else
|
51
|
-
raise
|
112
|
+
raise error
|
52
113
|
end
|
53
|
-
|
54
|
-
|
55
|
-
|
114
|
+
|
115
|
+
rescue NoMethodError => error
|
116
|
+
if handle_no_method_error? instance, error, caller
|
117
|
+
instance.class.handle_no_command_error name
|
56
118
|
else
|
57
|
-
raise
|
119
|
+
raise error
|
58
120
|
end
|
121
|
+
|
59
122
|
rescue Exception => error
|
60
123
|
# NOTE Need to use `#__send__` because the instance may define a
|
61
124
|
# command (method) `#send` - and one of the test fixtures **does**:
|
@@ -73,7 +136,8 @@ class Thor
|
|
73
136
|
|
74
137
|
# If you want something done right...
|
75
138
|
raise error
|
76
|
-
end
|
139
|
+
end # #run
|
140
|
+
|
77
141
|
|
78
142
|
# Returns the formatted usage by injecting given required arguments
|
79
143
|
# and required options into the given usage.
|
@@ -125,22 +189,76 @@ class Thor
|
|
125
189
|
sort.
|
126
190
|
join(" ")
|
127
191
|
end
|
128
|
-
|
129
|
-
|
192
|
+
|
193
|
+
|
194
|
+
|
195
|
+
# Is `name` a subcommand of `instance`?
|
196
|
+
#
|
197
|
+
# @param [Thor::Base] instance
|
198
|
+
# The Thor instance this command is being run for.
|
199
|
+
#
|
200
|
+
# @param [Symbol | String] name
|
201
|
+
# The subcommand / method name.
|
202
|
+
#
|
203
|
+
# @return [return_type]
|
204
|
+
# @todo Document return value.
|
205
|
+
#
|
206
|
+
def subcommand? instance, name
|
207
|
+
# It doesn't look like {Thor::Group} has `.subcommands`, so test for
|
208
|
+
# that first.
|
209
|
+
return false unless instance.class.respond_to?( :subcommands )
|
210
|
+
|
211
|
+
# See if the names is in the subcommands
|
212
|
+
instance.class.subcommands.include? name.to_s
|
213
|
+
end # #subcommand?
|
214
|
+
|
215
|
+
|
216
|
+
|
217
|
+
# Is this command's {#name} a public method of `instance`?
|
218
|
+
#
|
219
|
+
# @param [Thor::Base] instance
|
220
|
+
# The Thor instance this command is being run for.
|
221
|
+
#
|
222
|
+
# @return [Boolean]
|
223
|
+
# `true` if {#name} is a public method of `instance`.
|
224
|
+
#
|
130
225
|
def public_method?(instance) #:nodoc:
|
131
226
|
!(instance.public_methods & [name.to_s, name.to_sym]).empty?
|
132
227
|
end
|
133
|
-
|
228
|
+
|
229
|
+
|
230
|
+
# Is this command's {#name} a private method of `instance`?
|
231
|
+
#
|
232
|
+
# @param [Thor::Base] instance
|
233
|
+
# The Thor instance this command is being run for.
|
234
|
+
#
|
235
|
+
# @return [Boolean]
|
236
|
+
# `true` if {#name} is a private method of `instance`.
|
237
|
+
#
|
134
238
|
def private_method?(instance)
|
135
239
|
!(instance.private_methods & [name.to_s, name.to_sym]).empty?
|
136
240
|
end
|
137
|
-
|
241
|
+
|
242
|
+
|
243
|
+
# Is `name` the name of a method defined in `instance` itself (not
|
244
|
+
# any super class)?
|
245
|
+
#
|
246
|
+
# @param [Thor::Base] instance
|
247
|
+
# The Thor instance this command is being run for.
|
248
|
+
#
|
249
|
+
# @param [Symbol | String] name
|
250
|
+
# The method name.
|
251
|
+
#
|
252
|
+
# @return [Boolean]
|
253
|
+
# `true` if `name` is the name of a method defined in `instance` itself.
|
254
|
+
#
|
138
255
|
def local_method?(instance, name)
|
139
256
|
methods = instance.public_methods(false) +
|
140
257
|
instance.private_methods(false) +
|
141
258
|
instance.protected_methods(false)
|
142
259
|
!(methods & [name.to_s, name.to_sym]).empty?
|
143
260
|
end
|
261
|
+
|
144
262
|
|
145
263
|
def sans_backtrace(backtrace, caller) #:nodoc:
|
146
264
|
saned = backtrace.reject { |frame|
|
data/lib/thor/group.rb
CHANGED
@@ -203,7 +203,7 @@ class Thor::Group
|
|
203
203
|
[item]
|
204
204
|
end
|
205
205
|
alias_method :printable_tasks, :printable_commands
|
206
|
-
|
206
|
+
|
207
207
|
def handle_argument_error(command, error, _args, arity) #:nodoc:
|
208
208
|
msg = "#{basename} #{command.name} takes #{arity} argument".dup
|
209
209
|
msg << "s" if arity > 1
|
@@ -211,71 +211,78 @@ class Thor::Group
|
|
211
211
|
raise error, msg
|
212
212
|
end
|
213
213
|
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
214
|
+
protected
|
215
|
+
# ============================================================================
|
216
|
+
|
217
|
+
# The method responsible for dispatching given the args.
|
218
|
+
def dispatch(command, given_args, given_opts, config) #:nodoc:
|
219
|
+
if Thor::HELP_MAPPINGS.include?(given_args.first)
|
220
|
+
help(config[:shell])
|
221
|
+
return
|
222
|
+
end
|
222
223
|
|
223
|
-
|
224
|
-
|
224
|
+
args, opts = Thor::Options.split(given_args)
|
225
|
+
opts = given_opts || opts
|
225
226
|
|
226
|
-
|
227
|
-
|
227
|
+
instance = new(args, opts, config)
|
228
|
+
yield instance if block_given?
|
228
229
|
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
230
|
+
if command
|
231
|
+
instance.invoke_command(all_commands[command])
|
232
|
+
else
|
233
|
+
instance.invoke_all
|
234
|
+
end
|
233
235
|
end
|
234
|
-
end
|
235
236
|
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
237
|
+
# The banner for this class. You can customize it if you are invoking the
|
238
|
+
# thor class by another ways which is not the Thor::Runner.
|
239
|
+
def banner
|
240
|
+
"#{basename} #{self_command.formatted_usage(self, false)}"
|
241
|
+
end
|
241
242
|
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
243
|
+
# Represents the whole class as a command.
|
244
|
+
def self_command #:nodoc:
|
245
|
+
Thor::DynamicCommand.new(namespace, class_options)
|
246
|
+
end
|
247
|
+
alias_method :self_task, :self_command
|
247
248
|
|
248
|
-
|
249
|
-
|
250
|
-
|
249
|
+
def baseclass #:nodoc:
|
250
|
+
Thor::Group
|
251
|
+
end
|
251
252
|
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
253
|
+
def create_command(meth) #:nodoc:
|
254
|
+
commands[meth.to_s] = Thor::Command.new(meth, nil, nil, nil, nil)
|
255
|
+
true
|
256
|
+
end
|
257
|
+
alias_method :create_task, :create_command
|
258
|
+
|
259
|
+
public # end protected ***************************************************
|
260
|
+
|
261
|
+
end # class << self ********************************************************
|
258
262
|
|
259
263
|
include Thor::Base
|
260
264
|
|
261
|
-
protected
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
265
|
+
protected
|
266
|
+
# ==========================================================================
|
267
|
+
|
268
|
+
# Shortcut to invoke with padding and block handling. Use internally by
|
269
|
+
# invoke and invoke_from_option class methods.
|
270
|
+
def _invoke_for_class_method(klass, command = nil, *args, &block) #:nodoc:
|
271
|
+
with_padding do
|
272
|
+
if block
|
273
|
+
case block.arity
|
274
|
+
when 3
|
275
|
+
yield(self, klass, command)
|
276
|
+
when 2
|
277
|
+
yield(self, klass)
|
278
|
+
when 1
|
279
|
+
instance_exec(klass, &block)
|
280
|
+
end
|
281
|
+
else
|
282
|
+
invoke klass, command, *args
|
275
283
|
end
|
276
|
-
else
|
277
|
-
invoke klass, command, *args
|
278
284
|
end
|
279
285
|
end
|
280
|
-
|
286
|
+
|
287
|
+
public # end protected *****************************************************
|
281
288
|
end
|
data/lib/thor/parser/argument.rb
CHANGED
@@ -44,8 +44,15 @@ class Thor
|
|
44
44
|
protected
|
45
45
|
|
46
46
|
def validate!
|
47
|
-
|
48
|
-
|
47
|
+
if required? && !default.nil?
|
48
|
+
raise ArgumentError,
|
49
|
+
"An argument cannot be required and have default value."
|
50
|
+
end
|
51
|
+
|
52
|
+
if @enum && !@enum.is_a?(Array)
|
53
|
+
raise ArgumentError,
|
54
|
+
"An argument cannot have an enum other than an array."
|
55
|
+
end
|
49
56
|
end
|
50
57
|
|
51
58
|
def valid_type?(type)
|
@@ -1,5 +1,7 @@
|
|
1
1
|
class Thor
|
2
|
-
class Arguments
|
2
|
+
class Arguments # rubocop:disable ClassLength
|
3
|
+
include SemanticLogger::Loggable
|
4
|
+
|
3
5
|
NUMERIC = /[-+]?(\d*\.\d+|\d+)/
|
4
6
|
|
5
7
|
# Receives an array of args and returns two arrays, one with arguments
|
@@ -36,140 +38,170 @@ class Thor
|
|
36
38
|
end
|
37
39
|
end
|
38
40
|
end
|
41
|
+
|
39
42
|
|
40
|
-
def parse
|
43
|
+
def parse args
|
44
|
+
logger.debug __method__.to_s,
|
45
|
+
args: args
|
46
|
+
|
41
47
|
@pile = args.dup
|
42
48
|
|
43
49
|
@switches.each do |argument|
|
44
50
|
break unless peek
|
45
51
|
@non_assigned_required.delete(argument)
|
46
|
-
@assigns[argument.human_name] = send
|
52
|
+
@assigns[argument.human_name] = send :"parse_#{argument.type}",
|
53
|
+
argument.human_name
|
47
54
|
end
|
48
55
|
|
49
56
|
check_requirement!
|
50
57
|
@assigns
|
51
58
|
end
|
59
|
+
|
52
60
|
|
53
61
|
def remaining
|
54
62
|
@pile
|
55
63
|
end
|
64
|
+
|
65
|
+
|
66
|
+
private # Instance Methods
|
67
|
+
# ========================================================================
|
56
68
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
arg =~ /^--(no|skip)-([-\w]+)$/
|
61
|
-
$2
|
62
|
-
end
|
63
|
-
|
64
|
-
def last?
|
65
|
-
@pile.empty?
|
66
|
-
end
|
67
|
-
|
68
|
-
def peek
|
69
|
-
@pile.first
|
70
|
-
end
|
71
|
-
|
72
|
-
def shift
|
73
|
-
@pile.shift
|
74
|
-
end
|
75
|
-
|
76
|
-
def unshift(arg)
|
77
|
-
if arg.is_a?(Array)
|
78
|
-
@pile = arg + @pile
|
79
|
-
else
|
80
|
-
@pile.unshift(arg)
|
69
|
+
def no_or_skip?(arg)
|
70
|
+
arg =~ /^--(no|skip)-([-\w]+)$/
|
71
|
+
$2
|
81
72
|
end
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
end
|
87
|
-
|
88
|
-
# Runs through the argument array getting strings that contains ":" and
|
89
|
-
# mark it as a hash:
|
90
|
-
#
|
91
|
-
# [ "name:string", "age:integer" ]
|
92
|
-
#
|
93
|
-
# Becomes:
|
94
|
-
#
|
95
|
-
# { "name" => "string", "age" => "integer" }
|
96
|
-
#
|
97
|
-
def parse_hash(name)
|
98
|
-
return shift if peek.is_a?(Hash)
|
99
|
-
hash = {}
|
100
|
-
|
101
|
-
while current_is_value? && peek.include?(":")
|
102
|
-
key, value = shift.split(":", 2)
|
103
|
-
raise MalformattedArgumentError, "You can't specify '#{key}' more than once in option '#{name}'; got #{key}:#{hash[key]} and #{key}:#{value}" if hash.include? key
|
104
|
-
hash[key] = value
|
73
|
+
|
74
|
+
|
75
|
+
def last?
|
76
|
+
@pile.empty?
|
105
77
|
end
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
# found or a switch is found.
|
111
|
-
#
|
112
|
-
# ["a", "b", "c"]
|
113
|
-
#
|
114
|
-
# And returns it as an array:
|
115
|
-
#
|
116
|
-
# ["a", "b", "c"]
|
117
|
-
#
|
118
|
-
def parse_array(name)
|
119
|
-
return shift if peek.is_a?(Array)
|
120
|
-
array = []
|
121
|
-
array << shift while current_is_value?
|
122
|
-
array
|
123
|
-
end
|
124
|
-
|
125
|
-
# Check if the peek is numeric format and return a Float or Integer.
|
126
|
-
# Check if the peek is included in enum if enum is provided.
|
127
|
-
# Otherwise raises an error.
|
128
|
-
#
|
129
|
-
def parse_numeric(name)
|
130
|
-
return shift if peek.is_a?(Numeric)
|
131
|
-
|
132
|
-
unless peek =~ NUMERIC && $& == peek
|
133
|
-
raise MalformattedArgumentError, "Expected numeric value for '#{name}'; got #{peek.inspect}"
|
78
|
+
|
79
|
+
|
80
|
+
def peek
|
81
|
+
@pile.first
|
134
82
|
end
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
83
|
+
|
84
|
+
|
85
|
+
def shift
|
86
|
+
@pile.shift
|
87
|
+
end
|
88
|
+
|
89
|
+
|
90
|
+
def unshift(arg)
|
91
|
+
if arg.is_a?(Array)
|
92
|
+
@pile = arg + @pile
|
93
|
+
else
|
94
|
+
@pile.unshift(arg)
|
140
95
|
end
|
141
96
|
end
|
142
|
-
|
143
|
-
|
97
|
+
|
98
|
+
|
99
|
+
def current_is_value?
|
100
|
+
peek && peek.to_s !~ /^-/
|
101
|
+
end
|
102
|
+
|
103
|
+
|
104
|
+
# Runs through the argument array getting strings that contains ":" and
|
105
|
+
# mark it as a hash:
|
106
|
+
#
|
107
|
+
# [ "name:string", "age:integer" ]
|
108
|
+
#
|
109
|
+
# Becomes:
|
110
|
+
#
|
111
|
+
# { "name" => "string", "age" => "integer" }
|
112
|
+
#
|
113
|
+
def parse_hash(name)
|
114
|
+
return shift if peek.is_a?(Hash)
|
115
|
+
hash = {}
|
116
|
+
|
117
|
+
while current_is_value? && peek.include?(":")
|
118
|
+
key, value = shift.split(":", 2)
|
119
|
+
if hash.include? key
|
120
|
+
raise MalformattedArgumentError,
|
121
|
+
"You can't specify '#{key}' more than once in option " \
|
122
|
+
"'#{name}'; got #{key}:#{hash[key]} and #{key}:#{value}"
|
123
|
+
end
|
124
|
+
hash[key] = value
|
125
|
+
end
|
126
|
+
hash
|
127
|
+
end
|
128
|
+
|
129
|
+
|
130
|
+
# Runs through the argument array getting all strings until no string is
|
131
|
+
# found or a switch is found.
|
132
|
+
#
|
133
|
+
# ["a", "b", "c"]
|
134
|
+
#
|
135
|
+
# And returns it as an array:
|
136
|
+
#
|
137
|
+
# ["a", "b", "c"]
|
138
|
+
#
|
139
|
+
def parse_array(name)
|
140
|
+
return shift if peek.is_a?(Array)
|
141
|
+
array = []
|
142
|
+
array << shift while current_is_value?
|
143
|
+
array
|
144
|
+
end
|
145
|
+
|
146
|
+
|
147
|
+
# Check if the peek is numeric format and return a Float or Integer.
|
148
|
+
# Check if the peek is included in enum if enum is provided.
|
149
|
+
# Otherwise raises an error.
|
150
|
+
#
|
151
|
+
def parse_numeric(name)
|
152
|
+
return shift if peek.is_a?(Numeric)
|
153
|
+
|
154
|
+
unless peek =~ NUMERIC && $& == peek
|
155
|
+
raise MalformattedArgumentError,
|
156
|
+
"Expected numeric value for '#{name}'; got #{peek.inspect}"
|
157
|
+
end
|
144
158
|
|
145
|
-
|
146
|
-
# for --string-arg, just return the current value in the pile
|
147
|
-
# for --no-string-arg, nil
|
148
|
-
# Check if the peek is included in enum if enum is provided. Otherwise raises an error.
|
149
|
-
#
|
150
|
-
def parse_string(name)
|
151
|
-
if no_or_skip?(name)
|
152
|
-
nil
|
153
|
-
else
|
154
|
-
value = shift
|
159
|
+
value = $&.index(".") ? shift.to_f : shift.to_i
|
155
160
|
if @switches.is_a?(Hash) && switch = @switches[name]
|
156
161
|
if switch.enum && !switch.enum.include?(value)
|
157
|
-
raise MalformattedArgumentError,
|
162
|
+
raise MalformattedArgumentError,
|
163
|
+
"Expected '#{name}' to be one of #{switch.enum.join(', ')}; " \
|
164
|
+
"got #{value}"
|
158
165
|
end
|
159
166
|
end
|
160
167
|
value
|
161
168
|
end
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
169
|
+
|
170
|
+
|
171
|
+
# Parse string:
|
172
|
+
# for --string-arg, just return the current value in the pile
|
173
|
+
# for --no-string-arg, nil
|
174
|
+
# Check if the peek is included in enum if enum is provided. Otherwise raises an error.
|
175
|
+
#
|
176
|
+
def parse_string(name)
|
177
|
+
if no_or_skip?(name)
|
178
|
+
nil
|
179
|
+
else
|
180
|
+
value = shift
|
181
|
+
if @switches.is_a?(Hash) && switch = @switches[name]
|
182
|
+
if switch.enum && !switch.enum.include?(value)
|
183
|
+
raise MalformattedArgumentError,
|
184
|
+
"Expected '#{name}' to be one of #{switch.enum.join(', ')}; " \
|
185
|
+
"got #{value}"
|
186
|
+
end
|
187
|
+
end
|
188
|
+
value
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
|
193
|
+
# Raises an error if @non_assigned_required array is not empty.
|
194
|
+
#
|
195
|
+
def check_requirement!
|
196
|
+
return if @non_assigned_required.empty?
|
197
|
+
names = @non_assigned_required.map do |o|
|
198
|
+
o.respond_to?(:switch_name) ? o.switch_name : o.human_name
|
199
|
+
end.join("', '")
|
200
|
+
class_name = self.class.name.split("::").last.downcase
|
201
|
+
raise RequiredArgumentMissingError,
|
202
|
+
"No value provided for required #{class_name} '#{names}'"
|
203
|
+
end
|
204
|
+
|
205
|
+
public # end private Instance Methods ************************************
|
206
|
+
end # class Arguments
|
207
|
+
end # class Thor
|