Builders are merged when using hooks. [GH-1555]

This commit is contained in:
Mitchell Hashimoto 2013-04-07 14:17:40 -07:00
parent 9f49b9298e
commit f203c29fbb
3 changed files with 47 additions and 2 deletions

View File

@ -58,6 +58,8 @@ BUG FIXES:
for VirtualBox shared folders. for VirtualBox shared folders.
- Output the proper clear line text for shells in Cygwin when - Output the proper clear line text for shells in Cygwin when
reporting dynamic progress. reporting dynamic progress.
- When using `Builder` instances for hooks, the builders will be
merged for the proper before/after chain. [GH-1555]
## 1.1.6 (April 3, 2013) ## 1.1.6 (April 3, 2013)

View File

@ -74,7 +74,14 @@ module Vagrant
def insert(index, middleware, *args, &block) def insert(index, middleware, *args, &block)
index = self.index(index) unless index.is_a?(Integer) index = self.index(index) unless index.is_a?(Integer)
raise "no such middleware to insert before: #{index.inspect}" unless index raise "no such middleware to insert before: #{index.inspect}" unless index
stack.insert(index, [middleware, args, block])
if middleware.kind_of?(Builder)
middleware.stack.reverse.each do |stack_item|
stack.insert(index, stack_item)
end
else
stack.insert(index, [middleware, args, block])
end
end end
alias_method :insert_before, :insert alias_method :insert_before, :insert

View File

@ -6,7 +6,14 @@ describe Vagrant::Action::Builder do
# This returns a proc that can be used with the builder # This returns a proc that can be used with the builder
# that simply appends data to an array in the env. # that simply appends data to an array in the env.
def appender_proc(data) def appender_proc(data)
Proc.new { |env| env[:data] << data } result = Proc.new { |env| env[:data] << data }
# Define a to_s on it for helpful output
result.define_singleton_method(:to_s) do
"<Appender: #{data}>"
end
result
end end
context "copying" do context "copying" do
@ -119,6 +126,35 @@ describe Vagrant::Action::Builder do
data[:data].should == [1, 2, 3] data[:data].should == [1, 2, 3]
end end
it "merges middleware stacks of other builders" do
wrapper_class = Proc.new do |letter|
Class.new do
def initialize(app, env)
@app = app
end
define_method(:call) do |env|
env[:data] << "#{letter}1"
@app.call(env)
env[:data] << "#{letter}2"
end
end
end
proc2 = appender_proc(2)
subject.use appender_proc(1)
subject.use proc2
builder = described_class.new
builder.use wrapper_class.call("A")
builder.use wrapper_class.call("B")
subject.insert(proc2, builder)
subject.call(data)
data[:data].should == [1, "A1", "B1", 2, "B2", "A2"]
end
it "raises an exception if an invalid object given for insert" do it "raises an exception if an invalid object given for insert" do
expect { subject.insert "object", appender_proc(1) }. expect { subject.insert "object", appender_proc(1) }.
to raise_error(RuntimeError) to raise_error(RuntimeError)