diff --git a/plugins/commands/plugin/action/install_gem.rb b/plugins/commands/plugin/action/install_gem.rb index bb5d37423..c9e6e967a 100644 --- a/plugins/commands/plugin/action/install_gem.rb +++ b/plugins/commands/plugin/action/install_gem.rb @@ -50,11 +50,13 @@ module VagrantPlugins env[:ui].info(I18n.t("vagrant.commands.plugin.installing", :name => plugin_name_label)) - # TODO: support version, pre-release, custom sources manager = Vagrant::Plugin::Manager.instance plugin_spec = manager.install_plugin( plugin_name, version: version, require: entrypoint) + # Record it so we can uninstall if something goes wrong + @installed_plugin_name = plugin_spec.name + # Tell the user env[:ui].success(I18n.t("vagrant.commands.plugin.installed", :name => plugin_spec.name, diff --git a/test/unit/plugins/commands/plugin/action/install_gem_test.rb b/test/unit/plugins/commands/plugin/action/install_gem_test.rb new file mode 100644 index 000000000..918c63cdc --- /dev/null +++ b/test/unit/plugins/commands/plugin/action/install_gem_test.rb @@ -0,0 +1,83 @@ +require File.expand_path("../../../../../base", __FILE__) + +describe VagrantPlugins::CommandPlugin::Action::InstallGem do + let(:app) { lambda { |env| } } + let(:env) {{ + ui: Vagrant::UI::Silent.new + }} + + let(:manager) { double("manager") } + + subject { described_class.new(app, env) } + + before do + Vagrant::Plugin::Manager.stub(instance: manager) + end + + describe "#call" do + it "should install the plugin" do + spec = Gem::Specification.new + manager.should_receive(:install_plugin).with( + "foo", version: nil, require: nil).once.and_return(spec) + + app.should_receive(:call).with(env).once + + env[:plugin_name] = "foo" + subject.call(env) + end + + it "should specify the version if given" do + spec = Gem::Specification.new + manager.should_receive(:install_plugin).with( + "foo", version: "bar", require: nil).once.and_return(spec) + + app.should_receive(:call).with(env).once + + env[:plugin_name] = "foo" + env[:plugin_version] = "bar" + subject.call(env) + end + + it "should specify the entrypoint if given" do + spec = Gem::Specification.new + manager.should_receive(:install_plugin).with( + "foo", version: "bar", require: "baz").once.and_return(spec) + + app.should_receive(:call).with(env).once + + env[:plugin_entry_point] = "baz" + env[:plugin_name] = "foo" + env[:plugin_version] = "bar" + subject.call(env) + end + end + + describe "#recover" do + it "should do nothing by default" do + subject.recover(env) + end + + context "with a successful plugin install" do + let(:action_runner) { double("action_runner") } + + before do + spec = Gem::Specification.new + spec.name = "foo" + manager.stub(install_plugin: spec) + + env[:plugin_name] = "foo" + subject.call(env) + + env[:action_runner] = action_runner + end + + it "should uninstall the plugin" do + action_runner.should_receive(:run).with do |action, newenv| + expect(newenv[:plugin_name]).to eql("foo") + end + + subject.recover(env) + end + end + end +end