[rubygems/rubygems] Fix issue when cleaning up plugin stubs
When `gem uninstall <gem> --install-dir <dir>` is run, if the version removed had a plugin, and that same version happened to also be installed globally, then the plugin stub would fail to be removed. https://github.com/rubygems/rubygems/commit/4e2fa0be77
This commit is contained in:
parent
bd84236169
commit
965cb3ab4c
@ -906,9 +906,7 @@ class Gem::Specification < Gem::BasicSpecification
|
||||
# Return the directories that Specification uses to find specs.
|
||||
|
||||
def self.dirs
|
||||
@@dirs ||= Gem.path.collect do |dir|
|
||||
File.join dir, "specifications"
|
||||
end
|
||||
@@dirs ||= Gem::SpecificationRecord.dirs_from(Gem.path)
|
||||
end
|
||||
|
||||
##
|
||||
@ -918,7 +916,7 @@ class Gem::Specification < Gem::BasicSpecification
|
||||
def self.dirs=(dirs)
|
||||
reset
|
||||
|
||||
@@dirs = Array(dirs).map {|dir| File.join dir, "specifications" }
|
||||
@@dirs = Gem::SpecificationRecord.dirs_from(Array(dirs))
|
||||
end
|
||||
|
||||
extend Enumerable
|
||||
|
@ -2,6 +2,16 @@
|
||||
|
||||
module Gem
|
||||
class SpecificationRecord
|
||||
def self.dirs_from(paths)
|
||||
paths.map do |path|
|
||||
File.join(path, "specifications")
|
||||
end
|
||||
end
|
||||
|
||||
def self.from_path(path)
|
||||
new(dirs_from([path]))
|
||||
end
|
||||
|
||||
def initialize(dirs)
|
||||
@all = nil
|
||||
@stubs = nil
|
||||
|
@ -49,7 +49,8 @@ class Gem::Uninstaller
|
||||
# TODO: document the valid options
|
||||
@gem = gem
|
||||
@version = options[:version] || Gem::Requirement.default
|
||||
@gem_home = File.realpath(options[:install_dir] || Gem.dir)
|
||||
@install_dir = options[:install_dir]
|
||||
@gem_home = File.realpath(@install_dir || Gem.dir)
|
||||
@force_executables = options[:executables]
|
||||
@force_all = options[:all]
|
||||
@force_ignore = options[:ignore]
|
||||
@ -69,7 +70,7 @@ 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]
|
||||
@user_install = options[:user_install] unless @install_dir
|
||||
|
||||
# Optimization: populated during #uninstall
|
||||
@default_specs_matching_uninstall_params = []
|
||||
@ -290,7 +291,8 @@ class Gem::Uninstaller
|
||||
# Regenerates plugin wrappers after removal.
|
||||
|
||||
def regenerate_plugins
|
||||
latest = Gem::Specification.latest_spec_for(@spec.name)
|
||||
specification_record = @install_dir ? Gem::SpecificationRecord.from_path(@install_dir) : Gem::Specification.specification_record
|
||||
latest = specification_record.latest_spec_for(@spec.name)
|
||||
return if latest.nil?
|
||||
|
||||
regenerate_plugins_for(latest, plugin_dir_for(@spec))
|
||||
|
@ -213,6 +213,37 @@ class TestGemUninstaller < Gem::InstallerTestCase
|
||||
Gem::Uninstaller.new(@spec.name, executables: true, install_dir: install_dir).uninstall
|
||||
|
||||
assert File.exist?(plugin_path), "plugin unintentionally removed"
|
||||
refute File.exist?(install_dir_plugin_path), "plugin not removed"
|
||||
end
|
||||
|
||||
def test_uninstall_with_install_dir_regenerates_plugins
|
||||
write_file File.join(@tempdir, "lib", "rubygems_plugin.rb") do |io|
|
||||
io.write "# do nothing"
|
||||
end
|
||||
|
||||
@spec.files += %w[lib/rubygems_plugin.rb]
|
||||
|
||||
install_dir = "#{@gemhome}2"
|
||||
|
||||
package = Gem::Package.build(@spec)
|
||||
|
||||
spec_v9 = @spec.dup
|
||||
spec_v9.version = "9"
|
||||
package_v9 = Gem::Package.build(spec_v9)
|
||||
|
||||
Gem::Installer.at(package, force: true, install_dir: install_dir).install
|
||||
Gem::Installer.at(package_v9, force: true, install_dir: install_dir).install
|
||||
|
||||
install_dir_plugin_path = File.join install_dir, "plugins/a_plugin.rb"
|
||||
assert File.exist?(install_dir_plugin_path), "plugin not written"
|
||||
|
||||
Gem::Specification.dirs = [install_dir]
|
||||
Gem::Uninstaller.new(@spec.name, version: "9", executables: true, install_dir: install_dir).uninstall
|
||||
assert File.exist?(install_dir_plugin_path), "plugin unintentionally removed"
|
||||
|
||||
Gem::Specification.dirs = [install_dir]
|
||||
Gem::Uninstaller.new(@spec.name, executables: true, install_dir: install_dir).uninstall
|
||||
refute File.exist?(install_dir_plugin_path), "plugin not removed"
|
||||
end
|
||||
|
||||
def test_remove_plugins_user_installed
|
||||
|
Loading…
x
Reference in New Issue
Block a user