bundler 1.3.6 → 1.4.0.pre.1

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 (90) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +1 -3
  3. data/CHANGELOG.md +27 -14
  4. data/CONTRIBUTING.md +2 -2
  5. data/{CONTRIBUTE.md → DEVELOPMENT.md} +31 -12
  6. data/ISSUES.md +1 -1
  7. data/README.md +6 -4
  8. data/Rakefile +1 -15
  9. data/bin/bundle +5 -8
  10. data/bundler.gemspec +1 -1
  11. data/lib/bundler.rb +37 -21
  12. data/lib/bundler/cli.rb +33 -21
  13. data/lib/bundler/constants.rb +5 -0
  14. data/lib/bundler/current_ruby.rb +88 -0
  15. data/lib/bundler/definition.rb +35 -11
  16. data/lib/bundler/dependency.rb +7 -78
  17. data/lib/bundler/dsl.rb +1 -1
  18. data/lib/bundler/fetcher.rb +37 -24
  19. data/lib/bundler/gem_helper.rb +2 -2
  20. data/lib/bundler/gem_installer.rb +9 -0
  21. data/lib/bundler/installer.rb +76 -7
  22. data/lib/bundler/parallel_workers.rb +18 -0
  23. data/lib/bundler/parallel_workers/thread_worker.rb +27 -0
  24. data/lib/bundler/parallel_workers/unix_worker.rb +88 -0
  25. data/lib/bundler/parallel_workers/worker.rb +68 -0
  26. data/lib/bundler/resolver.rb +17 -11
  27. data/lib/bundler/rubygems_ext.rb +2 -2
  28. data/lib/bundler/rubygems_integration.rb +37 -25
  29. data/lib/bundler/runtime.rb +8 -1
  30. data/lib/bundler/safe_catch.rb +101 -0
  31. data/lib/bundler/shared_helpers.rb +27 -1
  32. data/lib/bundler/source/git.rb +2 -1
  33. data/lib/bundler/source/git/git_proxy.rb +3 -3
  34. data/lib/bundler/source/path.rb +3 -2
  35. data/lib/bundler/source/rubygems.rb +5 -17
  36. data/lib/bundler/spec_set.rb +16 -1
  37. data/lib/bundler/templates/newgem/newgem.gemspec.tt +1 -1
  38. data/lib/bundler/vendor/net/http/persistent.rb +136 -38
  39. data/lib/bundler/vendor/thor.rb +211 -188
  40. data/lib/bundler/vendor/thor/actions.rb +19 -19
  41. data/lib/bundler/vendor/thor/actions/create_link.rb +3 -0
  42. data/lib/bundler/vendor/thor/actions/directory.rb +30 -10
  43. data/lib/bundler/vendor/thor/actions/empty_directory.rb +3 -19
  44. data/lib/bundler/vendor/thor/actions/file_manipulation.rb +6 -3
  45. data/lib/bundler/vendor/thor/base.rb +101 -97
  46. data/lib/bundler/vendor/thor/{task.rb → command.rb} +17 -13
  47. data/lib/bundler/vendor/thor/core_ext/io_binary_read.rb +12 -0
  48. data/lib/bundler/vendor/thor/error.rb +8 -11
  49. data/lib/bundler/vendor/thor/group.rb +35 -38
  50. data/lib/bundler/vendor/thor/invocation.rb +28 -26
  51. data/lib/bundler/vendor/thor/parser/options.rb +21 -19
  52. data/lib/bundler/vendor/thor/rake_compat.rb +3 -2
  53. data/lib/bundler/vendor/thor/runner.rb +22 -21
  54. data/lib/bundler/vendor/thor/shell/basic.rb +44 -22
  55. data/lib/bundler/vendor/thor/shell/color.rb +13 -9
  56. data/lib/bundler/vendor/thor/shell/html.rb +13 -9
  57. data/lib/bundler/vendor/thor/util.rb +214 -210
  58. data/lib/bundler/vendor/thor/version.rb +1 -1
  59. data/lib/bundler/version.rb +1 -1
  60. data/man/bundle-install.ronn +5 -1
  61. data/man/gemfile.5.ronn +10 -2
  62. data/spec/bundler/dsl_spec.rb +3 -3
  63. data/spec/bundler/gem_helper_spec.rb +14 -17
  64. data/spec/bundler/safe_catch_spec.rb +37 -0
  65. data/spec/install/gems/dependency_api_spec.rb +1 -36
  66. data/spec/install/gems/packed_spec.rb +4 -2
  67. data/spec/install/gems/resolving_spec.rb +37 -0
  68. data/spec/install/gems/simple_case_spec.rb +18 -16
  69. data/spec/install/git_spec.rb +1 -1
  70. data/spec/other/binstubs_spec.rb +24 -13
  71. data/spec/other/exec_spec.rb +24 -2
  72. data/spec/other/help_spec.rb +6 -6
  73. data/spec/other/outdated_spec.rb +3 -3
  74. data/spec/quality_spec.rb +3 -2
  75. data/spec/realworld/dependency_api_spec.rb +1 -1
  76. data/spec/realworld/edgecases_spec.rb +3 -3
  77. data/spec/realworld/parallel_install_spec.rb +19 -0
  78. data/spec/resolver/basic_spec.rb +11 -0
  79. data/spec/runtime/require_spec.rb +9 -0
  80. data/spec/runtime/setup_spec.rb +2 -3
  81. data/spec/spec_helper.rb +0 -1
  82. data/spec/support/builders.rb +2 -4
  83. data/spec/support/helpers.rb +4 -8
  84. data/spec/support/indexes.rb +18 -0
  85. data/spec/support/streams.rb +13 -0
  86. metadata +19 -11
  87. data/lib/bundler/vendor/thor/core_ext/dir_escape.rb +0 -0
  88. data/lib/bundler/vendor/thor/core_ext/file_binary_read.rb +0 -9
  89. data/spec/support/artifice/endpoint_host_redirect.rb +0 -15
  90. data/spec/support/permissions.rb +0 -11
