From 3aaa57cac930f348f0eb721280f998b7364dc086 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Mon, 3 Feb 2014 21:30:01 +0100 Subject: [PATCH] kernel/v2: support merging properly --- plugins/kernel_v2/config/vm.rb | 22 ++++++++++- plugins/kernel_v2/config/vm_provisioner.rb | 7 +++- test/unit/plugins/kernel_v2/config/vm_test.rb | 39 +++++++++++++++++++ 3 files changed, 66 insertions(+), 2 deletions(-) diff --git a/plugins/kernel_v2/config/vm.rb b/plugins/kernel_v2/config/vm.rb index b593eb643..773771c56 100644 --- a/plugins/kernel_v2/config/vm.rb +++ b/plugins/kernel_v2/config/vm.rb @@ -65,7 +65,6 @@ module VagrantPlugins other_networks = other.instance_variable_get(:@__networks) result.instance_variable_set(:@__networks, @__networks.merge(other_networks)) - result.instance_variable_set(:@provisioners, @provisioners + other.provisioners) # Merge defined VMs by first merging the defined VM keys, # preserving the order in which they were defined. @@ -107,6 +106,27 @@ module VagrantPlugins new_overrides[key] += blocks end + # Merge provisioners. First we deal with overrides and making + # sure the ordering is good there. Then we merge them. + new_provs = [] + @provisioners.each do |p| + if p.id + other_p = other.provisioners.find { |o| p.id == o.id } + if other_p + # There is an override. Take it. + other_p.config = p.config.merge(other_p.config) + next + end + end + + # There is an override, merge it into the + new_provs << p.dup + end + other.provisioners.each do |p| + new_provs << p.dup + end + result.instance_variable_set(:@provisioners, new_provs) + # Merge synced folders. other_folders = other.instance_variable_get(:@__synced_folders) new_folders = {} diff --git a/plugins/kernel_v2/config/vm_provisioner.rb b/plugins/kernel_v2/config/vm_provisioner.rb index 76939bee0..3e479d0be 100644 --- a/plugins/kernel_v2/config/vm_provisioner.rb +++ b/plugins/kernel_v2/config/vm_provisioner.rb @@ -18,7 +18,7 @@ module VagrantPlugins # The configuration associated with the provisioner, if there is any. # # @return [Object] - attr_reader :config + attr_accessor :config def initialize(id, name) @logger = Log4r::Logger.new("vagrant::config::vm::provisioner") @@ -45,6 +45,11 @@ module VagrantPlugins end end + def initialize_copy(orig) + super + @config = @config.dup if @config + end + def add_config(**options, &block) return if invalid? diff --git a/test/unit/plugins/kernel_v2/config/vm_test.rb b/test/unit/plugins/kernel_v2/config/vm_test.rb index 983718d12..dd4f1f674 100644 --- a/test/unit/plugins/kernel_v2/config/vm_test.rb +++ b/test/unit/plugins/kernel_v2/config/vm_test.rb @@ -36,5 +36,44 @@ describe VagrantPlugins::Kernel_V2::VMConfig do expect(r.length).to eql(1) expect(r[0]).to be_invalid end + + describe "merging" do + it "copies the configs" do + subject.provision("shell", inline: "foo") + subject_provs = subject.provisioners + + other = described_class.new + other.provision("shell", inline: "bar") + + merged = subject.merge(other) + merged_provs = merged.provisioners + + expect(merged_provs.length).to eql(2) + expect(merged_provs[0].config.inline). + to eq(subject_provs[0].config.inline) + expect(merged_provs[0].config.object_id). + to_not eq(subject_provs[0].config.object_id) + end + + it "uses the proper order when merging overrides" do + subject.provision("shell", inline: "foo", id: "original") + subject.provision("shell", inline: "other", id: "other") + + other = described_class.new + other.provision("shell", inline: "bar") + other.provision("shell", inline: "foo-overload", id: "original") + + merged = subject.merge(other) + merged_provs = merged.provisioners + + expect(merged_provs.length).to eql(3) + expect(merged_provs[0].config.inline). + to eq("other") + expect(merged_provs[1].config.inline). + to eq("bar") + expect(merged_provs[2].config.inline). + to eq("foo-overload") + end + end end end