| 
									
										
										
										
											2023-03-21 21:42:51 -07:00
										 |  |  | # typed: true | 
					
						
							| 
									
										
										
										
											2019-04-19 15:38:03 +09:00
										 |  |  | # frozen_string_literal: true | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-14 11:56:34 -07:00
										 |  |  | require "keg_relocate" | 
					
						
							| 
									
										
										
										
											2018-09-06 18:38:43 +01:00
										 |  |  | require "language/python" | 
					
						
							| 
									
										
										
										
											2017-05-22 03:23:50 +02:00
										 |  |  | require "lock_file" | 
					
						
							| 
									
										
										
										
											2020-07-20 13:18:09 -04:00
										 |  |  | require "extend/cachable" | 
					
						
							| 
									
										
										
										
											2010-09-11 20:22:54 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-17 18:45:48 +02:00
										 |  |  | # Installation prefix of a formula. | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # @api private | 
					
						
							| 
									
										
										
										
											2014-06-26 19:06:31 -05:00
										 |  |  | class Keg | 
					
						
							| 
									
										
										
										
											2019-11-05 20:33:32 +00:00
										 |  |  |   extend Cachable | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-17 18:45:48 +02:00
										 |  |  |   # Error for when a keg is already linked. | 
					
						
							| 
									
										
										
										
											2014-04-21 09:40:24 -05:00
										 |  |  |   class AlreadyLinkedError < RuntimeError | 
					
						
							|  |  |  |     def initialize(keg) | 
					
						
							| 
									
										
										
										
											2017-10-15 02:28:32 +02:00
										 |  |  |       super <<~EOS | 
					
						
							| 
									
										
										
										
											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} | 
					
						
							| 
									
										
										
										
											2018-06-06 23:34:19 -04:00
										 |  |  |       EOS | 
					
						
							| 
									
										
										
										
											2014-04-21 09:40:24 -05:00
										 |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-17 18:45:48 +02:00
										 |  |  |   # Error for when a keg cannot be linked. | 
					
						
							| 
									
										
										
										
											2014-04-21 09:40:23 -05:00
										 |  |  |   class LinkError < RuntimeError | 
					
						
							|  |  |  |     attr_reader :keg, :src, :dst | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-09 14:24:18 -05:00
										 |  |  |     def initialize(keg, src, dst, cause) | 
					
						
							| 
									
										
										
										
											2014-04-21 09:40:23 -05:00
										 |  |  |       @src = src | 
					
						
							|  |  |  |       @dst = dst | 
					
						
							|  |  |  |       @keg = keg | 
					
						
							| 
									
										
										
										
											2014-09-09 14:24:18 -05:00
										 |  |  |       @cause = cause | 
					
						
							|  |  |  |       super(cause.message) | 
					
						
							|  |  |  |       set_backtrace(cause.backtrace) | 
					
						
							| 
									
										
										
										
											2014-04-21 09:40:23 -05:00
										 |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-17 18:45:48 +02:00
										 |  |  |   # Error for when a file already exists or belongs to another keg. | 
					
						
							| 
									
										
										
										
											2014-04-21 09:40:23 -05:00
										 |  |  |   class ConflictError < LinkError | 
					
						
							| 
									
										
										
										
											2020-10-20 12:03:48 +02:00
										 |  |  |     sig { returns(String) } | 
					
						
							| 
									
										
										
										
											2014-04-21 09:40:23 -05:00
										 |  |  |     def suggestion | 
					
						
							|  |  |  |       conflict = Keg.for(dst) | 
					
						
							| 
									
										
										
										
											2014-07-30 16:29:10 -05:00
										 |  |  |     rescue NotAKegError, Errno::ENOENT | 
					
						
							| 
									
										
										
										
											2014-12-24 16:59:40 +01:00
										 |  |  |       "already exists. You may want to remove it:\n  rm '#{dst}'\n" | 
					
						
							| 
									
										
										
										
											2014-04-21 09:40:23 -05:00
										 |  |  |     else | 
					
						
							| 
									
										
										
										
											2017-10-15 02:28:32 +02:00
										 |  |  |       <<~EOS | 
					
						
							|  |  |  |         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 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-20 12:03:48 +02:00
										 |  |  |     sig { returns(String) } | 
					
						
							| 
									
										
										
										
											2014-04-21 09:40:23 -05:00
										 |  |  |     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 | 
					
						
							| 
									
										
										
										
											2017-10-15 02:28:32 +02:00
										 |  |  |       s << <<~EOS | 
					
						
							| 
									
										
										
										
											2014-04-21 09:40:23 -05:00
										 |  |  |         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} | 
					
						
							| 
									
										
										
										
											2018-06-06 23:34:19 -04:00
										 |  |  |       EOS | 
					
						
							| 
									
										
										
										
											2014-04-21 09:40:23 -05:00
										 |  |  |       s.join("\n") | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-17 18:45:48 +02:00
										 |  |  |   # Error for when a directory is not writable. | 
					
						
							| 
									
										
										
										
											2014-04-21 09:40:23 -05:00
										 |  |  |   class DirectoryNotWritableError < LinkError | 
					
						
							| 
									
										
										
										
											2020-10-20 12:03:48 +02:00
										 |  |  |     sig { returns(String) } | 
					
						
							| 
									
										
										
										
											2018-01-17 10:42:43 +00:00
										 |  |  |     def to_s | 
					
						
							|  |  |  |       <<~EOS | 
					
						
							|  |  |  |         Could not symlink #{src} | 
					
						
							|  |  |  |         #{dst.dirname} is not writable. | 
					
						
							| 
									
										
										
										
											2014-04-21 09:40:23 -05:00
										 |  |  |       EOS | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-05 17:17:03 -05:00
										 |  |  |   # Locale-specific directories have the form `language[_territory][.codeset][@modifier]` | 
					
						
							| 
									
										
										
										
											2018-11-02 17:18:07 +00:00
										 |  |  |   LOCALEDIR_RX = %r{(locale|man)/([a-z]{2}|C|POSIX)(_[A-Z]{2})?(\.[a-zA-Z\-0-9]+(@.+)?)?}.freeze | 
					
						
							|  |  |  |   INFOFILE_RX = %r{info/([^.].*?\.info|dir)$}.freeze | 
					
						
							| 
									
										
										
										
											2018-09-06 18:38:43 +01:00
										 |  |  |   KEG_LINK_DIRECTORIES = %w[
 | 
					
						
							| 
									
										
										
										
											2018-10-04 22:55:00 -07:00
										 |  |  |     bin etc include lib sbin share var | 
					
						
							| 
									
										
										
										
											2018-09-06 18:38:43 +01:00
										 |  |  |   ].freeze | 
					
						
							| 
									
										
										
										
											2018-09-25 22:03:29 +01:00
										 |  |  |   MUST_EXIST_SUBDIRECTORIES = ( | 
					
						
							|  |  |  |     KEG_LINK_DIRECTORIES - %w[var] + %w[
 | 
					
						
							|  |  |  |       opt | 
					
						
							|  |  |  |       var/homebrew/linked | 
					
						
							|  |  |  |     ] | 
					
						
							| 
									
										
										
										
											2019-10-21 12:29:37 -07:00
										 |  |  |   ).map { |dir| HOMEBREW_PREFIX/dir }.sort.uniq.freeze | 
					
						
							| 
									
										
										
										
											2018-09-06 18:38:43 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |   # Keep relatively in sync with | 
					
						
							| 
									
										
										
										
											2020-11-03 12:39:26 -05:00
										 |  |  |   # {https://github.com/Homebrew/install/blob/HEAD/install.sh} | 
					
						
							| 
									
										
										
										
											2019-04-19 21:46:20 +09:00
										 |  |  |   MUST_EXIST_DIRECTORIES = (MUST_EXIST_SUBDIRECTORIES + [ | 
					
						
							| 
									
										
										
										
											2018-09-25 22:03:29 +01:00
										 |  |  |     HOMEBREW_CELLAR, | 
					
						
							| 
									
										
										
										
											2019-04-19 21:46:20 +09:00
										 |  |  |   ].sort.uniq).freeze | 
					
						
							| 
									
										
										
										
											2018-09-06 18:38:43 +01:00
										 |  |  |   MUST_BE_WRITABLE_DIRECTORIES = ( | 
					
						
							| 
									
										
										
										
											2018-09-25 22:03:29 +01:00
										 |  |  |     %w[
 | 
					
						
							| 
									
										
										
										
											2018-09-06 18:38:43 +01:00
										 |  |  |       etc/bash_completion.d lib/pkgconfig | 
					
						
							|  |  |  |       share/aclocal share/doc share/info share/locale share/man | 
					
						
							|  |  |  |       share/man/man1 share/man/man2 share/man/man3 share/man/man4 | 
					
						
							|  |  |  |       share/man/man5 share/man/man6 share/man/man7 share/man/man8 | 
					
						
							|  |  |  |       share/zsh share/zsh/site-functions | 
					
						
							|  |  |  |       var/log | 
					
						
							| 
									
										
										
										
											2018-09-25 22:03:29 +01:00
										 |  |  |     ].map { |dir| HOMEBREW_PREFIX/dir } + MUST_EXIST_SUBDIRECTORIES + [ | 
					
						
							| 
									
										
										
										
											2018-09-06 18:38:43 +01:00
										 |  |  |       HOMEBREW_CACHE, | 
					
						
							|  |  |  |       HOMEBREW_CELLAR, | 
					
						
							|  |  |  |       HOMEBREW_LOCKS, | 
					
						
							|  |  |  |       HOMEBREW_LOGS, | 
					
						
							|  |  |  |       HOMEBREW_REPOSITORY, | 
					
						
							|  |  |  |       Language::Python.homebrew_site_packages, | 
					
						
							|  |  |  |     ] | 
					
						
							| 
									
										
										
										
											2019-10-21 12:29:37 -07:00
										 |  |  |   ).sort.uniq.freeze | 
					
						
							| 
									
										
										
										
											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[
 | 
					
						
							| 
									
										
										
										
											2015-09-29 11:09:25 -07:00
										 |  |  |     aclocal doc info java locale man | 
					
						
							| 
									
										
										
										
											2014-03-27 17:13:39 -05:00
										 |  |  |     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 | 
					
						
							| 
									
										
										
										
											2015-11-06 17:32:14 +08:00
										 |  |  |     mime-info pixmaps sounds postgresql | 
					
						
							| 
									
										
										
										
											2016-09-17 15:17:27 +01:00
										 |  |  |   ].freeze | 
					
						
							| 
									
										
										
										
											2014-03-27 17:13:39 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-11 10:29:21 +01:00
										 |  |  |   ELISP_EXTENSIONS = %w[.el .elc].freeze | 
					
						
							|  |  |  |   PYC_EXTENSIONS = %w[.pyc .pyo].freeze | 
					
						
							|  |  |  |   LIBTOOL_EXTENSIONS = %w[.la .lai].freeze | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-05 15:19:56 -05:00
										 |  |  |   # @param path if this is a file in a keg, returns the containing {Keg} object. | 
					
						
							| 
									
										
										
										
											2015-08-03 13:09:07 +01:00
										 |  |  |   def self.for(path) | 
					
						
							| 
									
										
										
										
											2020-11-02 12:56:59 +00:00
										 |  |  |     original_path = path | 
					
						
							| 
									
										
										
										
											2020-11-27 13:12:09 +00:00
										 |  |  |     raise Errno::ENOENT, original_path.to_s unless original_path.exist? | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (path = original_path.realpath) | 
					
						
							| 
									
										
										
										
											2020-11-02 12:56:59 +00:00
										 |  |  |       until path.root? | 
					
						
							|  |  |  |         return Keg.new(path) if path.parent.parent == HOMEBREW_CELLAR.realpath | 
					
						
							| 
									
										
										
										
											2018-09-17 02:45:00 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-02 12:56:59 +00:00
										 |  |  |         path = path.parent.realpath # realpath() prevents root? failing | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2009-10-23 16:03:38 +01:00
										 |  |  |     end | 
					
						
							| 
									
										
										
										
											2020-11-02 12:56:59 +00:00
										 |  |  |     raise NotAKegError, "#{original_path} is not inside a keg" | 
					
						
							| 
									
										
										
										
											2009-10-23 16:03:38 +01:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-27 17:26:21 +00:00
										 |  |  |   def self.all | 
					
						
							|  |  |  |     Formula.racks.flat_map(&:subdirs).map { |d| new(d) } | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-30 20:16:01 -05:00
										 |  |  |   attr_reader :path, :name, :linked_keg_record, :opt_record | 
					
						
							| 
									
										
										
										
											2020-05-12 08:32:27 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-26 19:06:31 -05:00
										 |  |  |   protected :path | 
					
						
							| 
									
										
										
										
											2014-06-23 22:52:41 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-18 22:21:22 +00:00
										 |  |  |   extend Forwardable | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def_delegators :path, | 
					
						
							| 
									
										
										
										
											2019-04-30 08:44:35 +01:00
										 |  |  |                  :to_s, :hash, :abv, :disk_usage, :file_count, :directory?, :exist?, :/, | 
					
						
							|  |  |  |                  :join, :rename, :find | 
					
						
							| 
									
										
										
										
											2017-01-18 22:21:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-03 13:09:07 +01:00
										 |  |  |   def initialize(path) | 
					
						
							| 
									
										
										
										
											2016-12-31 16:38:05 +00:00
										 |  |  |     path = path.resolved_path if path.to_s.start_with?("#{HOMEBREW_PREFIX}/opt/") | 
					
						
							| 
									
										
										
										
											2020-07-09 14:21:09 +01:00
										 |  |  |     raise "#{path} is not a valid keg" if path.parent.parent.realpath != HOMEBREW_CELLAR.realpath | 
					
						
							| 
									
										
										
										
											2014-06-26 19:06:31 -05:00
										 |  |  |     raise "#{path} is not a directory" unless path.directory? | 
					
						
							| 
									
										
										
										
											2018-09-17 02:45:00 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-26 19:06:31 -05:00
										 |  |  |     @path = path | 
					
						
							|  |  |  |     @name = path.parent.basename.to_s | 
					
						
							| 
									
										
										
										
											2016-09-15 18:28:42 +01:00
										 |  |  |     @linked_keg_record = HOMEBREW_LINKED_KEGS/name | 
					
						
							|  |  |  |     @opt_record = HOMEBREW_PREFIX/"opt/#{name}" | 
					
						
							| 
									
										
										
										
											2023-04-27 04:09:28 +01:00
										 |  |  |     @oldname_opt_records = [] | 
					
						
							| 
									
										
										
										
											2017-02-11 13:43:00 +01:00
										 |  |  |     @require_relocation = false | 
					
						
							| 
									
										
										
										
											2014-03-27 22:35:08 -05:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-17 20:34:31 +08:00
										 |  |  |   def rack | 
					
						
							|  |  |  |     path.parent | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-18 22:20:44 +00:00
										 |  |  |   alias to_path to_s | 
					
						
							| 
									
										
										
										
											2014-06-26 19:06:31 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-20 12:03:48 +02:00
										 |  |  |   sig { returns(String) } | 
					
						
							| 
									
										
										
										
											2014-06-26 19:06:31 -05:00
										 |  |  |   def inspect | 
					
						
							|  |  |  |     "#<#{self.class.name}:#{path}>" | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def ==(other) | 
					
						
							|  |  |  |     instance_of?(other.class) && path == other.path | 
					
						
							|  |  |  |   end | 
					
						
							| 
									
										
										
										
											2016-09-23 18:13:48 +02:00
										 |  |  |   alias eql? == | 
					
						
							| 
									
										
										
										
											2014-06-26 19:06:31 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-20 12:03:48 +02:00
										 |  |  |   sig { returns(T::Boolean) } | 
					
						
							| 
									
										
										
										
											2016-01-09 18:59:34 +08:00
										 |  |  |   def empty_installation? | 
					
						
							| 
									
										
										
										
											2017-02-24 17:44:27 +09:00
										 |  |  |     Pathname.glob("#{path}/*") do |file| | 
					
						
							|  |  |  |       return false if file.directory? && !file.children.reject(&:ds_store?).empty? | 
					
						
							| 
									
										
										
										
											2018-09-17 02:45:00 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-09 18:59:34 +08:00
										 |  |  |       basename = file.basename.to_s | 
					
						
							|  |  |  |       next if Metafiles.copy?(basename) | 
					
						
							|  |  |  |       next if %w[.DS_Store INSTALL_RECEIPT.json].include?(basename) | 
					
						
							| 
									
										
										
										
											2018-09-17 02:45:00 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-09 18:59:34 +08:00
										 |  |  |       return false | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     true | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-11 13:43:00 +01:00
										 |  |  |   def require_relocation? | 
					
						
							|  |  |  |     @require_relocation | 
					
						
							|  |  |  |   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 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-28 11:41:12 +01:00
										 |  |  |   def remove_old_aliases | 
					
						
							|  |  |  |     opt = opt_record.parent | 
					
						
							| 
									
										
										
										
											2020-07-09 14:17:21 +01:00
										 |  |  |     linkedkegs = linked_keg_record.parent | 
					
						
							| 
									
										
										
										
											2017-07-28 11:41:12 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     tap = begin | 
					
						
							|  |  |  |       to_formula.tap | 
					
						
							| 
									
										
										
										
											2020-03-04 14:17:08 +00:00
										 |  |  |     rescue | 
					
						
							| 
									
										
										
										
											2017-07-28 11:41:12 +01:00
										 |  |  |       # If the formula can't be found, just ignore aliases for now. | 
					
						
							|  |  |  |       nil | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if tap | 
					
						
							|  |  |  |       bad_tap_opt = opt/tap.user | 
					
						
							| 
									
										
										
										
											2019-02-19 13:11:32 +00:00
										 |  |  |       FileUtils.rm_rf bad_tap_opt if !bad_tap_opt.symlink? && bad_tap_opt.directory? | 
					
						
							| 
									
										
										
										
											2017-07-28 11:41:12 +01:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-05 18:03:04 +01:00
										 |  |  |     aliases.each do |a| | 
					
						
							| 
									
										
										
										
											2018-04-08 16:02:02 -07:00
										 |  |  |       # versioned aliases are handled below | 
					
						
							| 
									
										
										
										
											2019-10-13 19:26:39 +01:00
										 |  |  |       next if a.match?(/.+@./) | 
					
						
							| 
									
										
										
										
											2018-09-17 02:45:00 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-14 16:02:06 +00:00
										 |  |  |       remove_alias_symlink(opt/a, opt_record) | 
					
						
							|  |  |  |       remove_alias_symlink(linkedkegs/a, linked_keg_record) | 
					
						
							| 
									
										
										
										
											2017-08-05 18:03:04 +01:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-28 11:41:12 +01:00
										 |  |  |     Pathname.glob("#{opt_record}@*").each do |a| | 
					
						
							| 
									
										
										
										
											2018-04-08 16:02:02 -07:00
										 |  |  |       a = a.basename.to_s | 
					
						
							| 
									
										
										
										
											2017-07-28 11:41:12 +01:00
										 |  |  |       next if aliases.include?(a) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-14 16:02:06 +00:00
										 |  |  |       remove_alias_symlink(opt/a, rack) | 
					
						
							|  |  |  |       remove_alias_symlink(linkedkegs/a, rack) | 
					
						
							| 
									
										
										
										
											2017-02-21 18:31:34 +00:00
										 |  |  |     end | 
					
						
							| 
									
										
										
										
											2017-07-28 11:41:12 +01:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def remove_opt_record | 
					
						
							|  |  |  |     opt_record.unlink | 
					
						
							| 
									
										
										
										
											2014-06-30 20:16:58 -05:00
										 |  |  |     opt_record.parent.rmdir_if_possible | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-21 13:03:52 +00:00
										 |  |  |   def uninstall(raise_failures: false) | 
					
						
							| 
									
										
										
										
											2018-06-06 13:27:59 +01:00
										 |  |  |     CacheStoreDatabase.use(:linkage) do |db| | 
					
						
							|  |  |  |       break unless db.created? | 
					
						
							| 
									
										
										
										
											2018-09-17 02:45:00 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-13 08:22:51 -07:00
										 |  |  |       LinkageCacheStore.new(path, db).delete! | 
					
						
							| 
									
										
										
										
											2018-06-06 13:27:59 +01:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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? | 
					
						
							| 
									
										
										
										
											2021-01-14 16:02:06 +00:00
										 |  |  |     remove_linked_keg_record if linked? | 
					
						
							| 
									
										
										
										
											2017-07-28 11:41:12 +01:00
										 |  |  |     remove_old_aliases | 
					
						
							| 
									
										
										
										
											2023-04-27 04:09:28 +01:00
										 |  |  |     remove_oldname_opt_records | 
					
						
							| 
									
										
										
										
											2019-05-24 16:46:54 +01:00
										 |  |  |   rescue Errno::EACCES, Errno::ENOTEMPTY | 
					
						
							| 
									
										
										
										
											2021-01-21 13:03:52 +00:00
										 |  |  |     raise if raise_failures | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-22 10:19:20 +01:00
										 |  |  |     odie <<~EOS | 
					
						
							|  |  |  |       Could not remove #{name} keg! Do so manually: | 
					
						
							|  |  |  |         sudo rm -rf #{path} | 
					
						
							|  |  |  |     EOS | 
					
						
							| 
									
										
										
										
											2009-07-24 15:10:01 +01:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-15 20:15:40 +09:00
										 |  |  |   def unlink(verbose: false, dry_run: false) | 
					
						
							| 
									
										
										
										
											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 = [] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-09 14:21:09 +01:00
										 |  |  |     keg_directories = KEG_LINK_DIRECTORIES.map { |d| path/d } | 
					
						
							|  |  |  |                                           .select(&:exist?) | 
					
						
							|  |  |  |     keg_directories.each do |dir| | 
					
						
							| 
									
										
										
										
											2013-02-17 22:54:43 -06:00
										 |  |  |       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 | 
					
						
							| 
									
										
										
										
											2020-07-09 14:21:09 +01:00
										 |  |  |         next unless dst.symlink? | 
					
						
							|  |  |  |         next if src != dst.resolved_path | 
					
						
							| 
									
										
										
										
											2018-09-17 02:45:00 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-15 20:15:40 +09:00
										 |  |  |         if dry_run | 
					
						
							| 
									
										
										
										
											2016-09-17 15:17:27 +01:00
										 |  |  |           puts dst | 
					
						
							| 
									
										
										
										
											2014-07-04 19:31:07 -05:00
										 |  |  |           Find.prune if src.directory? | 
					
						
							| 
									
										
										
										
											2016-09-17 15:17:27 +01:00
										 |  |  |           next | 
					
						
							| 
									
										
										
										
											2014-07-04 19:31:07 -05:00
										 |  |  |         end | 
					
						
							| 
									
										
										
										
											2016-09-17 15:17:27 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-13 19:26:39 +01:00
										 |  |  |         dst.uninstall_info if dst.to_s.match?(INFOFILE_RX) | 
					
						
							| 
									
										
										
										
											2016-09-17 15:17:27 +01:00
										 |  |  |         dst.unlink | 
					
						
							|  |  |  |         Find.prune if src.directory? | 
					
						
							| 
									
										
										
										
											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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-15 20:15:40 +09:00
										 |  |  |     unless dry_run | 
					
						
							| 
									
										
										
										
											2021-01-14 16:02:06 +00:00
										 |  |  |       remove_old_aliases | 
					
						
							| 
									
										
										
										
											2015-09-06 15:25:36 +08:00
										 |  |  |       remove_linked_keg_record if linked? | 
					
						
							|  |  |  |       dirs.reverse_each(&:rmdir_if_possible) | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2013-08-09 11:29:19 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-15 13:07:58 +02:00
										 |  |  |     ObserverPathnameExtension.n | 
					
						
							| 
									
										
										
										
											2009-08-29 21:07:26 +01:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-27 04:09:28 +01:00
										 |  |  |   def lock | 
					
						
							| 
									
										
										
										
											2015-08-18 19:33:24 +08:00
										 |  |  |     FormulaLock.new(name).with_lock do | 
					
						
							| 
									
										
										
										
											2023-04-27 04:09:28 +01:00
										 |  |  |       oldname_locks = oldname_opt_records.map do |record| | 
					
						
							|  |  |  |         FormulaLock.new(record.basename.to_s) | 
					
						
							| 
									
										
										
										
											2015-08-18 19:33:24 +08:00
										 |  |  |       end | 
					
						
							| 
									
										
										
										
											2023-04-27 04:09:28 +01:00
										 |  |  |       oldname_locks.each(&:lock) | 
					
						
							|  |  |  |       yield | 
					
						
							|  |  |  |     ensure | 
					
						
							|  |  |  |       oldname_locks&.each(&:unlock) | 
					
						
							| 
									
										
										
										
											2015-08-18 19:33:24 +08:00
										 |  |  |     end | 
					
						
							| 
									
										
										
										
											2013-01-23 00:26:25 -06:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-03 13:09:07 +01:00
										 |  |  |   def completion_installed?(shell) | 
					
						
							| 
									
										
										
										
											2012-07-18 03:22:00 -05:00
										 |  |  |     dir = case shell | 
					
						
							| 
									
										
										
										
											2017-06-01 16:06:51 +02:00
										 |  |  |     when :bash then path/"etc/bash_completion.d" | 
					
						
							| 
									
										
										
										
											2016-12-03 20:45:54 -06:00
										 |  |  |     when :zsh | 
					
						
							| 
									
										
										
										
											2017-03-07 10:36:57 -08:00
										 |  |  |       dir = path/"share/zsh/site-functions" | 
					
						
							|  |  |  |       dir if dir.directory? && dir.children.any? { |f| f.basename.to_s.start_with?("_") } | 
					
						
							|  |  |  |     when :fish then path/"share/fish/vendor_completions.d" | 
					
						
							| 
									
										
										
										
											2016-09-21 08:32:57 +02:00
										 |  |  |     end | 
					
						
							| 
									
										
										
										
											2017-09-24 19:24:46 +01:00
										 |  |  |     dir&.directory? && !dir.children.empty? | 
					
						
							| 
									
										
										
										
											2012-07-18 03:22:00 -05:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-07 10:36:57 -08:00
										 |  |  |   def functions_installed?(shell) | 
					
						
							|  |  |  |     case shell | 
					
						
							|  |  |  |     when :fish | 
					
						
							|  |  |  |       dir = path/"share/fish/vendor_functions.d" | 
					
						
							|  |  |  |       dir.directory? && !dir.children.empty? | 
					
						
							|  |  |  |     when :zsh | 
					
						
							|  |  |  |       # Check for non completion functions (i.e. files not started with an underscore), | 
					
						
							|  |  |  |       # since those can be checked separately | 
					
						
							|  |  |  |       dir = path/"share/zsh/site-functions" | 
					
						
							|  |  |  |       dir.directory? && dir.children.any? { |f| !f.basename.to_s.start_with?("_") } | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2016-12-03 11:36:49 -06:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-20 12:03:48 +02:00
										 |  |  |   sig { returns(T::Boolean) } | 
					
						
							| 
									
										
										
										
											2012-11-25 15:06:41 +00:00
										 |  |  |   def plist_installed? | 
					
						
							| 
									
										
										
										
											2016-08-05 22:01:32 +08:00
										 |  |  |     !Dir["#{path}/*.plist"].empty? | 
					
						
							| 
									
										
										
										
											2012-11-25 15:06:41 +00:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-04 13:18:27 +00:00
										 |  |  |   def python_site_packages_installed? | 
					
						
							| 
									
										
										
										
											2017-06-01 16:06:51 +02:00
										 |  |  |     (path/"lib/python2.7/site-packages").directory? | 
					
						
							| 
									
										
										
										
											2014-01-04 13:18:27 +00:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-20 12:03:48 +02:00
										 |  |  |   sig { returns(T::Boolean) } | 
					
						
							| 
									
										
										
										
											2014-11-02 10:33:24 -08:00
										 |  |  |   def python_pth_files_installed? | 
					
						
							| 
									
										
										
										
											2016-08-05 22:01:32 +08:00
										 |  |  |     !Dir["#{path}/lib/python2.7/site-packages/*.pth"].empty? | 
					
						
							| 
									
										
										
										
											2014-11-02 10:33:24 -08:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-20 12:03:48 +02:00
										 |  |  |   sig { returns(T::Array[Pathname]) } | 
					
						
							| 
									
										
										
										
											2015-10-20 07:05:21 +02:00
										 |  |  |   def apps | 
					
						
							|  |  |  |     app_prefix = optlinked? ? opt_record : path | 
					
						
							|  |  |  |     Pathname.glob("#{app_prefix}/{,libexec/}*.app") | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-05 14:45:26 -07:00
										 |  |  |   def elisp_installed? | 
					
						
							| 
									
										
										
										
											2015-11-01 18:04:42 -08:00
										 |  |  |     return false unless (path/"share/emacs/site-lisp"/name).exist? | 
					
						
							| 
									
										
										
										
											2018-09-17 02:45:00 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-11 10:29:21 +01:00
										 |  |  |     (path/"share/emacs/site-lisp"/name).children.any? { |f| ELISP_EXTENSIONS.include? f.extname } | 
					
						
							| 
									
										
										
										
											2015-07-05 14:45:26 -07:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-07-10 22:08:06 -05:00
										 |  |  |   def version | 
					
						
							| 
									
										
										
										
											2015-08-03 13:09:07 +01: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 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-27 22:01:22 +01:00
										 |  |  |   def to_formula | 
					
						
							| 
									
										
										
										
											2016-09-22 13:27:33 +01:00
										 |  |  |     Formulary.from_keg(self) | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-27 04:09:28 +01:00
										 |  |  |   def oldname_opt_records | 
					
						
							|  |  |  |     return @oldname_opt_records unless @oldname_opt_records.empty? | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @oldname_opt_records = if (opt_dir = HOMEBREW_PREFIX/"opt").directory? | 
					
						
							|  |  |  |       opt_dir.subdirs.select do |dir| | 
					
						
							| 
									
										
										
										
											2015-08-16 17:16:44 +03:00
										 |  |  |         dir.symlink? && dir != opt_record && path.parent == dir.resolved_path.parent | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2023-04-27 04:09:28 +01:00
										 |  |  |     else | 
					
						
							|  |  |  |       [] | 
					
						
							| 
									
										
										
										
											2015-08-16 17:16:44 +03:00
										 |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-15 20:15:40 +09:00
										 |  |  |   def link(verbose: false, dry_run: false, overwrite: false) | 
					
						
							| 
									
										
										
										
											2016-09-17 15:17:27 +01:00
										 |  |  |     raise AlreadyLinkedError, 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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-15 20:15:40 +09:00
										 |  |  |     optlink(verbose: verbose, dry_run: dry_run, overwrite: overwrite) unless dry_run | 
					
						
							| 
									
										
										
										
											2016-07-17 01:59:54 +08: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 | 
					
						
							| 
									
										
										
										
											2021-01-15 20:15:40 +09:00
										 |  |  |     link_dir("etc", verbose: verbose, dry_run: dry_run, overwrite: overwrite) { :mkpath } | 
					
						
							|  |  |  |     link_dir("bin", verbose: verbose, dry_run: dry_run, overwrite: overwrite) { :skip_dir } | 
					
						
							|  |  |  |     link_dir("sbin", verbose: verbose, dry_run: dry_run, overwrite: overwrite) { :skip_dir } | 
					
						
							|  |  |  |     link_dir("include", verbose: verbose, dry_run: dry_run, overwrite: overwrite) { :link } | 
					
						
							| 
									
										
										
										
											2012-01-04 20:50:19 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-15 20:15:40 +09:00
										 |  |  |     link_dir("share", verbose: verbose, dry_run: dry_run, overwrite: overwrite) do |relative_path| | 
					
						
							| 
									
										
										
										
											2014-12-26 11:58:09 -05:00
										 |  |  |       case relative_path.to_s | 
					
						
							| 
									
										
										
										
											2014-02-22 09:20:09 -08:00
										 |  |  |       when INFOFILE_RX then :info | 
					
						
							| 
									
										
										
										
											2020-11-13 10:07:02 -05:00
										 |  |  |       when "locale/locale.alias", | 
					
						
							|  |  |  |            %r{^icons/.*/icon-theme\.cache$} | 
					
						
							|  |  |  |         :skip_file | 
					
						
							|  |  |  |       when LOCALEDIR_RX, | 
					
						
							|  |  |  |            %r{^icons/}, # all icons subfolders should also mkpath | 
					
						
							|  |  |  |            /^zsh/, | 
					
						
							|  |  |  |            /^fish/, | 
					
						
							|  |  |  |            %r{^lua/}, #  Lua, Lua51, Lua53 all need the same handling. | 
					
						
							|  |  |  |            %r{^guile/}, | 
					
						
							|  |  |  |            *SHARE_PATHS | 
					
						
							|  |  |  |         :mkpath | 
					
						
							| 
									
										
										
										
											2020-11-13 17:21:51 +01:00
										 |  |  |       else | 
					
						
							|  |  |  |         :link | 
					
						
							| 
									
										
										
										
											2012-01-04 20:50:19 -06:00
										 |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2009-07-29 00:56:22 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-15 20:15:40 +09:00
										 |  |  |     link_dir("lib", verbose: verbose, dry_run: dry_run, overwrite: overwrite) do |relative_path| | 
					
						
							| 
									
										
										
										
											2014-12-26 11:58:09 -05:00
										 |  |  |       case relative_path.to_s | 
					
						
							| 
									
										
										
										
											2020-11-13 17:21:51 +01:00
										 |  |  |       when "charset.alias" | 
					
						
							|  |  |  |         :skip_file | 
					
						
							| 
									
										
										
										
											2020-11-13 10:07:02 -05:00
										 |  |  |       when "pkgconfig", # pkg-config database gets explicitly created | 
					
						
							|  |  |  |            "cmake",     # cmake database gets explicitly created | 
					
						
							|  |  |  |            "dtrace",    # lib/language folders also get explicitly created | 
					
						
							|  |  |  |            /^gdk-pixbuf/, | 
					
						
							|  |  |  |            "ghc", | 
					
						
							|  |  |  |            /^gio/, | 
					
						
							| 
									
										
										
										
											2022-07-11 10:10:38 +08:00
										 |  |  |            /^lua/, | 
					
						
							| 
									
										
										
										
											2020-11-13 10:07:02 -05:00
										 |  |  |            /^mecab/, | 
					
						
							|  |  |  |            /^node/, | 
					
						
							|  |  |  |            /^ocaml/, | 
					
						
							|  |  |  |            /^perl5/, | 
					
						
							|  |  |  |            "php", | 
					
						
							| 
									
										
										
										
											2021-07-03 23:33:09 +01:00
										 |  |  |            /^python[23]\.\d+/, | 
					
						
							| 
									
										
										
										
											2020-11-13 10:07:02 -05:00
										 |  |  |            /^R/, | 
					
						
							| 
									
										
										
										
											2020-11-13 17:21:51 +01:00
										 |  |  |            /^ruby/ | 
					
						
							| 
									
										
										
										
											2020-11-13 10:07:02 -05:00
										 |  |  |         :mkpath | 
					
						
							| 
									
										
										
										
											2020-11-13 17:21:51 +01:00
										 |  |  |       else | 
					
						
							|  |  |  |         # Everything else is symlinked to the cellar | 
					
						
							|  |  |  |         :link | 
					
						
							| 
									
										
										
										
											2009-09-17 21:26:17 +01:00
										 |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-15 20:15:40 +09:00
										 |  |  |     link_dir("Frameworks", verbose: verbose, dry_run: dry_run, overwrite: overwrite) do |relative_path| | 
					
						
							| 
									
										
										
										
											2013-06-17 09:01:37 +02:00
										 |  |  |       # 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. | 
					
						
							| 
									
										
										
										
											2019-10-13 19:26:39 +01:00
										 |  |  |       if relative_path.to_s.match?(%r{[^/]*\.framework(/Versions)?$}) | 
					
						
							| 
									
										
										
										
											2013-06-17 09:01:37 +02:00
										 |  |  |         :mkpath | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  |         :link | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2021-01-15 20:15:40 +09:00
										 |  |  |     unless dry_run | 
					
						
							|  |  |  |       make_relative_symlink(linked_keg_record, path, verbose: verbose, dry_run: dry_run, overwrite: overwrite) | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2014-04-21 09:40:24 -05:00
										 |  |  |   rescue LinkError | 
					
						
							| 
									
										
										
										
											2021-01-15 20:15:40 +09:00
										 |  |  |     unlink(verbose: verbose) | 
					
						
							| 
									
										
										
										
											2012-08-10 16:33:22 -04:00
										 |  |  |     raise | 
					
						
							| 
									
										
										
										
											2014-04-21 09:40:24 -05:00
										 |  |  |   else | 
					
						
							| 
									
										
										
										
											2016-05-15 13:07:58 +02:00
										 |  |  |     ObserverPathnameExtension.n | 
					
						
							| 
									
										
										
										
											2012-08-10 16:33:22 -04:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-30 11:08:52 +01:00
										 |  |  |   def prepare_debug_symbols; end | 
					
						
							| 
									
										
										
										
											2022-07-26 00:00:45 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-12 16:47:56 +00:00
										 |  |  |   def consistent_reproducible_symlink_permissions!; end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-27 04:09:28 +01:00
										 |  |  |   def remove_oldname_opt_records | 
					
						
							|  |  |  |     oldname_opt_records.reject! do |record| | 
					
						
							|  |  |  |       return false if record.resolved_path != path | 
					
						
							| 
									
										
										
										
											2018-09-17 02:45:00 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-27 04:09:28 +01:00
										 |  |  |       record.unlink | 
					
						
							|  |  |  |       record.parent.rmdir_if_possible | 
					
						
							|  |  |  |       true | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2015-08-16 17:16:44 +03:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-25 12:47:57 +01:00
										 |  |  |   def tab | 
					
						
							|  |  |  |     Tab.for_keg(self) | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def runtime_dependencies | 
					
						
							| 
									
										
										
										
											2019-11-05 20:33:32 +00:00
										 |  |  |     Keg.cache[:runtime_dependencies] ||= {} | 
					
						
							|  |  |  |     Keg.cache[:runtime_dependencies][path] ||= tab.runtime_dependencies | 
					
						
							| 
									
										
										
										
											2018-03-25 12:47:57 +01:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-30 03:22:09 -07:00
										 |  |  |   def aliases | 
					
						
							| 
									
										
										
										
											2018-03-25 12:47:57 +01:00
										 |  |  |     tab.aliases || [] | 
					
						
							| 
									
										
										
										
											2016-09-30 03:22:09 -07:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-15 20:15:40 +09:00
										 |  |  |   def optlink(verbose: false, dry_run: false, overwrite: false) | 
					
						
							| 
									
										
										
										
											2014-06-30 21:53:48 -05:00
										 |  |  |     opt_record.delete if opt_record.symlink? || opt_record.exist? | 
					
						
							| 
									
										
										
										
											2021-01-15 20:15:40 +09:00
										 |  |  |     make_relative_symlink(opt_record, path, verbose: verbose, dry_run: dry_run, overwrite: overwrite) | 
					
						
							| 
									
										
										
										
											2016-10-03 02:41:17 -07:00
										 |  |  |     aliases.each do |a| | 
					
						
							|  |  |  |       alias_opt_record = opt_record.parent/a | 
					
						
							|  |  |  |       alias_opt_record.delete if alias_opt_record.symlink? || alias_opt_record.exist? | 
					
						
							| 
									
										
										
										
											2021-01-15 20:15:40 +09:00
										 |  |  |       make_relative_symlink(alias_opt_record, path, verbose: verbose, dry_run: dry_run, overwrite: overwrite) | 
					
						
							| 
									
										
										
										
											2016-09-30 03:22:09 -07:00
										 |  |  |     end | 
					
						
							| 
									
										
										
										
											2015-08-16 17:16:44 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-27 04:09:28 +01:00
										 |  |  |     oldname_opt_records.each do |record| | 
					
						
							|  |  |  |       record.delete | 
					
						
							|  |  |  |       make_relative_symlink(record, path, verbose: verbose, dry_run: dry_run, overwrite: overwrite) | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2009-07-24 15:10:01 +01:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-13 09:05:40 +00:00
										 |  |  |   def delete_pyc_files! | 
					
						
							| 
									
										
										
										
											2023-03-21 21:42:51 -07:00
										 |  |  |     path.find { |pn| pn.delete if PYC_EXTENSIONS.include?(pn.extname) } | 
					
						
							|  |  |  |     path.find { |pn| FileUtils.rm_rf pn if pn.basename.to_s == "__pycache__" } | 
					
						
							| 
									
										
										
										
											2014-03-13 09:05:40 +00:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-03 19:23:19 +01:00
										 |  |  |   def binary_executable_or_library_files | 
					
						
							| 
									
										
										
										
											2023-01-26 21:41:45 +09:00
										 |  |  |     [] | 
					
						
							| 
									
										
										
										
											2021-07-03 19:23:19 +01:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-08 18:09:18 -07:00
										 |  |  |   def codesign_patched_binary(file); end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-26 18:45:34 -05:00
										 |  |  |   private | 
					
						
							| 
									
										
										
										
											2013-04-07 00:49:56 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-15 20:15:40 +09:00
										 |  |  |   def resolve_any_conflicts(dst, dry_run: false, verbose: false, overwrite: false) | 
					
						
							| 
									
										
										
										
											2014-10-20 17:07:53 -05:00
										 |  |  |     return unless dst.symlink? | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-12 19:56:58 -05:00
										 |  |  |     src = dst.resolved_path | 
					
						
							| 
									
										
										
										
											2014-10-20 17:07:54 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-12 19:56:58 -05:00
										 |  |  |     # 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-10-20 17:07:54 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     begin | 
					
						
							|  |  |  |       stat = src.lstat | 
					
						
							|  |  |  |     rescue Errno::ENOENT | 
					
						
							|  |  |  |       # dst is a broken symlink, so remove it. | 
					
						
							| 
									
										
										
										
											2021-01-15 20:15:40 +09:00
										 |  |  |       dst.unlink unless dry_run | 
					
						
							| 
									
										
										
										
											2014-10-20 17:07:54 -05:00
										 |  |  |       return | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-23 22:02:23 +02:00
										 |  |  |     return unless stat.directory? | 
					
						
							| 
									
										
										
										
											2018-09-17 02:45:00 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-23 22:02:23 +02:00
										 |  |  |     begin | 
					
						
							|  |  |  |       keg = Keg.for(src) | 
					
						
							|  |  |  |     rescue NotAKegError | 
					
						
							| 
									
										
										
										
											2021-01-26 15:21:24 -05:00
										 |  |  |       puts "Won't resolve conflicts for symlink #{dst} as it doesn't resolve into the Cellar." if verbose | 
					
						
							| 
									
										
										
										
											2016-09-23 22:02:23 +02:00
										 |  |  |       return | 
					
						
							| 
									
										
										
										
											2009-10-23 16:03:38 +01:00
										 |  |  |     end | 
					
						
							| 
									
										
										
										
											2016-09-23 22:02:23 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-15 20:15:40 +09:00
										 |  |  |     dst.unlink unless dry_run | 
					
						
							|  |  |  |     keg.link_dir(src, dry_run: false, verbose: false, overwrite: false) { :mkpath } | 
					
						
							| 
									
										
										
										
											2016-09-23 22:02:23 +02:00
										 |  |  |     true | 
					
						
							| 
									
										
										
										
											2009-10-23 16:03:38 +01:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-15 20:15:40 +09:00
										 |  |  |   def make_relative_symlink(dst, src, verbose: false, dry_run: false, overwrite: false) | 
					
						
							| 
									
										
										
										
											2014-07-04 17:22:58 -05:00
										 |  |  |     if dst.symlink? && src == dst.resolved_path | 
					
						
							| 
									
										
										
										
											2021-01-15 20:15:40 +09:00
										 |  |  |       puts "Skipping; link already exists: #{dst}" if 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 | 
					
						
							| 
									
										
										
										
											2021-01-15 20:15:40 +09:00
										 |  |  |     if dry_run && overwrite | 
					
						
							| 
									
										
										
										
											2013-07-10 08:50:53 -07:00
										 |  |  |       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 | 
					
						
							| 
									
										
										
										
											2021-01-15 20:15:40 +09:00
										 |  |  |     if 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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-15 20:15:40 +09:00
										 |  |  |     dst.delete if overwrite && (dst.exist? || dst.symlink?) | 
					
						
							| 
									
										
										
										
											2014-04-21 09:40:23 -05:00
										 |  |  |     dst.make_relative_symlink(src) | 
					
						
							| 
									
										
										
										
											2014-09-09 14:24:18 -05:00
										 |  |  |   rescue Errno::EEXIST => e | 
					
						
							| 
									
										
										
										
											2016-09-23 22:02:23 +02:00
										 |  |  |     raise ConflictError.new(self, src.relative_path_from(path), dst, e) if dst.exist? | 
					
						
							| 
									
										
										
										
											2018-09-17 02:45:00 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-23 22:02:23 +02:00
										 |  |  |     if dst.symlink? | 
					
						
							| 
									
										
										
										
											2014-04-21 09:40:23 -05:00
										 |  |  |       dst.unlink | 
					
						
							|  |  |  |       retry | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2014-09-09 14:24:18 -05:00
										 |  |  |   rescue Errno::EACCES => e | 
					
						
							|  |  |  |     raise DirectoryNotWritableError.new(self, src.relative_path_from(path), dst, e) | 
					
						
							|  |  |  |   rescue SystemCallError => e | 
					
						
							|  |  |  |     raise LinkError.new(self, src.relative_path_from(path), dst, e) | 
					
						
							| 
									
										
										
										
											2012-03-19 12:24:13 +00:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-14 16:02:06 +00:00
										 |  |  |   def remove_alias_symlink(alias_symlink, alias_match_path) | 
					
						
							|  |  |  |     if alias_symlink.symlink? && alias_symlink.exist? | 
					
						
							| 
									
										
										
										
											2021-01-15 08:57:02 +00:00
										 |  |  |       alias_symlink.delete if alias_match_path.exist? && alias_symlink.realpath == alias_match_path.realpath | 
					
						
							| 
									
										
										
										
											2021-01-14 16:02:06 +00:00
										 |  |  |     elsif alias_symlink.symlink? || alias_symlink.exist? | 
					
						
							|  |  |  |       alias_symlink.delete | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   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 | 
					
						
							| 
									
										
										
										
											2021-01-15 20:15:40 +09:00
										 |  |  |   def link_dir(relative_dir, verbose: false, dry_run: false, overwrite: false) | 
					
						
							| 
									
										
										
										
											2017-06-01 16:06:51 +02:00
										 |  |  |     root = path/relative_dir | 
					
						
							| 
									
										
										
										
											2010-04-04 13:45:02 -07:00
										 |  |  |     return unless root.exist? | 
					
						
							| 
									
										
										
										
											2018-09-17 02:45:00 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-10 16:48:30 +01:00
										 |  |  |     root.find do |src| | 
					
						
							|  |  |  |       next if src == root | 
					
						
							| 
									
										
										
										
											2018-09-17 02:45:00 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											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? | 
					
						
							| 
									
										
										
										
											2015-08-03 13:09:07 +01:00
										 |  |  |         Find.prune if File.basename(src) == ".DS_Store" | 
					
						
							| 
									
										
										
										
											2017-01-06 16:35:41 +00:00
										 |  |  |         Find.prune if src.resolved_path == dst | 
					
						
							| 
									
										
										
										
											2016-06-21 00:22:58 +01:00
										 |  |  |         # Don't link pyc or pyo files because Python overwrites these | 
					
						
							|  |  |  |         # cached object files and next time brew wants to link, the | 
					
						
							|  |  |  |         # file is in the way. | 
					
						
							| 
									
										
										
										
											2020-09-11 10:29:21 +01:00
										 |  |  |         Find.prune if PYC_EXTENSIONS.include?(src.extname) && src.to_s.include?("/site-packages/") | 
					
						
							| 
									
										
										
										
											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 | 
					
						
							| 
									
										
										
										
											2015-08-03 13:09:07 +01:00
										 |  |  |           next if File.basename(src) == "dir" # skip historical local 'dir' files | 
					
						
							| 
									
										
										
										
											2018-09-17 02:45:00 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-15 20:15:40 +09:00
										 |  |  |           make_relative_symlink dst, src, verbose: verbose, dry_run: dry_run, overwrite: overwrite | 
					
						
							| 
									
										
										
										
											2012-02-26 19:28:46 -06:00
										 |  |  |           dst.install_info | 
					
						
							|  |  |  |         else | 
					
						
							| 
									
										
										
										
											2021-01-15 20:15:40 +09:00
										 |  |  |           make_relative_symlink dst, src, verbose: verbose, dry_run: dry_run, overwrite: overwrite | 
					
						
							| 
									
										
										
										
											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 | 
					
						
							| 
									
										
										
										
											2015-08-03 13:09:07 +01:00
										 |  |  |         next if dst.directory? && !dst.symlink? | 
					
						
							| 
									
										
										
										
											2018-09-17 02:45:00 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											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 | 
					
						
							| 
									
										
										
										
											2015-08-03 13:09:07 +01: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 | 
					
						
							| 
									
										
										
										
											2021-01-15 20:15:40 +09:00
										 |  |  |           dst.mkpath unless resolve_any_conflicts(dst, verbose: verbose, dry_run: dry_run, overwrite: overwrite) | 
					
						
							| 
									
										
										
										
											2009-10-23 16:03:38 +01:00
										 |  |  |         else | 
					
						
							| 
									
										
										
										
											2021-01-15 20:15:40 +09:00
										 |  |  |           unless resolve_any_conflicts(dst, verbose: verbose, dry_run: dry_run, overwrite: overwrite) | 
					
						
							|  |  |  |             make_relative_symlink dst, src, verbose: verbose, dry_run: dry_run, overwrite: overwrite | 
					
						
							| 
									
										
										
										
											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 | 
					
						
							| 
									
										
										
										
											2018-10-04 22:55:00 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | require "extend/os/keg" |