From 1eafe3bc354626b3d54164c263a5c57313d8eeeb Mon Sep 17 00:00:00 2001 From: Jack Nagel Date: Sat, 12 Jul 2014 19:56:58 -0500 Subject: [PATCH] Handle conflicts where links point at symlinks Fixes Homebrew/homebrew#30664. --- Library/Homebrew/keg.rb | 11 ++++++----- Library/Homebrew/test/test_keg.rb | 16 ++++++++++++++++ 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/Library/Homebrew/keg.rb b/Library/Homebrew/keg.rb index 45aab7eb46..9b9625fbc1 100644 --- a/Library/Homebrew/keg.rb +++ b/Library/Homebrew/keg.rb @@ -322,11 +322,12 @@ class Keg private def resolve_any_conflicts dst, mode - # if it isn't a directory then a severe conflict is about to happen. Let - # it, and the exception that is generated will message to the user about - # the situation - if dst.symlink? and dst.directory? - src = dst.resolved_path + 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 onlly want to resolve one symlink. + # If it isn't a directory, make_relative_symlink will raise an exception. + if dst.symlink? && src.lstat.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 e415be4334..fa7d591dc6 100644 --- a/Library/Homebrew/test/test_keg.rb +++ b/Library/Homebrew/test/test_keg.rb @@ -217,4 +217,20 @@ class LinkTests < Homebrew::TestCase assert_predicate link.resolved_path, :symlink? assert_predicate link.lstat, :symlink? end + + def test_links_to_symlinks_are_not_removed + a = HOMEBREW_CELLAR.join("a", "1.0") + b = HOMEBREW_CELLAR.join("b", "1.0") + + a.join("lib", "example").mkpath + a.join("lib", "example2").make_symlink "example" + b.join("lib", "example2").mkpath + + Keg.new(a).link + + lib = HOMEBREW_PREFIX.join("lib") + assert_equal 2, lib.children.length + assert_raises(Keg::ConflictError) { Keg.new(b).link } + assert_equal 2, lib.children.length + end end