bundler 1.5.1 → 1.5.2

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of bundler might be problematic. Click here for more details.

Files changed (58) hide show
  1. data/CHANGELOG.md +26 -2
  2. data/bin/bundle +1 -3
  3. data/bundler.gemspec +1 -1
  4. data/lib/bundler/cli.rb +2 -4
  5. data/lib/bundler/fetcher.rb +13 -12
  6. data/lib/bundler/installer.rb +9 -36
  7. data/lib/bundler/parallel_workers/unix_worker.rb +12 -4
  8. data/lib/bundler/parallel_workers/worker.rb +1 -0
  9. data/lib/bundler/rubygems_ext.rb +1 -1
  10. data/lib/bundler/rubygems_integration.rb +15 -8
  11. data/lib/bundler/templates/newgem/newgem.gemspec.tt +1 -1
  12. data/lib/bundler/vendor/thor.rb +63 -56
  13. data/lib/bundler/vendor/thor/actions.rb +52 -51
  14. data/lib/bundler/vendor/thor/actions/create_file.rb +35 -37
  15. data/lib/bundler/vendor/thor/actions/create_link.rb +1 -2
  16. data/lib/bundler/vendor/thor/actions/directory.rb +36 -37
  17. data/lib/bundler/vendor/thor/actions/empty_directory.rb +67 -69
  18. data/lib/bundler/vendor/thor/actions/file_manipulation.rb +11 -12
  19. data/lib/bundler/vendor/thor/actions/inject_into_file.rb +41 -43
  20. data/lib/bundler/vendor/thor/base.rb +180 -178
  21. data/lib/bundler/vendor/thor/command.rb +22 -25
  22. data/lib/bundler/vendor/thor/core_ext/hash_with_indifferent_access.rb +21 -24
  23. data/lib/bundler/vendor/thor/core_ext/io_binary_read.rb +1 -3
  24. data/lib/bundler/vendor/thor/core_ext/ordered_hash.rb +8 -10
  25. data/lib/bundler/vendor/thor/error.rb +2 -2
  26. data/lib/bundler/vendor/thor/group.rb +59 -60
  27. data/lib/bundler/vendor/thor/invocation.rb +39 -38
  28. data/lib/bundler/vendor/thor/line_editor.rb +17 -0
  29. data/lib/bundler/vendor/thor/line_editor/basic.rb +35 -0
  30. data/lib/bundler/vendor/thor/line_editor/readline.rb +88 -0
  31. data/lib/bundler/vendor/thor/parser/argument.rb +29 -30
  32. data/lib/bundler/vendor/thor/parser/arguments.rb +102 -98
  33. data/lib/bundler/vendor/thor/parser/option.rb +25 -25
  34. data/lib/bundler/vendor/thor/parser/options.rb +85 -85
  35. data/lib/bundler/vendor/thor/rake_compat.rb +6 -7
  36. data/lib/bundler/vendor/thor/runner.rb +154 -154
  37. data/lib/bundler/vendor/thor/shell.rb +23 -30
  38. data/lib/bundler/vendor/thor/shell/basic.rb +66 -57
  39. data/lib/bundler/vendor/thor/shell/color.rb +44 -43
  40. data/lib/bundler/vendor/thor/shell/html.rb +43 -44
  41. data/lib/bundler/vendor/thor/util.rb +37 -40
  42. data/lib/bundler/vendor/thor/version.rb +1 -1
  43. data/lib/bundler/version.rb +1 -1
  44. data/man/bundle-install.ronn +1 -1
  45. data/man/gemfile.5.ronn +1 -2
  46. data/spec/commands/binstubs_spec.rb +13 -0
  47. data/spec/install/gemfile/git_spec.rb +2 -2
  48. data/spec/install/gems/dependency_api_spec.rb +34 -0
  49. data/spec/install/gems/packed_spec.rb +2 -4
  50. data/spec/quality_spec.rb +2 -2
  51. data/spec/realworld/parallel_spec.rb +69 -0
  52. data/spec/runtime/setup_spec.rb +3 -2
  53. data/spec/spec_helper.rb +1 -0
  54. data/spec/support/artifice/endpoint_host_redirect.rb +15 -0
  55. data/spec/support/permissions.rb +11 -0
  56. metadata +11 -6
  57. data/spec/realworld/parallel_install_spec.rb +0 -23
  58. 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 =~ /^https?\:\/\//
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
- block.arity == 1 ? block.call(render) : block.call
87
- else
88
- File.basename(source)
89
- end
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(/\.tt$/, '')
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.exists?(path)
291
+ ::FileUtils.rm_rf(path) if !options[:pretend] && File.exist?(path)
293
292
  end
