Allow multiple formula to symlink the same directory

During the link step, if the destination symlink already exists, unlink it, and create a directory instead, then relink the original contents. Then continue linking the formula in question.

Fixes Homebrew/homebrew#62
This commit is contained in:
Max Howell 2009-10-23 16:03:38 +01:00
parent 03f37bef79
commit 3570214d20

View File

@ -28,6 +28,15 @@ class Keg <Pathname
raise "#{to_s} is not a directory" unless directory? raise "#{to_s} is not a directory" unless directory?
end end
# if path is a file in a keg then this will return the containing Keg object
def self.for path
while not path.root?
return Keg.new(path) if path.parent.parent == HOMEBREW_CELLAR
path = path.parent.realpath # realpath() prevents root? failing
end
raise "#{path} is not inside a keg"
end
def uninstall def uninstall
chmod_R 0777 # ensure we have permission to delete chmod_R 0777 # ensure we have permission to delete
rmtree rmtree
@ -72,28 +81,50 @@ class Keg <Pathname
return $n+$d return $n+$d
end end
private protected
def resolve_any_conflicts dst
# 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.parent+dst.readlink).cleanpath
keg = Keg.for(src)
dst.unlink
keg.link_dir(src) { :mkpath }
return true
end
end
# symlinks the contents of self+foo recursively into /usr/local/foo # symlinks the contents of self+foo recursively into /usr/local/foo
def link_dir foo def link_dir foo
root=self+foo root = self+foo
root.find do |src| root.find do |src|
next if src == root next if src == root
dst=HOMEBREW_PREFIX+src.relative_path_from(self) dst = HOMEBREW_PREFIX+src.relative_path_from(self)
dst.extend ObserverPathnameExtension dst.extend ObserverPathnameExtension
if src.file? if src.file?
dst.make_relative_symlink src dst.make_relative_symlink src
elsif src.directory? elsif src.directory?
# if the dst dir already exists, then great! walk the rest of the tree tho
next if dst.directory? and not dst.symlink?
# no need to put .app bundles in the path, the user can just use # no need to put .app bundles in the path, the user can just use
# spotlight, or the open command and actual mac apps use an equivalent # spotlight, or the open command and actual mac apps use an equivalent
Find.prune if src.extname.to_s == '.app' Find.prune if src.extname.to_s == '.app'
case yield src.relative_path_from(root) case yield src.relative_path_from(root)
when :skip then Find.prune when :skip
when :mkpath then dst.mkpath Find.prune
else dst.make_relative_symlink src; Find.prune when :mkpath
dst.mkpath unless resolve_any_conflicts(dst)
else
unless resolve_any_conflicts(dst)
dst.make_relative_symlink(src)
Find.prune
end
end end
end end
end end