thor 0.19.1 → 0.19.2
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 +24 -0
- data/CONTRIBUTING.md +15 -0
- data/README.md +7 -1
- data/lib/thor.rb +31 -23
- data/lib/thor/actions.rb +21 -22
- data/lib/thor/actions/create_file.rb +1 -1
- data/lib/thor/actions/create_link.rb +1 -1
- data/lib/thor/actions/directory.rb +2 -2
- data/lib/thor/actions/empty_directory.rb +8 -8
- data/lib/thor/actions/file_manipulation.rb +23 -12
- data/lib/thor/actions/inject_into_file.rb +10 -14
- data/lib/thor/base.rb +33 -33
- data/lib/thor/command.rb +9 -9
- data/lib/thor/core_ext/hash_with_indifferent_access.rb +9 -1
- data/lib/thor/core_ext/io_binary_read.rb +7 -5
- data/lib/thor/core_ext/ordered_hash.rb +94 -63
- data/lib/thor/error.rb +3 -3
- data/lib/thor/group.rb +12 -12
- data/lib/thor/invocation.rb +4 -5
- data/lib/thor/parser/argument.rb +4 -7
- data/lib/thor/parser/arguments.rb +16 -16
- data/lib/thor/parser/option.rb +39 -19
- data/lib/thor/parser/options.rb +7 -5
- data/lib/thor/runner.rb +25 -25
- data/lib/thor/shell.rb +1 -1
- data/lib/thor/shell/basic.rb +41 -26
- data/lib/thor/shell/color.rb +1 -1
- data/lib/thor/shell/html.rb +4 -4
- data/lib/thor/util.rb +8 -7
- data/lib/thor/version.rb +1 -1
- data/thor.gemspec +6 -9
- metadata +6 -148
- data/Thorfile +0 -29
- data/spec/actions/create_file_spec.rb +0 -168
- data/spec/actions/create_link_spec.rb +0 -96
- data/spec/actions/directory_spec.rb +0 -169
- data/spec/actions/empty_directory_spec.rb +0 -129
- data/spec/actions/file_manipulation_spec.rb +0 -392
- data/spec/actions/inject_into_file_spec.rb +0 -135
- data/spec/actions_spec.rb +0 -331
- data/spec/base_spec.rb +0 -298
- data/spec/command_spec.rb +0 -79
- data/spec/core_ext/hash_with_indifferent_access_spec.rb +0 -48
- data/spec/core_ext/ordered_hash_spec.rb +0 -115
- data/spec/exit_condition_spec.rb +0 -19
- data/spec/fixtures/application.rb +0 -2
- data/spec/fixtures/app{1}/README +0 -3
- data/spec/fixtures/bundle/execute.rb +0 -6
- data/spec/fixtures/bundle/main.thor +0 -1
- data/spec/fixtures/command.thor +0 -10
- data/spec/fixtures/doc/%file_name%.rb.tt +0 -1
- data/spec/fixtures/doc/COMMENTER +0 -11
- data/spec/fixtures/doc/README +0 -3
- data/spec/fixtures/doc/block_helper.rb +0 -3
- data/spec/fixtures/doc/config.rb +0 -1
- data/spec/fixtures/doc/config.yaml.tt +0 -1
- data/spec/fixtures/doc/excluding/%file_name%.rb.tt +0 -1
- data/spec/fixtures/enum.thor +0 -10
- data/spec/fixtures/group.thor +0 -128
- data/spec/fixtures/invoke.thor +0 -131
- data/spec/fixtures/path with spaces b/data/spec/fixtures/path with → spaces +0 -0
- data/spec/fixtures/preserve/script.sh +0 -3
- data/spec/fixtures/script.thor +0 -220
- data/spec/fixtures/subcommand.thor +0 -17
- data/spec/group_spec.rb +0 -222
- data/spec/helper.rb +0 -80
- data/spec/invocation_spec.rb +0 -120
- data/spec/line_editor/basic_spec.rb +0 -28
- data/spec/line_editor/readline_spec.rb +0 -69
- data/spec/line_editor_spec.rb +0 -43
- data/spec/parser/argument_spec.rb +0 -53
- data/spec/parser/arguments_spec.rb +0 -66
- data/spec/parser/option_spec.rb +0 -210
- data/spec/parser/options_spec.rb +0 -414
- data/spec/quality_spec.rb +0 -75
- data/spec/rake_compat_spec.rb +0 -72
- data/spec/register_spec.rb +0 -227
- data/spec/runner_spec.rb +0 -246
- data/spec/sandbox/application.rb +0 -2
- data/spec/sandbox/app{1}/README +0 -3
- data/spec/sandbox/bundle/execute.rb +0 -6
- data/spec/sandbox/bundle/main.thor +0 -1
- data/spec/sandbox/command.thor +0 -10
- data/spec/sandbox/doc/%file_name%.rb.tt +0 -1
- data/spec/sandbox/doc/COMMENTER +0 -11
- data/spec/sandbox/doc/README +0 -3
- data/spec/sandbox/doc/block_helper.rb +0 -3
- data/spec/sandbox/doc/config.rb +0 -1
- data/spec/sandbox/doc/config.yaml.tt +0 -1
- data/spec/sandbox/doc/excluding/%file_name%.rb.tt +0 -1
- data/spec/sandbox/enum.thor +0 -10
- data/spec/sandbox/group.thor +0 -128
- data/spec/sandbox/invoke.thor +0 -131
- data/spec/sandbox/path with spaces b/data/spec/sandbox/path with → spaces +0 -0
- data/spec/sandbox/preserve/script.sh +0 -3
- data/spec/sandbox/script.thor +0 -220
- data/spec/sandbox/subcommand.thor +0 -17
- data/spec/shell/basic_spec.rb +0 -337
- data/spec/shell/color_spec.rb +0 -119
- data/spec/shell/html_spec.rb +0 -31
- data/spec/shell_spec.rb +0 -47
- data/spec/subcommand_spec.rb +0 -48
- data/spec/thor_spec.rb +0 -505
- data/spec/util_spec.rb +0 -196
data/lib/thor/error.rb
CHANGED
@@ -3,7 +3,7 @@ class Thor
|
|
3
3
|
# errors have their backtrace suppressed and are nicely shown to the user.
|
4
4
|
#
|
5
5
|
# Errors that are caused by the developer, like declaring a method which
|
6
|
-
# overwrites a thor keyword,
|
6
|
+
# overwrites a thor keyword, SHOULD NOT raise a Thor::Error. This way, we
|
7
7
|
# ensure that developer errors are shown with full backtrace.
|
8
8
|
class Error < StandardError
|
9
9
|
end
|
@@ -11,11 +11,11 @@ class Thor
|
|
11
11
|
# Raised when a command was not found.
|
12
12
|
class UndefinedCommandError < Error
|
13
13
|
end
|
14
|
-
UndefinedTaskError = UndefinedCommandError
|
14
|
+
UndefinedTaskError = UndefinedCommandError
|
15
15
|
|
16
16
|
class AmbiguousCommandError < Error
|
17
17
|
end
|
18
|
-
AmbiguousTaskError = AmbiguousCommandError
|
18
|
+
AmbiguousTaskError = AmbiguousCommandError
|
19
19
|
|
20
20
|
# Raised when a command was found, but not invoked properly.
|
21
21
|
class InvocationError < Error
|
data/lib/thor/group.rb
CHANGED
@@ -4,7 +4,7 @@ require "thor/base"
|
|
4
4
|
# is that it invokes all commands at once. It also include some methods that allows
|
5
5
|
# invocations to be done at the class method, which are not available to Thor
|
6
6
|
# commands.
|
7
|
-
class Thor::Group
|
7
|
+
class Thor::Group
|
8
8
|
class << self
|
9
9
|
# The description for this Thor::Group. If none is provided, but a source root
|
10
10
|
# exists, tries to find the USAGE one folder above it, otherwise searches
|
@@ -53,7 +53,7 @@ class Thor::Group # rubocop:disable ClassLength
|
|
53
53
|
# The namespace/class given will have its options showed on the help
|
54
54
|
# usage. Check invoke_from_option for more information.
|
55
55
|
#
|
56
|
-
def invoke(*names, &block)
|
56
|
+
def invoke(*names, &block)
|
57
57
|
options = names.last.is_a?(Hash) ? names.pop : {}
|
58
58
|
verbose = options.fetch(:verbose, true)
|
59
59
|
|
@@ -62,7 +62,7 @@ class Thor::Group # rubocop:disable ClassLength
|
|
62
62
|
invocation_blocks[name] = block if block_given?
|
63
63
|
|
64
64
|
class_eval <<-METHOD, __FILE__, __LINE__
|
65
|
-
def _invoke_#{name.to_s.gsub(/\W/,
|
65
|
+
def _invoke_#{name.to_s.gsub(/\W/, '_')}
|
66
66
|
klass, command = self.class.prepare_for_invocation(nil, #{name.inspect})
|
67
67
|
|
68
68
|
if klass
|
@@ -107,21 +107,21 @@ class Thor::Group # rubocop:disable ClassLength
|
|
107
107
|
# invoked. The block receives two parameters, an instance of the current
|
108
108
|
# class and the klass to be invoked.
|
109
109
|
#
|
110
|
-
def invoke_from_option(*names, &block)
|
110
|
+
def invoke_from_option(*names, &block)
|
111
111
|
options = names.last.is_a?(Hash) ? names.pop : {}
|
112
112
|
verbose = options.fetch(:verbose, :white)
|
113
113
|
|
114
114
|
names.each do |name|
|
115
115
|
unless class_options.key?(name)
|
116
|
-
|
117
|
-
|
116
|
+
raise ArgumentError, "You have to define the option #{name.inspect} " \
|
117
|
+
"before setting invoke_from_option."
|
118
118
|
end
|
119
119
|
|
120
120
|
invocations[name] = true
|
121
121
|
invocation_blocks[name] = block if block_given?
|
122
122
|
|
123
123
|
class_eval <<-METHOD, __FILE__, __LINE__
|
124
|
-
def _invoke_from_option_#{name.to_s.gsub(/\W/,
|
124
|
+
def _invoke_from_option_#{name.to_s.gsub(/\W/, '_')}
|
125
125
|
return unless options[#{name.inspect}]
|
126
126
|
|
127
127
|
value = options[#{name.inspect}]
|
@@ -188,7 +188,7 @@ class Thor::Group # rubocop:disable ClassLength
|
|
188
188
|
group_options[human_name] ||= []
|
189
189
|
group_options[human_name] += klass.class_options.values.select do |class_option|
|
190
190
|
base_options[class_option.name.to_sym].nil? && class_option.group.nil? &&
|
191
|
-
|
191
|
+
!group_options.values.flatten.any? { |i| i.name == class_option.name }
|
192
192
|
end
|
193
193
|
|
194
194
|
yield klass if block_given?
|
@@ -204,11 +204,11 @@ class Thor::Group # rubocop:disable ClassLength
|
|
204
204
|
end
|
205
205
|
alias_method :printable_tasks, :printable_commands
|
206
206
|
|
207
|
-
def handle_argument_error(command, error,
|
207
|
+
def handle_argument_error(command, error, _args, arity) #:nodoc:
|
208
208
|
msg = "#{basename} #{command.name} takes #{arity} argument"
|
209
209
|
msg << "s" if arity > 1
|
210
210
|
msg << ", but it should not."
|
211
|
-
|
211
|
+
raise error, msg
|
212
212
|
end
|
213
213
|
|
214
214
|
protected
|
@@ -267,9 +267,9 @@ protected
|
|
267
267
|
if block
|
268
268
|
case block.arity
|
269
269
|
when 3
|
270
|
-
|
270
|
+
yield(self, klass, command)
|
271
271
|
when 2
|
272
|
-
|
272
|
+
yield(self, klass)
|
273
273
|
when 1
|
274
274
|
instance_exec(klass, &block)
|
275
275
|
end
|
data/lib/thor/invocation.rb
CHANGED
@@ -108,8 +108,8 @@ class Thor
|
|
108
108
|
command, args, opts, config = args
|
109
109
|
|
110
110
|
klass, command = _retrieve_class_and_command(name, command)
|
111
|
-
|
112
|
-
|
111
|
+
raise "Missing Thor class for invoke #{name}" unless klass
|
112
|
+
raise "Expected Thor class, got #{klass}" unless klass <= Thor::Base
|
113
113
|
|
114
114
|
args, opts, config = _parse_initialization_options(args, opts, config)
|
115
115
|
klass.send(:dispatch, command, args, opts, config) do |instance|
|
@@ -150,10 +150,9 @@ class Thor
|
|
150
150
|
# use the given name and return self as class. Otherwise, call
|
151
151
|
# prepare_for_invocation in the current class.
|
152
152
|
def _retrieve_class_and_command(name, sent_command = nil) #:nodoc:
|
153
|
-
|
154
|
-
when name.nil?
|
153
|
+
if name.nil?
|
155
154
|
[self.class, nil]
|
156
|
-
|
155
|
+
elsif self.class.all_commands[name.to_s]
|
157
156
|
[self.class, name.to_s]
|
158
157
|
else
|
159
158
|
klass, command = self.class.prepare_for_invocation(nil, name)
|
data/lib/thor/parser/argument.rb
CHANGED
@@ -10,8 +10,8 @@ class Thor
|
|
10
10
|
|
11
11
|
type = options[:type]
|
12
12
|
|
13
|
-
|
14
|
-
|
13
|
+
raise ArgumentError, "#{class_name} name can't be nil." if name.nil?
|
14
|
+
raise ArgumentError, "Type :#{type} is not valid for #{class_name.downcase}s." if type && !valid_type?(type)
|
15
15
|
|
16
16
|
@name = name.to_s
|
17
17
|
@description = options[:desc]
|
@@ -44,11 +44,8 @@ class Thor
|
|
44
44
|
protected
|
45
45
|
|
46
46
|
def validate!
|
47
|
-
if required? && !default.nil?
|
48
|
-
|
49
|
-
elsif @enum && !@enum.is_a?(Array)
|
50
|
-
fail ArgumentError, "An argument cannot have an enum other than an array."
|
51
|
-
end
|
47
|
+
raise ArgumentError, "An argument cannot be required and have default value." if required? && !default.nil?
|
48
|
+
raise ArgumentError, "An argument cannot have an enum other than an array." if @enum && !@enum.is_a?(Array)
|
52
49
|
end
|
53
50
|
|
54
51
|
def valid_type?(type)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
class Thor
|
2
2
|
class Arguments #:nodoc: # rubocop:disable ClassLength
|
3
|
-
NUMERIC = /(\d*\.\d+|\d+)/
|
3
|
+
NUMERIC = /[-+]?(\d*\.\d+|\d+)/
|
4
4
|
|
5
5
|
# Receives an array of args and returns two arrays, one with arguments
|
6
6
|
# and one with switches.
|
@@ -24,7 +24,8 @@ class Thor
|
|
24
24
|
# Takes an array of Thor::Argument objects.
|
25
25
|
#
|
26
26
|
def initialize(arguments = [])
|
27
|
-
@assigns
|
27
|
+
@assigns = {}
|
28
|
+
@non_assigned_required = []
|
28
29
|
@switches = arguments
|
29
30
|
|
30
31
|
arguments.each do |argument|
|
@@ -49,7 +50,7 @@ class Thor
|
|
49
50
|
@assigns
|
50
51
|
end
|
51
52
|
|
52
|
-
def remaining
|
53
|
+
def remaining
|
53
54
|
@pile
|
54
55
|
end
|
55
56
|
|
@@ -73,7 +74,7 @@ class Thor
|
|
73
74
|
end
|
74
75
|
|
75
76
|
def unshift(arg)
|
76
|
-
if arg.
|
77
|
+
if arg.is_a?(Array)
|
77
78
|
@pile = arg + @pile
|
78
79
|
else
|
79
80
|
@pile.unshift(arg)
|
@@ -99,6 +100,7 @@ class Thor
|
|
99
100
|
|
100
101
|
while current_is_value? && peek.include?(":")
|
101
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
|
102
104
|
hash[key] = value
|
103
105
|
end
|
104
106
|
hash
|
@@ -128,13 +130,13 @@ class Thor
|
|
128
130
|
return shift if peek.is_a?(Numeric)
|
129
131
|
|
130
132
|
unless peek =~ NUMERIC && $& == peek
|
131
|
-
|
133
|
+
raise MalformattedArgumentError, "Expected numeric value for '#{name}'; got #{peek.inspect}"
|
132
134
|
end
|
133
135
|
|
134
136
|
value = $&.index(".") ? shift.to_f : shift.to_i
|
135
137
|
if @switches.is_a?(Hash) && switch = @switches[name]
|
136
138
|
if switch.enum && !switch.enum.include?(value)
|
137
|
-
|
139
|
+
raise MalformattedArgumentError, "Expected '#{name}' to be one of #{switch.enum.join(', ')}; got #{value}"
|
138
140
|
end
|
139
141
|
end
|
140
142
|
value
|
@@ -150,9 +152,9 @@ class Thor
|
|
150
152
|
nil
|
151
153
|
else
|
152
154
|
value = shift
|
153
|
-
if @switches.is_a?(Hash) && switch = @switches[name]
|
155
|
+
if @switches.is_a?(Hash) && switch = @switches[name]
|
154
156
|
if switch.enum && !switch.enum.include?(value)
|
155
|
-
|
157
|
+
raise MalformattedArgumentError, "Expected '#{name}' to be one of #{switch.enum.join(', ')}; got #{value}"
|
156
158
|
end
|
157
159
|
end
|
158
160
|
value
|
@@ -162,14 +164,12 @@ class Thor
|
|
162
164
|
# Raises an error if @non_assigned_required array is not empty.
|
163
165
|
#
|
164
166
|
def check_requirement!
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
fail RequiredArgumentMissingError, "No value provided for required #{class_name} '#{names}'"
|
172
|
-
end
|
167
|
+
return if @non_assigned_required.empty?
|
168
|
+
names = @non_assigned_required.map do |o|
|
169
|
+
o.respond_to?(:switch_name) ? o.switch_name : o.human_name
|
170
|
+
end.join("', '")
|
171
|
+
class_name = self.class.name.split("::").last.downcase
|
172
|
+
raise RequiredArgumentMissingError, "No value provided for required #{class_name} '#{names}'"
|
173
173
|
end
|
174
174
|
end
|
175
175
|
end
|
data/lib/thor/parser/option.rb
CHANGED
@@ -40,31 +40,33 @@ class Thor
|
|
40
40
|
#
|
41
41
|
# By default all options are optional, unless :required is given.
|
42
42
|
#
|
43
|
-
def self.parse(key, value)
|
43
|
+
def self.parse(key, value)
|
44
44
|
if key.is_a?(Array)
|
45
45
|
name, *aliases = key
|
46
46
|
else
|
47
|
-
name
|
47
|
+
name = key
|
48
|
+
aliases = []
|
48
49
|
end
|
49
50
|
|
50
51
|
name = name.to_s
|
51
52
|
default = value
|
52
53
|
|
53
54
|
type = case value
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
55
|
+
when Symbol
|
56
|
+
default = nil
|
57
|
+
if VALID_TYPES.include?(value)
|
58
|
+
value
|
59
|
+
elsif required = (value == :required) # rubocop:disable AssignmentInCondition
|
60
|
+
:string
|
61
|
+
end
|
62
|
+
when TrueClass, FalseClass
|
63
|
+
:boolean
|
64
|
+
when Numeric
|
65
|
+
:numeric
|
66
|
+
when Hash, Array, String
|
67
|
+
value.class.name.downcase.to_sym
|
68
|
+
end
|
69
|
+
|
68
70
|
new(name.to_s, :required => required, :type => type, :default => default, :aliases => aliases)
|
69
71
|
end
|
70
72
|
|
@@ -86,7 +88,7 @@ class Thor
|
|
86
88
|
sample = "[#{sample}]" unless required?
|
87
89
|
|
88
90
|
if boolean?
|
89
|
-
sample << ", [#{dasherize(
|
91
|
+
sample << ", [#{dasherize('no-' + human_name)}]" unless (name == "force") || name.start_with?("no-")
|
90
92
|
end
|
91
93
|
|
92
94
|
if aliases.empty?
|
@@ -107,7 +109,25 @@ class Thor
|
|
107
109
|
protected
|
108
110
|
|
109
111
|
def validate!
|
110
|
-
|
112
|
+
raise ArgumentError, "An option cannot be boolean and required." if boolean? && required?
|
113
|
+
validate_default_type!
|
114
|
+
end
|
115
|
+
|
116
|
+
def validate_default_type!
|
117
|
+
default_type = case @default
|
118
|
+
when nil
|
119
|
+
return
|
120
|
+
when TrueClass, FalseClass
|
121
|
+
required? ? :string : :boolean
|
122
|
+
when Numeric
|
123
|
+
:numeric
|
124
|
+
when Symbol
|
125
|
+
:string
|
126
|
+
when Hash, Array, String
|
127
|
+
@default.class.name.downcase.to_sym
|
128
|
+
end
|
129
|
+
|
130
|
+
raise ArgumentError, "An option's default must match its type." unless default_type == @type
|
111
131
|
end
|
112
132
|
|
113
133
|
def dasherized?
|
@@ -119,7 +139,7 @@ class Thor
|
|
119
139
|
end
|
120
140
|
|
121
141
|
def dasherize(str)
|
122
|
-
(str.length > 1 ? "--" : "-") + str.
|
142
|
+
(str.length > 1 ? "--" : "-") + str.tr("_", "-")
|
123
143
|
end
|
124
144
|
end
|
125
145
|
end
|
data/lib/thor/parser/options.rb
CHANGED
@@ -14,7 +14,7 @@ class Thor
|
|
14
14
|
when true
|
15
15
|
"--#{key}"
|
16
16
|
when Array
|
17
|
-
"--#{key} #{value.map
|
17
|
+
"--#{key} #{value.map(&:inspect).join(' ')}"
|
18
18
|
when Hash
|
19
19
|
"--#{key} #{value.map { |k, v| "#{k}:#{v}" }.join(' ')}"
|
20
20
|
when nil, false
|
@@ -40,7 +40,9 @@ class Thor
|
|
40
40
|
@non_assigned_required.delete(hash_options[key])
|
41
41
|
end
|
42
42
|
|
43
|
-
@shorts
|
43
|
+
@shorts = {}
|
44
|
+
@switches = {}
|
45
|
+
@extra = []
|
44
46
|
|
45
47
|
options.each do |option|
|
46
48
|
@switches[option.switch_name] = option
|
@@ -52,7 +54,7 @@ class Thor
|
|
52
54
|
end
|
53
55
|
end
|
54
56
|
|
55
|
-
def remaining
|
57
|
+
def remaining
|
56
58
|
@extra
|
57
59
|
end
|
58
60
|
|
@@ -119,7 +121,7 @@ class Thor
|
|
119
121
|
def check_unknown!
|
120
122
|
# an unknown option starts with - or -- and has no more --'s afterward.
|
121
123
|
unknown = @extra.select { |str| str =~ /^--?(?:(?!--).)*$/ }
|
122
|
-
|
124
|
+
raise UnknownArgumentError, "Unknown switches '#{unknown.join(', ')}'" unless unknown.empty?
|
123
125
|
end
|
124
126
|
|
125
127
|
protected
|
@@ -207,7 +209,7 @@ class Thor
|
|
207
209
|
elsif option.lazy_default
|
208
210
|
return option.lazy_default
|
209
211
|
else
|
210
|
-
|
212
|
+
raise MalformattedArgumentError, "No value provided for option '#{switch}'"
|
211
213
|
end
|
212
214
|
end
|
213
215
|
|
data/lib/thor/runner.rb
CHANGED
@@ -11,10 +11,18 @@ require "pathname"
|
|
11
11
|
class Thor::Runner < Thor #:nodoc: # rubocop:disable ClassLength
|
12
12
|
map "-T" => :list, "-i" => :install, "-u" => :update, "-v" => :version
|
13
13
|
|
14
|
+
def self.banner(command, all = false, subcommand = false)
|
15
|
+
"thor " + command.formatted_usage(self, all, subcommand)
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.exit_on_failure?
|
19
|
+
true
|
20
|
+
end
|
21
|
+
|
14
22
|
# Override Thor#help so it can give information about any class and any method.
|
15
23
|
#
|
16
24
|
def help(meth = nil)
|
17
|
-
if meth && !
|
25
|
+
if meth && !respond_to?(meth)
|
18
26
|
initialize_thorfiles(meth)
|
19
27
|
klass, command = Thor::Util.find_class_and_command_by_namespace(meth)
|
20
28
|
self.class.handle_no_command_error(command, false) if klass.nil?
|
@@ -45,16 +53,18 @@ class Thor::Runner < Thor #:nodoc: # rubocop:disable ClassLength
|
|
45
53
|
# command in said directory.
|
46
54
|
begin
|
47
55
|
if File.directory?(File.expand_path(name))
|
48
|
-
base
|
49
|
-
|
56
|
+
base = File.join(name, "main.thor")
|
57
|
+
package = :directory
|
58
|
+
contents = open(base, &:read)
|
50
59
|
else
|
51
|
-
base
|
52
|
-
|
60
|
+
base = name
|
61
|
+
package = :file
|
62
|
+
contents = open(name, &:read)
|
53
63
|
end
|
54
64
|
rescue OpenURI::HTTPError
|
55
65
|
raise Error, "Error opening URI '#{name}'"
|
56
66
|
rescue Errno::ENOENT
|
57
|
-
|
67
|
+
raise Error, "Error opening file '#{name}'"
|
58
68
|
end
|
59
69
|
|
60
70
|
say "Your Thorfile contains:"
|
@@ -108,9 +118,9 @@ class Thor::Runner < Thor #:nodoc: # rubocop:disable ClassLength
|
|
108
118
|
|
109
119
|
desc "uninstall NAME", "Uninstall a named Thor module"
|
110
120
|
def uninstall(name)
|
111
|
-
|
121
|
+
raise Error, "Can't find module '#{name}'" unless thor_yaml[name]
|
112
122
|
say "Uninstalling #{name}."
|
113
|
-
FileUtils.rm_rf(File.join(thor_root,
|
123
|
+
FileUtils.rm_rf(File.join(thor_root, (thor_yaml[name][:filename]).to_s))
|
114
124
|
|
115
125
|
thor_yaml.delete(name)
|
116
126
|
save_yaml(thor_yaml)
|
@@ -120,7 +130,7 @@ class Thor::Runner < Thor #:nodoc: # rubocop:disable ClassLength
|
|
120
130
|
|
121
131
|
desc "update NAME", "Update a Thor file from its original location"
|
122
132
|
def update(name)
|
123
|
-
|
133
|
+
raise Error, "Can't find module '#{name}'" if !thor_yaml[name] || !thor_yaml[name][:location]
|
124
134
|
|
125
135
|
say "Updating '#{name}' from #{thor_yaml[name][:location]}"
|
126
136
|
|
@@ -138,9 +148,7 @@ class Thor::Runner < Thor #:nodoc: # rubocop:disable ClassLength
|
|
138
148
|
filename = install(thor_yaml[name][:location])
|
139
149
|
end
|
140
150
|
|
141
|
-
unless filename == old_filename
|
142
|
-
File.delete(File.join(thor_root, old_filename))
|
143
|
-
end
|
151
|
+
File.delete(File.join(thor_root, old_filename)) unless filename == old_filename
|
144
152
|
end
|
145
153
|
|
146
154
|
desc "installed", "List the installed Thor modules and commands"
|
@@ -168,10 +176,6 @@ class Thor::Runner < Thor #:nodoc: # rubocop:disable ClassLength
|
|
168
176
|
|
169
177
|
private
|
170
178
|
|
171
|
-
def self.banner(command, all = false, subcommand = false)
|
172
|
-
"thor " + command.formatted_usage(self, all, subcommand)
|
173
|
-
end
|
174
|
-
|
175
179
|
def thor_root
|
176
180
|
Thor::Util.thor_root
|
177
181
|
end
|
@@ -198,10 +202,6 @@ private
|
|
198
202
|
File.open(yaml_file, "w") { |f| f.puts yaml.to_yaml }
|
199
203
|
end
|
200
204
|
|
201
|
-
def self.exit_on_failure?
|
202
|
-
true
|
203
|
-
end
|
204
|
-
|
205
205
|
# Load the Thorfiles. If relevant_to is supplied, looks for specific files
|
206
206
|
# in the thor_root instead of loading them all.
|
207
207
|
#
|
@@ -263,11 +263,11 @@ private
|
|
263
263
|
def thorfiles_relevant_to(meth)
|
264
264
|
lookup = [meth, meth.split(":")[0...-1].join(":")]
|
265
265
|
|
266
|
-
files = thor_yaml.select do |
|
266
|
+
files = thor_yaml.select do |_, v|
|
267
267
|
v[:namespaces] && !(v[:namespaces] & lookup).empty?
|
268
268
|
end
|
269
269
|
|
270
|
-
files.map { |
|
270
|
+
files.map { |_, v| File.join(thor_root, (v[:filename]).to_s) }
|
271
271
|
end
|
272
272
|
|
273
273
|
# Display information about the given klasses. If with_module is given,
|
@@ -276,7 +276,7 @@ private
|
|
276
276
|
def display_klasses(with_modules = false, show_internal = false, klasses = Thor::Base.subclasses)
|
277
277
|
klasses -= [Thor, Thor::Runner, Thor::Group] unless show_internal
|
278
278
|
|
279
|
-
|
279
|
+
raise Error, "No Thor commands available" if klasses.empty?
|
280
280
|
show_modules if with_modules && !thor_yaml.empty?
|
281
281
|
|
282
282
|
list = Hash.new { |h, k| h[k] = [] }
|
@@ -306,8 +306,8 @@ private
|
|
306
306
|
alias_method :display_tasks, :display_commands
|
307
307
|
|
308
308
|
def show_modules #:nodoc:
|
309
|
-
info
|
310
|
-
labels = %w
|
309
|
+
info = []
|
310
|
+
labels = %w(Modules Namespaces)
|
311
311
|
|
312
312
|
info << labels
|
313
313
|
info << ["-" * labels[0].size, "-" * labels[1].size]
|