@@ -1,6 +1,6 @@
1
1
  require 'fileutils'
2
2
  require 'uri'
3
- require 'thor/core_ext/file_binary_read'
3
+ require 'thor/core_ext/io_binary_read'
4
4
  require 'thor/actions/create_file'
5
5
  require 'thor/actions/create_link'
6
6
  require 'thor/actions/directory'
@@ -73,13 +73,13 @@ class Thor
73
73
  #
74
74
  def initialize(args=[], options={}, config={})
75
75
  self.behavior = case config[:behavior].to_s
76
- when "force", "skip"
77
- _cleanup_options_and_set(options, config[:behavior])
78
- :invoke
79
- when "revoke"
80
- :revoke
81
- else
82
- :invoke
76
+ when "force", "skip"
77
+ _cleanup_options_and_set(options, config[:behavior])
78
+ :invoke
79
+ when "revoke"
80
+ :revoke
81
+ else
82
+ :invoke
83
83
  end
84
84
 
85
85
  super
@@ -227,7 +227,7 @@ class Thor
227
227
  # ==== Parameters
228
228
  # command<String>:: the command to be executed.
229
229
  # config<Hash>:: give :verbose => false to not log the status, :capture => true to hide to output. Specify :with
230
- # to append an executable to command executation.
230
+ # to append an executable to command execution.
231
231
  #
232
232
  # ==== Example
233
233
  #
@@ -268,8 +268,8 @@ class Thor
268
268
  # switches.
269
269
  #
270
270
  # ==== Parameters
271
- # task<String>:: the task to be invoked
272
- # args<Array>:: arguments to the task
271
+ # command<String>:: the command to be invoked
272
+ # args<Array>:: arguments to the command
273
273
  # config<Hash>:: give :verbose => false to not log the status, :capture => true to hide to output.
