Retain original trigger behavior
These updates allow the after trigger to behave the same as the original with regards to the execution location of the trigger within the execution stack.
This commit is contained in:
parent
217f2530db
commit
5d70cc3bf2
@ -16,6 +16,7 @@ module Vagrant
|
||||
autoload :CleanupDisks, "vagrant/action/builtin/cleanup_disks"
|
||||
autoload :Confirm, "vagrant/action/builtin/confirm"
|
||||
autoload :ConfigValidate, "vagrant/action/builtin/config_validate"
|
||||
autoload :Delayed, "vagrant/action/builtin/delayed"
|
||||
autoload :DestroyConfirm, "vagrant/action/builtin/destroy_confirm"
|
||||
autoload :Disk, "vagrant/action/builtin/disk"
|
||||
autoload :EnvSet, "vagrant/action/builtin/env_set"
|
||||
|
||||
@ -247,15 +247,24 @@ module Vagrant
|
||||
hook_proc.call(hook)
|
||||
end
|
||||
|
||||
# Finally load any action triggers defined
|
||||
# Finally load any action triggers defined. The action triggers
|
||||
# are the originally implemented trigger style. They run before
|
||||
# and after specific provider actions (like :up, :halt, etc) and
|
||||
# are different from true action triggers
|
||||
if env[:triggers]
|
||||
if !env[:triggers].find(env[:raw_action_name], :before, machine_name, :action).empty?
|
||||
hook.prepend(Vagrant::Action::Builtin::Trigger,
|
||||
env[:raw_action_name], env[:triggers], :before, :action)
|
||||
end
|
||||
if !env[:triggers].find(env[:raw_action_name], :after, machine_name, :action).empty?
|
||||
hook.append(Vagrant::Action::Builtin::Trigger,
|
||||
# NOTE: These after triggers need to be delayed before running to
|
||||
# allow the rest of the call stack to complete before being
|
||||
# run. The delayed action is prepended to the stack (not appended)
|
||||
# to ensure it is called first, which results in it properly
|
||||
# waiting for everything to finish before itself completing.
|
||||
builder = self.class.build(Vagrant::Action::Builtin::Trigger,
|
||||
env[:raw_action_name], env[:triggers], :after, :action)
|
||||
hook.prepend(Vagrant::Action::Builtin::Delayed, builder)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
26
lib/vagrant/action/builtin/delayed.rb
Normal file
26
lib/vagrant/action/builtin/delayed.rb
Normal file
@ -0,0 +1,26 @@
|
||||
module Vagrant
|
||||
module Action
|
||||
module Builtin
|
||||
# This class is used to delay execution until the end of
|
||||
# a configured stack
|
||||
class Delayed
|
||||
# @param [Object] callable The object to call (must respond to #call)
|
||||
def initialize(app, env, callable)
|
||||
if !callable.respond_to?(:call)
|
||||
raise TypeError, "Callable argument is expected to respond to `#call`"
|
||||
end
|
||||
@app = app
|
||||
@env = env
|
||||
@callable = callable
|
||||
end
|
||||
|
||||
def call(env)
|
||||
# Allow the rest of the call stack to execute
|
||||
@app.call(env)
|
||||
# Now call our delayed stack
|
||||
@callable.call(env)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -700,12 +700,14 @@ describe Vagrant::Action::Builder do
|
||||
|
||||
it "should add a trigger action to the end of the stack" do
|
||||
subject.apply_action_name(env)
|
||||
expect(subject.stack.last.first).to eq(Vagrant::Action::Builtin::Trigger)
|
||||
expect(subject.stack.first.first).to eq(Vagrant::Action::Builtin::Delayed)
|
||||
end
|
||||
|
||||
it "should include arguments to the trigger action" do
|
||||
subject.apply_action_name(env)
|
||||
args = subject.stack.last[1]
|
||||
builder = subject.stack.first[1]&.first
|
||||
expect(builder).not_to be_nil
|
||||
args = builder.stack.first[1]
|
||||
expect(args).to include(raw_action_name)
|
||||
expect(args).to include(timing)
|
||||
expect(args).to include(:action)
|
||||
|
||||
22
test/unit/vagrant/action/builtin/delayed_test.rb
Normal file
22
test/unit/vagrant/action/builtin/delayed_test.rb
Normal file
@ -0,0 +1,22 @@
|
||||
require File.expand_path("../../../../base", __FILE__)
|
||||
|
||||
describe Vagrant::Action::Builtin::Delayed do
|
||||
let(:app) { lambda {|*_|} }
|
||||
let(:env) { {} }
|
||||
|
||||
it "should raise error when callable does not provide #call" do
|
||||
expect { described_class.new(app, env, true) }.
|
||||
to raise_error(TypeError)
|
||||
end
|
||||
|
||||
it "should delay executing action to end of stack" do
|
||||
result = []
|
||||
one = proc{ |*_| result << :one }
|
||||
two = proc{ |*_| result << :two }
|
||||
builder = Vagrant::Action::Builder.build(described_class, two)
|
||||
builder.use(one)
|
||||
builder.call(env)
|
||||
expect(result.first).to eq(:one)
|
||||
expect(result.last).to eq(:two)
|
||||
end
|
||||
end
|
||||
Loading…
x
Reference in New Issue
Block a user