Module: Capistrano::Configuration::Callbacks

Included in:
Capistrano::Configuration
Defined in:
lib/capistrano/configuration/callbacks.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#callbacksObject (readonly)

The hash of callbacks that have been registered for this configuration



14
15
16
# File 'lib/capistrano/configuration/callbacks.rb', line 14

def callbacks
  @callbacks
end

Class Method Details

.included(base) ⇒ Object

:nodoc:



6
7
8
9
10
11
# File 'lib/capistrano/configuration/callbacks.rb', line 6

def self.included(base) #:nodoc:
  %w(initialize invoke_task_directly).each do |method|
    base.send :alias_method, "#{method}_without_callbacks", method
    base.send :alias_method, method, "#{method}_with_callbacks"
  end
end

Instance Method Details

#after(task_name, *args, &block) ⇒ Object

Defines a callback to be invoked after the given task. You must specify the fully-qualified task name, both for the primary task, and for the task(s) to be executed after. Alternatively, you can pass a block to be executed after the given task.

after "deploy:update_code", :log_difference
after :deploy, "custom:announce"
after :deploy, :this, "then:this", "and:then:this"
after :some_task do
  puts "an anonymous hook!"
end

This just provides a convenient interface to the more general #on method.



64
65
66
67
68
# File 'lib/capistrano/configuration/callbacks.rb', line 64

def after(task_name, *args, &block)
  options = args.last.is_a?(Hash) ? args.pop : {}
  args << options.merge(:only => task_name)
  on :after, *args, &block
end

#before(task_name, *args, &block) ⇒ Object

Defines a callback to be invoked before the given task. You must specify the fully-qualified task name, both for the primary task, and for the task(s) to be executed before. Alternatively, you can pass a block to be executed before the given task.

before "deploy:update_code", :record_difference
before :deploy, "custom:log_deploy"
before :deploy, :this, "then:this", "and:then:this"
before :some_task do
  puts "an anonymous hook!"
end

This just provides a convenient interface to the more general #on method.



45
46
47
48
49
# File 'lib/capistrano/configuration/callbacks.rb', line 45

def before(task_name, *args, &block)
  options = args.last.is_a?(Hash) ? args.pop : {}
  args << options.merge(:only => task_name)
  on :before, *args, &block
end

#filter_deprecated_tasks(names) ⇒ Object

Filters the given task name or names and attempts to replace deprecated tasks with their equivalents.



118
119
120
121
122
123
124
125
126
127
128
129
130
131
# File 'lib/capistrano/configuration/callbacks.rb', line 118

def filter_deprecated_tasks(names)
  deprecation_msg = "[Deprecation Warning] This API has changed, please hook `deploy:create_symlink` instead of" \
    " `deploy:symlink`."

  if names == "deploy:symlink"
    warn deprecation_msg
    names = "deploy:create_symlink"
  elsif names.is_a?(Array) && names.include?("deploy:symlink")
    warn deprecation_msg
    names = names.map { |name| name == "deploy:symlink" ? "deploy:create_symlink" : name }
  end

  names
end

#initialize_with_callbacks(*args) ⇒ Object

:nodoc:



16
17
18
19
# File 'lib/capistrano/configuration/callbacks.rb', line 16

def initialize_with_callbacks(*args) #:nodoc:
  initialize_without_callbacks(*args)
  @callbacks = {}
end

#invoke_task_directly_with_callbacks(task) ⇒ Object

:nodoc:



21
22
23
24
25
26
27
28
29
30
# File 'lib/capistrano/configuration/callbacks.rb', line 21

def invoke_task_directly_with_callbacks(task) #:nodoc:

  trigger :before, task

  result = invoke_task_directly_without_callbacks(task)

  trigger :after, task

  return result
end

#on(event, *args, &block) ⇒ Object

Defines one or more callbacks to be invoked in response to some event. Capistrano currently understands the following events:

  • :before, triggered before a task is invoked

  • :after, triggered after a task is invoked

  • :start, triggered before a top-level task is invoked via the command-line

  • :finish, triggered when a top-level task completes

  • :load, triggered after all recipes have loaded

  • :exit, triggered after all tasks have completed

Specify the (fully-qualified) task names that you want invoked in response to the event. Alternatively, you can specify a block to invoke when the event is triggered. You can also pass a hash of options as the last parameter, which may include either of two keys:

  • :only, should specify an array of task names. Restricts this callback so that it will only fire when the event applies to those tasks.

  • :except, should specify an array of task names. Restricts this callback so that it will never fire when the event applies to those tasks.

Usage:

on :before, "some:hook", "another:hook", :only => "deploy:update"
on :after, "some:hook", :except => "deploy:create_symlink"
on :before, "global:hook"
on :after, :only => :deploy do
  puts "after deploy here"
end


98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/capistrano/configuration/callbacks.rb', line 98

def on(event, *args, &block)
  options = args.last.is_a?(Hash) ? args.pop : {}
  callbacks[event] ||= []

  if args.empty? && block.nil?
    raise ArgumentError, "please specify either a task name or a block to invoke"
  elsif args.any? && block
    raise ArgumentError, "please specify only a task name or a block, but not both"
  elsif block
    callbacks[event] << ProcCallback.new(block, options)
  else
    args = filter_deprecated_tasks(args)
    options[:only] = filter_deprecated_tasks(options[:only])
    options[:except] = filter_deprecated_tasks(options[:except])

    callbacks[event].concat(args.map { |name| TaskCallback.new(self, name, options) })
  end
end

#trigger(event, task = nil) ⇒ Object

Trigger the named event for the named task. All associated callbacks will be fired, in the order they were defined.



135
136
137
138
139
140
141
142
143
# File 'lib/capistrano/configuration/callbacks.rb', line 135

def trigger(event, task=nil)
  pending = Array(callbacks[event]).select { |c| c.applies_to?(task) }
  if pending.any?
    msg = "triggering #{event} callbacks"
    msg << " for `#{task.fully_qualified_name}'" if task
    logger.trace(msg)
    pending.each { |callback| callback.call }
  end
end