274
274
  # Other options are given as parameter to Thor.
275
275
  #
@@ -282,13 +282,13 @@ class Thor
282
282
  # thor :list, :all => true, :substring => 'rails'
283
283
  # #=> thor list --all --substring=rails
284
284
  #
285
- def thor(task, *args)
285
+ def thor(command, *args)
286
286
  config = args.last.is_a?(Hash) ? args.pop : {}
287
287
  verbose = config.key?(:verbose) ? config.delete(:verbose) : true
288
288
  pretend = config.key?(:pretend) ? config.delete(:pretend) : false
289
289
  capture = config.key?(:capture) ? config.delete(:capture) : false
290
290
 
291
- args.unshift task
291
+ args.unshift(command)
292
292
  args.push Thor::Options.to_switches(config)
293
293
  command = args.join(' ').strip
294
294
 
@@ -305,12 +305,12 @@ class Thor
305
305
 
306
306
  def _cleanup_options_and_set(options, key) #:nodoc:
307
307
  case options
308
- when Array
309
- %w(--force -f --skip -s).each { |i| options.delete(i) }
310
- options << "--#{key}"
311
- when Hash
312
- [:force, :skip, "force", "skip"].each { |i| options.delete(i) }
313
- options.merge!(key => true)
308
+ when Array
309
+ %w(--force -f --skip -s).each { |i| options.delete(i) }
310
+ options << "--#{key}"
311
+ when Hash
312
+ [:force, :skip, "force", "skip"].each { |i| options.delete(i) }
313
+ options.merge!(key => true)
314
314
  end
315
315
  end
316
316
 
@@ -52,6 +52,9 @@ class Thor
52
52
  given_destination
53
53
  end
54
54
 
55
+ def exists?
56
+ super || File.symlink?(destination)
57
+ end
55
58
  end
56
59
  end
57
60
  end
@@ -39,6 +39,7 @@ class Thor
39
39
  # config<Hash>:: give :verbose => false to not log the status.
40
40
  # If :recursive => false, does not look for paths recursively.
41
41
  # If :mode => :preserve, preserve the file mode from the source.
42
+ # If :exclude_pattern => /regexp/, prevents copying files that match that regexp.
42
43
  #
43
44
  # ==== Examples
44
45
  #
@@ -74,26 +75,45 @@ class Thor
74
75
  def execute!
75
76
  lookup = Util.escape_globs(source)
76
77
  lookup = config[:recursive] ? File.join(lookup, '**') : lookup
77
- lookup = File.join(lookup, '{*,.[a-z]*}')
78
+ lookup = file_level_lookup(lookup)
78
79
 
79
- Dir[lookup].sort.each do |file_source|
80
+ files(lookup).sort.each do |file_source|
80
81
  next if File.directory?(file_source)
82
+ next if config[:exclude_pattern] && file_source.match(config[:exclude_pattern])
81
83
  file_destination = File.join(given_destination, file_source.gsub(source, '.'))
82
84
  file_destination.gsub!('/./', '/')
83
85
 
84
86
  case file_source
85
- when /\.empty_directory$/
86
- dirname = File.dirname(file_destination).gsub(/\/\.$/, '')
87
- next if dirname == given_destination
88
- base.empty_directory(dirname, config)
89
- when /\.tt$/
90
- destination = base.template(file_source, file_destination[0..-4], config, &@block)
91
- else
92
- destination = base.copy_file(file_source, file_destination, config, &@block)
87
+ when /\.empty_directory$/
88
+ dirname = File.dirname(file_destination).gsub(/\/\.$/, '')
89
+ next if dirname == given_destination
90
+ base.empty_directory(dirname, config)
91
+ when /\.tt$/
92
+ destination = base.template(file_source, file_destination[0..-4], config, &@block)
93
+ else
94
+ destination = base.copy_file(file_source, file_destination, config, &@block)
93
95
  end
94
96
  end
95
97
  end
