127 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
			
		
		
	
	
			127 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
| require 'extend/pathname'
 | |
| 
 | |
| class Keg <Pathname
 | |
|   def initialize path
 | |
|     super path
 | |
|     raise "#{to_s} is not a valid keg" unless parent.parent.realpath == HOMEBREW_CELLAR.realpath
 | |
|     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
 | |
|     path = path.realpath
 | |
|     while not path.root?
 | |
|       return Keg.new(path) if path.parent.parent == HOMEBREW_CELLAR.realpath
 | |
|       path = path.parent.realpath # realpath() prevents root? failing
 | |
|     end
 | |
|     raise NotAKegError, "#{path} is not inside a keg"
 | |
|   end
 | |
| 
 | |
|   def uninstall
 | |
|     chmod_R 0777 # ensure we have permission to delete
 | |
|     rmtree
 | |
|     parent.rmdir_if_possible
 | |
|   end
 | |
| 
 | |
|   def unlink
 | |
|     n=0
 | |
|     Pathname.new(self).find do |src|
 | |
|       next if src == self
 | |
|       dst=HOMEBREW_PREFIX+src.relative_path_from(self)
 | |
|       next unless dst.symlink?
 | |
|       dst.unlink
 | |
|       n+=1
 | |
|       Find.prune if src.directory?
 | |
|     end
 | |
|     n
 | |
|   end
 | |
| 
 | |
|   def link
 | |
|     $n=0
 | |
|     $d=0
 | |
| 
 | |
|     share_mkpaths=%w[aclocal doc info locale man]+(1..8).collect{|x|"man/man#{x}"}
 | |
| 
 | |
|     # yeah indeed, you have to force anything you need in the main tree into
 | |
|     # these dirs REMEMBER that *NOT* everything needs to be in the main tree
 | |
|     link_dir('etc') {:mkpath}
 | |
|     link_dir('bin') {:skip}
 | |
|     link_dir('sbin') {:link}
 | |
|     link_dir('include') {:link}
 | |
|     link_dir('share') {|path| :mkpath if share_mkpaths.include? path.to_s}
 | |
| 
 | |
|     link_dir('lib') do |path|
 | |
|       case path.to_s
 | |
|       # pkg-config database gets explicitly created
 | |
|       when 'pkgconfig' then :mkpath
 | |
|       # lib/language folders also get explicitly created
 | |
|       when 'ghc' then :mkpath
 | |
|       when 'lua' then :mkpath
 | |
|       when 'node' then :mkpath
 | |
|       when 'ocaml' then :mkpath
 | |
|       when /^perl5/ then :mkpath
 | |
|       when 'php' then :mkpath
 | |
|       when /^python[23]\.\d$/ then :mkpath
 | |
|       # Everything else is symlinked to the cellar
 | |
|       else :link
 | |
|       end
 | |
|     end
 | |
| 
 | |
|     return $n+$d
 | |
|   end
 | |
| 
 | |
| 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
 | |
|   rescue NotAKegError
 | |
|     puts "Won't resolve conflicts for symlink #{dst} as it doesn't resolve into the Cellar" if ARGV.verbose?
 | |
|   end
 | |
| 
 | |
|   # symlinks the contents of self+foo recursively into /usr/local/foo
 | |
|   def link_dir foo
 | |
|     root = self+foo
 | |
|     return unless root.exist?
 | |
| 
 | |
|     root.find do |src|
 | |
|       next if src == root
 | |
| 
 | |
|       dst = HOMEBREW_PREFIX+src.relative_path_from(self)
 | |
|       dst.extend ObserverPathnameExtension
 | |
| 
 | |
|       if src.file?
 | |
|         dst.make_relative_symlink src unless File.basename(src) == '.DS_Store'
 | |
|       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
 | |
|           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
 | |
| 
 | |
| require 'keg_fix_install_names'
 | 
