| 
									
										
										
										
											2014-03-27 22:34:22 -05:00
										 |  |  | require "extend/pathname" | 
					
						
							|  |  |  | require "keg_fix_install_names" | 
					
						
							|  |  |  | require "formula_lock" | 
					
						
							|  |  |  | require "ostruct" | 
					
						
							| 
									
										
										
										
											2010-09-11 20:22:54 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-26 19:06:31 -05:00
										 |  |  | class Keg | 
					
						
							| 
									
										
										
										
											2014-04-21 09:40:24 -05:00
										 |  |  |   class AlreadyLinkedError < RuntimeError | 
					
						
							|  |  |  |     def initialize(keg) | 
					
						
							|  |  |  |       super <<-EOS.undent
 | 
					
						
							| 
									
										
										
										
											2014-06-24 19:04:52 -05:00
										 |  |  |         Cannot link #{keg.name} | 
					
						
							| 
									
										
										
										
											2014-04-21 09:40:24 -05:00
										 |  |  |         Another version is already linked: #{keg.linked_keg_record.resolved_path} | 
					
						
							|  |  |  |         EOS | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-21 09:40:23 -05:00
										 |  |  |   class LinkError < RuntimeError | 
					
						
							|  |  |  |     attr_reader :keg, :src, :dst | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def initialize(keg, src, dst) | 
					
						
							|  |  |  |       @src = src | 
					
						
							|  |  |  |       @dst = dst | 
					
						
							|  |  |  |       @keg = keg | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   class ConflictError < LinkError | 
					
						
							|  |  |  |     def suggestion | 
					
						
							|  |  |  |       conflict = Keg.for(dst) | 
					
						
							| 
									
										
										
										
											2014-07-30 16:29:10 -05:00
										 |  |  |     rescue NotAKegError, Errno::ENOENT | 
					
						
							| 
									
										
										
										
											2014-04-21 09:40:23 -05:00
										 |  |  |       "already exists. You may want to remove it:\n  rm #{dst}\n" | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |       <<-EOS.undent
 | 
					
						
							| 
									
										
										
										
											2014-06-24 19:04:52 -05:00
										 |  |  |       is a symlink belonging to #{conflict.name}. You can unlink it: | 
					
						
							|  |  |  |         brew unlink #{conflict.name} | 
					
						
							| 
									
										
										
										
											2014-04-21 09:40:23 -05:00
										 |  |  |       EOS | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def to_s | 
					
						
							|  |  |  |       s = [] | 
					
						
							| 
									
										
										
										
											2014-07-02 10:47:54 -05:00
										 |  |  |       s << "Could not symlink #{src}" | 
					
						
							| 
									
										
										
										
											2014-04-21 09:40:23 -05:00
										 |  |  |       s << "Target #{dst}" << suggestion | 
					
						
							|  |  |  |       s << <<-EOS.undent
 | 
					
						
							|  |  |  |         To force the link and overwrite all conflicting files: | 
					
						
							| 
									
										
										
										
											2014-06-24 19:04:52 -05:00
										 |  |  |           brew link --overwrite #{keg.name} | 
					
						
							| 
									
										
										
										
											2014-04-21 09:40:23 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         To list all files that would be deleted: | 
					
						
							| 
									
										
										
										
											2014-06-24 19:04:52 -05:00
										 |  |  |           brew link --overwrite --dry-run #{keg.name} | 
					
						
							| 
									
										
										
										
											2014-04-21 09:40:23 -05:00
										 |  |  |         EOS | 
					
						
							|  |  |  |       s.join("\n") | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   class DirectoryNotWritableError < LinkError | 
					
						
							|  |  |  |     def to_s; <<-EOS.undent
 | 
					
						
							| 
									
										
										
										
											2014-07-02 10:47:54 -05:00
										 |  |  |       Could not symlink #{src} | 
					
						
							| 
									
										
										
										
											2014-04-21 09:40:23 -05:00
										 |  |  |       #{dst.dirname} is not writable. | 
					
						
							|  |  |  |       EOS | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-01 22:20:34 -06:00
										 |  |  |   # locale-specific directories have the form language[_territory][.codeset][@modifier] | 
					
						
							|  |  |  |   LOCALEDIR_RX = /(locale|man)\/([a-z]{2}|C|POSIX)(_[A-Z]{2})?(\.[a-zA-Z\-0-9]+(@.+)?)?/ | 
					
						
							| 
									
										
										
										
											2012-03-20 10:40:00 -05:00
										 |  |  |   INFOFILE_RX = %r[info/([^.].*?\.info|dir)$] | 
					
						
							| 
									
										
										
										
											2012-11-05 18:13:14 -06:00
										 |  |  |   TOP_LEVEL_DIRECTORIES = %w[bin etc include lib sbin share var Frameworks] | 
					
						
							| 
									
										
										
										
											2013-01-07 17:50:23 -06:00
										 |  |  |   PRUNEABLE_DIRECTORIES = %w[bin etc include lib sbin share Frameworks LinkedKegs].map do |d| | 
					
						
							|  |  |  |     case d when 'LinkedKegs' then HOMEBREW_LIBRARY/d else HOMEBREW_PREFIX/d end | 
					
						
							|  |  |  |   end | 
					
						
							| 
									
										
										
										
											2012-01-21 00:51:20 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-27 17:13:39 -05:00
										 |  |  |   # These paths relative to the keg's share directory should always be real | 
					
						
							|  |  |  |   # directories in the prefix, never symlinks. | 
					
						
							|  |  |  |   SHARE_PATHS = %w[
 | 
					
						
							|  |  |  |     aclocal doc info locale man | 
					
						
							|  |  |  |     man/man1 man/man2 man/man3 man/man4 | 
					
						
							|  |  |  |     man/man5 man/man6 man/man7 man/man8 | 
					
						
							|  |  |  |     man/cat1 man/cat2 man/cat3 man/cat4 | 
					
						
							|  |  |  |     man/cat5 man/cat6 man/cat7 man/cat8 | 
					
						
							|  |  |  |     applications gnome gnome/help icons | 
					
						
							|  |  |  |     mime-info pixmaps sounds | 
					
						
							|  |  |  |   ] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-30 20:16:01 -05:00
										 |  |  |   attr_reader :path, :name, :linked_keg_record, :opt_record | 
					
						
							| 
									
										
										
										
											2014-06-26 19:06:31 -05:00
										 |  |  |   protected :path | 
					
						
							| 
									
										
										
										
											2014-06-23 22:52:41 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-27 22:35:08 -05:00
										 |  |  |   def initialize path | 
					
						
							| 
									
										
										
										
											2014-06-26 19:06:31 -05:00
										 |  |  |     raise "#{path} is not a valid keg" unless path.parent.parent.realpath == HOMEBREW_CELLAR.realpath | 
					
						
							|  |  |  |     raise "#{path} is not a directory" unless path.directory? | 
					
						
							|  |  |  |     @path = path | 
					
						
							|  |  |  |     @name = path.parent.basename.to_s | 
					
						
							| 
									
										
										
										
											2014-06-24 19:04:52 -05:00
										 |  |  |     @linked_keg_record = HOMEBREW_LIBRARY.join("LinkedKegs", name) | 
					
						
							| 
									
										
										
										
											2014-06-30 20:16:01 -05:00
										 |  |  |     @opt_record = HOMEBREW_PREFIX.join("opt", name) | 
					
						
							| 
									
										
										
										
											2014-03-27 22:35:08 -05:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-26 16:10:15 -05:00
										 |  |  |   def fname | 
					
						
							|  |  |  |     opoo "Keg#fname is a deprecated alias for Keg#name and will be removed soon" | 
					
						
							|  |  |  |     name | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-26 19:06:31 -05:00
										 |  |  |   def to_s | 
					
						
							|  |  |  |     path.to_s | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if Pathname.method_defined?(:to_path) | 
					
						
							|  |  |  |     alias_method :to_path, :to_s | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |     alias_method :to_str, :to_s | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def inspect | 
					
						
							|  |  |  |     "#<#{self.class.name}:#{path}>" | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def ==(other) | 
					
						
							|  |  |  |     instance_of?(other.class) && path == other.path | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  |   alias_method :eql?, :== | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def hash | 
					
						
							|  |  |  |     path.hash | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def abv | 
					
						
							|  |  |  |     path.abv | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-28 19:43:52 -05:00
										 |  |  |   def directory? | 
					
						
							|  |  |  |     path.directory? | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-26 19:06:31 -05:00
										 |  |  |   def exist? | 
					
						
							|  |  |  |     path.exist? | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def /(other) | 
					
						
							|  |  |  |     path / other | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def join(*args) | 
					
						
							|  |  |  |     path.join(*args) | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def rename(*args) | 
					
						
							|  |  |  |     path.rename(*args) | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-30 20:09:13 -05:00
										 |  |  |   def linked? | 
					
						
							|  |  |  |     linked_keg_record.symlink? && | 
					
						
							|  |  |  |       linked_keg_record.directory? && | 
					
						
							|  |  |  |       path == linked_keg_record.resolved_path | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def remove_linked_keg_record | 
					
						
							|  |  |  |     linked_keg_record.unlink | 
					
						
							|  |  |  |     linked_keg_record.parent.rmdir_if_possible | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-30 20:16:58 -05:00
										 |  |  |   def optlinked? | 
					
						
							|  |  |  |     opt_record.symlink? && path == opt_record.resolved_path | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def remove_opt_record | 
					
						
							|  |  |  |     opt_record.unlink | 
					
						
							|  |  |  |     opt_record.parent.rmdir_if_possible | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-10 16:48:30 +01:00
										 |  |  |   def uninstall | 
					
						
							| 
									
										
										
										
											2014-06-26 19:06:31 -05:00
										 |  |  |     path.rmtree | 
					
						
							|  |  |  |     path.parent.rmdir_if_possible | 
					
						
							| 
									
										
										
										
											2014-06-30 20:16:58 -05:00
										 |  |  |     remove_opt_record if optlinked? | 
					
						
							| 
									
										
										
										
											2009-07-24 15:10:01 +01:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-29 21:07:26 +01:00
										 |  |  |   def unlink | 
					
						
							| 
									
										
										
										
											2013-08-09 21:09:48 -05:00
										 |  |  |     ObserverPathnameExtension.reset_counts! | 
					
						
							| 
									
										
										
										
											2012-07-20 12:01:37 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-08-09 11:29:19 -05:00
										 |  |  |     dirs = [] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-26 19:06:31 -05:00
										 |  |  |     TOP_LEVEL_DIRECTORIES.map{ |d| path.join(d) }.each do |dir| | 
					
						
							| 
									
										
										
										
											2013-02-17 22:54:43 -06:00
										 |  |  |       next unless dir.exist? | 
					
						
							|  |  |  |       dir.find do |src| | 
					
						
							| 
									
										
										
										
											2014-06-26 19:06:31 -05:00
										 |  |  |         dst = HOMEBREW_PREFIX + src.relative_path_from(path) | 
					
						
							| 
									
										
										
										
											2013-08-09 11:29:19 -05:00
										 |  |  |         dst.extend(ObserverPathnameExtension) | 
					
						
							| 
									
										
										
										
											2012-10-04 08:52:48 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-08-09 11:29:19 -05:00
										 |  |  |         dirs << dst if dst.directory? && !dst.symlink? | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-04 08:52:48 -05:00
										 |  |  |         # check whether the file to be unlinked is from the current keg first | 
					
						
							| 
									
										
										
										
											2014-07-04 19:31:07 -05:00
										 |  |  |         if dst.symlink? && src == dst.resolved_path | 
					
						
							|  |  |  |           dst.uninstall_info if dst.to_s =~ INFOFILE_RX | 
					
						
							|  |  |  |           dst.unlink | 
					
						
							|  |  |  |           Find.prune if src.directory? | 
					
						
							|  |  |  |         end | 
					
						
							| 
									
										
										
										
											2012-03-25 13:08:58 +01:00
										 |  |  |       end | 
					
						
							| 
									
										
										
										
											2009-08-29 21:07:26 +01:00
										 |  |  |     end | 
					
						
							| 
									
										
										
										
											2014-06-23 21:47:52 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-27 16:20:17 -05:00
										 |  |  |     remove_linked_keg_record if linked? | 
					
						
							| 
									
										
										
										
											2013-08-09 11:29:19 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     dirs.reverse_each(&:rmdir_if_possible) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-08-09 21:09:48 -05:00
										 |  |  |     ObserverPathnameExtension.total | 
					
						
							| 
									
										
										
										
											2009-08-29 21:07:26 +01:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-23 00:26:25 -06:00
										 |  |  |   def lock | 
					
						
							| 
									
										
										
										
											2014-06-24 19:04:52 -05:00
										 |  |  |     FormulaLock.new(name).with_lock { yield } | 
					
						
							| 
									
										
										
										
											2013-01-23 00:26:25 -06:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-07-18 03:22:00 -05:00
										 |  |  |   def completion_installed? shell | 
					
						
							|  |  |  |     dir = case shell | 
					
						
							| 
									
										
										
										
											2014-06-26 19:06:31 -05:00
										 |  |  |           when :bash then path.join("etc", "bash_completion.d") | 
					
						
							|  |  |  |           when :zsh  then path.join("share", "zsh", "site-functions") | 
					
						
							|  |  |  |           end | 
					
						
							|  |  |  |     dir && dir.directory? && dir.children.any? | 
					
						
							| 
									
										
										
										
											2012-07-18 03:22:00 -05:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-11-25 15:06:41 +00:00
										 |  |  |   def plist_installed? | 
					
						
							| 
									
										
										
										
											2014-06-26 19:06:31 -05:00
										 |  |  |     Dir["#{path}/*.plist"].any? | 
					
						
							| 
									
										
										
										
											2012-11-25 15:06:41 +00:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-04 13:18:27 +00:00
										 |  |  |   def python_site_packages_installed? | 
					
						
							| 
									
										
										
										
											2014-06-26 19:06:31 -05:00
										 |  |  |     path.join("lib", "python2.7", "site-packages").directory? | 
					
						
							| 
									
										
										
										
											2014-01-04 13:18:27 +00:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-18 21:57:42 +00:00
										 |  |  |   def app_installed? | 
					
						
							| 
									
										
										
										
											2014-06-26 19:06:31 -05:00
										 |  |  |     Dir["#{path}/{,libexec/}*.app"].any? | 
					
						
							| 
									
										
										
										
											2014-01-18 21:57:42 +00:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-07-10 22:08:06 -05:00
										 |  |  |   def version | 
					
						
							| 
									
										
										
										
											2014-03-05 20:12:51 -06:00
										 |  |  |     require 'pkg_version' | 
					
						
							| 
									
										
										
										
											2014-06-26 19:06:31 -05:00
										 |  |  |     PkgVersion.parse(path.basename.to_s) | 
					
						
							| 
									
										
										
										
											2014-03-27 17:05:17 -05:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def find(*args, &block) | 
					
						
							| 
									
										
										
										
											2014-06-26 19:06:31 -05:00
										 |  |  |     path.find(*args, &block) | 
					
						
							| 
									
										
										
										
											2012-07-10 22:08:06 -05:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-20 20:54:11 -05:00
										 |  |  |   def link mode=OpenStruct.new | 
					
						
							| 
									
										
										
										
											2014-04-21 09:40:24 -05:00
										 |  |  |     raise AlreadyLinkedError.new(self) if linked_keg_record.directory? | 
					
						
							| 
									
										
										
										
											2011-08-24 11:30:32 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-08-09 21:09:48 -05:00
										 |  |  |     ObserverPathnameExtension.reset_counts! | 
					
						
							| 
									
										
										
										
											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 | 
					
						
							| 
									
										
										
										
											2013-10-05 20:39:51 +01:00
										 |  |  |     link_dir('etc', mode) {:mkpath} | 
					
						
							| 
									
										
										
										
											2012-06-17 16:54:20 -05:00
										 |  |  |     link_dir('bin', mode) {:skip_dir} | 
					
						
							|  |  |  |     link_dir('sbin', mode) {:skip_dir} | 
					
						
							|  |  |  |     link_dir('include', mode) {:link} | 
					
						
							| 
									
										
										
										
											2012-01-04 20:50:19 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-06-17 16:54:20 -05:00
										 |  |  |     link_dir('share', mode) do |path| | 
					
						
							| 
									
										
										
										
											2012-02-26 19:28:46 -06:00
										 |  |  |       case path.to_s | 
					
						
							| 
									
										
										
										
											2012-03-11 10:18:12 -05:00
										 |  |  |       when 'locale/locale.alias' then :skip_file | 
					
						
							| 
									
										
										
										
											2014-02-22 09:20:09 -08:00
										 |  |  |       when INFOFILE_RX then :info | 
					
						
							| 
									
										
										
										
											2012-02-26 19:28:46 -06:00
										 |  |  |       when LOCALEDIR_RX then :mkpath | 
					
						
							| 
									
										
										
										
											2014-03-27 17:13:39 -05:00
										 |  |  |       when *SHARE_PATHS then :mkpath | 
					
						
							| 
									
										
										
										
											2013-07-02 08:19:29 -07:00
										 |  |  |       when /^icons\/.*\/icon-theme\.cache$/ then :skip_file | 
					
						
							|  |  |  |       # all icons subfolders should also mkpath | 
					
						
							|  |  |  |       when /^icons\// then :mkpath | 
					
						
							| 
									
										
										
										
											2012-04-29 02:12:26 -04:00
										 |  |  |       when /^zsh/ then :mkpath | 
					
						
							| 
									
										
										
										
											2012-02-26 19:28:46 -06:00
										 |  |  |       else :link | 
					
						
							| 
									
										
										
										
											2012-01-04 20:50:19 -06:00
										 |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2009-07-29 00:56:22 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-06-17 16:54:20 -05:00
										 |  |  |     link_dir('lib', mode) do |path| | 
					
						
							| 
									
										
										
										
											2009-09-17 21:26:17 +01:00
										 |  |  |       case path.to_s | 
					
						
							| 
									
										
										
										
											2012-03-11 10:18:12 -05:00
										 |  |  |       when 'charset.alias' then :skip_file | 
					
						
							| 
									
										
										
										
											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 | 
					
						
							| 
									
										
										
										
											2013-11-17 10:34:19 -08:00
										 |  |  |       when 'dtrace' then :mkpath | 
					
						
							| 
									
										
										
										
											2012-03-08 20:31:32 -06:00
										 |  |  |       when /^gdk-pixbuf/ then :mkpath | 
					
						
							| 
									
										
										
										
											2010-04-29 15:50:24 -07:00
										 |  |  |       when 'ghc' then :mkpath | 
					
						
							|  |  |  |       when 'lua' then :mkpath | 
					
						
							| 
									
										
										
										
											2013-07-31 13:51:05 -05:00
										 |  |  |       when /^node/ then :mkpath | 
					
						
							| 
									
										
										
										
											2012-01-30 00:02:28 -06: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 | 
					
						
							| 
									
										
										
										
											2012-04-26 20:35:09 -05:00
										 |  |  |       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 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-17 09:01:37 +02:00
										 |  |  |     link_dir('Frameworks', mode) do |path| | 
					
						
							|  |  |  |       # Frameworks contain symlinks pointing into a subdir, so we have to use | 
					
						
							|  |  |  |       # the :link strategy. However, for Foo.framework and | 
					
						
							|  |  |  |       # Foo.framework/Versions we have to use :mkpath so that multiple formulae | 
					
						
							|  |  |  |       # can link their versions into it and `brew [un]link` works. | 
					
						
							|  |  |  |       if path.to_s =~ /[^\/]*\.framework(\/Versions)?$/ | 
					
						
							|  |  |  |         :mkpath | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  |         :link | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-11-05 18:12:26 -06:00
										 |  |  |     unless mode.dry_run | 
					
						
							| 
									
										
										
										
											2014-06-26 19:06:31 -05:00
										 |  |  |       make_relative_symlink(linked_keg_record, path, mode) | 
					
						
							| 
									
										
										
										
											2014-06-30 21:55:58 -05:00
										 |  |  |       optlink(mode) | 
					
						
							| 
									
										
										
										
											2012-11-05 18:12:26 -06:00
										 |  |  |     end | 
					
						
							| 
									
										
										
										
											2014-04-21 09:40:24 -05:00
										 |  |  |   rescue LinkError | 
					
						
							| 
									
										
										
										
											2012-08-10 16:33:22 -04:00
										 |  |  |     unlink | 
					
						
							|  |  |  |     raise | 
					
						
							| 
									
										
										
										
											2014-04-21 09:40:24 -05:00
										 |  |  |   else | 
					
						
							|  |  |  |     ObserverPathnameExtension.total | 
					
						
							| 
									
										
										
										
											2012-08-10 16:33:22 -04:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-30 21:55:58 -05:00
										 |  |  |   def optlink(mode=OpenStruct.new) | 
					
						
							| 
									
										
										
										
											2014-06-30 21:53:48 -05:00
										 |  |  |     opt_record.delete if opt_record.symlink? || opt_record.exist? | 
					
						
							| 
									
										
										
										
											2014-06-30 21:55:58 -05:00
										 |  |  |     make_relative_symlink(opt_record, path, mode) | 
					
						
							| 
									
										
										
										
											2009-07-24 15:10:01 +01:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-13 09:05:40 +00:00
										 |  |  |   def delete_pyc_files! | 
					
						
							| 
									
										
										
										
											2014-03-27 17:05:17 -05:00
										 |  |  |     find { |pn| pn.delete if pn.extname == ".pyc" } | 
					
						
							| 
									
										
										
										
											2014-03-13 09:05:40 +00:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-26 18:45:34 -05:00
										 |  |  |   private | 
					
						
							| 
									
										
										
										
											2013-04-07 00:49:56 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-31 21:33:37 -05:00
										 |  |  |   def resolve_any_conflicts dst, mode | 
					
						
							| 
									
										
										
										
											2014-07-12 19:56:58 -05:00
										 |  |  |     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 | 
					
						
							| 
									
										
										
										
											2014-07-12 20:15:57 -05:00
										 |  |  |     # treated as a file). In other words, we only want to resolve one symlink. | 
					
						
							| 
									
										
										
										
											2014-07-12 19:56:58 -05:00
										 |  |  |     # If it isn't a directory, make_relative_symlink will raise an exception. | 
					
						
							|  |  |  |     if dst.symlink? && src.lstat.directory? | 
					
						
							| 
									
										
										
										
											2009-10-23 16:03:38 +01:00
										 |  |  |       keg = Keg.for(src) | 
					
						
							| 
									
										
										
										
											2014-03-31 21:33:37 -05:00
										 |  |  |       dst.unlink unless mode.dry_run | 
					
						
							|  |  |  |       keg.link_dir(src, mode) { :mkpath } | 
					
						
							| 
									
										
										
										
											2009-10-23 16:03:38 +01:00
										 |  |  |       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 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-30 21:56:46 -05:00
										 |  |  |   def make_relative_symlink dst, src, mode | 
					
						
							| 
									
										
										
										
											2014-07-04 17:22:58 -05:00
										 |  |  |     if dst.symlink? && src == dst.resolved_path | 
					
						
							| 
									
										
										
										
											2014-04-05 12:17:19 -05:00
										 |  |  |       puts "Skipping; link already exists: #{dst}" if ARGV.verbose? | 
					
						
							| 
									
										
										
										
											2013-07-10 08:50:53 -07:00
										 |  |  |       return | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-06-17 16:54:20 -05:00
										 |  |  |     # cf. git-clean -n: list files to delete, don't really link or delete | 
					
						
							| 
									
										
										
										
											2013-07-10 08:50:53 -07:00
										 |  |  |     if mode.dry_run and mode.overwrite | 
					
						
							|  |  |  |       if dst.symlink? | 
					
						
							|  |  |  |         puts "#{dst} -> #{dst.resolved_path}" | 
					
						
							|  |  |  |       elsif dst.exist? | 
					
						
							|  |  |  |         puts dst | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2012-06-17 16:54:20 -05:00
										 |  |  |       return | 
					
						
							| 
									
										
										
										
											2013-07-10 08:50:53 -07:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-20 20:54:11 -05:00
										 |  |  |     # list all link targets | 
					
						
							| 
									
										
										
										
											2013-07-10 08:50:53 -07:00
										 |  |  |     if mode.dry_run | 
					
						
							| 
									
										
										
										
											2012-10-20 20:54:11 -05:00
										 |  |  |       puts dst | 
					
						
							|  |  |  |       return | 
					
						
							| 
									
										
										
										
											2012-03-19 12:24:13 +00:00
										 |  |  |     end | 
					
						
							| 
									
										
										
										
											2013-07-10 08:50:53 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-27 17:37:38 -05:00
										 |  |  |     dst.delete if mode.overwrite && (dst.exist? || dst.symlink?) | 
					
						
							| 
									
										
										
										
											2014-04-21 09:40:23 -05:00
										 |  |  |     dst.make_relative_symlink(src) | 
					
						
							|  |  |  |   rescue Errno::EEXIST | 
					
						
							| 
									
										
										
										
											2014-04-21 09:40:23 -05:00
										 |  |  |     if dst.exist? | 
					
						
							| 
									
										
										
										
											2014-07-02 10:47:54 -05:00
										 |  |  |       raise ConflictError.new(self, src.relative_path_from(path), dst) | 
					
						
							| 
									
										
										
										
											2014-04-21 09:40:23 -05:00
										 |  |  |     elsif dst.symlink? | 
					
						
							|  |  |  |       dst.unlink | 
					
						
							|  |  |  |       retry | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   rescue Errno::EACCES | 
					
						
							| 
									
										
										
										
											2014-07-02 10:47:54 -05:00
										 |  |  |     raise DirectoryNotWritableError.new(self, src.relative_path_from(path), dst) | 
					
						
							| 
									
										
										
										
											2014-04-21 09:40:23 -05:00
										 |  |  |   rescue SystemCallError | 
					
						
							| 
									
										
										
										
											2014-07-02 10:47:54 -05:00
										 |  |  |     raise LinkError.new(self, src.relative_path_from(path), dst) | 
					
						
							| 
									
										
										
										
											2012-03-19 12:24:13 +00:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-26 18:45:34 -05:00
										 |  |  |   protected | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-26 19:06:31 -05:00
										 |  |  |   # symlinks the contents of path+relative_dir recursively into #{HOMEBREW_PREFIX}/relative_dir | 
					
						
							| 
									
										
										
										
											2014-06-26 18:48:31 -05:00
										 |  |  |   def link_dir relative_dir, mode | 
					
						
							| 
									
										
										
										
											2014-06-26 19:06:31 -05:00
										 |  |  |     root = path+relative_dir | 
					
						
							| 
									
										
										
										
											2010-04-04 13:45:02 -07:00
										 |  |  |     return unless root.exist? | 
					
						
							| 
									
										
										
										
											2009-08-10 16:48:30 +01:00
										 |  |  |     root.find do |src| | 
					
						
							|  |  |  |       next if src == root | 
					
						
							| 
									
										
										
										
											2014-06-26 19:06:31 -05:00
										 |  |  |       dst = HOMEBREW_PREFIX + src.relative_path_from(path) | 
					
						
							| 
									
										
										
										
											2009-08-10 16:48:30 +01:00
										 |  |  |       dst.extend ObserverPathnameExtension | 
					
						
							| 
									
										
										
										
											2009-07-24 15:10:01 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-12 19:56:58 -05:00
										 |  |  |       if src.symlink? || src.file? | 
					
						
							| 
									
										
										
										
											2012-02-26 19:28:46 -06:00
										 |  |  |         Find.prune if File.basename(src) == '.DS_Store' | 
					
						
							| 
									
										
										
										
											2013-01-21 10:33:56 +01:00
										 |  |  |         # Don't link pyc files because Python overwrites these cached object | 
					
						
							|  |  |  |         # files and next time brew wants to link, the pyc file is in the way. | 
					
						
							| 
									
										
										
										
											2013-12-14 09:35:57 -06:00
										 |  |  |         if src.extname == '.pyc' && src.to_s =~ /site-packages/ | 
					
						
							| 
									
										
										
										
											2013-01-21 10:33:56 +01:00
										 |  |  |           Find.prune | 
					
						
							|  |  |  |         end | 
					
						
							| 
									
										
										
										
											2012-02-26 19:28:46 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |         case yield src.relative_path_from(root) | 
					
						
							| 
									
										
										
										
											2012-03-20 14:27:07 -05:00
										 |  |  |         when :skip_file, nil | 
					
						
							| 
									
										
										
										
											2012-02-26 19:28:46 -06:00
										 |  |  |           Find.prune | 
					
						
							|  |  |  |         when :info | 
					
						
							| 
									
										
										
										
											2012-03-20 16:57:49 -05:00
										 |  |  |           next if File.basename(src) == 'dir' # skip historical local 'dir' files | 
					
						
							| 
									
										
										
										
											2012-06-17 16:54:20 -05:00
										 |  |  |           make_relative_symlink dst, src, mode | 
					
						
							| 
									
										
										
										
											2012-02-26 19:28:46 -06:00
										 |  |  |           dst.install_info | 
					
						
							|  |  |  |         else | 
					
						
							| 
									
										
										
										
											2012-06-17 16:54:20 -05:00
										 |  |  |           make_relative_symlink dst, src, mode | 
					
						
							| 
									
										
										
										
											2012-02-26 19:28:46 -06:00
										 |  |  |         end | 
					
						
							| 
									
										
										
										
											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 | 
					
						
							| 
									
										
										
										
											2013-12-14 09:35:57 -06:00
										 |  |  |         Find.prune if src.extname == '.app' | 
					
						
							| 
									
										
										
										
											2009-07-24 15:10:01 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-10 16:48:30 +01:00
										 |  |  |         case yield src.relative_path_from(root) | 
					
						
							| 
									
										
										
										
											2012-03-11 10:18:12 -05:00
										 |  |  |         when :skip_dir | 
					
						
							| 
									
										
										
										
											2009-10-23 16:03:38 +01:00
										 |  |  |           Find.prune | 
					
						
							|  |  |  |         when :mkpath | 
					
						
							| 
									
										
										
										
											2014-03-31 21:33:37 -05:00
										 |  |  |           dst.mkpath unless resolve_any_conflicts(dst, mode) | 
					
						
							| 
									
										
										
										
											2009-10-23 16:03:38 +01:00
										 |  |  |         else | 
					
						
							| 
									
										
										
										
											2014-03-31 21:33:37 -05:00
										 |  |  |           unless resolve_any_conflicts(dst, mode) | 
					
						
							| 
									
										
										
										
											2012-07-11 22:32:00 -05:00
										 |  |  |             make_relative_symlink dst, src, mode | 
					
						
							| 
									
										
										
										
											2009-10-23 16:03:38 +01:00
										 |  |  |             Find.prune | 
					
						
							|  |  |  |           end | 
					
						
							| 
									
										
										
										
											2009-07-24 15:10:01 +01:00
										 |  |  |         end | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							| 
									
										
										
										
											2009-08-10 16:48:30 +01:00
										 |  |  | end |