aboutsummaryrefslogtreecommitdiffstats
path: root/Library
diff options
context:
space:
mode:
Diffstat (limited to 'Library')
-rw-r--r--Library/Homebrew/keg.rb13
-rw-r--r--Library/Homebrew/test/test_keg.rb16
2 files changed, 27 insertions, 2 deletions
diff --git a/Library/Homebrew/keg.rb b/Library/Homebrew/keg.rb
index 0a7d9ae2c..0cf6e122e 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 9f4cc11fb..0fb419f0d 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