diff --git a/lib/bundler/plugin.rb b/lib/bundler/plugin.rb index e6aaa6b464..edd1900135 100644 --- a/lib/bundler/plugin.rb +++ b/lib/bundler/plugin.rb @@ -62,7 +62,8 @@ module Bundler if names.any? names.each do |name| if index.installed?(name) - Bundler.rm_rf(index.plugin_path(name)) + path = index.plugin_path(name).to_s + Bundler.rm_rf(path) if index.installed_in_plugin_root?(name) index.unregister_plugin(name) Bundler.ui.info "Uninstalled plugin #{name}" else diff --git a/lib/bundler/plugin/index.rb b/lib/bundler/plugin/index.rb index a2d5eaa38a..c2ab8f90da 100644 --- a/lib/bundler/plugin/index.rb +++ b/lib/bundler/plugin/index.rb @@ -136,6 +136,14 @@ module Bundler @hooks[event] || [] end + # This plugin is installed inside the .bundle/plugin directory, + # and thus is managed solely by Bundler + def installed_in_plugin_root?(name) + return false unless (path = installed?(name)) + + path.start_with?("#{Plugin.root}/") + end + private # Reads the index file from the directory and initializes the instance diff --git a/spec/bundler/plugins/uninstall_spec.rb b/spec/bundler/plugins/uninstall_spec.rb index 8180241911..555c6a7002 100644 --- a/spec/bundler/plugins/uninstall_spec.rb +++ b/spec/bundler/plugins/uninstall_spec.rb @@ -30,6 +30,31 @@ RSpec.describe "bundler plugin uninstall" do plugin_should_not_be_installed("foo") end + it "doesn't wipe out path plugins" do + build_lib "path_plugin" do |s| + s.write "plugins.rb" + end + path = lib_path("path_plugin-1.0") + expect(path).to be_a_directory + + allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile) + + install_gemfile <<-G + source '#{file_uri_for(gem_repo2)}' + plugin 'path_plugin', :path => "#{path}" + gem 'rack', '1.0.0' + G + + plugin_should_be_installed("path_plugin") + expect(Bundler::Plugin.index.plugin_path("path_plugin")).to eq path + + bundle "plugin uninstall path_plugin" + expect(out).to include("Uninstalled plugin path_plugin") + plugin_should_not_be_installed("path_plugin") + # the actual gem still exists though + expect(path).to be_a_directory + end + describe "with --all" do it "uninstalls all installed plugins" do bundle "plugin install foo kung-foo --source #{file_uri_for(gem_repo2)}"