bundler 1.5.1 → 1.5.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.
Potentially problematic release.
This version of bundler might be problematic. Click here for more details.
- data/CHANGELOG.md +26 -2
- data/bin/bundle +1 -3
- data/bundler.gemspec +1 -1
- data/lib/bundler/cli.rb +2 -4
- data/lib/bundler/fetcher.rb +13 -12
- data/lib/bundler/installer.rb +9 -36
- data/lib/bundler/parallel_workers/unix_worker.rb +12 -4
- data/lib/bundler/parallel_workers/worker.rb +1 -0
- data/lib/bundler/rubygems_ext.rb +1 -1
- data/lib/bundler/rubygems_integration.rb +15 -8
- data/lib/bundler/templates/newgem/newgem.gemspec.tt +1 -1
- data/lib/bundler/vendor/thor.rb +63 -56
- data/lib/bundler/vendor/thor/actions.rb +52 -51
- data/lib/bundler/vendor/thor/actions/create_file.rb +35 -37
- data/lib/bundler/vendor/thor/actions/create_link.rb +1 -2
- data/lib/bundler/vendor/thor/actions/directory.rb +36 -37
- data/lib/bundler/vendor/thor/actions/empty_directory.rb +67 -69
- data/lib/bundler/vendor/thor/actions/file_manipulation.rb +11 -12
- data/lib/bundler/vendor/thor/actions/inject_into_file.rb +41 -43
- data/lib/bundler/vendor/thor/base.rb +180 -178
- data/lib/bundler/vendor/thor/command.rb +22 -25
- data/lib/bundler/vendor/thor/core_ext/hash_with_indifferent_access.rb +21 -24
- data/lib/bundler/vendor/thor/core_ext/io_binary_read.rb +1 -3
- data/lib/bundler/vendor/thor/core_ext/ordered_hash.rb +8 -10
- data/lib/bundler/vendor/thor/error.rb +2 -2
- data/lib/bundler/vendor/thor/group.rb +59 -60
- data/lib/bundler/vendor/thor/invocation.rb +39 -38
- data/lib/bundler/vendor/thor/line_editor.rb +17 -0
- data/lib/bundler/vendor/thor/line_editor/basic.rb +35 -0
- data/lib/bundler/vendor/thor/line_editor/readline.rb +88 -0
- data/lib/bundler/vendor/thor/parser/argument.rb +29 -30
- data/lib/bundler/vendor/thor/parser/arguments.rb +102 -98
- data/lib/bundler/vendor/thor/parser/option.rb +25 -25
- data/lib/bundler/vendor/thor/parser/options.rb +85 -85
- data/lib/bundler/vendor/thor/rake_compat.rb +6 -7
- data/lib/bundler/vendor/thor/runner.rb +154 -154
- data/lib/bundler/vendor/thor/shell.rb +23 -30
- data/lib/bundler/vendor/thor/shell/basic.rb +66 -57
- data/lib/bundler/vendor/thor/shell/color.rb +44 -43
- data/lib/bundler/vendor/thor/shell/html.rb +43 -44
- data/lib/bundler/vendor/thor/util.rb +37 -40
- data/lib/bundler/vendor/thor/version.rb +1 -1
- data/lib/bundler/version.rb +1 -1
- data/man/bundle-install.ronn +1 -1
- data/man/gemfile.5.ronn +1 -2
- data/spec/commands/binstubs_spec.rb +13 -0
- data/spec/install/gemfile/git_spec.rb +2 -2
- data/spec/install/gems/dependency_api_spec.rb +34 -0
- data/spec/install/gems/packed_spec.rb +2 -4
- data/spec/quality_spec.rb +2 -2
- data/spec/realworld/parallel_spec.rb +69 -0
- data/spec/runtime/setup_spec.rb +3 -2
- data/spec/spec_helper.rb +1 -0
- data/spec/support/artifice/endpoint_host_redirect.rb +15 -0
- data/spec/support/permissions.rb +11 -0
- metadata +11 -6
- data/spec/realworld/parallel_install_spec.rb +0 -23
- data/spec/realworld/parallel_update_spec.rb +0 -31
@@ -3,7 +3,6 @@ require 'open-uri'
|
|
3
3
|
|
4
4
|
class Thor
|
5
5
|
module Actions
|
6
|
-
|
7
6
|
# Copies the file from the relative source to the relative destination. If
|
8
7
|
# the destination is not given it's assumed to be equal to the source.
|
9
8
|
#
|
@@ -79,14 +78,14 @@ class Thor
|
|
79
78
|
config = args.last.is_a?(Hash) ? args.pop : {}
|
80
79
|
destination = args.first
|
81
80
|
|
82
|
-
source = File.expand_path(find_in_source_paths(source.to_s)) unless source =~
|
83
|
-
render = open(source) {|input| input.binmode.read }
|
81
|
+
source = File.expand_path(find_in_source_paths(source.to_s)) unless source =~ %r{^https?\://}
|
82
|
+
render = open(source) { |input| input.binmode.read }
|
84
83
|
|
85
84
|
destination ||= if block_given?
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
85
|
+
block.arity == 1 ? block.call(render) : block.call
|
86
|
+
else
|
87
|
+
File.basename(source)
|
88
|
+
end
|
90
89
|
|
91
90
|
create_file destination, render, config
|
92
91
|
end
|
@@ -108,7 +107,7 @@ class Thor
|
|
108
107
|
#
|
109
108
|
def template(source, *args, &block)
|
110
109
|
config = args.last.is_a?(Hash) ? args.pop : {}
|
111
|
-
destination = args.first || source.sub(
|
110
|
+
destination = args.first || source.sub(/#{TEMPLATE_EXTNAME}$/, '')
|
112
111
|
|
113
112
|
source = File.expand_path(find_in_source_paths(source.to_s))
|
114
113
|
context = instance_eval('binding')
|
@@ -131,7 +130,7 @@ class Thor
|
|
131
130
|
#
|
132
131
|
# chmod "script/server", 0755
|
133
132
|
#
|
134
|
-
def chmod(path, mode, config={})
|
133
|
+
def chmod(path, mode, config = {})
|
135
134
|
return unless behavior == :invoke
|
136
135
|
path = File.expand_path(path, destination_root)
|
137
136
|
say_status :chmod, relative_to_original_destination_root(path), config.fetch(:verbose, true)
|
@@ -284,14 +283,14 @@ class Thor
|
|
284
283
|
# remove_file 'README'
|
285
284
|
# remove_file 'app/controllers/application_controller.rb'
|
286
285
|
#
|
287
|
-
def remove_file(path, config={})
|
286
|
+
def remove_file(path, config = {})
|
288
287
|
return unless behavior == :invoke
|
289
288
|
path = File.expand_path(path, destination_root)
|
290
289
|
|
291
290
|
say_status :remove, relative_to_original_destination_root(path), config.fetch(:verbose, true)
|
292
|
-
::FileUtils.rm_rf(path) if !options[:pretend] && File.
|
291
|
+
::FileUtils.rm_rf(path) if !options[:pretend] && File.exist?(path)
|
293
292
|
end
|
294
|
-
|
293
|
+
alias_method :remove_dir, :remove_file
|
295
294
|
|
296
295
|
attr_accessor :output_buffer
|
297
296
|
private :output_buffer, :output_buffer=
|
@@ -2,7 +2,6 @@ require 'thor/actions/empty_directory'
|
|
2
2
|
|
3
3
|
class Thor
|
4
4
|
module Actions
|
5
|
-
|
6
5
|
# Injects the given content into a file. Different from gsub_file, this
|
7
6
|
# method is reversible.
|
8
7
|
#
|
@@ -36,13 +35,13 @@ class Thor
|
|
36
35
|
attr_reader :replacement, :flag, :behavior
|
37
36
|
|
38
37
|
def initialize(base, destination, data, config)
|
39
|
-
super(base, destination, {
|
38
|
+
super(base, destination, {:verbose => true}.merge(config))
|
40
39
|
|
41
40
|
@behavior, @flag = if @config.key?(:after)
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
41
|
+
[:after, @config.delete(:after)]
|
42
|
+
else
|
43
|
+
[:before, @config.delete(:before)]
|
44
|
+
end
|
46
45
|
|
47
46
|
@replacement = data.is_a?(Proc) ? data.call : data
|
48
47
|
@flag = Regexp.escape(@flag) unless @flag.is_a?(Regexp)
|
@@ -52,10 +51,10 @@ class Thor
|
|
52
51
|
say_status :invoke
|
53
52
|
|
54
53
|
content = if @behavior == :after
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
54
|
+
'\0' + replacement
|
55
|
+
else
|
56
|
+
replacement + '\0'
|
57
|
+
end
|
59
58
|
|
60
59
|
replace!(/#{flag}/, content, config[:force])
|
61
60
|
end
|
@@ -64,46 +63,45 @@ class Thor
|
|
64
63
|
say_status :revoke
|
65
64
|
|
66
65
|
regexp = if @behavior == :after
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
66
|
+
content = '\1\2'
|
67
|
+
/(#{flag})(.*)(#{Regexp.escape(replacement)})/m
|
68
|
+
else
|
69
|
+
content = '\2\3'
|
70
|
+
/(#{Regexp.escape(replacement)})(.*)(#{flag})/m
|
71
|
+
end
|
73
72
|
|
74
73
|
replace!(regexp, content, true)
|
75
74
|
end
|
76
75
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
76
|
+
protected
|
77
|
+
|
78
|
+
def say_status(behavior)
|
79
|
+
status = if behavior == :invoke
|
80
|
+
if flag == /\A/
|
81
|
+
:prepend
|
82
|
+
elsif flag == /\z/
|
83
|
+
:append
|
84
|
+
else
|
85
|
+
:insert
|
86
|
+
end
|
87
|
+
else
|
88
|
+
:subtract
|
89
|
+
end
|
90
|
+
|
91
|
+
super(status, config[:verbose])
|
92
|
+
end
|
94
93
|
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
end
|
94
|
+
# Adds the content to the file.
|
95
|
+
#
|
96
|
+
def replace!(regexp, string, force)
|
97
|
+
unless base.options[:pretend]
|
98
|
+
content = File.binread(destination)
|
99
|
+
if force || !content.include?(replacement)
|
100
|
+
content.gsub!(regexp, string)
|
101
|
+
File.open(destination, 'wb') { |file| file.write(content) }
|
104
102
|
end
|
105
103
|
end
|
106
|
-
|
104
|
+
end
|
107
105
|
end
|
108
106
|
end
|
109
107
|
end
|
@@ -5,6 +5,7 @@ require 'thor/error'
|
|
5
5
|
require 'thor/invocation'
|
6
6
|
require 'thor/parser'
|
7
7
|
require 'thor/shell'
|
8
|
+
require 'thor/line_editor'
|
8
9
|
require 'thor/util'
|
9
10
|
|
10
11
|
class Thor
|
@@ -19,6 +20,8 @@ class Thor
|
|
19
20
|
THOR_RESERVED_WORDS = %w(invoke shell options behavior root destination_root relative_root
|
20
21
|
action add_file create_file in_root inside run run_ruby_script)
|
21
22
|
|
23
|
+
TEMPLATE_EXTNAME = '.tt'
|
24
|
+
|
22
25
|
module Base
|
23
26
|
attr_accessor :options, :parent_options, :args
|
24
27
|
|
@@ -38,7 +41,7 @@ class Thor
|
|
38
41
|
#
|
39
42
|
# config<Hash>:: Configuration for this Thor class.
|
40
43
|
#
|
41
|
-
def initialize(args=[],
|
44
|
+
def initialize(args = [], local_options = {}, config = {}) # rubocop:disable MethodLength
|
42
45
|
parse_options = self.class.class_options
|
43
46
|
|
44
47
|
# The start method splits inbound arguments at the first argument
|
@@ -46,14 +49,14 @@ class Thor
|
|
46
49
|
# new, passing in the two halves of the arguments Array as the
|
47
50
|
# first two parameters.
|
48
51
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
array_options, hash_options =
|
52
|
+
command_options = config.delete(:command_options) # hook for start
|
53
|
+
parse_options = parse_options.merge(command_options) if command_options
|
54
|
+
if local_options.is_a?(Array)
|
55
|
+
array_options, hash_options = local_options, {}
|
53
56
|
else
|
54
57
|
# Handle the case where the class was explicitly instantiated
|
55
58
|
# with pre-parsed options.
|
56
|
-
array_options, hash_options = [],
|
59
|
+
array_options, hash_options = [], local_options
|
57
60
|
end
|
58
61
|
|
59
62
|
# Let Thor::Options parse the options first, so it can remove
|
@@ -62,7 +65,7 @@ class Thor
|
|
62
65
|
stop_on_unknown = self.class.stop_on_unknown_option? config[:current_command]
|
63
66
|
opts = Thor::Options.new(parse_options, hash_options, stop_on_unknown)
|
64
67
|
self.options = opts.parse(array_options)
|
65
|
-
self.options = config[:class_options].merge(
|
68
|
+
self.options = config[:class_options].merge(options) if config[:class_options]
|
66
69
|
|
67
70
|
# If unknown options are disallowed, make sure that none of the
|
68
71
|
# remaining arguments looks like an option.
|
@@ -77,13 +80,13 @@ class Thor
|
|
77
80
|
to_parse += opts.remaining unless self.class.strict_args_position?(config)
|
78
81
|
|
79
82
|
thor_args = Thor::Arguments.new(self.class.arguments)
|
80
|
-
thor_args.parse(to_parse).each { |k,v| __send__("#{k}=", v) }
|
83
|
+
thor_args.parse(to_parse).each { |k, v| __send__("#{k}=", v) }
|
81
84
|
@args = thor_args.remaining
|
82
85
|
end
|
83
86
|
|
84
87
|
class << self
|
85
88
|
def included(base) #:nodoc:
|
86
|
-
base.
|
89
|
+
base.extend ClassMethods
|
87
90
|
base.send :include, Invocation
|
88
91
|
base.send :include, Shell
|
89
92
|
end
|
@@ -103,7 +106,7 @@ class Thor
|
|
103
106
|
# Hash[path<String> => Class]
|
104
107
|
#
|
105
108
|
def subclass_files
|
106
|
-
@subclass_files ||= Hash.new{ |h,k| h[k] = [] }
|
109
|
+
@subclass_files ||= Hash.new { |h, k| h[k] = [] }
|
107
110
|
end
|
108
111
|
|
109
112
|
# Whenever a class inherits from Thor or Thor::Group, we should track the
|
@@ -202,23 +205,23 @@ class Thor
|
|
202
205
|
# ==== Errors
|
203
206
|
# ArgumentError:: Raised if you supply a required argument after a non required one.
|
204
207
|
#
|
205
|
-
def argument(name, options={})
|
208
|
+
def argument(name, options = {}) # rubocop:disable MethodLength
|
206
209
|
is_thor_reserved_word?(name, :argument)
|
207
210
|
no_commands { attr_accessor name }
|
208
211
|
|
209
212
|
required = if options.key?(:optional)
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
213
|
+
!options[:optional]
|
214
|
+
elsif options.key?(:required)
|
215
|
+
options[:required]
|
216
|
+
else
|
217
|
+
options[:default].nil?
|
218
|
+
end
|
216
219
|
|
217
220
|
remove_argument name
|
218
221
|
|
219
222
|
arguments.each do |argument|
|
220
223
|
next if argument.required?
|
221
|
-
|
224
|
+
fail ArgumentError, "You cannot have #{name.to_s.inspect} as required argument after " <<
|
222
225
|
"the non-required argument #{argument.human_name.inspect}."
|
223
226
|
end if required
|
224
227
|
|
@@ -245,7 +248,7 @@ class Thor
|
|
245
248
|
# ==== Parameters
|
246
249
|
# Hash[Symbol => Object]
|
247
250
|
#
|
248
|
-
def class_options(options=nil)
|
251
|
+
def class_options(options = nil)
|
249
252
|
@class_options ||= from_superclass(:class_options, {})
|
250
253
|
build_options(options, @class_options) if options
|
251
254
|
@class_options
|
@@ -267,7 +270,7 @@ class Thor
|
|
267
270
|
# :banner:: -- String to show on usage notes.
|
268
271
|
# :hide:: -- If you want to hide this option from the help.
|
269
272
|
#
|
270
|
-
def class_option(name, options={})
|
273
|
+
def class_option(name, options = {})
|
271
274
|
build_option(name, options, class_options)
|
272
275
|
end
|
273
276
|
|
@@ -313,12 +316,11 @@ class Thor
|
|
313
316
|
# ==== Parameters
|
314
317
|
# name<String|Symbol>
|
315
318
|
#
|
316
|
-
def group(name=nil)
|
317
|
-
|
318
|
-
|
319
|
-
@group || from_superclass(:group, 'standard')
|
319
|
+
def group(name = nil)
|
320
|
+
if name
|
321
|
+
@group = name.to_s
|
320
322
|
else
|
321
|
-
|
323
|
+
@group ||= from_superclass(:group, 'standard')
|
322
324
|
end
|
323
325
|
end
|
324
326
|
|
@@ -331,7 +333,7 @@ class Thor
|
|
331
333
|
def commands
|
332
334
|
@commands ||= Thor::CoreExt::OrderedHash.new
|
333
335
|
end
|
334
|
-
|
336
|
+
alias_method :tasks, :commands
|
335
337
|
|
336
338
|
# Returns the commands for this Thor class and all subclasses.
|
337
339
|
#
|
@@ -343,7 +345,7 @@ class Thor
|
|
343
345
|
@all_commands ||= from_superclass(:all_commands, Thor::CoreExt::OrderedHash.new)
|
344
346
|
@all_commands.merge(commands)
|
345
347
|
end
|
346
|
-
|
348
|
+
alias_method :all_tasks, :all_commands
|
347
349
|
|
348
350
|
# Removes a given command from this Thor class. This is usually done if you
|
349
351
|
# are inheriting from another class and don't want it to be available
|
@@ -366,7 +368,7 @@ class Thor
|
|
366
368
|
undef_method name if options[:undefine]
|
367
369
|
end
|
368
370
|
end
|
369
|
-
|
371
|
+
alias_method :remove_task, :remove_command
|
370
372
|
|
371
373
|
# All methods defined inside the given block are not added as commands.
|
372
374
|
#
|
@@ -393,7 +395,7 @@ class Thor
|
|
393
395
|
ensure
|
394
396
|
@no_commands = false
|
395
397
|
end
|
396
|
-
|
398
|
+
alias_method :no_tasks, :no_commands
|
397
399
|
|
398
400
|
# Sets the namespace for the Thor or Thor::Group class. By default the
|
399
401
|
# namespace is retrieved from the class name. If your Thor class is named
|
@@ -417,7 +419,7 @@ class Thor
|
|
417
419
|
#
|
418
420
|
# thor :my_command
|
419
421
|
#
|
420
|
-
def namespace(name=nil)
|
422
|
+
def namespace(name = nil)
|
421
423
|
if name
|
422
424
|
@namespace = name.to_s
|
423
425
|
else
|
@@ -433,11 +435,11 @@ class Thor
|
|
433
435
|
# script = MyScript.new(args, options, config)
|
434
436
|
# script.invoke(:command, first_arg, second_arg, third_arg)
|
435
437
|
#
|
436
|
-
def start(given_args=ARGV, config={})
|
438
|
+
def start(given_args = ARGV, config = {})
|
437
439
|
config[:shell] ||= Thor::Base.shell.new
|
438
440
|
dispatch(nil, given_args.dup, nil, config)
|
439
441
|
rescue Thor::Error => e
|
440
|
-
ENV[
|
442
|
+
config[:debug] || ENV['THOR_DEBUG'] == '1' ? (raise e) : config[:shell].error(e.message)
|
441
443
|
exit(1) if exit_on_failure?
|
442
444
|
rescue Errno::EPIPE
|
443
445
|
# This happens if a thor command is piped to something like `head`,
|
@@ -462,193 +464,193 @@ class Thor
|
|
462
464
|
class_eval "def #{name}(*); super end"
|
463
465
|
end
|
464
466
|
end
|
465
|
-
|
467
|
+
alias_method :public_task, :public_command
|
466
468
|
|
467
469
|
def handle_no_command_error(command, has_namespace = $thor_runner) #:nodoc:
|
468
470
|
if has_namespace
|
469
|
-
|
471
|
+
fail UndefinedCommandError, "Could not find command #{command.inspect} in #{namespace.inspect} namespace."
|
470
472
|
else
|
471
|
-
|
473
|
+
fail UndefinedCommandError, "Could not find command #{command.inspect}."
|
472
474
|
end
|
473
475
|
end
|
474
|
-
|
476
|
+
alias_method :handle_no_task_error, :handle_no_command_error
|
475
477
|
|
476
478
|
def handle_argument_error(command, error, args, arity) #:nodoc:
|
477
479
|
msg = "ERROR: \"#{basename} #{command.name}\" was called with "
|
478
|
-
msg << 'no arguments' if
|
479
|
-
msg << 'arguments ' << args.inspect
|
480
|
-
msg << "\nUsage: #{
|
481
|
-
|
482
|
-
end
|
483
|
-
|
484
|
-
protected
|
485
|
-
|
486
|
-
# Prints the class options per group. If an option does not belong to
|
487
|
-
# any group, it's printed as Class option.
|
488
|
-
#
|
489
|
-
def class_options_help(shell, groups={}) #:nodoc:
|
490
|
-
# Group options by group
|
491
|
-
class_options.each do |_, value|
|
492
|
-
groups[value.group] ||= []
|
493
|
-
groups[value.group] << value
|
494
|
-
end
|
480
|
+
msg << 'no arguments' if args.empty?
|
481
|
+
msg << 'arguments ' << args.inspect unless args.empty?
|
482
|
+
msg << "\nUsage: #{banner(command).inspect}"
|
483
|
+
fail InvocationError, msg
|
484
|
+
end
|
495
485
|
|
496
|
-
|
497
|
-
global_options = groups.delete(nil) || []
|
498
|
-
print_options(shell, global_options)
|
486
|
+
protected
|
499
487
|
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
488
|
+
# Prints the class options per group. If an option does not belong to
|
489
|
+
# any group, it's printed as Class option.
|
490
|
+
#
|
491
|
+
def class_options_help(shell, groups = {}) #:nodoc:
|
492
|
+
# Group options by group
|
493
|
+
class_options.each do |_, value|
|
494
|
+
groups[value.group] ||= []
|
495
|
+
groups[value.group] << value
|
504
496
|
end
|
505
497
|
|
506
|
-
#
|
507
|
-
|
508
|
-
|
498
|
+
# Deal with default group
|
499
|
+
global_options = groups.delete(nil) || []
|
500
|
+
print_options(shell, global_options)
|
509
501
|
|
510
|
-
|
511
|
-
|
502
|
+
# Print all others
|
503
|
+
groups.each do |group_name, options|
|
504
|
+
print_options(shell, options, group_name)
|
505
|
+
end
|
506
|
+
end
|
512
507
|
|
513
|
-
|
514
|
-
|
515
|
-
|
516
|
-
item.push(option.description ? "# #{option.description}" : "")
|
508
|
+
# Receives a set of options and print them.
|
509
|
+
def print_options(shell, options, group_name = nil)
|
510
|
+
return if options.empty?
|
517
511
|
|
518
|
-
|
519
|
-
|
520
|
-
list << [ "", "# Possible values: #{option.enum.join(', ')}" ] if option.enum
|
521
|
-
end
|
522
|
-
end
|
512
|
+
list = []
|
513
|
+
padding = options.map { |o| o.aliases.size }.max.to_i * 4
|
523
514
|
|
524
|
-
|
525
|
-
|
526
|
-
|
527
|
-
|
515
|
+
options.each do |option|
|
516
|
+
unless option.hide
|
517
|
+
item = [option.usage(padding)]
|
518
|
+
item.push(option.description ? "# #{option.description}" : '')
|
528
519
|
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
|
520
|
+
list << item
|
521
|
+
list << ['', "# Default: #{option.default}"] if option.show_default?
|
522
|
+
list << ['', "# Possible values: #{option.enum.join(', ')}"] if option.enum
|
523
|
+
end
|
533
524
|
end
|
534
525
|
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
# options<Hash>:: Described in both class_option and method_option.
|
540
|
-
# scope<Hash>:: Options hash that is being built up
|
541
|
-
def build_option(name, options, scope) #:nodoc:
|
542
|
-
scope[name] = Thor::Option.new(name, options)
|
543
|
-
end
|
526
|
+
shell.say(group_name ? "#{group_name} options:" : 'Options:')
|
527
|
+
shell.print_table(list, :indent => 2)
|
528
|
+
shell.say ''
|
529
|
+
end
|
544
530
|
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
#
|
549
|
-
|
550
|
-
# ==== Parameters
|
551
|
-
# Hash[Symbol => Object]
|
552
|
-
def build_options(options, scope) #:nodoc:
|
553
|
-
options.each do |key, value|
|
554
|
-
scope[key] = Thor::Option.parse(key, value)
|
555
|
-
end
|
556
|
-
end
|
531
|
+
# Raises an error if the word given is a Thor reserved word.
|
532
|
+
def is_thor_reserved_word?(word, type) #:nodoc:
|
533
|
+
return false unless THOR_RESERVED_WORDS.include?(word.to_s)
|
534
|
+
fail "#{word.inspect} is a Thor reserved word and cannot be defined as #{type}"
|
535
|
+
end
|
557
536
|
|
558
|
-
|
559
|
-
|
560
|
-
|
561
|
-
|
562
|
-
|
563
|
-
|
564
|
-
|
565
|
-
|
566
|
-
|
567
|
-
|
568
|
-
|
537
|
+
# Build an option and adds it to the given scope.
|
538
|
+
#
|
539
|
+
# ==== Parameters
|
540
|
+
# name<Symbol>:: The name of the argument.
|
541
|
+
# options<Hash>:: Described in both class_option and method_option.
|
542
|
+
# scope<Hash>:: Options hash that is being built up
|
543
|
+
def build_option(name, options, scope) #:nodoc:
|
544
|
+
scope[name] = Thor::Option.new(name, options)
|
545
|
+
end
|
546
|
+
|
547
|
+
# Receives a hash of options, parse them and add to the scope. This is a
|
548
|
+
# fast way to set a bunch of options:
|
549
|
+
#
|
550
|
+
# build_options :foo => true, :bar => :required, :baz => :string
|
551
|
+
#
|
552
|
+
# ==== Parameters
|
553
|
+
# Hash[Symbol => Object]
|
554
|
+
def build_options(options, scope) #:nodoc:
|
555
|
+
options.each do |key, value|
|
556
|
+
scope[key] = Thor::Option.parse(key, value)
|
569
557
|
end
|
570
|
-
|
558
|
+
end
|
571
559
|
|
572
|
-
|
573
|
-
|
574
|
-
|
575
|
-
|
576
|
-
|
560
|
+
# Finds a command with the given name. If the command belongs to the current
|
561
|
+
# class, just return it, otherwise dup it and add the fresh copy to the
|
562
|
+
# current command hash.
|
563
|
+
def find_and_refresh_command(name) #:nodoc:
|
564
|
+
if commands[name.to_s]
|
565
|
+
commands[name.to_s]
|
566
|
+
elsif command = all_commands[name.to_s] # rubocop:disable AssignmentInCondition
|
567
|
+
commands[name.to_s] = command.clone
|
568
|
+
else
|
569
|
+
fail ArgumentError, "You supplied :for => #{name.inspect}, but the command #{name.inspect} could not be found."
|
577
570
|
end
|
571
|
+
end
|
572
|
+
alias_method :find_and_refresh_task, :find_and_refresh_command
|
578
573
|
|
579
|
-
|
580
|
-
|
581
|
-
|
582
|
-
|
574
|
+
# Everytime someone inherits from a Thor class, register the klass
|
575
|
+
# and file into baseclass.
|
576
|
+
def inherited(klass)
|
577
|
+
Thor::Base.register_klass_file(klass)
|
578
|
+
klass.instance_variable_set(:@no_commands, false)
|
579
|
+
end
|
583
580
|
|
584
|
-
|
585
|
-
|
586
|
-
|
587
|
-
|
581
|
+
# Fire this callback whenever a method is added. Added methods are
|
582
|
+
# tracked as commands by invoking the create_command method.
|
583
|
+
def method_added(meth)
|
584
|
+
meth = meth.to_s
|
588
585
|
|
589
|
-
|
590
|
-
|
586
|
+
if meth == 'initialize'
|
587
|
+
initialize_added
|
588
|
+
return
|
589
|
+
end
|
591
590
|
|
592
|
-
|
591
|
+
# Return if it's not a public instance method
|
592
|
+
return unless public_method_defined?(meth.to_sym)
|
593
593
|
|
594
|
-
|
595
|
-
|
596
|
-
end
|
594
|
+
@no_commands ||= false
|
595
|
+
return if @no_commands || !create_command(meth)
|
597
596
|
|
598
|
-
|
599
|
-
|
600
|
-
|
601
|
-
if self == baseclass || !superclass.respond_to?(method, true)
|
602
|
-
default
|
603
|
-
else
|
604
|
-
value = superclass.send(method)
|
605
|
-
|
606
|
-
# Ruby implements `dup` on Object, but raises a `TypeError`
|
607
|
-
# if the method is called on immediates. As a result, we
|
608
|
-
# don't have a good way to check whether dup will succeed
|
609
|
-
# without calling it and rescuing the TypeError.
|
610
|
-
begin
|
611
|
-
value.dup
|
612
|
-
rescue TypeError
|
613
|
-
value
|
614
|
-
end
|
597
|
+
is_thor_reserved_word?(meth, :command)
|
598
|
+
Thor::Base.register_klass_file(self)
|
599
|
+
end
|
615
600
|
|
601
|
+
# Retrieves a value from superclass. If it reaches the baseclass,
|
602
|
+
# returns default.
|
603
|
+
def from_superclass(method, default = nil)
|
604
|
+
if self == baseclass || !superclass.respond_to?(method, true)
|
605
|
+
default
|
606
|
+
else
|
607
|
+
value = superclass.send(method)
|
608
|
+
|
609
|
+
# Ruby implements `dup` on Object, but raises a `TypeError`
|
610
|
+
# if the method is called on immediates. As a result, we
|
611
|
+
# don't have a good way to check whether dup will succeed
|
612
|
+
# without calling it and rescuing the TypeError.
|
613
|
+
begin
|
614
|
+
value.dup
|
615
|
+
rescue TypeError
|
616
|
+
value
|
616
617
|
end
|
617
|
-
end
|
618
618
|
|
619
|
-
# A flag that makes the process exit with status 1 if any error happens.
|
620
|
-
def exit_on_failure?
|
621
|
-
false
|
622
619
|
end
|
620
|
+
end
|
623
621
|
|
624
|
-
|
625
|
-
|
626
|
-
|
627
|
-
|
628
|
-
File.basename($0).split(' ').first
|
629
|
-
end
|
622
|
+
# A flag that makes the process exit with status 1 if any error happens.
|
623
|
+
def exit_on_failure?
|
624
|
+
false
|
625
|
+
end
|
630
626
|
|
631
|
-
|
632
|
-
|
633
|
-
|
634
|
-
|
627
|
+
#
|
628
|
+
# The basename of the program invoking the thor class.
|
629
|
+
#
|
630
|
+
def basename
|
631
|
+
File.basename($PROGRAM_NAME).split(' ').first
|
632
|
+
end
|
635
633
|
|
636
|
-
|
637
|
-
|
638
|
-
|
639
|
-
|
640
|
-
alias create_task create_command
|
634
|
+
# SIGNATURE: Sets the baseclass. This is where the superclass lookup
|
635
|
+
# finishes.
|
636
|
+
def baseclass #:nodoc:
|
637
|
+
end
|
641
638
|
|
642
|
-
|
643
|
-
|
644
|
-
|
645
|
-
|
639
|
+
# SIGNATURE: Creates a new command if valid_command? is true. This method is
|
640
|
+
# called when a new method is added to the class.
|
641
|
+
def create_command(meth) #:nodoc:
|
642
|
+
end
|
643
|
+
alias_method :create_task, :create_command
|
646
644
|
|
647
|
-
|
648
|
-
|
649
|
-
|
650
|
-
|
645
|
+
# SIGNATURE: Defines behavior when the initialize method is added to the
|
646
|
+
# class.
|
647
|
+
def initialize_added #:nodoc:
|
648
|
+
end
|
651
649
|
|
650
|
+
# SIGNATURE: The hook invoked by start.
|
651
|
+
def dispatch(command, given_args, given_opts, config) #:nodoc:
|
652
|
+
fail NotImplementedError
|
653
|
+
end
|
652
654
|
end
|
653
655
|
end
|
654
656
|
end
|