diff --git a/lib/vagrant.rb b/lib/vagrant.rb index da8df7a82..1dd2542ab 100644 --- a/lib/vagrant.rb +++ b/lib/vagrant.rb @@ -140,7 +140,10 @@ module Vagrant # be used from the Vagrantfile to easily branch based on plugin # availability. def self.has_plugin?(name) - plugin("2").manager.registered.any? { |plugin| plugin.name == name } + manager = plugin("2").manager + + manager.required.any? { |gem_name| gem_name == name } || + manager.registered.any? { |plugin| plugin.name == name } end # Returns a superclass to use when creating a plugin for Vagrant. @@ -198,6 +201,7 @@ module Vagrant # Attempt the normal require begin require name + plugin("2").manager.plugin_required(name) rescue Exception => e # Since this is a rare case, we create a one-time logger here # in order to output the error diff --git a/lib/vagrant/plugin/v2/manager.rb b/lib/vagrant/plugin/v2/manager.rb index 1e71e0359..748586428 100644 --- a/lib/vagrant/plugin/v2/manager.rb +++ b/lib/vagrant/plugin/v2/manager.rb @@ -8,10 +8,12 @@ module Vagrant # those plugins as a single unit. class Manager attr_reader :registered + attr_reader :required def initialize @logger = Log4r::Logger.new("vagrant::plugin::v2::manager") @registered = [] + @required = [] end # This returns all the action hooks. @@ -164,10 +166,20 @@ module Vagrant end end + # This registers a required plugin. This should _NEVER_ be called by + # the public and should only be called from within Vagrant. + def plugin_required(gem_name) + if !@required.include?(gem_name) + @logger.info("Registered required plugin: #{gem_name}") + @required << gem_name + end + end + # This clears out all the registered plugins. This is only used by # unit tests and should not be called directly. def reset! @registered.clear + @required.clear end # This unregisters a plugin so that its components will no longer diff --git a/test/unit/vagrant/plugin/v2/manager_test.rb b/test/unit/vagrant/plugin/v2/manager_test.rb index d726f49b4..67dc989e1 100644 --- a/test/unit/vagrant/plugin/v2/manager_test.rb +++ b/test/unit/vagrant/plugin/v2/manager_test.rb @@ -188,4 +188,16 @@ describe Vagrant::Plugin::V2::Manager do instance.synced_folders[:foo].should == ["bar", 10] instance.synced_folders[:bar].should == ["baz", 50] end + + it "should list the required plugins" do + instance.plugin_required("foo") + instance.plugin_required("bar") + expect(instance.required).to eq(["foo", "bar"]) + end + + it "should list the required plugins only once" do + instance.plugin_required("foo") + instance.plugin_required("foo") + expect(instance.required).to eq(["foo"]) + end end diff --git a/test/unit/vagrant_test.rb b/test/unit/vagrant_test.rb index afe0e25bd..0d143d42b 100644 --- a/test/unit/vagrant_test.rb +++ b/test/unit/vagrant_test.rb @@ -54,6 +54,12 @@ describe Vagrant do to_not raise_error end + it "should add the gem name to plugin manager" do + expect(described_class.plugin("2").manager). + to receive(:plugin_required).with("set") + described_class.require_plugin "set" + 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) @@ -72,20 +78,27 @@ describe Vagrant do end describe "has_plugin?" do - after(:each) do - described_class.plugin('2').manager.reset! - end - - it "should return true if the plugin is installed" do - plugin = Class.new(described_class.plugin('2')) do + before(:each) do + Class.new(described_class.plugin("2")) do name "i_am_installed" end + manager.plugin_required("plugin_gem") + end + after(:each) do + manager.reset! + end + let(:manager) { described_class.plugin("2").manager } - described_class.has_plugin?("i_am_installed").should be_true + it "should find the installed plugin by the gem name" do + expect(described_class.has_plugin?("plugin_gem")).to be_true + end + + it "should find the installed plugin by the registered name" do + expect(described_class.has_plugin?("i_am_installed")).to be_true end it "should return false if the plugin is not installed" do - described_class.has_plugin?("i_dont_exist").should be_false + expect(described_class.has_plugin?("i_dont_exist")).to be_false end end