96
98
 
99
+ if RUBY_VERSION < '2.0'
100
+ def file_level_lookup(previous_lookup)
101
+ File.join(previous_lookup, '{*,.[a-z]*}')
102
+ end
103
+
104
+ def files(lookup)
105
+ Dir[lookup]
106
+ end
107
+ else
108
+ def file_level_lookup(previous_lookup)
109
+ File.join(previous_lookup, '*')
110
+ end
111
+
112
+ def files(lookup)
113
+ Dir.glob(lookup, File::FNM_DOTMATCH)
114
+ end
115
+ end
116
+
97
117
  end
98
118
  end
99
119
  end
@@ -97,28 +97,12 @@ class Thor
97
97
  #
98
98
  # user.rb
99
99
  #
100
- # The method referenced by %-string SHOULD be public. Otherwise you
101
- # get the exception with the corresponding error message.
100
+ # The method referenced can be either public or private.
102
101
  #
103
102
  def convert_encoded_instructions(filename)
104
103
  filename.gsub(/%(.*?)%/) do |initial_string|
105
- call_public_method($1.strip) or initial_string
106
- end
107
- end
108
-
109
- # Calls `base`'s public method `sym`.
110
- # Returns:: result of `base.sym` or `nil` if `sym` wasn't found in
111
- # `base`
112
- # Raises:: Thor::PrivateMethodEncodedError if `sym` references
113
- # a private method.
114
- def call_public_method(sym)
115
- if base.respond_to?(sym)
116
- base.send(sym)
117
- elsif base.respond_to?(sym, true)
118
- raise Thor::PrivateMethodEncodedError,
119
- "Method #{base.class}##{sym} should be public, not private"
120
- else
121
- nil
104
+ method = $1.strip
105
+ base.respond_to?(method, true) ? base.send(method) : initial_string
122
106
  end
123
107
  end
124
108
 
@@ -129,7 +129,7 @@ class Thor
129
129
  #
130
130
  # ==== Example
131
131
  #
132
- # chmod "script/*", 0755
132
+ # chmod "script/server", 0755
133
133
  #
134
134
  def chmod(path, mode, config={})
135
135
  return unless behavior == :invoke
@@ -251,7 +251,7 @@ class Thor
251
251
  def uncomment_lines(path, flag, *args)
252
252
  flag = flag.respond_to?(:source) ? flag.source : flag
253
253
 
