lib/cape/capistrano.rb in cape-1.6.2 vs lib/cape/capistrano.rb in cape-1.7.0
- old
+ new
@@ -1,7 +1,7 @@
-require 'cape/hash_list'
require 'cape/rake'
+require 'cape/recipe_definition'
require 'cape/util'
module Cape
# An abstraction of the Capistrano installation.
@@ -15,52 +15,46 @@
# @param [Hash] attributes attribute values
def initialize(attributes={})
attributes.each do |name, value|
send "#{name}=", value
end
- self.rake ||= Rake.new
+ self.rake ||= new_rake
end
# Defines a wrapper in Capistrano around the specified Rake _task_.
#
# @param [Hash] task metadata for a Rake task
- # @param [Hash] named_arguments named arguments, including options to pass to
- # the Capistrano +task+ method
+ # @param [Hash] named_arguments
#
# @option task [String] :name the name of the Rake task
# @option task [Array of String, nil] :parameters the names of the Rake
# task's parameters, if any
# @option task [String] :description documentation for the Rake
# task
#
- # @option named_arguments [Binding] :binding the Binding of your
- # Capistrano recipes
- # file
+ # @option named_arguments [Binding] :binding the Binding of your Capistrano
+ # recipes file
#
- # @yield [env] a block that defines environment variables for the Rake task;
- # optional
- # @yieldparam [Hash] env the environment variables to set before executing
- # the Rake task
+ # @yield [recipes] a block that customizes the Capistrano recipe(s)
+ # generated for the Rake task(s); optional
+ # @yieldparam [RecipeDefinition] recipes an interface for customizing the
+ # Capistrano recipe(s) generated for
+ # the Rake task(s)
#
# @return [Capistrano] the object
#
# @raise [ArgumentError] +named_arguments[:binding]+ is missing
#
# @note Any parameters that the Rake task has are integrated via environment variables, since Capistrano does not support recipe parameters per se.
- #
- # @see http://github.com/capistrano/capistrano/blob/master/lib/capistrano/configuration/actions/invocation.rb#L99-L144 Valid Capistrano ‘task’ method options
def define_rake_wrapper(task, named_arguments, &block)
unless (binding = named_arguments[:binding])
raise ::ArgumentError, ':binding named argument is required'
end
capistrano_context = binding.eval('self', __FILE__, __LINE__)
- options = named_arguments.reject do |key, value|
- key == :binding
- end
describe task, capistrano_context
- implement(task, capistrano_context, options, &block)
+ implement(task, capistrano_context, &block)
end
private
def build_capistrano_description(task)
@@ -86,24 +80,34 @@
end
description.join
end
+ def capture_recipe_definition(recipe_definition, &recipe_definition_block)
+ recipe_definition_block.call(recipe_definition) if recipe_definition_block
+ true
+ end
+
def describe(task, capistrano_context)
if (description = build_capistrano_description(task))
capistrano_context.desc description
end
self
end
- def implement(task, capistrano_context, options, &env_block)
- name_tokens = task[:name].split(':')
- name_tokens << 'default' if task[:default]
+ def implement(task, capistrano_context, &recipe_definition_block)
+ name_tokens = tokenize_name(task)
+ recipe_definition = new_recipe_definition
+ capture_recipe_definition(recipe_definition, &recipe_definition_block)
+ env = nil
rake = self.rake
- # Define the recipe.
block = lambda { |context|
- context.task name_tokens.last, options do
+ recipe_name = name_tokens.last
+ 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
end
value
@@ -111,21 +115,30 @@
if arguments.empty?
arguments = nil
else
arguments = "[#{arguments.join ','}]"
end
- env_hash = HashList.new
- env_block.call(env_hash) if env_block
- env_hash.reject! do |var_name, var_value|
- var_name.nil? || var_value.nil?
+
+ 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
+ end.compact
+ env = env_strings.empty? ? nil : (' ' + env_strings.join(' '))
end
- env_strings = env_hash.collect do |var_name, var_value|
- "#{var_name}=#{var_value.inspect}"
- end
- env = env_strings.empty? ? nil : (' ' + env_strings.join(' '))
- command = "cd #{context.current_path} && " +
- "#{rake.remote_executable} " +
+
+ 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
}
# Nest the recipe inside its containing namespaces.
@@ -135,9 +148,23 @@
context.namespace(namespace_token, &inner_block)
}
end
block.call capistrano_context
self
+ end
+
+ def new_rake(*arguments)
+ Rake.new(*arguments)
+ end
+
+ def new_recipe_definition(*arguments)
+ RecipeDefinition.new(*arguments)
+ end
+
+ def tokenize_name(task)
+ task[:name].split(':').tap do |result|
+ result << 'default' if task[:default]
+ end
end
end
end