bundler 1.3.6 → 1.4.0.pre.1
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.
Potentially problematic release.
This version of bundler might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/.travis.yml +1 -3
- data/CHANGELOG.md +27 -14
- data/CONTRIBUTING.md +2 -2
- data/{CONTRIBUTE.md → DEVELOPMENT.md} +31 -12
- data/ISSUES.md +1 -1
- data/README.md +6 -4
- data/Rakefile +1 -15
- data/bin/bundle +5 -8
- data/bundler.gemspec +1 -1
- data/lib/bundler.rb +37 -21
- data/lib/bundler/cli.rb +33 -21
- data/lib/bundler/constants.rb +5 -0
- data/lib/bundler/current_ruby.rb +88 -0
- data/lib/bundler/definition.rb +35 -11
- data/lib/bundler/dependency.rb +7 -78
- data/lib/bundler/dsl.rb +1 -1
- data/lib/bundler/fetcher.rb +37 -24
- data/lib/bundler/gem_helper.rb +2 -2
- data/lib/bundler/gem_installer.rb +9 -0
- data/lib/bundler/installer.rb +76 -7
- data/lib/bundler/parallel_workers.rb +18 -0
- data/lib/bundler/parallel_workers/thread_worker.rb +27 -0
- data/lib/bundler/parallel_workers/unix_worker.rb +88 -0
- data/lib/bundler/parallel_workers/worker.rb +68 -0
- data/lib/bundler/resolver.rb +17 -11
- data/lib/bundler/rubygems_ext.rb +2 -2
- data/lib/bundler/rubygems_integration.rb +37 -25
- data/lib/bundler/runtime.rb +8 -1
- data/lib/bundler/safe_catch.rb +101 -0
- data/lib/bundler/shared_helpers.rb +27 -1
- data/lib/bundler/source/git.rb +2 -1
- data/lib/bundler/source/git/git_proxy.rb +3 -3
- data/lib/bundler/source/path.rb +3 -2
- data/lib/bundler/source/rubygems.rb +5 -17
- data/lib/bundler/spec_set.rb +16 -1
- data/lib/bundler/templates/newgem/newgem.gemspec.tt +1 -1
- data/lib/bundler/vendor/net/http/persistent.rb +136 -38
- data/lib/bundler/vendor/thor.rb +211 -188
- data/lib/bundler/vendor/thor/actions.rb +19 -19
- data/lib/bundler/vendor/thor/actions/create_link.rb +3 -0
- data/lib/bundler/vendor/thor/actions/directory.rb +30 -10
- data/lib/bundler/vendor/thor/actions/empty_directory.rb +3 -19
- data/lib/bundler/vendor/thor/actions/file_manipulation.rb +6 -3
- data/lib/bundler/vendor/thor/base.rb +101 -97
- data/lib/bundler/vendor/thor/{task.rb → command.rb} +17 -13
- data/lib/bundler/vendor/thor/core_ext/io_binary_read.rb +12 -0
- data/lib/bundler/vendor/thor/error.rb +8 -11
- data/lib/bundler/vendor/thor/group.rb +35 -38
- data/lib/bundler/vendor/thor/invocation.rb +28 -26
- data/lib/bundler/vendor/thor/parser/options.rb +21 -19
- data/lib/bundler/vendor/thor/rake_compat.rb +3 -2
- data/lib/bundler/vendor/thor/runner.rb +22 -21
- data/lib/bundler/vendor/thor/shell/basic.rb +44 -22
- data/lib/bundler/vendor/thor/shell/color.rb +13 -9
- data/lib/bundler/vendor/thor/shell/html.rb +13 -9
- data/lib/bundler/vendor/thor/util.rb +214 -210
- data/lib/bundler/vendor/thor/version.rb +1 -1
- data/lib/bundler/version.rb +1 -1
- data/man/bundle-install.ronn +5 -1
- data/man/gemfile.5.ronn +10 -2
- data/spec/bundler/dsl_spec.rb +3 -3
- data/spec/bundler/gem_helper_spec.rb +14 -17
- data/spec/bundler/safe_catch_spec.rb +37 -0
- data/spec/install/gems/dependency_api_spec.rb +1 -36
- data/spec/install/gems/packed_spec.rb +4 -2
- data/spec/install/gems/resolving_spec.rb +37 -0
- data/spec/install/gems/simple_case_spec.rb +18 -16
- data/spec/install/git_spec.rb +1 -1
- data/spec/other/binstubs_spec.rb +24 -13
- data/spec/other/exec_spec.rb +24 -2
- data/spec/other/help_spec.rb +6 -6
- data/spec/other/outdated_spec.rb +3 -3
- data/spec/quality_spec.rb +3 -2
- data/spec/realworld/dependency_api_spec.rb +1 -1
- data/spec/realworld/edgecases_spec.rb +3 -3
- data/spec/realworld/parallel_install_spec.rb +19 -0
- data/spec/resolver/basic_spec.rb +11 -0
- data/spec/runtime/require_spec.rb +9 -0
- data/spec/runtime/setup_spec.rb +2 -3
- data/spec/spec_helper.rb +0 -1
- data/spec/support/builders.rb +2 -4
- data/spec/support/helpers.rb +4 -8
- data/spec/support/indexes.rb +18 -0
- data/spec/support/streams.rb +13 -0
- metadata +19 -11
- data/lib/bundler/vendor/thor/core_ext/dir_escape.rb +0 -0
- data/lib/bundler/vendor/thor/core_ext/file_binary_read.rb +0 -9
- data/spec/support/artifice/endpoint_host_redirect.rb +0 -15
- data/spec/support/permissions.rb +0 -11
@@ -1,5 +1,5 @@
|
|
1
1
|
class Thor
|
2
|
-
class
|
2
|
+
class Command < Struct.new(:name, :description, :long_description, :usage, :options)
|
3
3
|
FILE_REGEXP = /^#{Regexp.escape(File.dirname(__FILE__))}/
|
4
4
|
|
5
5
|
def initialize(name, description, long_description, usage, options=nil)
|
@@ -15,27 +15,27 @@ class Thor
|
|
15
15
|
false
|
16
16
|
end
|
17
17
|
|
18
|
-
# By default, a
|
19
|
-
# implementation to create custom
|
18
|
+
# By default, a command invokes a method in the thor class. You can change this
|
19
|
+
# implementation to create custom commands.
|
20
20
|
def run(instance, args=[])
|
21
21
|
arity = nil
|
22
22
|
|
23
23
|
if private_method?(instance)
|
24
|
-
instance.class.
|
24
|
+
instance.class.handle_no_command_error(name)
|
25
25
|
elsif public_method?(instance)
|
26
26
|
arity = instance.method(name).arity
|
27
27
|
instance.__send__(name, *args)
|
28
28
|
elsif local_method?(instance, :method_missing)
|
29
29
|
instance.__send__(:method_missing, name.to_sym, *args)
|
30
30
|
else
|
31
|
-
instance.class.
|
31
|
+
instance.class.handle_no_command_error(name)
|
32
32
|
end
|
33
33
|
rescue ArgumentError => e
|
34
34
|
handle_argument_error?(instance, e, caller) ?
|
35
|
-
instance.class.handle_argument_error(self, e, arity) : (raise e)
|
35
|
+
instance.class.handle_argument_error(self, e, args, arity) : (raise e)
|
36
36
|
rescue NoMethodError => e
|
37
37
|
handle_no_method_error?(instance, e, caller) ?
|
38
|
-
instance.class.
|
38
|
+
instance.class.handle_no_command_error(name) : (raise e)
|
39
39
|
end
|
40
40
|
|
41
41
|
# Returns the formatted usage by injecting given required arguments
|
@@ -107,26 +107,30 @@ class Thor
|
|
107
107
|
error.message =~ /^undefined method `#{name}' for #{Regexp.escape(instance.to_s)}$/
|
108
108
|
end
|
109
109
|
end
|
110
|
+
Task = Command
|
110
111
|
|
111
|
-
# A
|
112
|
-
class
|
112
|
+
# A command that is hidden in help messages but still invocable.
|
113
|
+
class HiddenCommand < Command
|
113
114
|
def hidden?
|
114
115
|
true
|
115
116
|
end
|
116
117
|
end
|
118
|
+
HiddenTask = HiddenCommand
|
117
119
|
|
118
|
-
# A dynamic
|
119
|
-
class
|
120
|
+
# A dynamic command that handles method missing scenarios.
|
121
|
+
class DynamicCommand < Command
|
120
122
|
def initialize(name, options=nil)
|
121
|
-
super(name.to_s, "A dynamically-generated
|
123
|
+
super(name.to_s, "A dynamically-generated command", name.to_s, name.to_s, options)
|
122
124
|
end
|
123
125
|
|
124
126
|
def run(instance, args=[])
|
125
127
|
if (instance.methods & [name.to_s, name.to_sym]).empty?
|
126
128
|
super
|
127
129
|
else
|
128
|
-
instance.class.
|
130
|
+
instance.class.handle_no_command_error(name)
|
129
131
|
end
|
130
132
|
end
|
131
133
|
end
|
134
|
+
DynamicTask = DynamicCommand
|
135
|
+
|
132
136
|
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
class IO #:nodoc:
|
2
|
+
class << self
|
3
|
+
|
4
|
+
def binread(file, *args)
|
5
|
+
raise ArgumentError, "wrong number of arguments (#{1 + args.size} for 1..3)" unless args.size < 3
|
6
|
+
File.open(file, 'rb') do |f|
|
7
|
+
f.read(*args)
|
8
|
+
end
|
9
|
+
end unless method_defined? :binread
|
10
|
+
|
11
|
+
end
|
12
|
+
end
|
@@ -5,17 +5,19 @@ class Thor
|
|
5
5
|
# Errors that are caused by the developer, like declaring a method which
|
6
6
|
# overwrites a thor keyword, it SHOULD NOT raise a Thor::Error. This way, we
|
7
7
|
# ensure that developer errors are shown with full backtrace.
|
8
|
-
#
|
9
8
|
class Error < StandardError
|
10
9
|
end
|
11
10
|
|
12
|
-
# Raised when a
|
13
|
-
|
14
|
-
class UndefinedTaskError < Error
|
11
|
+
# Raised when a command was not found.
|
12
|
+
class UndefinedCommandError < Error
|
15
13
|
end
|
14
|
+
UndefinedTaskError = UndefinedCommandError
|
16
15
|
|
17
|
-
|
18
|
-
|
16
|
+
class AmbiguousCommandError < Error
|
17
|
+
end
|
18
|
+
AmbiguousTaskError = AmbiguousCommandError
|
19
|
+
|
20
|
+
# Raised when a command was found, but not invoked properly.
|
19
21
|
class InvocationError < Error
|
20
22
|
end
|
21
23
|
|
@@ -27,9 +29,4 @@ class Thor
|
|
27
29
|
|
28
30
|
class MalformattedArgumentError < InvocationError
|
29
31
|
end
|
30
|
-
|
31
|
-
# Raised when a user tries to call a private method encoded in templated filename.
|
32
|
-
#
|
33
|
-
class PrivateMethodEncodedError < Error
|
34
|
-
end
|
35
32
|
end
|
@@ -1,9 +1,9 @@
|
|
1
1
|
require 'thor/base'
|
2
2
|
|
3
3
|
# Thor has a special class called Thor::Group. The main difference to Thor class
|
4
|
-
# is that it invokes all
|
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
7
|
class Thor::Group
|
8
8
|
class << self
|
9
9
|
# The description for this Thor::Group. If none is provided, but a source root
|
@@ -14,11 +14,11 @@ class Thor::Group
|
|
14
14
|
# description<String>:: The description for this Thor::Group.
|
15
15
|
#
|
16
16
|
def desc(description=nil)
|
17
|
-
case description
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
17
|
+
@desc = case description
|
18
|
+
when nil
|
19
|
+
@desc || from_superclass(:desc, nil)
|
20
|
+
else
|
21
|
+
description
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
@@ -48,7 +48,7 @@ class Thor::Group
|
|
48
48
|
end
|
49
49
|
|
50
50
|
# Invoke the given namespace or class given. It adds an instance
|
51
|
-
# method that will invoke the klass and
|
51
|
+
# method that will invoke the klass and command. You can give a block to
|
52
52
|
# configure how it will be invoked.
|
53
53
|
#
|
54
54
|
# The namespace/class given will have its options showed on the help
|
@@ -64,12 +64,12 @@ class Thor::Group
|
|
64
64
|
|
65
65
|
class_eval <<-METHOD, __FILE__, __LINE__
|
66
66
|
def _invoke_#{name.to_s.gsub(/\W/, '_')}
|
67
|
-
klass,
|
67
|
+
klass, command = self.class.prepare_for_invocation(nil, #{name.inspect})
|
68
68
|
|
69
69
|
if klass
|
70
70
|
say_status :invoke, #{name.inspect}, #{verbose.inspect}
|
71
71
|
block = self.class.invocation_blocks[#{name.inspect}]
|
72
|
-
_invoke_for_class_method klass,
|
72
|
+
_invoke_for_class_method klass, command, &block
|
73
73
|
else
|
74
74
|
say_status :error, %(#{name.inspect} [not found]), :red
|
75
75
|
end
|
@@ -100,7 +100,7 @@ class Thor::Group
|
|
100
100
|
# In some cases you want to customize how a specified hook is going to be
|
101
101
|
# invoked. You can do that by overwriting the class method
|
102
102
|
# prepare_for_invocation. The class method must necessarily return a klass
|
103
|
-
# and an optional
|
103
|
+
# and an optional command.
|
104
104
|
#
|
105
105
|
# ==== Custom invocations
|
106
106
|
#
|
@@ -127,12 +127,12 @@ class Thor::Group
|
|
127
127
|
|
128
128
|
value = options[#{name.inspect}]
|
129
129
|
value = #{name.inspect} if TrueClass === value
|
130
|
-
klass,
|
130
|
+
klass, command = self.class.prepare_for_invocation(#{name.inspect}, value)
|
131
131
|
|
132
132
|
if klass
|
133
133
|
say_status :invoke, value, #{verbose.inspect}
|
134
134
|
block = self.class.invocation_blocks[#{name.inspect}]
|
135
|
-
_invoke_for_class_method klass,
|
135
|
+
_invoke_for_class_method klass, command, &block
|
136
136
|
else
|
137
137
|
say_status :error, %(\#{value} [not found]), :red
|
138
138
|
end
|
@@ -149,7 +149,7 @@ class Thor::Group
|
|
149
149
|
#
|
150
150
|
def remove_invocation(*names)
|
151
151
|
names.each do |name|
|
152
|
-
|
152
|
+
remove_command(name)
|
153
153
|
remove_class_option(name)
|
154
154
|
invocations.delete(name)
|
155
155
|
invocation_blocks.delete(name)
|
@@ -196,30 +196,26 @@ class Thor::Group
|
|
196
196
|
end
|
197
197
|
end
|
198
198
|
|
199
|
-
# Returns
|
200
|
-
def
|
199
|
+
# Returns commands ready to be printed.
|
200
|
+
def printable_commands(*)
|
201
201
|
item = []
|
202
202
|
item << banner
|
203
203
|
item << (desc ? "# #{desc.gsub(/\s+/m,' ')}" : "")
|
204
204
|
[item]
|
205
205
|
end
|
206
|
+
alias printable_tasks printable_commands
|
206
207
|
|
207
|
-
def handle_argument_error(
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
msg << ", but it should not."
|
212
|
-
else
|
213
|
-
msg = "You should not pass arguments to #{basename} #{task.name}."
|
214
|
-
end
|
215
|
-
|
208
|
+
def handle_argument_error(command, error, args, arity) #:nodoc:
|
209
|
+
msg = "#{basename} #{command.name} takes #{arity} argument"
|
210
|
+
msg << "s" if arity > 1
|
211
|
+
msg << ", but it should not."
|
216
212
|
raise error, msg
|
217
213
|
end
|
218
214
|
|
219
215
|
protected
|
220
216
|
|
221
217
|
# The method responsible for dispatching given the args.
|
222
|
-
def dispatch(
|
218
|
+
def dispatch(command, given_args, given_opts, config) #:nodoc:
|
223
219
|
if Thor::HELP_MAPPINGS.include?(given_args.first)
|
224
220
|
help(config[:shell])
|
225
221
|
return
|
@@ -230,10 +226,9 @@ class Thor::Group
|
|
230
226
|
|
231
227
|
instance = new(args, opts, config)
|
232
228
|
yield instance if block_given?
|
233
|
-
args = instance.args
|
234
229
|
|
235
|
-
if
|
236
|
-
instance.
|
230
|
+
if command
|
231
|
+
instance.invoke_command(all_commands[command])
|
237
232
|
else
|
238
233
|
instance.invoke_all
|
239
234
|
end
|
@@ -242,22 +237,24 @@ class Thor::Group
|
|
242
237
|
# The banner for this class. You can customize it if you are invoking the
|
243
238
|
# thor class by another ways which is not the Thor::Runner.
|
244
239
|
def banner
|
245
|
-
"#{basename} #{
|
240
|
+
"#{basename} #{self_command.formatted_usage(self, false)}"
|
246
241
|
end
|
247
242
|
|
248
|
-
# Represents the whole class as a
|
249
|
-
def
|
250
|
-
Thor::
|
243
|
+
# Represents the whole class as a command.
|
244
|
+
def self_command #:nodoc:
|
245
|
+
Thor::DynamicCommand.new(self.namespace, class_options)
|
251
246
|
end
|
247
|
+
alias self_task self_command
|
252
248
|
|
253
249
|
def baseclass #:nodoc:
|
254
250
|
Thor::Group
|
255
251
|
end
|
256
252
|
|
257
|
-
def
|
258
|
-
|
253
|
+
def create_command(meth) #:nodoc:
|
254
|
+
commands[meth.to_s] = Thor::Command.new(meth, nil, nil, nil, nil)
|
259
255
|
true
|
260
256
|
end
|
257
|
+
alias create_task create_command
|
261
258
|
end
|
262
259
|
|
263
260
|
include Thor::Base
|
@@ -266,19 +263,19 @@ class Thor::Group
|
|
266
263
|
|
267
264
|
# Shortcut to invoke with padding and block handling. Use internally by
|
268
265
|
# invoke and invoke_from_option class methods.
|
269
|
-
def _invoke_for_class_method(klass,
|
266
|
+
def _invoke_for_class_method(klass, command=nil, *args, &block) #:nodoc:
|
270
267
|
with_padding do
|
271
268
|
if block
|
272
269
|
case block.arity
|
273
270
|
when 3
|
274
|
-
block.call(self, klass,
|
271
|
+
block.call(self, klass, command)
|
275
272
|
when 2
|
276
273
|
block.call(self, klass)
|
277
274
|
when 1
|
278
275
|
instance_exec(klass, &block)
|
279
276
|
end
|
280
277
|
else
|
281
|
-
invoke klass,
|
278
|
+
invoke klass, command, *args
|
282
279
|
end
|
283
280
|
end
|
284
281
|
end
|
@@ -6,12 +6,12 @@ class Thor
|
|
6
6
|
|
7
7
|
module ClassMethods
|
8
8
|
# This method is responsible for receiving a name and find the proper
|
9
|
-
# class and
|
9
|
+
# class and command for it. The key is an optional parameter which is
|
10
10
|
# available only in class methods invocations (i.e. in Thor::Group).
|
11
11
|
def prepare_for_invocation(key, name) #:nodoc:
|
12
12
|
case name
|
13
13
|
when Symbol, String
|
14
|
-
Thor::Util.
|
14
|
+
Thor::Util.find_class_and_command_by_namespace(name.to_s, !key)
|
15
15
|
else
|
16
16
|
name
|
17
17
|
end
|
@@ -25,15 +25,15 @@ class Thor
|
|
25
25
|
super
|
26
26
|
end
|
27
27
|
|
28
|
-
# Receives a name and invokes it. The name can be a string (either "
|
29
|
-
# "namespace:
|
30
|
-
# cannot be guessed by name, it can also be supplied as second argument.
|
28
|
+
# Receives a name and invokes it. The name can be a string (either "command" or
|
29
|
+
# "namespace:command"), a Thor::Command, a Class or a Thor instance. If the
|
30
|
+
# command cannot be guessed by name, it can also be supplied as second argument.
|
31
31
|
#
|
32
32
|
# You can also supply the arguments, options and configuration values for
|
33
|
-
# the
|
33
|
+
# the command to be invoked, if none is given, the same values used to
|
34
34
|
# initialize the invoker are used to initialize the invoked.
|
35
35
|
#
|
36
|
-
# When no name is given, it will invoke the default
|
36
|
+
# When no name is given, it will invoke the default command of the current class.
|
37
37
|
#
|
38
38
|
# ==== Examples
|
39
39
|
#
|
@@ -54,16 +54,16 @@ class Thor
|
|
54
54
|
# end
|
55
55
|
# end
|
56
56
|
#
|
57
|
-
# You can notice that the method "foo" above invokes two
|
57
|
+
# You can notice that the method "foo" above invokes two commands: "bar",
|
58
58
|
# which belongs to the same class and "hello" which belongs to the class B.
|
59
59
|
#
|
60
|
-
# By using an invocation system you ensure that a
|
60
|
+
# By using an invocation system you ensure that a command is invoked only once.
|
61
61
|
# In the example above, invoking "foo" will invoke "b:hello" just once, even
|
62
62
|
# if it's invoked later by "bar" method.
|
63
63
|
#
|
64
64
|
# When class A invokes class B, all arguments used on A initialization are
|
65
65
|
# supplied to B. This allows lazy parse of options. Let's suppose you have
|
66
|
-
# some rspec
|
66
|
+
# some rspec commands:
|
67
67
|
#
|
68
68
|
# class Rspec < Thor::Group
|
69
69
|
# class_option :mock_framework, :type => :string, :default => :rr
|
@@ -100,30 +100,31 @@ class Thor
|
|
100
100
|
end
|
101
101
|
|
102
102
|
args.unshift(nil) if Array === args.first || NilClass === args.first
|
103
|
-
|
103
|
+
command, args, opts, config = args
|
104
104
|
|
105
|
-
klass,
|
105
|
+
klass, command = _retrieve_class_and_command(name, command)
|
106
106
|
raise "Expected Thor class, got #{klass}" unless klass <= Thor::Base
|
107
107
|
|
108
108
|
args, opts, config = _parse_initialization_options(args, opts, config)
|
109
|
-
klass.send(:dispatch,
|
109
|
+
klass.send(:dispatch, command, args, opts, config) do |instance|
|
110
110
|
instance.parent_options = options
|
111
111
|
end
|
112
112
|
end
|
113
113
|
|
114
|
-
# Invoke the given
|
115
|
-
def
|
114
|
+
# Invoke the given command if the given args.
|
115
|
+
def invoke_command(command, *args) #:nodoc:
|
116
116
|
current = @_invocations[self.class]
|
117
117
|
|
118
|
-
unless current.include?(
|
119
|
-
current <<
|
120
|
-
|
118
|
+
unless current.include?(command.name)
|
119
|
+
current << command.name
|
120
|
+
command.run(self, *args)
|
121
121
|
end
|
122
122
|
end
|
123
|
+
alias invoke_task invoke_command
|
123
124
|
|
124
|
-
# Invoke all
|
125
|
+
# Invoke all commands for the current instance.
|
125
126
|
def invoke_all #:nodoc:
|
126
|
-
self.class.
|
127
|
+
self.class.all_commands.map { |_, command| invoke_command(command) }
|
127
128
|
end
|
128
129
|
|
129
130
|
# Invokes using shell padding.
|
@@ -138,21 +139,22 @@ class Thor
|
|
138
139
|
{ :invocations => @_invocations }
|
139
140
|
end
|
140
141
|
|
141
|
-
# This method simply retrieves the class and
|
142
|
-
# If the name is nil or the given name is a
|
142
|
+
# This method simply retrieves the class and command to be invoked.
|
143
|
+
# If the name is nil or the given name is a command in the current class,
|
143
144
|
# use the given name and return self as class. Otherwise, call
|
144
145
|
# prepare_for_invocation in the current class.
|
145
|
-
def
|
146
|
+
def _retrieve_class_and_command(name, sent_command=nil) #:nodoc:
|
146
147
|
case
|
147
148
|
when name.nil?
|
148
149
|
[self.class, nil]
|
149
|
-
when self.class.
|
150
|
+
when self.class.all_commands[name.to_s]
|
150
151
|
[self.class, name.to_s]
|
151
152
|
else
|
152
|
-
klass,
|
153
|
-
[klass,
|
153
|
+
klass, command = self.class.prepare_for_invocation(nil, name)
|
154
|
+
[klass, command || sent_command]
|
154
155
|
end
|
155
156
|
end
|
157
|
+
alias _retrieve_class_and_task _retrieve_class_and_command
|
156
158
|
|
157
159
|
# Initialize klass using values stored in the @_initializer.
|
158
160
|
def _parse_initialization_options(args, opts, config) #:nodoc:
|
@@ -11,16 +11,16 @@ class Thor
|
|
11
11
|
def self.to_switches(options)
|
12
12
|
options.map do |key, value|
|
13
13
|
case value
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
14
|
+
when true
|
15
|
+
"--#{key}"
|
16
|
+
when Array
|
17
|
+
"--#{key} #{value.map{ |v| v.inspect }.join(' ')}"
|
18
|
+
when Hash
|
19
|
+
"--#{key} #{value.map{ |k,v| "#{k}:#{v}" }.join(' ')}"
|
20
|
+
when nil, false
|
21
|
+
""
|
22
|
+
else
|
23
|
+
"--#{key} #{value.inspect}"
|
24
24
|
end
|
25
25
|
end.join(" ")
|
26
26
|
end
|
@@ -46,7 +46,8 @@ class Thor
|
|
46
46
|
@switches[option.switch_name] = option
|
47
47
|
|
48
48
|
option.aliases.each do |short|
|
49
|
-
|
49
|
+
name = short.to_s.sub(/^(?!\-)/, '-')
|
50
|
+
@shorts[name] ||= option.switch_name
|
50
51
|
end
|
51
52
|
end
|
52
53
|
end
|
@@ -79,20 +80,21 @@ class Thor
|
|
79
80
|
|
80
81
|
if is_switch
|
81
82
|
case shifted
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
83
|
+
when SHORT_SQ_RE
|
84
|
+
unshift($1.split('').map { |f| "-#{f}" })
|
85
|
+
next
|
86
|
+
when EQ_RE, SHORT_NUM
|
87
|
+
unshift($2)
|
88
|
+
switch = $1
|
89
|
+
when LONG_RE, SHORT_RE
|
90
|
+
switch = $1
|
90
91
|
end
|
91
92
|
|
92
93
|
switch = normalize_switch(switch)
|
93
94
|
option = switch_option(switch)
|
94
95
|
@assigns[option.human_name] = parse_peek(switch, option)
|
95
96
|
elsif @stop_on_unknown
|
97
|
+
@parsing_options = false
|
96
98
|
@extra << shifted
|
97
99
|
@extra << shift while peek
|
98
100
|
break
|