Plugins can now have action_hooks

This commit is contained in:
Mitchell Hashimoto 2012-05-05 18:28:07 -07:00
parent 462136cbf2
commit 8850c086b1
3 changed files with 53 additions and 1 deletions

View File

@ -20,7 +20,7 @@ module Vagrant
def run(callable_id, options=nil)
callable = callable_id
callable = Builder.new.use(callable_id) if callable_id.kind_of?(Class)
callable = @registry.get(callable_id) if callable_id.kind_of?(Symbol)
callable = registry_sequence(callable_id) if callable_id.kind_of?(Symbol)
raise ArgumentError, "Argument to run must be a callable object or registered action." if !callable || !callable.respond_to?(:call)
# Create the initial environment with the options given
@ -48,6 +48,25 @@ module Vagrant
@logger.info("Running action: #{callable_id}")
Util::Busy.busy(int_callback) { callable.call(environment) }
end
protected
def registry_sequence(id)
# Attempt to get the sequence
seq = @registry.get(id)
return nil if !seq
# Go through all the registered plugins and get all the hooks
# for this sequence.
Vagrant.plugin("1").registered.each do |plugin|
plugin.action_hook(id).each do |hook|
hook.call(seq)
end
end
# Return the sequence
seq
end
end
end
end

View File

@ -40,6 +40,24 @@ module Vagrant
get_or_set(:description, value)
end
# Registers a callback to be called when a specific action sequence
# is run. This allows plugin authors to hook into things like VM
# bootup, VM provisioning, etc.
#
# @param [Symbol] name Name of the action.
# @return [Array] List of the hooks for the given action.
def self.action_hook(name, &block)
# Get the list of hooks for the given hook name
data[:action_hooks] ||= {}
hooks = data[:action_hooks][name.to_sym] ||= []
# Return the list if we don't have a block
return hooks if !block_given?
# Otherwise add the block to the list of hooks for this action.
hooks << block
end
# Defines additional command line commands available by key. The key
# becomes the subcommand, so if you register a command "foo" then
# "vagrant foo" becomes available.
@ -116,6 +134,9 @@ module Vagrant
# Registers the plugin. This makes the plugin actually work with
# Vagrant. Prior to registering, the plugin is merely a skeleton.
#
# This shouldn't be called by the general public. Plugins are automatically
# registered when they are given a name.
def self.register!(plugin=nil)
plugin ||= self

View File

@ -23,6 +23,18 @@ describe Vagrant::Plugin::V1 do
plugin.description.should == "bar"
end
describe "action hooks" do
it "should register action hooks" do
plugin = Class.new(described_class) do
action_hook("foo") { "bar" }
end
hooks = plugin.action_hook("foo")
hooks.length.should == 1
hooks[0].call.should == "bar"
end
end
describe "commands" do
it "should register command classes" do
plugin = Class.new(described_class) do