Simpler "use the correct symlink" checks

When determining whether to remove a symlink during unlinking, we check
three things:

  (a) Is the destination a symlink?
  (b) Does the destination exist?
  (c) Does the destination resolve to the source path?

However, since we know that the source path exists, (b) is guaranteed if
(a) and (c) are true. Thus checking (b) is unnecessary.

Similarly, when creating a new symlink during linking, we first check to
see if the link already exists by checking the same three criteria.
Again, checking (b) is unnecessary here.

See also the expanded test coverage in b52b579b.

Addendum: although we know that the source path exists during unlinking,
it doesn't matter. If the source path does not exist, then we still know
we have a broken symlink pointing into the keg we are unlinking, and
removing that symlink is still safe.
This commit is contained in:
Jack Nagel 2014-07-04 17:22:58 -05:00
parent f666b76c39
commit 810b5838b2

View File

@ -192,7 +192,7 @@ class Keg
dirs << dst if dst.directory? && !dst.symlink? dirs << dst if dst.directory? && !dst.symlink?
# check whether the file to be unlinked is from the current keg first # check whether the file to be unlinked is from the current keg first
next if !dst.symlink? || !dst.exist? || src != dst.resolved_path next unless dst.symlink? && src == dst.resolved_path
dst.uninstall_info if dst.to_s =~ INFOFILE_RX dst.uninstall_info if dst.to_s =~ INFOFILE_RX
dst.unlink dst.unlink
@ -337,7 +337,7 @@ class Keg
end end
def make_relative_symlink dst, src, mode def make_relative_symlink dst, src, mode
if dst.symlink? && dst.exist? && dst.resolved_path == src if dst.symlink? && src == dst.resolved_path
puts "Skipping; link already exists: #{dst}" if ARGV.verbose? puts "Skipping; link already exists: #{dst}" if ARGV.verbose?
return return
end end