254
- gsub_file(path, /^(\s*)#\s*(.*#{flag})/, '\1\2', *args)
254
+ gsub_file(path, /^(\s*)#[[:blank:]]*(.*#{flag})/, '\1\2', *args)
255
255
  end
256
256
 
257
257
  # Comment all lines matching a given regex. It will leave the space
@@ -293,8 +293,11 @@ class Thor
293
293
  end
294
294
  alias :remove_dir :remove_file
295
295
 
296
- attr_accessor :output_buffer
296
+ attr_accessor :output_buffer
297
+ private :output_buffer, :output_buffer=
298
+
297
299
  private
300
+
298
301
  def concat(string)
299
302
  @output_buffer.concat(string)
300
303
  end
@@ -1,10 +1,10 @@
1
+ require 'thor/command'
1
2
  require 'thor/core_ext/hash_with_indifferent_access'
2
3
  require 'thor/core_ext/ordered_hash'
3
4
  require 'thor/error'
4
- require 'thor/shell'
5
5
  require 'thor/invocation'
6
6
  require 'thor/parser'
7
- require 'thor/task'
7
+ require 'thor/shell'
8
8
  require 'thor/util'
9
9
 
10
10
  class Thor
@@ -47,8 +47,8 @@ class Thor
47
47
  # first two parameters.
48
48
 
49
49
  if options.is_a?(Array)
50
- task_options = config.delete(:task_options) # hook for start
51
- parse_options = parse_options.merge(task_options) if task_options
50
+ command_options = config.delete(:command_options) # hook for start
51
+ parse_options = parse_options.merge(command_options) if command_options
52
52
  array_options, hash_options = options, {}
53
53
  else
54
54
  # Handle the case where the class was explicitly instantiated
@@ -59,9 +59,10 @@ class Thor
59
59
  # Let Thor::Options parse the options first, so it can remove
60
60
  # declared options from the array. This will leave us with
61
61
  # a list of arguments that weren't declared.
62
- stop_on_unknown = self.class.stop_on_unknown_option? config[:current_task]
62
+ stop_on_unknown = self.class.stop_on_unknown_option? config[:current_command]
63
63
  opts = Thor::Options.new(parse_options, hash_options, stop_on_unknown)
64
64
  self.options = opts.parse(array_options)
65
+ self.options = config[:class_options].merge(self.options) if config[:class_options]
65
66
 
66
67
  # If unknown options are disallowed, make sure that none of the
67
68
  # remaining arguments looks like an option.
@@ -119,15 +120,15 @@ class Thor
119
120
 
120
121
  module ClassMethods
121
122
  def attr_reader(*) #:nodoc:
122
- no_tasks { super }
123
+ no_commands { super }
123
124
  end
124
125
 
125
126
  def attr_writer(*) #:nodoc:
126
- no_tasks { super }
127
+ no_commands { super }
127
128
  end
128
129
 
129
130
  def attr_accessor(*) #:nodoc:
130
- no_tasks { super }
131
+ no_commands { super }
131
132
  end
132
133
 
133
134
  # If you want to raise an error for unknown options, call check_unknown_options!
@@ -146,8 +147,8 @@ class Thor
146
147
 
147
148
  # If true, option parsing is suspended as soon as an unknown option or a
148
149
  # regular argument is encountered. All remaining arguments are passed to
149
- # the task as regular arguments.
150
- def stop_on_unknown_option?(task_name) #:nodoc:
150
+ # the command as regular arguments.
151
+ def stop_on_unknown_option?(command_name) #:nodoc:
151
152
  false
152
153
  end
153
154
 
@@ -172,11 +173,11 @@ class Thor
172
173
  # is how they are parsed from the command line, arguments are retrieved
173
174
  # from position:
174
175
  #
175
- # thor task NAME
176
+ # thor command NAME
176
177
  #
177
178
  # Instead of:
178
179
  #
179
- # thor task --name=NAME
180
+ # thor command --name=NAME
180
181
  #
181
182
  # Besides, arguments are used inside your code as an accessor (self.argument),
182
183
  # while options are all kept in a hash (self.options).
@@ -203,7 +204,7 @@ class Thor
203
204
  #
204
205
  def argument(name, options={})
205
206
  is_thor_reserved_word?(name, :argument)
206
- no_tasks { attr_accessor name }
207
+ no_commands { attr_accessor name }
207
208
 
208
209
  required = if options.key?(:optional)
209
210
  !options[:optional]
@@ -307,88 +308,92 @@ class Thor
307
308
  end
308
309
 
309
310
  # Defines the group. This is used when thor list is invoked so you can specify
310
- # that only tasks from a pre-defined group will be shown. Defaults to standard.
311
+ # that only commands from a pre-defined group will be shown. Defaults to standard.
311
312
  #
312
313
  # ==== Parameters
313
314
  # name<String|Symbol>
314
315
  #
315
316
  def group(name=nil)
316
- case name
317
- when nil
318
- @group ||= from_superclass(:group, 'standard')
319
- else
320
- @group = name.to_s
317
+ @group = case name
318
+ when nil
319
+ @group || from_superclass(:group, 'standard')
320
+ else
321
+ name.to_s
321
322
  end
322
323
  end
323
324
 
324
- # Returns the tasks for this Thor class.
325
+ # Returns the commands for this Thor class.
325
326
  #
326
327
  # ==== Returns
327
- # OrderedHash:: An ordered hash with tasks names as keys and Thor::Task
328
+ # OrderedHash:: An ordered hash with commands names as keys and Thor::Command
328
329
  # objects as values.
329
330
  #
330
- def tasks
331
- @tasks ||= Thor::CoreExt::OrderedHash.new
331
+ def commands
332
+ @commands ||= Thor::CoreExt::OrderedHash.new
332
333
  end
334
+ alias tasks commands
333
335
 
334
- # Returns the tasks for this Thor class and all subclasses.
336
+ # Returns the commands for this Thor class and all subclasses.
335
337
  #
336
338
  # ==== Returns
337
- # OrderedHash:: An ordered hash with tasks names as keys and Thor::Task
339
+ # OrderedHash:: An ordered hash with commands names as keys and Thor::Command
338
340
  # objects as values.
339
341
  #
340
- def all_tasks
341
- @all_tasks ||= from_superclass(:all_tasks, Thor::CoreExt::OrderedHash.new)
342
- @all_tasks.merge(tasks)
342
+ def all_commands
343
+ @all_commands ||= from_superclass(:all_commands, Thor::CoreExt::OrderedHash.new)
344
+ @all_commands.merge(commands)
343
345
  end
346
+ alias all_tasks all_commands
344
347
 
345
- # Removes a given task from this Thor class. This is usually done if you
348
+ # Removes a given command from this Thor class. This is usually done if you
346
349
  # are inheriting from another class and don't want it to be available
347
350
  # anymore.
348
351
  #
349
- # By default it only remove the mapping to the task. But you can supply
352
+ # By default it only remove the mapping to the command. But you can supply
350
353
  # :undefine => true to undefine the method from the class as well.
351
354
  #
352
355
  # ==== Parameters
353
- # name<Symbol|String>:: The name of the task to be removed
354
- # options<Hash>:: You can give :undefine => true if you want tasks the method
356
+ # name<Symbol|String>:: The name of the command to be removed
357
+ # options<Hash>:: You can give :undefine => true if you want commands the method
355
358
  # to be undefined from the class as well.
356
359
  #
357
- def remove_task(*names)
360
+ def remove_command(*names)
358
361
  options = names.last.is_a?(Hash) ? names.pop : {}
359
362
 
360
363
  names.each do |name|
361
- tasks.delete(name.to_s)
362
- all_tasks.delete(name.to_s)
364
+ commands.delete(name.to_s)
365
+ all_commands.delete(name.to_s)
363
366
  undef_method name if options[:undefine]
364
367
  end
365
368
  end
369
+ alias remove_task remove_command
366
370
 
367
- # All methods defined inside the given block are not added as tasks.
371
+ # All methods defined inside the given block are not added as commands.
368
372
  #
369
373
  # So you can do:
370
374
  #
371
375
  # class MyScript < Thor
372
- # no_tasks do
373
- # def this_is_not_a_task
376
+ # no_commands do
377
+ # def this_is_not_a_command
374
378
  # end
375
379
  # end
376
380
  # end
377
381
  #
378
- # You can also add the method and remove it from the task list:
382
+ # You can also add the method and remove it from the command list:
379
383
  #
380
384
  # class MyScript < Thor
381
- # def this_is_not_a_task
385
+ # def this_is_not_a_command
382
386
  # end
383
- # remove_task :this_is_not_a_task
387
+ # remove_command :this_is_not_a_command
384
388
  # end
385
389
  #
386
- def no_tasks
387
- @no_tasks = true
390
+ def no_commands
391
+ @no_commands = true
388
392
  yield
389
393
  ensure
390
- @no_tasks = false
394
+ @no_commands = false
391
395
  end
396
+ alias no_tasks no_commands
392
397
 
393
398
  # Sets the namespace for the Thor or Thor::Group class. By default the
394
399
  # namespace is retrieved from the class name. If your Thor class is named
@@ -400,7 +405,7 @@ class Thor
400
405
  #
401
406
  # namespace :my_scripts
402
407
  #
403
- # You change how your tasks are invoked:
408
+ # You change how your commands are invoked:
404
409
  #
405
410
  # thor my_scripts -h
406
411
  #
@@ -408,26 +413,25 @@ class Thor
408
413
  #
409
414
  # namespace :default
410
415
  #
411
- # Your tasks can be invoked with a shortcut. Instead of:
416
+ # Your commands can be invoked with a shortcut. Instead of:
412
417
  #
413
- # thor :my_task
418
+ # thor :my_command
414
419
  #
415
420
  def namespace(name=nil)
416
- case name
417
- when nil
418
- @namespace ||= Thor::Util.namespace_from_thor_class(self)
419
- else
421
+ if name
420
422
  @namespace = name.to_s
423
+ else
424
+ @namespace ||= Thor::Util.namespace_from_thor_class(self)
421
425
  end
422
426
  end
423
427
 
424
- # Parses the task and options from the given args, instantiate the class
425
- # and invoke the task. This method is used when the arguments must be parsed
428
+ # Parses the command and options from the given args, instantiate the class
429
+ # and invoke the command. This method is used when the arguments must be parsed
426
430
  # from an array. If you are inside Ruby and want to use a Thor class, you
427
431
  # can simply initialize it:
428
432
  #
429
433
  # script = MyScript.new(args, options, config)
430
- # script.invoke(:task, first_arg, second_arg, third_arg)
434
+ # script.invoke(:command, first_arg, second_arg, third_arg)
431
435
  #
432
436
  def start(given_args=ARGV, config={})
433
437
  config[:shell] ||= Thor::Base.shell.new
@@ -436,48 +440,44 @@ class Thor
436
440
  ENV["THOR_DEBUG"] == "1" ? (raise e) : config[:shell].error(e.message)
437
441
  exit(1) if exit_on_failure?
438
442
  rescue Errno::EPIPE
439
- # This happens if a thor task is piped to something like `head`,
443
+ # This happens if a thor command is piped to something like `head`,
440
444
  # which closes the pipe when it's done reading. This will also
441
445
  # mean that if the pipe is closed, further unnecessary
442
446
  # computation will not occur.
443
447
  exit(0)
444
448
  end
445
449
 
446
- # Allows to use private methods from parent in child classes as tasks.
450
+ # Allows to use private methods from parent in child classes as commands.
447
451
  #
448
452
  # ==== Parameters
449
- # names<Array>:: Method names to be used as tasks
453
+ # names<Array>:: Method names to be used as commands
450
454
  #
451
455
  # ==== Examples
452
456
  #
453
- # public_task :foo
454
- # public_task :foo, :bar, :baz
457
+ # public_command :foo
458
+ # public_command :foo, :bar, :baz
455
459
  #
456
- def public_task(*names)
460
+ def public_command(*names)
457
461
  names.each do |name|
458
462
  class_eval "def #{name}(*); super end"
459
463
  end
460
464
  end
465
+ alias public_task public_command
461
466
 
462
- def handle_no_task_error(task, has_namespace = $thor_runner) #:nodoc:
467
+ def handle_no_command_error(command, has_namespace = $thor_runner) #:nodoc:
463
468
  if has_namespace
464
- raise UndefinedTaskError, "Could not find task #{task.inspect} in #{namespace.inspect} namespace."
469
+ raise UndefinedCommandError, "Could not find command #{command.inspect} in #{namespace.inspect} namespace."
465
470
  else
466
- raise UndefinedTaskError, "Could not find task #{task.inspect}."
471
+ raise UndefinedCommandError, "Could not find command #{command.inspect}."
467
472
  end
468
473
  end
474
+ alias handle_no_task_error handle_no_command_error
469
475
 
470
- def handle_argument_error(task, error, arity=nil) #:nodoc:
471
- msg = "#{basename} #{task.name}"
472
- if arity
473
- required = arity < 0 ? (-1 - arity) : arity
474
- msg << " requires at least #{required} argument"
475
- msg << "s" if required > 1
476
- else
477
- msg = "call #{msg} as"
478
- end
479
-
480
- msg << ": #{self.banner(task).inspect}."
476
+ def handle_argument_error(command, error, args, arity) #:nodoc:
477
+ 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
481
  raise InvocationError, msg
482
482
  end
483
483
 
@@ -555,28 +555,29 @@ class Thor
555
555
  end
556
556
  end
557
557
 
558
- # Finds a task with the given name. If the task belongs to the current
558
+ # Finds a command with the given name. If the command belongs to the current
559
559
  # class, just return it, otherwise dup it and add the fresh copy to the
560
- # current task hash.
561
- def find_and_refresh_task(name) #:nodoc:
562
- task = if task = tasks[name.to_s]
563
- task
564
- elsif task = all_tasks[name.to_s]
565
- tasks[name.to_s] = task.clone
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
566
  else
567
- raise ArgumentError, "You supplied :for => #{name.inspect}, but the task #{name.inspect} could not be found."
567
+ raise ArgumentError, "You supplied :for => #{name.inspect}, but the command #{name.inspect} could not be found."
568
568
  end
569
569
  end
570
+ alias find_and_refresh_task find_and_refresh_command
570
571
 
571
572
  # Everytime someone inherits from a Thor class, register the klass
572
573
  # and file into baseclass.
573
574
  def inherited(klass)
574
575
  Thor::Base.register_klass_file(klass)
575
- klass.instance_variable_set(:@no_tasks, false)
576
+ klass.instance_variable_set(:@no_commands, false)
576
577
  end
577
578
 
578
579
  # Fire this callback whenever a method is added. Added methods are
579
- # tracked as tasks by invoking the create_task method.
580
+ # tracked as commands by invoking the create_command method.
580
581
  def method_added(meth)
581
582
  meth = meth.to_s
582
583
 
@@ -586,12 +587,11 @@ class Thor
586
587
  end
587
588
 
588
589
  # Return if it's not a public instance method
589
- return unless public_instance_methods.include?(meth) ||
590
- public_instance_methods.include?(meth.to_sym)
590
+ return unless public_method_defined?(meth.to_sym)
591
591
 
592
- return if (defined?(@no_tasks) && @no_tasks) || !create_task(meth)
592
+ return if @no_commands || !create_command(meth)
593
593
 
594
- is_thor_reserved_word?(meth, :task)
594
+ is_thor_reserved_word?(meth, :command)
595
595
  Thor::Base.register_klass_file(self)
596
596
  end
597
597
 
@@ -603,13 +603,16 @@ class Thor
603
603
  else
604
604
  value = superclass.send(method)
605
605
 
606
- if value
607
- if value.is_a?(TrueClass) || value.is_a?(Symbol)
608
- value
609
- else
610
- value.dup
611
- end
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
612
614
  end
615
+
613
616
  end
614
617
  end
615
618
 
@@ -630,10 +633,11 @@ class Thor
630
633
  def baseclass #:nodoc:
631
634
  end
632
635
 
633
- # SIGNATURE: Creates a new task if valid_task? is true. This method is
636
+ # SIGNATURE: Creates a new command if valid_command? is true. This method is
634
637
  # called when a new method is added to the class.
635
- def create_task(meth) #:nodoc:
638
+ def create_command(meth) #:nodoc:
636
639
  end
640
+ alias create_task create_command
637
641
 
638
642
  # SIGNATURE: Defines behavior when the initialize method is added to the
639
643
  # class.
@@ -641,7 +645,7 @@ class Thor
641
645
  end
642
646
 
643
647
  # SIGNATURE: The hook invoked by start.
644
- def dispatch(task, given_args, given_opts, config) #:nodoc:
648
+ def dispatch(command, given_args, given_opts, config) #:nodoc:
645
649
  raise NotImplementedError
646
650
  end
647
651