294
- alias :remove_dir :remove_file
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, { :verbose => true }.merge(config))
38
+ super(base, destination, {:verbose => true}.merge(config))
40
39
 
41
40
  @behavior, @flag = if @config.key?(:after)
42
- [:after, @config.delete(:after)]
43
- else
44
- [:before, @config.delete(:before)]
45
- end
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
- '\0' + replacement
56
- else
57
- replacement + '\0'
58
- end
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
- content = '\1\2'
68
- /(#{flag})(.*)(#{Regexp.escape(replacement)})/m
69
- else
70
- content = '\2\3'
71
- /(#{Regexp.escape(replacement)})(.*)(#{flag})/m
72
- end
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
- protected
78
-
79
- def say_status(behavior)
80
- status = if behavior == :invoke
81
- if flag == /\A/
82
- :prepend
83
- elsif flag == /\z/
84
- :append
85
- else
86
- :insert
87
- end
88
- else
89
- :subtract
90
- end
91
-
92
- super(status, config[:verbose])
93
- end
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
- # Adds the content to the file.
96
- #
97
- def replace!(regexp, string, force)
98
- unless base.options[:pretend]
99
- content = File.binread(destination)
100
- if force || !content.include?(replacement)
101
- content.gsub!(regexp, string)
102
- File.open(destination, 'wb') { |file| file.write(content) }
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=[], options={}, config={})
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
- if options.is_a?(Array)
50
- command_options = config.delete(:command_options) # hook for start
51
- parse_options = parse_options.merge(command_options) if command_options
52
- array_options, hash_options = 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 = [], 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(self.options) if config[:class_options]
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.send :extend, ClassMethods
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
- !options[:optional]
211
- elsif options.key?(:required)
212
- options[:required]
213
- else
214
- options[:default].nil?
215
- end
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
- raise ArgumentError, "You cannot have #{name.to_s.inspect} as required argument after " <<
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
- @group = case name
318
- when nil
319
- @group || from_superclass(:group, 'standard')
319
+ def group(name = nil)
320
+ if name
321
+ @group = name.to_s
320
322
  else
321
- name.to_s
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
- alias tasks commands
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
- alias all_tasks all_commands
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
- alias remove_task remove_command
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
- alias no_tasks no_commands
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["THOR_DEBUG"] == "1" ? (raise e) : config[:shell].error(e.message)
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
- alias public_task public_command
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
- raise UndefinedCommandError, "Could not find command #{command.inspect} in #{namespace.inspect} namespace."
471
+ fail UndefinedCommandError, "Could not find command #{command.inspect} in #{namespace.inspect} namespace."
470
472
  else
471
- raise UndefinedCommandError, "Could not find command #{command.inspect}."
473
+ fail UndefinedCommandError, "Could not find command #{command.inspect}."
472
474
  end
473
475
  end
474
- alias handle_no_task_error handle_no_command_error
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 args.empty?
479
- msg << 'arguments ' << args.inspect if !args.empty?
480
- msg << "\nUsage: #{self.banner(command).inspect}"
481
- raise InvocationError, msg
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
- # Deal with default group
497
- global_options = groups.delete(nil) || []
498
- print_options(shell, global_options)
486
+ protected
499
487
 
500
- # Print all others
501
- groups.each do |group_name, options|
502
- print_options(shell, options, group_name)
503
- end
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
- # Receives a set of options and print them.
507
- def print_options(shell, options, group_name=nil)
508
- return if options.empty?
498
+ # Deal with default group
499
+ global_options = groups.delete(nil) || []
500
+ print_options(shell, global_options)
509
501
 
510
- list = []
511
- padding = options.collect{ |o| o.aliases.size }.max.to_i * 4
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
- options.each do |option|
514
- unless option.hide
515
- item = [ option.usage(padding) ]
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
- list << item
519
- list << [ "", "# Default: #{option.default}" ] if option.show_default?
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
- shell.say(group_name ? "#{group_name} options:" : "Options:")
525
- shell.print_table(list, :indent => 2)
526
- shell.say ""
527
- end
515
+ options.each do |option|
516
+ unless option.hide
517
+ item = [option.usage(padding)]
518
+ item.push(option.description ? "# #{option.description}" : '')
528
519
 
529
- # Raises an error if the word given is a Thor reserved word.
530
- def is_thor_reserved_word?(word, type) #:nodoc:
531
- return false unless THOR_RESERVED_WORDS.include?(word.to_s)
532
- raise "#{word.inspect} is a Thor reserved word and cannot be defined as #{type}"
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
- # Build an option and adds it to the given scope.
536
- #
537
- # ==== Parameters
538
- # name<Symbol>:: The name of the argument.
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
- # Receives a hash of options, parse them and add to the scope. This is a
546
- # fast way to set a bunch of options:
547
- #
548
- # build_options :foo => true, :bar => :required, :baz => :string
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
- # Finds a command with the given name. If the command belongs to the current
559
- # class, just return it, otherwise dup it and add the fresh copy to the
560
- # current command hash.
561
- def find_and_refresh_command(name) #:nodoc:
562
- command = if command = commands[name.to_s]
563
- command
564
- elsif command = all_commands[name.to_s]
565
- commands[name.to_s] = command.clone
566
- else
567
- raise ArgumentError, "You supplied :for => #{name.inspect}, but the command #{name.inspect} could not be found."
568
- end
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
- alias find_and_refresh_task find_and_refresh_command
558
+ end
571
559
 
572
- # Everytime someone inherits from a Thor class, register the klass
573
- # and file into baseclass.
574
- def inherited(klass)
575
- Thor::Base.register_klass_file(klass)
576
- klass.instance_variable_set(:@no_commands, false)
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
- # Fire this callback whenever a method is added. Added methods are
580
- # tracked as commands by invoking the create_command method.
581
- def method_added(meth)
582
- meth = meth.to_s
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
- if meth == "initialize"
585
- initialize_added
586
- return
587
- end
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
- # Return if it's not a public instance method
590
- return unless public_method_defined?(meth.to_sym)
586
+ if meth == 'initialize'
587
+ initialize_added
588
+ return
589
+ end
591
590
 
592
- return if @no_commands || !create_command(meth)
591
+ # Return if it's not a public instance method
592
+ return unless public_method_defined?(meth.to_sym)
593
593
 
594
- is_thor_reserved_word?(meth, :command)
595
- Thor::Base.register_klass_file(self)
596
- end
594
+ @no_commands ||= false
595
+ return if @no_commands || !create_command(meth)
597
596
 
598
- # Retrieves a value from superclass. If it reaches the baseclass,
599
- # returns default.
600
- def from_superclass(method, default=nil)
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
- # The basename of the program invoking the thor class.
626
- #
627
- def basename
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
- # SIGNATURE: Sets the baseclass. This is where the superclass lookup
632
- # finishes.
633
- def baseclass #:nodoc:
634
- end
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
- # SIGNATURE: Creates a new command if valid_command? is true. This method is
637
- # called when a new method is added to the class.
638
- def create_command(meth) #:nodoc:
639
- end
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
- # SIGNATURE: Defines behavior when the initialize method is added to the
643
- # class.
644
- def initialize_added #:nodoc:
645
- end
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
- # SIGNATURE: The hook invoked by start.
648
- def dispatch(command, given_args, given_opts, config) #:nodoc:
649
- raise NotImplementedError
650
- end
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