diff --git a/lib/vagrant.rb b/lib/vagrant.rb index 7adf8402f..cc10d327c 100644 --- a/lib/vagrant.rb +++ b/lib/vagrant.rb @@ -92,6 +92,18 @@ module Vagrant @source_root ||= Pathname.new(File.expand_path('../../', __FILE__)) end + # Configure a Vagrant environment. The version specifies the version + # of the configuration that is expected by the block. The block, based + # on that version, configures the environment. + # + # Note that the block isn't run immediately. Instead, the configuration + # block is stored until later, and is run when an environment is loaded. + # + # @param [String] version Version of the configuration + def self.configure(version, &block) + Config.run(version, &block) + end + # Returns a superclass to use when creating a plugin for Vagrant. # Given a specific version, this returns a proper superclass to use # to register plugins for that version. diff --git a/lib/vagrant/config.rb b/lib/vagrant/config.rb index a6aef45aa..71b4e5b48 100644 --- a/lib/vagrant/config.rb +++ b/lib/vagrant/config.rb @@ -32,10 +32,10 @@ module Vagrant # # Note that the block is not run immediately. Instead, it's proc is stored # away for execution later. - def self.run(&block) + def self.run(version="1", &block) # Store it for later @last_procs ||= [] - @last_procs << block + @last_procs << [version, block] end # This is a method which will yield to a block and will capture all diff --git a/lib/vagrant/config/loader.rb b/lib/vagrant/config/loader.rb index e2df7ef04..fceed7d55 100644 --- a/lib/vagrant/config/loader.rb +++ b/lib/vagrant/config/loader.rb @@ -80,11 +80,10 @@ module Vagrant @load_order.each do |key| next if !@sources.has_key?(key) - @sources[key].each do |proc| + @sources[key].each do |version, proc| if !@config_cache.has_key?(proc) @logger.debug("Loading from: #{key} (evaluating)") - current = current_config_klass.load(proc) - @config_cache[proc] = current + @config_cache[proc] = current_config_klass.load(proc) else @logger.debug("Loading from: #{key} (cache)") end @@ -105,7 +104,11 @@ module Vagrant # the configuration object and are expected to mutate this # configuration object. def procs_for_source(source) - return [source] if source.is_a?(Proc) + # If the source is just a proc, we assume it is for the latest + # version of the configuration. This may be an ill assumption, + # but it made building the initial version of multi-versioned + # configuration easy to support the old sub-VM stuff. + return [[Config::VERSIONS_ORDER.last, source]] if source.is_a?(Proc) # Assume all string sources are actually pathnames source = Pathname.new(source) if source.is_a?(String) diff --git a/templates/commands/init/Vagrantfile.erb b/templates/commands/init/Vagrantfile.erb index d0cfa0d8a..ce577b14b 100644 --- a/templates/commands/init/Vagrantfile.erb +++ b/templates/commands/init/Vagrantfile.erb @@ -1,7 +1,7 @@ # -*- mode: ruby -*- # vi: set ft=ruby : -Vagrant::Config.run do |config| +Vagrant.configure("1") do |config| # All Vagrant configuration is done here. The most common configuration # options are documented and commented below. For a complete reference, # please see the online documentation at vagrantup.com. @@ -60,7 +60,7 @@ Vagrant::Config.run do |config| # end # Enable provisioning with chef solo, specifying a cookbooks path, roles - # path, and data_bags path (all relative to this Vagrantfile), and adding + # path, and data_bags path (all relative to this Vagrantfile), and adding # some recipes and/or roles. # # config.vm.provision :chef_solo do |chef| diff --git a/test/unit/vagrant/config_test.rb b/test/unit/vagrant/config_test.rb index 451745e23..aa90fdf77 100644 --- a/test/unit/vagrant/config_test.rb +++ b/test/unit/vagrant/config_test.rb @@ -7,6 +7,31 @@ describe Vagrant::Config do end end + it "should capture calls to `Vagrant.configure`" do + receiver = double() + + procs = described_class.capture_configures do + Vagrant.configure("1") do + receiver.one + end + + Vagrant.configure("2") do + receiver.two + end + end + + procs.should be_kind_of(Array) + procs.length.should == 2 + procs[0][0].should == "1" + procs[1][0].should == "2" + + # Verify the proper procs were captured + receiver.should_receive(:one).once.ordered + receiver.should_receive(:two).once.ordered + procs[0][1].call + procs[1][1].call + end + it "should capture configuration procs" do receiver = double() @@ -22,6 +47,20 @@ describe Vagrant::Config do # Verify that the proper proc was captured receiver.should_receive(:hello!).once - procs[0].call + procs[0][0].should == "1" + procs[0][1].call + end + + it "should capture the proper version" do + procs = described_class.capture_configures do + described_class.run("1") {} + described_class.run("2") {} + end + + # Verify the structure of the result + procs.should be_kind_of(Array) + procs.length.should == 2 + procs[0][0].should == "1" + procs[1][0].should == "2" end end