diff --git a/lib/vagrant/action/builder.rb b/lib/vagrant/action/builder.rb index 5276ec3ab..da95af792 100644 --- a/lib/vagrant/action/builder.rb +++ b/lib/vagrant/action/builder.rb @@ -93,8 +93,6 @@ module Vagrant to_app(env).call(env) end - protected - # Returns the numeric index for the given middleware object. # # @param [Object] object The item to find the index for @@ -108,6 +106,8 @@ module Vagrant nil end + protected + # Returns the current stack of middlewares. You probably won't # need to use this directly, and it's recommended that you don't. # diff --git a/lib/vagrant/action/runner.rb b/lib/vagrant/action/runner.rb index 69cd4569d..02b20a4a4 100644 --- a/lib/vagrant/action/runner.rb +++ b/lib/vagrant/action/runner.rb @@ -59,7 +59,10 @@ module Vagrant # 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| + hooks = plugin.action_hook(Vagrant::Plugin::V1::ALL_ACTIONS) + hooks += plugin.action_hook(id) + + hooks.each do |hook| hook.call(seq) end end diff --git a/lib/vagrant/action/vm/import.rb b/lib/vagrant/action/vm/import.rb index 7d2f385fe..6e690d24d 100644 --- a/lib/vagrant/action/vm/import.rb +++ b/lib/vagrant/action/vm/import.rb @@ -2,6 +2,11 @@ module Vagrant module Action module VM class Import + # The name for easy reference + def self.name + :import + end + def initialize(app, env) @app = app end diff --git a/lib/vagrant/easy.rb b/lib/vagrant/easy.rb index 55a861bcb..2e3a4caf8 100644 --- a/lib/vagrant/easy.rb +++ b/lib/vagrant/easy.rb @@ -12,5 +12,17 @@ module Vagrant command.configure(name, &block) command end + + # This creates a new easy hook. This should not be called by the + # general public. Instead, use the plugin interface. + # + # @return [Proc] + def self.create_hook(&block) + # Create a lambda which simply calls the plugin with the operations + lambda do |env| + ops = Operations.new(env[:vm]) + block.call(ops) + end + end end end diff --git a/lib/vagrant/plugin/v1.rb b/lib/vagrant/plugin/v1.rb index ea78aa297..30e9760df 100644 --- a/lib/vagrant/plugin/v1.rb +++ b/lib/vagrant/plugin/v1.rb @@ -11,6 +11,13 @@ module Vagrant # This is thrown when a command name given is invalid. class InvalidCommandName < Error; end + # This is thrown when a hook "position" is invalid. + class InvalidEasyHookPosition < Error; end + + # Special marker that can be used for action hooks that matches + # all action sequences. + ALL_ACTIONS = :__all_actions__ + LOGGER = Log4r::Logger.new("vagrant::plugin::v1") # Returns a list of registered plugins for this version. @@ -105,6 +112,27 @@ module Vagrant data[:config] end + # Defines an "easy hook," which gives an easier interface to hook + # into action sequences. + def self.easy_hook(position, name, &block) + if ![:before, :after].include?(position) + raise InvalidEasyHookPosition, "must be :before, :after" + end + + # This is the command sent to sequences to insert + insert_method = "insert_#{position}".to_sym + + # Create the hook + hook = Easy.create_hook(&block) + + # Define an action hook that listens to all actions and inserts + # the hook properly if the sequence contains what we're looking for + action_hook(ALL_ACTIONS) do |seq| + index = seq.index(name) + seq.send(insert_method, index, hook) if index + end + end + # Defines an "easy command," which is a command with limited # functionality but far less boilerplate required over traditional # commands. Easy commands let you make basic commands quickly and