Keg: fix alias and versioned symlink handling.
Previously, `brew upgrade gcc@10` could get overzealous and remove the `LinkedKeg` record for `gcc@9`. This is bad because we then think `gcc@9` is unlinked when it is not and it causes a tonne of conflicts when trying to link `gcc@9` again. Instead, fix up the alias and versioned alias cleanup to be more precise and only delete the symlinks that point to the current `rack`, `opt_record` or `linked_keg_record` and unify the logic so it's performed consistently. While we're here: - don't `remove_old_aliases` every time we try to unlink a directory but just perform it once per `unlink` operation - remove the linked keg record on `uninstall`
This commit is contained in:
parent
9e26db3a55
commit
128aeba3a4
@ -301,28 +301,16 @@ class Keg
|
|||||||
# versioned aliases are handled below
|
# versioned aliases are handled below
|
||||||
next if a.match?(/.+@./)
|
next if a.match?(/.+@./)
|
||||||
|
|
||||||
alias_opt_symlink = opt/a
|
remove_alias_symlink(opt/a, opt_record)
|
||||||
if alias_opt_symlink.symlink? && alias_opt_symlink.exist?
|
remove_alias_symlink(linkedkegs/a, linked_keg_record)
|
||||||
alias_opt_symlink.delete if alias_opt_symlink.realpath == opt_record.realpath
|
|
||||||
elsif alias_opt_symlink.symlink? || alias_opt_symlink.exist?
|
|
||||||
alias_opt_symlink.delete
|
|
||||||
end
|
|
||||||
|
|
||||||
alias_linkedkegs_symlink = linkedkegs/a
|
|
||||||
alias_linkedkegs_symlink.delete if alias_linkedkegs_symlink.symlink? || alias_linkedkegs_symlink.exist?
|
|
||||||
end
|
end
|
||||||
|
|
||||||
Pathname.glob("#{opt_record}@*").each do |a|
|
Pathname.glob("#{opt_record}@*").each do |a|
|
||||||
a = a.basename.to_s
|
a = a.basename.to_s
|
||||||
next if aliases.include?(a)
|
next if aliases.include?(a)
|
||||||
|
|
||||||
alias_opt_symlink = opt/a
|
remove_alias_symlink(opt/a, rack)
|
||||||
if alias_opt_symlink.symlink? && alias_opt_symlink.exist? && rack == alias_opt_symlink.realpath.parent
|
remove_alias_symlink(linkedkegs/a, rack)
|
||||||
alias_opt_symlink.delete
|
|
||||||
end
|
|
||||||
|
|
||||||
alias_linkedkegs_symlink = linkedkegs/a
|
|
||||||
alias_linkedkegs_symlink.delete if alias_linkedkegs_symlink.symlink? || alias_linkedkegs_symlink.exist?
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -341,6 +329,7 @@ class Keg
|
|||||||
path.rmtree
|
path.rmtree
|
||||||
path.parent.rmdir_if_possible
|
path.parent.rmdir_if_possible
|
||||||
remove_opt_record if optlinked?
|
remove_opt_record if optlinked?
|
||||||
|
remove_linked_keg_record if linked?
|
||||||
remove_old_aliases
|
remove_old_aliases
|
||||||
remove_oldname_opt_record
|
remove_oldname_opt_record
|
||||||
rescue Errno::EACCES, Errno::ENOTEMPTY
|
rescue Errno::EACCES, Errno::ENOTEMPTY
|
||||||
@ -377,12 +366,12 @@ class Keg
|
|||||||
|
|
||||||
dst.uninstall_info if dst.to_s.match?(INFOFILE_RX)
|
dst.uninstall_info if dst.to_s.match?(INFOFILE_RX)
|
||||||
dst.unlink
|
dst.unlink
|
||||||
remove_old_aliases
|
|
||||||
Find.prune if src.directory?
|
Find.prune if src.directory?
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
unless options[:dry_run]
|
unless options[:dry_run]
|
||||||
|
remove_old_aliases
|
||||||
remove_linked_keg_record if linked?
|
remove_linked_keg_record if linked?
|
||||||
dirs.reverse_each(&:rmdir_if_possible)
|
dirs.reverse_each(&:rmdir_if_possible)
|
||||||
end
|
end
|
||||||
@ -659,6 +648,14 @@ class Keg
|
|||||||
raise LinkError.new(self, src.relative_path_from(path), dst, e)
|
raise LinkError.new(self, src.relative_path_from(path), dst, e)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def remove_alias_symlink(alias_symlink, alias_match_path)
|
||||||
|
if alias_symlink.symlink? && alias_symlink.exist?
|
||||||
|
alias_symlink.delete if alias_symlink.realpath == alias_match_path.realpath
|
||||||
|
elsif alias_symlink.symlink? || alias_symlink.exist?
|
||||||
|
alias_symlink.delete
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
||||||
# symlinks the contents of path+relative_dir recursively into #{HOMEBREW_PREFIX}/relative_dir
|
# symlinks the contents of path+relative_dir recursively into #{HOMEBREW_PREFIX}/relative_dir
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user