From 2cc56119b7fdb6c19477d4a02c68a5fe4dabd75b Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Mon, 3 Feb 2014 22:03:20 +0100 Subject: [PATCH] kernel/v2: support the preserve_order option (documented) --- plugins/kernel_v2/config/vm.rb | 14 ++++++++---- plugins/kernel_v2/config/vm_provisioner.rb | 7 ++++++ test/unit/plugins/kernel_v2/config/vm_test.rb | 22 +++++++++++++++++++ 3 files changed, 39 insertions(+), 4 deletions(-) diff --git a/plugins/kernel_v2/config/vm.rb b/plugins/kernel_v2/config/vm.rb index 773771c56..0c8a6e859 100644 --- a/plugins/kernel_v2/config/vm.rb +++ b/plugins/kernel_v2/config/vm.rb @@ -108,21 +108,26 @@ module VagrantPlugins # Merge provisioners. First we deal with overrides and making # sure the ordering is good there. Then we merge them. - new_provs = [] + new_provs = [] + other_provs = other.provisioners.dup @provisioners.each do |p| if p.id - other_p = other.provisioners.find { |o| p.id == o.id } + other_p = other_provs.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 + next if !other_p.preserve_order + + # We're preserving order, delete from other + p = other_p + other_provs.delete(other_p) end end # There is an override, merge it into the new_provs << p.dup end - other.provisioners.each do |p| + other_provs.each do |p| new_provs << p.dup end result.instance_variable_set(:@provisioners, new_provs) @@ -254,6 +259,7 @@ module VagrantPlugins @provisioners << prov end + prov.preserve_order = !!options[:preserve_order] prov.add_config(options, &block) nil end diff --git a/plugins/kernel_v2/config/vm_provisioner.rb b/plugins/kernel_v2/config/vm_provisioner.rb index 3e479d0be..af4222f11 100644 --- a/plugins/kernel_v2/config/vm_provisioner.rb +++ b/plugins/kernel_v2/config/vm_provisioner.rb @@ -20,6 +20,12 @@ module VagrantPlugins # @return [Object] attr_accessor :config + # Whether or not to preserve the order when merging this with a + # parent scope. + # + # @return [Boolean] + attr_accessor :preserve_order + def initialize(id, name) @logger = Log4r::Logger.new("vagrant::config::vm::provisioner") @logger.debug("Provisioner defined: #{name}") @@ -28,6 +34,7 @@ module VagrantPlugins @id = id @invalid = false @name = name + @preserve_order = false # Attempt to find the provisioner... if !Vagrant.plugin("2").manager.provisioners[name] diff --git a/test/unit/plugins/kernel_v2/config/vm_test.rb b/test/unit/plugins/kernel_v2/config/vm_test.rb index dd4f1f674..e7af9921c 100644 --- a/test/unit/plugins/kernel_v2/config/vm_test.rb +++ b/test/unit/plugins/kernel_v2/config/vm_test.rb @@ -74,6 +74,28 @@ describe VagrantPlugins::Kernel_V2::VMConfig do expect(merged_provs[2].config.inline). to eq("foo-overload") end + + it "can preserve order for 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", + preserve_order: true) + + merged = subject.merge(other) + merged_provs = merged.provisioners + + expect(merged_provs.length).to eql(3) + expect(merged_provs[0].config.inline). + to eq("foo-overload") + expect(merged_provs[1].config.inline). + to eq("other") + expect(merged_provs[2].config.inline). + to eq("bar") + end end end end