Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Warn instead of bubbling Capistrano's ArgumentError on illegal task name

The readme implies you can mirror all Rake tasks in a standard Rails
project by simply calling Cape.mirror_rake_tasks with no arguments.
Capistrano raises ArgumentError when you try to define a task whose name
collides with a Ruby method name. For example a 'load' Rake task
collides with the core method Kernel#load when you try to mirror it as a
Capistrano recipe. There are Rake tasks defined by Rails that have the
same problem.

Instead of bubbling the error from Capistrano, we are writing a warning
to stderr and ignoring the offending task.
  • Loading branch information...
commit f48fe85c4fc0f76c616690741cf5d5e2c95c50b5 1 parent 77773d7
@njonsson authored
View
93 features/dsl/mirror_rake_tasks/unqualified.feature
@@ -46,6 +46,53 @@ Feature: The #mirror_rake_tasks DSL method
cap hidden_task #
"""
+ Scenario: mirror all Rake tasks except a Ruby-method-shadowing task
+ Given a full-featured Rakefile defining a Ruby-method-shadowing task
+ And a Capfile with:
+ """
+ Cape do
+ mirror_rake_tasks
+ end
+ """
+ When I run `cap -vT`
+ Then the output should contain:
+ """
+ cap long # My long task -- it has a ve...
+ """
+ And the output should contain:
+ """
+ cap with_one_arg # My task with one argument.
+ """
+ And the output should contain:
+ """
+ cap my_namespace # A task that shadows a names...
+ """
+ And the output should contain:
+ """
+ cap my_namespace:in_a_namespace # My task in a namespace.
+ """
+ And the output should contain:
+ """
+ cap my_namespace:my_nested_namespace:in_a_nested_namespace # My task in a nested namespace.
+ """
+ And the output should contain:
+ """
+ cap with_two_args # My task with two arguments.
+ """
+ And the output should contain:
+ """
+ cap with_three_args # My task with three arguments.
+ """
+ And the output should contain:
+ """
+ cap hidden_task #
+ """
+ And the output should not contain "cap load"
+ And the output should contain:
+ """
+ *** WARNING: You will need to use Cape's renaming API if you want to mirror Rake task load (defining a task named `load' would shadow an existing method with that name)
+ """
+
Scenario: mirror Rake task 'long' with its description
Given a full-featured Rakefile
And a Capfile with:
@@ -87,6 +134,52 @@ Feature: The #mirror_rake_tasks DSL method
`long' is only run for servers matching {}, but no servers matched
"""
+ Scenario: mirror Rake task 'long' with its description when a Ruby-method-shadowing task is defined
+ Given a full-featured Rakefile defining a Ruby-method-shadowing task
+ And a Capfile with:
+ """
+ Cape do
+ mirror_rake_tasks
+ end
+ """
+ When I run `cap -e long`
+ Then the output should contain exactly:
+ """
+ ------------------------------------------------------------
+ cap long
+ ------------------------------------------------------------
+ My long task -- it has a very, very, very, very, very, very, very, very, very,
+ very, very, very, very, very, very, very, very, very, very, very, very, very,
+ very, very, very, very long description.
+
+ *** WARNING: You will need to use Cape's renaming API if you want to mirror Rake task load (defining a task named `load' would shadow an existing method with that name)
+
+ """
+
+ Scenario: mirror Rake task 'long' with its implementation when a Ruby-method-shadowing task is defined
+ Given a full-featured Rakefile defining a Ruby-method-shadowing task
+ And a Capfile with:
+ """
+ set :current_path, '/current/path'
+
+ Cape do
+ mirror_rake_tasks
+ end
+ """
+ When I run `cap long`
+ Then the output should contain:
+ """
+ * executing `long'
+ """
+ And the output should contain:
+ """
+ `long' is only run for servers matching {}, but no servers matched
+ """
+ And the output should contain:
+ """
+ *** WARNING: You will need to use Cape's renaming API if you want to mirror Rake task load (defining a task named `load' would shadow an existing method with that name)
+ """
+
Scenario: mirror Rake task 'with_one_arg' with its description
Given a full-featured Rakefile
And a Capfile with:
View
68 lib/cape/capistrano.rb
@@ -1,6 +1,7 @@
require 'cape/rake'
require 'cape/recipe_definition'
require 'cape/util'
+require 'cape/xterm'
module Cape
@@ -105,40 +106,49 @@ def implement(task, capistrano_context, &recipe_definition_block)
if recipe_definition.rename
recipe_name = recipe_definition.rename.call(name_tokens.last)
end
- context.task recipe_name, recipe_definition.options do
- arguments = Array(task[:parameters]).collect do |a|
- if (value = ENV[a.upcase])
- value = value.inspect
+ begin
+ context.task recipe_name, recipe_definition.options do
+ arguments = Array(task[:parameters]).collect do |a|
+ if (value = ENV[a.upcase])
+ value = value.inspect
+ end
+ value
+ end
+ if arguments.empty?
+ arguments = nil
+ else
+ arguments = "[#{arguments.join ','}]"
end
- value
- end
- if arguments.empty?
- arguments = nil
- else
- arguments = "[#{arguments.join ','}]"
- end
- unless env
- env_strings = recipe_definition.env.collect do |var_name, var_value|
- if var_name.nil? || var_value.nil?
- nil
- else
- if var_value.is_a?(Proc)
- var_value = context.instance_eval do
- var_value.call
+ unless env
+ env_strings = recipe_definition.env.collect do |var_name, var_value|
+ if var_name.nil? || var_value.nil?
+ nil
+ else
+ if var_value.is_a?(Proc)
+ var_value = context.instance_eval do
+ var_value.call
+ end
end
+ "#{var_name}=#{var_value.inspect}"
end
- "#{var_name}=#{var_value.inspect}"
- end
- end.compact
- env = env_strings.empty? ? nil : (' ' + env_strings.join(' '))
- end
+ end.compact
+ env = env_strings.empty? ? nil : (' ' + env_strings.join(' '))
+ end
- path = recipe_definition.cd || context.current_path
- path = path.call if path.respond_to?(:call)
- command = "cd #{path} && #{rake.remote_executable} " +
- "#{task[:name]}#{arguments}#{env}"
- context.run command
+ path = recipe_definition.cd || context.current_path
+ path = path.call if path.respond_to?(:call)
+ command = "cd #{path} && #{rake.remote_executable} " +
+ "#{task[:name]}#{arguments}#{env}"
+ context.run command
+ end
+ rescue => e
+ $stderr.puts XTerm.bold_and_foreground_red('*** WARNING:') +
+ ' ' +
+ XTerm.bold("You will need to use Cape's renaming API " +
+ 'if you want to mirror Rake task ') +
+ XTerm.bold_and_underlined(task[:name]) +
+ XTerm.bold(" (#{e.message})")
end
}
# Nest the recipe inside its containing namespaces.
Please sign in to comment.
Something went wrong with that request. Please try again.