aboutsummaryrefslogtreecommitdiffstats
path: root/Library
diff options
context:
space:
mode:
authorJack Nagel2014-10-20 17:07:54 -0500
committerJack Nagel2014-10-20 17:07:54 -0500
commit55e0f40d020062a03a56a50cc67c65c3dfea78c0 (patch)
treed291431797f8d5ce7fb46608e385898d1e3afe47 /Library
parent05ba3f0e3429bf326933e0ced66b2754fc1ee673 (diff)
downloadbrew-55e0f40d020062a03a56a50cc67c65c3dfea78c0.tar.bz2
Handle broken symlinks in resolve_any_conflicts
Fixes Homebrew/homebrew#33328.
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