Call hooks before and after each action if they are available
This commit is contained in:
parent
8c137e2bba
commit
80c05460ab
|
@ -47,7 +47,16 @@ module Vagrant
|
||||||
raise Errors::VagrantInterrupt if env[:interrupted]
|
raise Errors::VagrantInterrupt if env[:interrupted]
|
||||||
action = @actions.shift
|
action = @actions.shift
|
||||||
@logger.info("Calling IN action: #{action}")
|
@logger.info("Calling IN action: #{action}")
|
||||||
|
|
||||||
|
if !action.is_a?(Proc) && env[:hook]
|
||||||
|
hook_name = action.class.name.split("::").last.
|
||||||
|
gsub(/([a-z])([A-Z])/, '\1_\2').gsub('-', '_').downcase
|
||||||
|
end
|
||||||
|
|
||||||
|
env[:hook].call("before_#{hook_name}".to_sym) if hook_name
|
||||||
@stack.unshift(action).first.call(env)
|
@stack.unshift(action).first.call(env)
|
||||||
|
env[:hook].call("after_#{hook_name}".to_sym) if hook_name
|
||||||
|
|
||||||
raise Errors::VagrantInterrupt if env[:interrupted]
|
raise Errors::VagrantInterrupt if env[:interrupted]
|
||||||
@logger.info("Calling OUT action: #{action}")
|
@logger.info("Calling OUT action: #{action}")
|
||||||
rescue SystemExit
|
rescue SystemExit
|
||||||
|
|
|
@ -1,24 +1,7 @@
|
||||||
require File.expand_path("../../../base", __FILE__)
|
require File.expand_path("../../../base", __FILE__)
|
||||||
|
|
||||||
describe Vagrant::Action::Warden do
|
describe Vagrant::Action::Warden do
|
||||||
let(:data) { { data: [] } }
|
class ActionOne
|
||||||
let(:instance) { described_class.new }
|
|
||||||
|
|
||||||
# This returns a proc that can be used with the builder
|
|
||||||
# that simply appends data to an array in the env.
|
|
||||||
def appender_proc(data)
|
|
||||||
Proc.new { |env| env[:data] << data }
|
|
||||||
end
|
|
||||||
|
|
||||||
it "calls the actions like normal" do
|
|
||||||
instance = described_class.new([appender_proc(1), appender_proc(2)], data)
|
|
||||||
instance.call(data)
|
|
||||||
|
|
||||||
expect(data[:data]).to eq([1, 2])
|
|
||||||
end
|
|
||||||
|
|
||||||
it "starts a recovery sequence when an exception is raised" do
|
|
||||||
class Action
|
|
||||||
def initialize(app, env)
|
def initialize(app, env)
|
||||||
@app = app
|
@app = app
|
||||||
end
|
end
|
||||||
|
@ -46,24 +29,7 @@ describe Vagrant::Action::Warden do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
error_proc = Proc.new { raise "ERROR!" }
|
class ExitAction
|
||||||
|
|
||||||
data = { recover: [] }
|
|
||||||
instance = described_class.new([Action, ActionTwo, error_proc], data)
|
|
||||||
|
|
||||||
# The error should be raised back up
|
|
||||||
expect { instance.call(data) }.
|
|
||||||
to raise_error(RuntimeError)
|
|
||||||
|
|
||||||
# Verify the recovery process goes in reverse order
|
|
||||||
expect(data[:recover]).to eq([2, 1])
|
|
||||||
|
|
||||||
# Verify that the error is available in the data
|
|
||||||
expect(data["vagrant.error"]).to be_kind_of(RuntimeError)
|
|
||||||
end
|
|
||||||
|
|
||||||
it "does not do a recovery sequence if SystemExit is raised" do
|
|
||||||
class Action
|
|
||||||
def initialize(app, env)
|
def initialize(app, env)
|
||||||
@app = app
|
@app = app
|
||||||
end
|
end
|
||||||
|
@ -77,11 +43,45 @@ describe Vagrant::Action::Warden do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
let(:data) { { data: [] } }
|
||||||
|
let(:instance) { described_class.new }
|
||||||
|
|
||||||
|
# This returns a proc that can be used with the builder
|
||||||
|
# that simply appends data to an array in the env.
|
||||||
|
def appender_proc(data)
|
||||||
|
Proc.new { |env| env[:data] << data }
|
||||||
|
end
|
||||||
|
|
||||||
|
it "calls the actions like normal" do
|
||||||
|
instance = described_class.new([appender_proc(1), appender_proc(2)], data)
|
||||||
|
instance.call(data)
|
||||||
|
|
||||||
|
expect(data[:data]).to eq([1, 2])
|
||||||
|
end
|
||||||
|
|
||||||
|
it "starts a recovery sequence when an exception is raised" do
|
||||||
|
error_proc = Proc.new { raise "ERROR!" }
|
||||||
|
|
||||||
|
data = { recover: [] }
|
||||||
|
instance = described_class.new([ActionOne, ActionTwo, error_proc], data)
|
||||||
|
|
||||||
|
# The error should be raised back up
|
||||||
|
expect { instance.call(data) }.
|
||||||
|
to raise_error(RuntimeError)
|
||||||
|
|
||||||
|
# Verify the recovery process goes in reverse order
|
||||||
|
expect(data[:recover]).to eq([2, 1])
|
||||||
|
|
||||||
|
# Verify that the error is available in the data
|
||||||
|
expect(data["vagrant.error"]).to be_kind_of(RuntimeError)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "does not do a recovery sequence if SystemExit is raised" do
|
||||||
# Make a proc that just calls "abort" which raises a
|
# Make a proc that just calls "abort" which raises a
|
||||||
# SystemExit exception.
|
# SystemExit exception.
|
||||||
error_proc = Proc.new { abort }
|
error_proc = Proc.new { abort }
|
||||||
|
|
||||||
instance = described_class.new([Action, error_proc], data)
|
instance = described_class.new([ExitAction, error_proc], data)
|
||||||
|
|
||||||
# The SystemExit should come through
|
# The SystemExit should come through
|
||||||
expect { instance.call(data) }.to raise_error(SystemExit)
|
expect { instance.call(data) }.to raise_error(SystemExit)
|
||||||
|
@ -89,4 +89,36 @@ describe Vagrant::Action::Warden do
|
||||||
# The recover should not have been called
|
# The recover should not have been called
|
||||||
expect(data.key?(:recover)).not_to be
|
expect(data.key?(:recover)).not_to be
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context "when hook is defined" do
|
||||||
|
let(:hook) { double("hook") }
|
||||||
|
|
||||||
|
before do
|
||||||
|
data[:hook] = hook
|
||||||
|
allow(hook).to receive(:call)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should receive a before hook call" do
|
||||||
|
expect(hook).to receive(:call).with(:before_action_one)
|
||||||
|
described_class.new([ActionOne], data).call(data)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should receive an after hook call" do
|
||||||
|
expect(hook).to receive(:call).with(:after_action_one)
|
||||||
|
described_class.new([ActionOne], data).call(data)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should not receive any hook calls for proc instances" do
|
||||||
|
expect(hook).not_to receive(:call)
|
||||||
|
described_class.new([proc{|*_| :testing }], data).call(data)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should receive before and after calls for each class" do
|
||||||
|
expect(hook).to receive(:call).with(:before_action_one)
|
||||||
|
expect(hook).to receive(:call).with(:after_action_one)
|
||||||
|
expect(hook).to receive(:call).with(:before_action_two)
|
||||||
|
expect(hook).to receive(:call).with(:after_action_two)
|
||||||
|
described_class.new([ActionOne, proc{|*_| :testing }, ActionTwo], data).call(data)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue