From 55e0f40d020062a03a56a50cc67c65c3dfea78c0 Mon Sep 17 00:00:00 2001 From: Jack Nagel Date: Mon, 20 Oct 2014 17:07:54 -0500 Subject: [PATCH] Handle broken symlinks in resolve_any_conflicts Fixes Homebrew/homebrew#33328. --- Library/Homebrew/keg.rb | 13 +++++++++++-- Library/Homebrew/test/test_keg.rb | 16 ++++++++++++++++ 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/Library/Homebrew/keg.rb b/Library/Homebrew/keg.rb index 0a7d9ae2c9..0cf6e122e7 100644 --- a/Library/Homebrew/keg.rb +++ b/Library/Homebrew/keg.rb @@ -328,11 +328,20 @@ class Keg return unless dst.symlink? src = dst.resolved_path + # src itself may be a symlink, so check lstat to ensure we are dealing with # a directory, and not a symlink pointing at a directory (which needs to be # treated as a file). In other words, we only want to resolve one symlink. - # If it isn't a directory, make_relative_symlink will raise an exception. - if src.lstat.directory? + + begin + stat = src.lstat + rescue Errno::ENOENT + # dst is a broken symlink, so remove it. + dst.unlink unless mode.dry_run + return + end + + if stat.directory? keg = Keg.for(src) dst.unlink unless mode.dry_run keg.link_dir(src, mode) { :mkpath } diff --git a/Library/Homebrew/test/test_keg.rb b/Library/Homebrew/test/test_keg.rb index 9f4cc11fba..0fb419f0d2 100644 --- a/Library/Homebrew/test/test_keg.rb +++ b/Library/Homebrew/test/test_keg.rb @@ -239,4 +239,20 @@ class LinkTests < Homebrew::TestCase a.uninstall b.uninstall end + + def test_removes_broken_symlinks_that_conflict_with_directories + a = HOMEBREW_CELLAR.join("a", "1.0") + a.join("lib", "foo").mkpath + + keg = Keg.new(a) + + link = HOMEBREW_PREFIX.join("lib", "foo") + link.parent.mkpath + link.make_symlink(@nonexistent) + + keg.link + ensure + keg.unlink + keg.uninstall + end end