Keg: allow overwriting same-formula conflicts

This is weird. We're seeing some installs where formulae
have no opt prefix and no linked keg record, *but* still
ended up linked into the prefix. Upgrades will blow up in
this case because the old symlinks won't get deleted and
Homebrew will report a nonsensical error message about
not being able to link over another link from the same
formula!

Since the optpath is either missing or pointing to the
wrong destination at this point, the checks for conflict
linking above will have failed. We should instead be safe
to simply blow away these conflicting symlinks and replace
them with the new targets.

Fixes https://github.com/Homebrew/homebrew-core/issues/68866.
This commit is contained in:
Misty De Meo 2021-01-12 23:46:39 -08:00
parent 8cf9a52b29
commit 53fe6b518f

View File

@ -647,6 +647,18 @@ class Keg
dst.delete if options[:overwrite] && (dst.exist? || dst.symlink?) dst.delete if options[:overwrite] && (dst.exist? || dst.symlink?)
dst.make_relative_symlink(src) dst.make_relative_symlink(src)
rescue Errno::EEXIST => e rescue Errno::EEXIST => e
# We're linking a different version of the same formula
# Note that the AlreadyLinkedError check above *should*
# have caught this, but there are circumstances in which
# we end up with symlinks for a formula even though
# it seems to be missing an optlink. In that case,
# we should be clear to blow those away and replace
# them.
if dst.symlink? && Keg.for(dst).name == name
dst.unlink
retry
end
raise ConflictError.new(self, src.relative_path_from(path), dst, e) if dst.exist? raise ConflictError.new(self, src.relative_path_from(path), dst, e) if dst.exist?
if dst.symlink? if dst.symlink?