From be01d57034ca298963e57dc763bf5715149be17b Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Fri, 22 Feb 2013 12:12:55 -0800 Subject: [PATCH] action_hooks can hook into specific actions --- lib/vagrant/action/runner.rb | 2 +- lib/vagrant/plugin/v2/components.rb | 5 ++- lib/vagrant/plugin/v2/manager.rb | 5 ++- lib/vagrant/plugin/v2/plugin.rb | 7 +++- test/unit/vagrant/plugin/v2/manager_test.rb | 41 +++++++++++++++++++++ test/unit/vagrant/plugin/v2/plugin_test.rb | 16 +++++++- 6 files changed, 67 insertions(+), 9 deletions(-) diff --git a/lib/vagrant/action/runner.rb b/lib/vagrant/action/runner.rb index 052043e9e..ea1aad862 100644 --- a/lib/vagrant/action/runner.rb +++ b/lib/vagrant/action/runner.rb @@ -29,7 +29,7 @@ module Vagrant environment.merge!(options || {}) # Setup the action hooks - hooks = Vagrant.plugin("2").manager.action_hooks + hooks = Vagrant.plugin("2").manager.action_hooks(environment[:action_name]) if !hooks.empty? @logger.info("Preparing hooks for middleware sequence...") environment[:action_hooks] = hooks.map do |hook_proc| diff --git a/lib/vagrant/plugin/v2/components.rb b/lib/vagrant/plugin/v2/components.rb index a9a7e50f7..f7035cb07 100644 --- a/lib/vagrant/plugin/v2/components.rb +++ b/lib/vagrant/plugin/v2/components.rb @@ -8,7 +8,7 @@ module Vagrant class Components # This contains all the action hooks. # - # @return [Array] + # @return [Hash] attr_reader :action_hooks # This contains all the configuration plugins by scope. @@ -17,7 +17,8 @@ module Vagrant attr_reader :configs def initialize - @action_hooks = [] + # The action hooks hash defaults to [] + @action_hooks = Hash.new { |h, k| h[k] = [] } # Create the configs hash which defaults to a registry @configs = Hash.new { |h, k| h[k] = Registry.new } diff --git a/lib/vagrant/plugin/v2/manager.rb b/lib/vagrant/plugin/v2/manager.rb index def073a45..572cea429 100644 --- a/lib/vagrant/plugin/v2/manager.rb +++ b/lib/vagrant/plugin/v2/manager.rb @@ -17,11 +17,12 @@ module Vagrant # This returns all the action hooks. # # @return [Array] - def action_hooks + def action_hooks(hook_name) result = [] @registered.each do |plugin| - result += plugin.components.action_hooks + result += plugin.components.action_hooks[Plugin::ALL_ACTIONS] + result += plugin.components.action_hooks[hook_name] end result diff --git a/lib/vagrant/plugin/v2/plugin.rb b/lib/vagrant/plugin/v2/plugin.rb index 2246895dc..77ece03fd 100644 --- a/lib/vagrant/plugin/v2/plugin.rb +++ b/lib/vagrant/plugin/v2/plugin.rb @@ -66,11 +66,14 @@ module Vagrant # bootup, VM provisioning, etc. # # @param [String] name Name of the action. + # @param [Symbol] hook_name The location to hook. If this isn't + # set, every middleware action is hooked. # @return [Array] List of the hooks for the given action. - def self.action_hook(name, &block) + def self.action_hook(name, hook_name=nil, &block) # The name is currently not used but we want it for the future. - components.action_hooks << block + hook_name ||= ALL_ACTIONS + components.action_hooks[hook_name] << block end # Defines additional command line commands available by key. The key diff --git a/test/unit/vagrant/plugin/v2/manager_test.rb b/test/unit/vagrant/plugin/v2/manager_test.rb index 85431c337..6d31ad5c7 100644 --- a/test/unit/vagrant/plugin/v2/manager_test.rb +++ b/test/unit/vagrant/plugin/v2/manager_test.rb @@ -11,6 +11,47 @@ describe Vagrant::Plugin::V2::Manager do p end + describe "#action_hooks" do + it "should contain globally registered hooks" do + pA = plugin do |p| + p.action_hook("foo") { "bar" } + end + + pB = plugin do |p| + p.action_hook("bar") { "baz" } + end + + instance.register(pA) + instance.register(pB) + + result = instance.action_hooks(nil) + result.length.should == 2 + result[0].call.should == "bar" + result[1].call.should == "baz" + end + + it "should contain specific hooks with globally registered hooks" do + pA = plugin do |p| + p.action_hook("foo") { "bar" } + p.action_hook("foo", :foo) { "bar_foo" } + p.action_hook("foo", :bar) { "bar_bar" } + end + + pB = plugin do |p| + p.action_hook("bar") { "baz" } + end + + instance.register(pA) + instance.register(pB) + + result = instance.action_hooks(:foo) + result.length.should == 3 + result[0].call.should == "bar" + result[1].call.should == "bar_foo" + result[2].call.should == "baz" + end + end + it "should enumerate registered communicator classes" do pA = plugin do |p| p.communicator("foo") { "bar" } diff --git a/test/unit/vagrant/plugin/v2/plugin_test.rb b/test/unit/vagrant/plugin/v2/plugin_test.rb index 935936920..bb64a393a 100644 --- a/test/unit/vagrant/plugin/v2/plugin_test.rb +++ b/test/unit/vagrant/plugin/v2/plugin_test.rb @@ -24,12 +24,24 @@ describe Vagrant::Plugin::V2::Plugin do end describe "action hooks" do - it "should register action hooks" do + it "should register on all actions by default" do plugin = Class.new(described_class) do action_hook("foo") { "bar" } end - hooks = plugin.components.action_hooks + hooks_registry = plugin.components.action_hooks + hooks = hooks_registry[described_class.const_get("ALL_ACTIONS")] + hooks.length.should == 1 + hooks[0].call.should == "bar" + end + + it "should register for a specific action by default" do + plugin = Class.new(described_class) do + action_hook("foo", :bar) { "bar" } + end + + hooks_registry = plugin.components.action_hooks + hooks = hooks_registry[:bar] hooks.length.should == 1 hooks[0].call.should == "bar" end