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:
		
							parent
							
								
									03f37bef79
								
							
						
					
					
						commit
						3570214d20
					
				@ -28,6 +28,15 @@ class Keg <Pathname
 | 
			
		||||
    raise "#{to_s} is not a directory" unless directory?
 | 
			
		||||
  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
 | 
			
		||||
    chmod_R 0777 # ensure we have permission to delete
 | 
			
		||||
    rmtree
 | 
			
		||||
@ -72,28 +81,50 @@ class Keg <Pathname
 | 
			
		||||
    return $n+$d
 | 
			
		||||
  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
 | 
			
		||||
  def link_dir foo
 | 
			
		||||
    root=self+foo
 | 
			
		||||
    root = self+foo
 | 
			
		||||
 | 
			
		||||
    root.find do |src|
 | 
			
		||||
      next if src == root
 | 
			
		||||
 | 
			
		||||
      dst=HOMEBREW_PREFIX+src.relative_path_from(self)
 | 
			
		||||
      dst = HOMEBREW_PREFIX+src.relative_path_from(self)
 | 
			
		||||
      dst.extend ObserverPathnameExtension
 | 
			
		||||
 | 
			
		||||
      if src.file?
 | 
			
		||||
        dst.make_relative_symlink src
 | 
			
		||||
      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
 | 
			
		||||
        # spotlight, or the open command and actual mac apps use an equivalent
 | 
			
		||||
        Find.prune if src.extname.to_s == '.app'
 | 
			
		||||
 | 
			
		||||
        case yield src.relative_path_from(root)
 | 
			
		||||
          when :skip then Find.prune
 | 
			
		||||
          when :mkpath then dst.mkpath
 | 
			
		||||
          else dst.make_relative_symlink src; Find.prune
 | 
			
		||||
        when :skip
 | 
			
		||||
          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
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user