| 
									
										
										
										
											2010-09-11 20:22:54 +01:00
										 |  |  | require 'extend/pathname' | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-15 21:48:24 -07:00
										 |  |  | class Keg < Pathname | 
					
						
							| 
									
										
										
										
											2009-08-10 16:48:30 +01:00
										 |  |  |   def initialize path | 
					
						
							|  |  |  |     super path | 
					
						
							| 
									
										
										
										
											2009-11-12 11:09:20 -08:00
										 |  |  |     raise "#{to_s} is not a valid keg" unless parent.parent.realpath == HOMEBREW_CELLAR.realpath | 
					
						
							| 
									
										
										
										
											2009-08-10 16:48:30 +01:00
										 |  |  |     raise "#{to_s} is not a directory" unless directory? | 
					
						
							|  |  |  |   end | 
					
						
							| 
									
										
										
										
											2009-07-24 15:10:01 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-23 16:03:38 +01:00
										 |  |  |   # if path is a file in a keg then this will return the containing Keg object | 
					
						
							|  |  |  |   def self.for path | 
					
						
							| 
									
										
										
										
											2009-11-12 11:09:20 -08:00
										 |  |  |     path = path.realpath | 
					
						
							| 
									
										
										
										
											2009-10-23 16:03:38 +01:00
										 |  |  |     while not path.root? | 
					
						
							| 
									
										
										
										
											2009-11-12 11:09:20 -08:00
										 |  |  |       return Keg.new(path) if path.parent.parent == HOMEBREW_CELLAR.realpath | 
					
						
							| 
									
										
										
										
											2009-10-23 16:03:38 +01:00
										 |  |  |       path = path.parent.realpath # realpath() prevents root? failing | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2009-12-17 18:45:07 +00:00
										 |  |  |     raise NotAKegError, "#{path} is not inside a keg" | 
					
						
							| 
									
										
										
										
											2009-10-23 16:03:38 +01:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-10 16:48:30 +01:00
										 |  |  |   def uninstall | 
					
						
							|  |  |  |     chmod_R 0777 # ensure we have permission to delete | 
					
						
							|  |  |  |     rmtree | 
					
						
							|  |  |  |     parent.rmdir_if_possible | 
					
						
							| 
									
										
										
										
											2009-07-24 15:10:01 +01:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-29 21:07:26 +01:00
										 |  |  |   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 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-10 16:48:30 +01:00
										 |  |  |   def link | 
					
						
							|  |  |  |     $n=0
 | 
					
						
							|  |  |  |     $d=0
 | 
					
						
							| 
									
										
										
										
											2009-07-24 15:10:01 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-21 11:25:14 -07:00
										 |  |  |     share_mkpaths=%w[aclocal doc info locale man]+(1..8).collect{|x|"man/man#{x}"} | 
					
						
							| 
									
										
										
										
											2009-07-24 15:10:01 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-10 16:48:30 +01:00
										 |  |  |     # 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} | 
					
						
							| 
									
										
										
										
											2009-08-23 19:05:42 +01:00
										 |  |  |     link_dir('bin') {:skip} | 
					
						
							| 
									
										
										
										
											2009-08-12 09:43:16 +08:00
										 |  |  |     link_dir('sbin') {:link} | 
					
						
							| 
									
										
										
										
											2009-08-10 16:48:30 +01:00
										 |  |  |     link_dir('include') {:link} | 
					
						
							| 
									
										
										
										
											2010-04-29 15:50:24 -07:00
										 |  |  |     link_dir('share') {|path| :mkpath if share_mkpaths.include? path.to_s} | 
					
						
							| 
									
										
										
										
											2009-07-29 00:56:22 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-17 21:26:17 +01:00
										 |  |  |     link_dir('lib') do |path| | 
					
						
							|  |  |  |       case path.to_s | 
					
						
							| 
									
										
										
										
											2010-04-29 15:50:24 -07:00
										 |  |  |       # 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 | 
					
						
							| 
									
										
										
										
											2010-07-22 09:41:07 -07:00
										 |  |  |       when 'node' then :mkpath | 
					
						
							| 
									
										
										
										
											2010-04-29 15:50:24 -07:00
										 |  |  |       when 'ocaml' then :mkpath | 
					
						
							| 
									
										
										
										
											2009-09-17 21:26:17 +01:00
										 |  |  |       when /^perl5/ then :mkpath | 
					
						
							| 
									
										
										
										
											2010-04-29 15:50:24 -07:00
										 |  |  |       when 'php' then :mkpath | 
					
						
							|  |  |  |       when /^python[23]\.\d$/ then :mkpath | 
					
						
							| 
									
										
										
										
											2011-03-13 12:19:25 -07:00
										 |  |  |       when 'ruby' then :mkpath | 
					
						
							| 
									
										
										
										
											2010-08-21 10:51:43 -07:00
										 |  |  |       # Everything else is symlinked to the cellar | 
					
						
							| 
									
										
										
										
											2010-04-29 15:50:24 -07:00
										 |  |  |       else :link | 
					
						
							| 
									
										
										
										
											2009-09-17 21:26:17 +01:00
										 |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-10 16:48:30 +01:00
										 |  |  |     return $n+$d | 
					
						
							| 
									
										
										
										
											2009-07-24 15:10:01 +01:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-23 16:03:38 +01:00
										 |  |  | 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 | 
					
						
							| 
									
										
										
										
											2009-12-17 18:45:07 +00:00
										 |  |  |   rescue NotAKegError | 
					
						
							|  |  |  |     puts "Won't resolve conflicts for symlink #{dst} as it doesn't resolve into the Cellar" if ARGV.verbose? | 
					
						
							| 
									
										
										
										
											2009-10-23 16:03:38 +01:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-10 16:48:30 +01:00
										 |  |  |   # symlinks the contents of self+foo recursively into /usr/local/foo | 
					
						
							|  |  |  |   def link_dir foo | 
					
						
							| 
									
										
										
										
											2009-10-23 16:03:38 +01:00
										 |  |  |     root = self+foo | 
					
						
							| 
									
										
										
										
											2010-04-04 13:45:02 -07:00
										 |  |  |     return unless root.exist? | 
					
						
							| 
									
										
										
										
											2009-07-24 15:10:01 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-10 16:48:30 +01:00
										 |  |  |     root.find do |src| | 
					
						
							|  |  |  |       next if src == root | 
					
						
							| 
									
										
										
										
											2009-07-24 15:10:01 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-23 16:03:38 +01:00
										 |  |  |       dst = HOMEBREW_PREFIX+src.relative_path_from(self) | 
					
						
							| 
									
										
										
										
											2009-08-10 16:48:30 +01:00
										 |  |  |       dst.extend ObserverPathnameExtension | 
					
						
							| 
									
										
										
										
											2009-07-24 15:10:01 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-10 16:48:30 +01:00
										 |  |  |       if src.file? | 
					
						
							| 
									
										
										
										
											2010-09-02 11:47:18 -04:00
										 |  |  |         dst.make_relative_symlink src unless File.basename(src) == '.DS_Store' | 
					
						
							| 
									
										
										
										
											2009-08-10 16:48:30 +01:00
										 |  |  |       elsif src.directory? | 
					
						
							| 
									
										
										
										
											2009-10-23 16:03:38 +01:00
										 |  |  |         # if the dst dir already exists, then great! walk the rest of the tree tho | 
					
						
							|  |  |  |         next if dst.directory? and not dst.symlink? | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-07-24 15:10:01 +01:00
										 |  |  |         # 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 | 
					
						
							| 
									
										
										
										
											2009-08-10 16:48:30 +01:00
										 |  |  |         Find.prune if src.extname.to_s == '.app' | 
					
						
							| 
									
										
										
										
											2009-07-24 15:10:01 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-10 16:48:30 +01:00
										 |  |  |         case yield src.relative_path_from(root) | 
					
						
							| 
									
										
										
										
											2009-10-23 16:03:38 +01:00
										 |  |  |         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 | 
					
						
							| 
									
										
										
										
											2009-07-24 15:10:01 +01:00
										 |  |  |         end | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							| 
									
										
										
										
											2009-08-10 16:48:30 +01:00
										 |  |  | end | 
					
						
							| 
									
										
										
										
											2010-05-10 00:19:14 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | require 'keg_fix_install_names' |