From bc0643613a30a3848bbccc303d001783bb689877 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Sun, 6 May 2012 14:01:10 -0700 Subject: [PATCH] Vagrant.require_plugin [GH-916] --- CHANGELOG.md | 3 ++- lib/vagrant.rb | 16 ++++++++++++++++ lib/vagrant/errors.rb | 5 +++++ templates/locales/en.yml | 3 +++ test/unit/vagrant_test.rb | 13 +++++++++++++ 5 files changed, 39 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3fb10b693..4289948e2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,8 @@ not be _functional_ in future versions of Vagrant). - Plugins no longer "autoload" by simply gem installing them. This increases Vagrant's initial startup time considerably. To replace this, you must now - explicitly require plugins in the `~/.vagrantrc` file. + explicitly require plugins in the `~/.vagrantrc` file, using + `Vagrant.require_plugin`. - Improve the SSH "ready?" check. [GH-841] - Human friendly error if connection times out for HTTP downloads. [GH-849] - Detect when the VirtualBox installation is incomplete and error. [GH-846] diff --git a/lib/vagrant.rb b/lib/vagrant.rb index 1783dc27f..7adf8402f 100644 --- a/lib/vagrant.rb +++ b/lib/vagrant.rb @@ -107,6 +107,22 @@ module Vagrant # Raise an error that the plugin version is invalid raise ArgumentError, "Invalid plugin version API: #{version}" end + + # This should be used instead of Ruby's built-in `require` in order to + # load a Vagrant plugin. This will load the given plugin by first doing + # a normal `require`, giving a nice error message if things go wrong, + # and second by verifying that a Vagrant plugin was actually defined in + # the process. + # + # @param [String] name Name of the plugin to load. + def self.require_plugin(name) + # Attempt the normal require + begin + require name + rescue LoadError + raise Errors::PluginLoadError, :plugin => name + end + end end # # Default I18n to load the en locale diff --git a/lib/vagrant/errors.rb b/lib/vagrant/errors.rb index 6f17fbfab..9a192386a 100644 --- a/lib/vagrant/errors.rb +++ b/lib/vagrant/errors.rb @@ -298,6 +298,11 @@ module Vagrant error_key(:dotfile_error, "vagrant.actions.vm.persist") end + class PluginLoadError < VagrantError + status_code(81) + error_key(:plugin_load_error) + end + class SCPUnavailable < VagrantError status_code(56) error_key(:scp_unavailable) diff --git a/templates/locales/en.yml b/templates/locales/en.yml index 1d70599d0..deac589cb 100644 --- a/templates/locales/en.yml +++ b/templates/locales/en.yml @@ -83,6 +83,9 @@ en: no_env: |- A Vagrant environment is required to run this command. Run `vagrant init` to set one up. + plugin_load_error: |- + The plugin "%{plugin}" could not be found. Please make sure that it is + properly installed via `vagrant gem`. port_collision_resume: |- This VM cannot be resumed, because the forwarded ports would collide with another running virtual machine. Normally, Vagrant will attempt to fix this diff --git a/test/unit/vagrant_test.rb b/test/unit/vagrant_test.rb index a97ad657a..5dd502aa8 100644 --- a/test/unit/vagrant_test.rb +++ b/test/unit/vagrant_test.rb @@ -15,4 +15,17 @@ describe Vagrant do to raise_error(ArgumentError) end end + + describe "requiring plugins" do + it "should require the plugin given" do + # For now, just require a stdlib + expect { described_class.require_plugin "set" }. + to_not raise_error + end + + it "should raise an error if the file doesn't exist" do + expect { described_class.require_plugin("i_dont_exist") }. + to raise_error(Vagrant::Errors::PluginLoadError) + end + end end