diff --git a/CHANGELOG.md b/CHANGELOG.md index b4c4f47ef..2c1fad071 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ FEATURES: - New plugin type: synced folder implementation. This allows new ways of syncing folders to be added as plugins to Vagrant. + - The `Vagrant.require_version` function can be used at the top of a Vagrantfile + to enforce a minimum/maximum Vagrant version. - The `--debug` flag can be specified on any command now to get debug-level log output to ease reporting bugs. - You can now specify a memory using `vb.memory` setting with VirtualBox. diff --git a/lib/vagrant.rb b/lib/vagrant.rb index ee2b61a20..56c9b9fae 100644 --- a/lib/vagrant.rb +++ b/lib/vagrant.rb @@ -1,4 +1,5 @@ require 'log4r' +require 'rubygems' # Enable logging if it is requested. We do this before # anything else so that we can setup the output before @@ -230,6 +231,33 @@ module Vagrant $stderr = previous_stderr if previous_stderr $stdout = previous_stdout if previous_stdout end + + # This allows a Vagrantfile to specify the version of Vagrant that is + # required. You can specify a list of requirements which will all be checked + # against the running Vagrant version. + # + # This should be specified at the _top_ of any Vagrantfile. + # + # Examples are shown below: + # + # Vagrant.require_version(">= 1.3.5") + # Vagrant.require_version(">= 1.3.5", "< 1.4.0") + # Vagrant.require_version("~> 1.3.5") + # + def self.require_version(*requirements) + logger = Log4r::Logger.new("vagrant::root") + logger.info("Version requirements from Vagrantfile: #{requirements.inspect}") + + req = Gem::Requirement.new(*requirements) + if req.satisfied_by?(Gem::Version.new(VERSION)) + logger.info(" - Version requirements satisfied!") + return + end + + raise Errors::VagrantVersionBad, + requirements: requirements.join(", "), + version: VERSION + end end # Default I18n to load the en locale diff --git a/lib/vagrant/errors.rb b/lib/vagrant/errors.rb index 835ef0ac3..ac3ff70f5 100644 --- a/lib/vagrant/errors.rb +++ b/lib/vagrant/errors.rb @@ -544,6 +544,10 @@ module Vagrant error_key(:vagrantfile_syntax_error) end + class VagrantVersionBad < VagrantError + error_key(:vagrant_version_bad) + end + class VBoxManageError < VagrantError error_key(:vboxmanage_error) end diff --git a/templates/locales/en.yml b/templates/locales/en.yml index 4d42b3132..52091a1d1 100644 --- a/templates/locales/en.yml +++ b/templates/locales/en.yml @@ -614,6 +614,18 @@ en: message is reproduced below for convenience: %{file} + vagrant_version_bad: |- + This Vagrant environment has specified that it requires the Vagrant + version to satisfy the following version requirements: + + %{requirements} + + You are running Vagrant %{version}, which does not satisify + these requirements. Please change your Vagrant version or update + the Vagrantfile to allow this Vagrant version. However, be warned + that if the Vagrantfile has specified another version, it probably has + good reason to do so, and changing that may cause the environment to + not function properly. vboxmanage_error: |- There was an error while executing `VBoxManage`, a CLI used by Vagrant for controlling VirtualBox. The command and stderr is shown below. diff --git a/test/unit/vagrant_test.rb b/test/unit/vagrant_test.rb index 8cb0799e5..afe0e25bd 100644 --- a/test/unit/vagrant_test.rb +++ b/test/unit/vagrant_test.rb @@ -88,4 +88,16 @@ describe Vagrant do described_class.has_plugin?("i_dont_exist").should be_false end end + + describe "require_version" do + it "should succeed if valid range" do + expect { described_class.require_version(Vagrant::VERSION) }. + to_not raise_error + end + + it "should not succeed if bad range" do + expect { described_class.require_version("> #{Vagrant::VERSION}") }. + to raise_error(Vagrant::Errors::VagrantVersionBad) + end + end end diff --git a/website/docs/source/layouts/layout.erb b/website/docs/source/layouts/layout.erb index 08dfe2473..c743215d5 100644 --- a/website/docs/source/layouts/layout.erb +++ b/website/docs/source/layouts/layout.erb @@ -108,6 +108,7 @@ <% if sidebar_section == "vagrantfile" %>