The proper enter/exit sequence is called for multisteps
This commit is contained in:
parent
822226cae4
commit
2c73de0043
|
@ -121,8 +121,9 @@ module Vagrant
|
||||||
|
|
||||||
# For each step, call it with proper inputs, using the output
|
# For each step, call it with proper inputs, using the output
|
||||||
# of that call as inputs to the next.
|
# of that call as inputs to the next.
|
||||||
step_outputs = {}
|
entered_steps = []
|
||||||
steps.inject(params) do |inputs, data|
|
step_outputs = {}
|
||||||
|
result = steps.inject(params) do |inputs, data|
|
||||||
name, step, mappings = data
|
name, step, mappings = data
|
||||||
|
|
||||||
# If we have inputs to remap, remap them.
|
# If we have inputs to remap, remap them.
|
||||||
|
@ -139,11 +140,26 @@ module Vagrant
|
||||||
|
|
||||||
# Call the actual step, using the results for the next
|
# Call the actual step, using the results for the next
|
||||||
# iteration.
|
# iteration.
|
||||||
step_outputs[name] = step.call(inputs)
|
entered_steps << step
|
||||||
|
begin
|
||||||
|
step_outputs[name] = step.call_enter(inputs)
|
||||||
|
rescue Exception => e
|
||||||
|
entered_steps.reverse.each do |s|
|
||||||
|
s.call_exit(e)
|
||||||
|
end
|
||||||
|
|
||||||
|
raise
|
||||||
|
end
|
||||||
|
|
||||||
# Return a shallow dup of the results
|
# Return a shallow dup of the results
|
||||||
step_outputs[name].dup
|
step_outputs[name].dup
|
||||||
end
|
end
|
||||||
|
|
||||||
|
entered_steps.reverse.each do |s|
|
||||||
|
s.call_exit(nil)
|
||||||
|
end
|
||||||
|
|
||||||
|
result
|
||||||
end
|
end
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
|
@ -173,4 +173,61 @@ describe Vagrant::Action::MultiStep do
|
||||||
g = described_class.new
|
g = described_class.new
|
||||||
expect { g.step step_A, g.input(:foo) => :input_B }.to raise_error(ArgumentError)
|
expect { g.step step_A, g.input(:foo) => :input_B }.to raise_error(ArgumentError)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "should call the enter methods in order, and the exit in reverse order" do
|
||||||
|
step = Class.new(Vagrant::Action::Step) do
|
||||||
|
input :key
|
||||||
|
input :data
|
||||||
|
output :data
|
||||||
|
|
||||||
|
def enter
|
||||||
|
@data << @key
|
||||||
|
return :data => @data
|
||||||
|
end
|
||||||
|
|
||||||
|
def exit(error)
|
||||||
|
@data << @key
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
g = described_class.new
|
||||||
|
g.step step
|
||||||
|
g.step :two, step, g.input(:key2) => :key
|
||||||
|
g.step :three, step, g.input(:key3) => :key
|
||||||
|
result = g.call(:data => [], :key => "1", :key2 => "2", :key3 => "3")
|
||||||
|
result[:data].should == %W[1 2 3 3 2 1]
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should halt the steps and call exit with the error if an error occurs" do
|
||||||
|
step = Class.new(Vagrant::Action::Step) do
|
||||||
|
input :key
|
||||||
|
input :data
|
||||||
|
output :data
|
||||||
|
|
||||||
|
def enter
|
||||||
|
@data << @key
|
||||||
|
raise Exception, "E" if @data.last == "2"
|
||||||
|
return :data => @data
|
||||||
|
end
|
||||||
|
|
||||||
|
def exit(error)
|
||||||
|
prefix = error ? error.message : ""
|
||||||
|
@data << "#{prefix}#{@key}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
g = described_class.new
|
||||||
|
g.step step
|
||||||
|
g.step :two, step, g.input(:key2) => :key
|
||||||
|
g.step :three, step, g.input(:key3) => :key
|
||||||
|
|
||||||
|
# Run the actual steps
|
||||||
|
data = []
|
||||||
|
expect do
|
||||||
|
result = g.call(:data => data, :key => "1", :key2 => "2", :key3 => "3")
|
||||||
|
end.to raise_error(Exception)
|
||||||
|
|
||||||
|
# Verify the result hit the methods in the proper order
|
||||||
|
data.should == %W[1 2 E2 E1]
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue