lib/cape/capistrano.rb in cape-1.1.0 vs lib/cape/capistrano.rb in cape-1.2.0
- old
+ new
@@ -1,83 +1,104 @@
+require 'cape/rake'
require 'cape/util'
module Cape
# An abstraction of the Capistrano installation.
class Capistrano
- # Defines the specified _task_ as a Capistrano task.
+ # A Cape abstraction of the Rake installation.
+ attr_accessor :rake
+
+ # Constructs a new Capistrano object with the specified _attributes_.
+ def initialize(attributes={})
+ attributes.each do |name, value|
+ send "#{name}=", value
+ end
+ self.rake ||= Rake.new
+ end
+
+ # Defines a wrapper in Capistrano around the specified Rake _task_.
#
- # @param [Hash] task metadata for a task
- # @param [Hash] named_arguments named arguments
+ # @param [Hash] task metadata for a Rake task
+ # @param [Hash] named_arguments named arguments, including options to pass to
+ # the Capistrano +task+ method
#
- # @option task [String] :name the name of the task
- # @option task [Array of String, nil] :parameters the names of the task's
- # parameters, if any
- # @option task [String] :description documentation for the task
+ # @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 [Rake] :rake a Cape abstraction of
- # the Rake installation
- # @option named_arguments [[Array of] Symbol] :roles the Capistrano role(s)
- # of remote computers
- # that will execute
- # _task_
+ # @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
+ #
# @return [Capistrano] the object
#
# @raise [ArgumentError] +named_arguments[:binding]+ is missing
- # @raise [ArgumentError] +named_arguments[:rake]+ is missing
#
- # @note Any parameters that the task has are integrated via environment variables, since Capistrano does not support task parameters per se.
- def define(task, named_arguments)
+ # @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/task_definition.rb#L15-L17 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
- unless (rake = named_arguments[:rake])
- raise ::ArgumentError, ':rake named argument is required'
- end
- roles = named_arguments[:roles] || :app
- capistrano = binding.eval('self', __FILE__, __LINE__)
- if (description = build_capistrano_description(task))
- capistrano.desc description
+ capistrano_context = binding.eval('self', __FILE__, __LINE__)
+ options = named_arguments.reject do |key, value|
+ key == :binding
end
- implement task, roles, capistrano, rake
- self
+ describe( task, capistrano_context, options, &block)
+ implement(task, capistrano_context, options, &block)
end
private
- def build_capistrano_description(task)
+ def build_capistrano_description(task, options, &block)
return nil unless task[:description]
description = [task[:description]]
description << '.' unless task[:description].end_with?('.')
+
unless (parameters = Array(task[:parameters])).empty?
noun = Util.pluralize('variable', parameters.length)
parameters_list = Util.to_list_phrase(parameters.collect(&:upcase))
singular = 'Rake task argument'
noun_phrase = (parameters.length == 1) ?
"a #{singular}" :
Util.pluralize(singular)
- description << <<-end_description
+ description << <<-end_fragment
-Set environment #{noun} #{parameters_list} to pass #{noun_phrase}.
- end_description
+Set environment #{noun} #{parameters_list} if you want to pass #{noun_phrase}.
+ end_fragment
end
+
description.join
end
- def implement(task, roles, capistrano_context, rake)
- name = task[:name].split(':')
- # Define the task.
+ def describe(task, capistrano_context, options, &block)
+ if (description = build_capistrano_description(task, options, &block))
+ 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]
+ rake = self.rake
+ # Define the recipe.
block = lambda { |context|
- context.task name.last, :roles => roles do
+ context.task name_tokens.last, options do
arguments = Array(task[:parameters]).collect do |a|
if (value = ENV[a.upcase])
value = value.inspect
end
value
@@ -85,21 +106,30 @@
if arguments.empty?
arguments = nil
else
arguments = "[#{arguments.join ','}]"
end
- context.run "cd #{context.current_path} && " +
- "#{rake.remote_executable} #{name.join ':'}#{arguments}"
+ env_hash = {}
+ env_block.call(env_hash) if env_block
+ 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} " +
+ "#{task[:name]}#{arguments}#{env}"
+ context.run command
end
}
- # Nest the task inside its containing namespaces.
- name[0...-1].reverse.each do |namespace_token|
+ # Nest the recipe inside its containing namespaces.
+ name_tokens[0...-1].reverse.each do |namespace_token|
inner_block = block
block = lambda { |context|
context.namespace(namespace_token, &inner_block)
}
end
block.call capistrano_context
+ self
end
end
end