summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/rubygems/uninstaller.rb41
-rw-r--r--test/rubygems/test_gem_uninstaller.rb11
2 files changed, 45 insertions, 7 deletions
diff --git a/lib/rubygems/uninstaller.rb b/lib/rubygems/uninstaller.rb
index 3bc202863c..87a5ef770f 100644
--- a/lib/rubygems/uninstaller.rb
+++ b/lib/rubygems/uninstaller.rb
@@ -70,6 +70,9 @@ class Gem::Uninstaller
# only add user directory if install_dir is not set
@user_install = false
@user_install = options[:user_install] unless options[:install_dir]
+
+ # Optimization: populated during #uninstall
+ @default_specs_matching_uninstall_params = []
end
##
@@ -98,10 +101,8 @@ class Gem::Uninstaller
default_specs, list = list.partition do |spec|
spec.default_gem?
end
-
- default_specs.each do |default_spec|
- say "Gem #{default_spec.full_name} cannot be uninstalled because it is a default gem"
- end
+ warn_cannot_uninstall_default_gems(default_specs - list)
+ @default_specs_matching_uninstall_params = default_specs
list, other_repo_specs = list.partition do |spec|
@gem_home == spec.base_dir or
@@ -273,7 +274,7 @@ class Gem::Uninstaller
end
safe_delete { FileUtils.rm_r gemspec }
- say "Successfully uninstalled #{spec.full_name}"
+ announce_deletion_of(spec)
Gem::Specification.reset
end
@@ -376,4 +377,34 @@ class Gem::Uninstaller
raise e
end
+
+ private
+
+ def announce_deletion_of(spec)
+ name = spec.full_name
+ say "Successfully uninstalled #{name}"
+ if default_spec_matches?(spec)
+ say(
+ "There was both a regular copy and a default copy of #{name}. The " \
+ "regular copy was successfully uninstalled, but the default copy " \
+ "was left around because default gems can't be removed."
+ )
+ end
+ end
+
+ # @return true if the specs of any default gems are `==` to the given `spec`.
+ def default_spec_matches?(spec)
+ !default_specs_that_match(spec).empty?
+ end
+
+ # @return [Array] specs of default gems that are `==` to the given `spec`.
+ def default_specs_that_match(spec)
+ @default_specs_matching_uninstall_params.select {|default_spec| spec == default_spec }
+ end
+
+ def warn_cannot_uninstall_default_gems(specs)
+ specs.each do |spec|
+ say "Gem #{spec.full_name} cannot be uninstalled because it is a default gem"
+ end
+ end
end
diff --git a/test/rubygems/test_gem_uninstaller.rb b/test/rubygems/test_gem_uninstaller.rb
index a002c0c7c8..9e18972864 100644
--- a/test/rubygems/test_gem_uninstaller.rb
+++ b/test/rubygems/test_gem_uninstaller.rb
@@ -295,8 +295,15 @@ class TestGemUninstaller < Gem::InstallerTestCase
uninstaller = Gem::Uninstaller.new spec.name, :executables => true
- uninstaller.uninstall
-
+ ui = Gem::MockGemUi.new "1\ny\n"
+ use_ui ui do
+ uninstaller.uninstall
+ end
+ expected = "Successfully uninstalled default-2\n" \
+ "There was both a regular copy and a default copy of default-2. The " \
+ "regular copy was successfully uninstalled, but the default copy " \
+ "was left around because default gems can't be removed.\n"
+ assert_equal expected, ui.output
assert_path_not_exist spec.gem_dir
end