| 
									
										
										
										
											2019-04-19 15:38:03 +09:00
										 |  |  | # frozen_string_literal: true | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-07 00:31:28 +02:00
										 |  |  | require "extend/cachable" | 
					
						
							| 
									
										
										
										
											2016-07-09 13:51:19 +01:00
										 |  |  | require "readall" | 
					
						
							| 
									
										
										
										
											2018-10-13 08:22:51 -07:00
										 |  |  | require "description_cache_store" | 
					
						
							| 
									
										
										
										
											2016-01-04 16:22:26 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-18 21:42:43 -04:00
										 |  |  | # A {Tap} is used to extend the formulae provided by Homebrew core. | 
					
						
							| 
									
										
										
										
											2015-06-13 01:53:55 +08:00
										 |  |  | # Usually, it's synced with a remote git repository. And it's likely | 
					
						
							| 
									
										
										
										
											2018-09-04 09:58:58 +01:00
										 |  |  | # a GitHub repository with the name of `user/homebrew-repo`. In such | 
					
						
							| 
									
										
										
										
											2015-06-13 01:53:55 +08:00
										 |  |  | # case, `user/repo` will be used as the {#name} of this {Tap}, where | 
					
						
							| 
									
										
										
										
											2018-09-04 09:58:58 +01:00
										 |  |  | # {#user} represents GitHub username and {#repo} represents repository | 
					
						
							| 
									
										
										
										
											2015-06-13 01:53:55 +08:00
										 |  |  | # name without leading `homebrew-`. | 
					
						
							| 
									
										
										
										
											2015-06-10 15:39:47 +08:00
										 |  |  | class Tap | 
					
						
							| 
									
										
										
										
											2017-10-07 00:31:28 +02:00
										 |  |  |   extend Cachable | 
					
						
							| 
									
										
										
										
											2015-09-27 16:52:14 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-19 21:46:20 +09:00
										 |  |  |   TAP_DIRECTORY = (HOMEBREW_LIBRARY/"Taps").freeze | 
					
						
							| 
									
										
										
										
											2015-09-27 16:52:14 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-06 21:36:26 +08:00
										 |  |  |   def self.fetch(*args) | 
					
						
							|  |  |  |     case args.length | 
					
						
							|  |  |  |     when 1
 | 
					
						
							|  |  |  |       user, repo = args.first.split("/", 2) | 
					
						
							|  |  |  |     when 2
 | 
					
						
							| 
									
										
										
										
											2018-09-17 19:44:12 +02:00
										 |  |  |       user = args.first | 
					
						
							|  |  |  |       repo = args.second | 
					
						
							| 
									
										
										
										
											2015-12-06 21:36:26 +08:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-19 13:11:32 +00:00
										 |  |  |     raise "Invalid tap name '#{args.join("/")}'" if [user, repo].any? { |part| part.nil? || part.include?("/") } | 
					
						
							| 
									
										
										
										
											2015-12-06 21:36:26 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-18 23:32:06 -07:00
										 |  |  |     # We special case homebrew and linuxbrew so that users don't have to shift in a terminal. | 
					
						
							|  |  |  |     user = user.capitalize if ["homebrew", "linuxbrew"].include? user | 
					
						
							| 
									
										
										
										
											2019-02-25 22:56:29 +01:00
										 |  |  |     repo = repo.sub(HOMEBREW_OFFICIAL_REPO_PREFIXES_REGEX, "") | 
					
						
							| 
									
										
										
										
											2015-12-06 21:36:26 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-19 13:11:32 +00:00
										 |  |  |     return CoreTap.instance if ["Homebrew", "Linuxbrew"].include?(user) && ["core", "homebrew"].include?(repo) | 
					
						
							| 
									
										
										
										
											2015-12-06 21:36:26 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-27 16:52:14 +08:00
										 |  |  |     cache_key = "#{user}/#{repo}".downcase | 
					
						
							| 
									
										
										
										
											2017-10-07 00:31:28 +02:00
										 |  |  |     cache.fetch(cache_key) { |key| cache[key] = Tap.new(user, repo) } | 
					
						
							| 
									
										
										
										
											2015-09-27 16:52:14 +08:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-18 16:56:59 +02:00
										 |  |  |   def self.from_path(path) | 
					
						
							| 
									
										
										
										
											2018-03-29 22:05:02 +02:00
										 |  |  |     match = File.expand_path(path).match(HOMEBREW_TAP_PATH_REGEX) | 
					
						
							| 
									
										
										
										
											2017-07-29 16:27:54 +02:00
										 |  |  |     raise "Invalid tap path '#{path}'" unless match | 
					
						
							| 
									
										
										
										
											2018-09-17 02:45:00 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-29 16:27:54 +02:00
										 |  |  |     fetch(match[:user], match[:repo]) | 
					
						
							| 
									
										
										
										
											2017-03-18 16:56:59 +02:00
										 |  |  |   rescue | 
					
						
							|  |  |  |     # No need to error as a nil tap is sufficient to show failure. | 
					
						
							|  |  |  |     nil | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-09 10:13:28 +02:00
										 |  |  |   def self.default_cask_tap | 
					
						
							|  |  |  |     @default_cask_tap ||= fetch("Homebrew", "cask") | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-10 15:39:47 +08:00
										 |  |  |   extend Enumerable | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-04 09:58:58 +01:00
										 |  |  |   # The user name of this {Tap}. Usually, it's the GitHub username of | 
					
						
							| 
									
										
										
										
											2018-10-18 21:42:43 -04:00
										 |  |  |   # this {Tap}'s remote repository. | 
					
						
							| 
									
										
										
										
											2015-06-10 15:39:47 +08:00
										 |  |  |   attr_reader :user | 
					
						
							| 
									
										
										
										
											2015-06-13 01:53:55 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   # The repository name of this {Tap} without leading `homebrew-`. | 
					
						
							| 
									
										
										
										
											2015-06-10 15:39:47 +08:00
										 |  |  |   attr_reader :repo | 
					
						
							| 
									
										
										
										
											2015-06-13 01:53:55 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   # The name of this {Tap}. It combines {#user} and {#repo} with a slash. | 
					
						
							|  |  |  |   # {#name} is always in lowercase. | 
					
						
							|  |  |  |   # e.g. `user/repo` | 
					
						
							| 
									
										
										
										
											2015-06-10 15:39:47 +08:00
										 |  |  |   attr_reader :name | 
					
						
							| 
									
										
										
										
											2015-06-13 01:53:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-12 17:30:02 -04:00
										 |  |  |   # The full name of this {Tap}, including the `homebrew-` prefix. | 
					
						
							|  |  |  |   # It combines {#user} and 'homebrew-'-prefixed {#repo} with a slash. | 
					
						
							|  |  |  |   # e.g. `user/homebrew-repo` | 
					
						
							|  |  |  |   attr_reader :full_name | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-13 01:53:55 +08:00
										 |  |  |   # The local path to this {Tap}. | 
					
						
							|  |  |  |   # e.g. `/usr/local/Library/Taps/user/homebrew-repo` | 
					
						
							| 
									
										
										
										
											2015-06-10 15:39:47 +08:00
										 |  |  |   attr_reader :path | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-02 14:35:42 +08:00
										 |  |  |   # @private | 
					
						
							| 
									
										
										
										
											2015-06-13 01:57:00 +08:00
										 |  |  |   def initialize(user, repo) | 
					
						
							| 
									
										
										
										
											2015-12-02 14:35:42 +08:00
										 |  |  |     @user = user | 
					
						
							| 
									
										
										
										
											2015-06-10 15:39:47 +08:00
										 |  |  |     @repo = repo | 
					
						
							|  |  |  |     @name = "#{@user}/#{@repo}".downcase | 
					
						
							| 
									
										
										
										
											2017-06-12 17:30:02 -04:00
										 |  |  |     @full_name = "#{@user}/homebrew-#{@repo}" | 
					
						
							|  |  |  |     @path = TAP_DIRECTORY/@full_name.downcase | 
					
						
							| 
									
										
										
										
											2016-07-02 09:43:12 +02:00
										 |  |  |     @path.extend(GitRepositoryExtension) | 
					
						
							| 
									
										
										
										
											2018-04-07 20:28:56 +01:00
										 |  |  |     @alias_table = nil | 
					
						
							|  |  |  |     @alias_reverse_table = nil | 
					
						
							| 
									
										
										
										
											2015-06-13 01:57:00 +08:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-18 21:42:43 -04:00
										 |  |  |   # Clear internal cache | 
					
						
							| 
									
										
										
										
											2016-02-06 03:50:06 +08:00
										 |  |  |   def clear_cache | 
					
						
							|  |  |  |     @remote = nil | 
					
						
							| 
									
										
										
										
											2018-05-25 22:47:31 +02:00
										 |  |  |     @repo_var = nil | 
					
						
							| 
									
										
										
										
											2016-02-06 03:50:06 +08:00
										 |  |  |     @formula_dir = nil | 
					
						
							| 
									
										
										
										
											2016-08-04 14:37:37 +04:00
										 |  |  |     @cask_dir = nil | 
					
						
							| 
									
										
										
										
											2018-07-25 11:38:19 +02:00
										 |  |  |     @command_dir = nil | 
					
						
							| 
									
										
										
										
											2016-02-06 03:50:06 +08:00
										 |  |  |     @formula_files = nil | 
					
						
							| 
									
										
										
										
											2016-03-23 14:55:42 +08:00
										 |  |  |     @alias_dir = nil | 
					
						
							| 
									
										
										
										
											2016-02-06 03:50:06 +08:00
										 |  |  |     @alias_files = nil | 
					
						
							|  |  |  |     @aliases = nil | 
					
						
							|  |  |  |     @alias_table = nil | 
					
						
							|  |  |  |     @alias_reverse_table = nil | 
					
						
							|  |  |  |     @command_files = nil | 
					
						
							|  |  |  |     @formula_renames = nil | 
					
						
							| 
									
										
										
										
											2016-02-25 14:14:33 +08:00
										 |  |  |     @tap_migrations = nil | 
					
						
							| 
									
										
										
										
											2016-04-12 11:00:23 +01:00
										 |  |  |     @config = nil | 
					
						
							|  |  |  |     remove_instance_variable(:@private) if instance_variable_defined?(:@private) | 
					
						
							| 
									
										
										
										
											2016-02-06 03:50:06 +08:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-13 01:53:55 +08:00
										 |  |  |   # The remote path to this {Tap}. | 
					
						
							|  |  |  |   # e.g. `https://github.com/user/homebrew-repo` | 
					
						
							| 
									
										
										
										
											2015-06-13 01:57:00 +08:00
										 |  |  |   def remote | 
					
						
							| 
									
										
										
										
											2016-07-02 09:43:12 +02:00
										 |  |  |     raise TapUnavailableError, name unless installed? | 
					
						
							| 
									
										
										
										
											2018-09-17 02:45:00 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-02 09:43:12 +02:00
										 |  |  |     @remote ||= path.git_origin | 
					
						
							| 
									
										
										
										
											2015-06-10 15:39:47 +08:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-19 15:25:29 +08:00
										 |  |  |   # The default remote path to this {Tap}. | 
					
						
							|  |  |  |   def default_remote | 
					
						
							| 
									
										
										
										
											2017-06-12 17:30:02 -04:00
										 |  |  |     "https://github.com/#{full_name}" | 
					
						
							| 
									
										
										
										
											2016-04-19 15:25:29 +08:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-25 16:21:37 +02:00
										 |  |  |   def repo_var | 
					
						
							|  |  |  |     @repo_var ||= path.to_s | 
					
						
							| 
									
										
										
										
											2018-09-15 00:04:01 +02:00
										 |  |  |                       .delete_prefix(TAP_DIRECTORY.to_s) | 
					
						
							| 
									
										
										
										
											2018-05-25 16:21:37 +02:00
										 |  |  |                       .tr("^A-Za-z0-9", "_") | 
					
						
							|  |  |  |                       .upcase | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-30 16:51:00 +08:00
										 |  |  |   # True if this {Tap} is a git repository. | 
					
						
							|  |  |  |   def git? | 
					
						
							| 
									
										
										
										
											2016-07-02 09:43:12 +02:00
										 |  |  |     path.git? | 
					
						
							| 
									
										
										
										
											2015-07-30 16:51:00 +08:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-27 16:32:13 -04:00
										 |  |  |   # git branch for this {Tap}. | 
					
						
							|  |  |  |   def git_branch | 
					
						
							|  |  |  |     raise TapUnavailableError, name unless installed? | 
					
						
							| 
									
										
										
										
											2018-09-17 02:45:00 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-27 16:32:13 -04:00
										 |  |  |     path.git_branch | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-05 20:03:43 +08:00
										 |  |  |   # git HEAD for this {Tap}. | 
					
						
							|  |  |  |   def git_head | 
					
						
							|  |  |  |     raise TapUnavailableError, name unless installed? | 
					
						
							| 
									
										
										
										
											2018-09-17 02:45:00 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-02 09:43:12 +02:00
										 |  |  |     path.git_head | 
					
						
							| 
									
										
										
										
											2016-03-05 20:03:43 +08:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   # git HEAD in short format for this {Tap}. | 
					
						
							|  |  |  |   def git_short_head | 
					
						
							|  |  |  |     raise TapUnavailableError, name unless installed? | 
					
						
							| 
									
										
										
										
											2018-09-17 02:45:00 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-02 09:43:12 +02:00
										 |  |  |     path.git_short_head | 
					
						
							| 
									
										
										
										
											2016-03-05 20:03:43 +08:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-18 21:42:43 -04:00
										 |  |  |   # Time since git last commit for this {Tap}. | 
					
						
							| 
									
										
										
										
											2016-03-05 20:03:43 +08:00
										 |  |  |   def git_last_commit | 
					
						
							|  |  |  |     raise TapUnavailableError, name unless installed? | 
					
						
							| 
									
										
										
										
											2018-09-17 02:45:00 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-02 09:43:12 +02:00
										 |  |  |     path.git_last_commit | 
					
						
							| 
									
										
										
										
											2016-03-05 20:03:43 +08:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   # git last commit date for this {Tap}. | 
					
						
							|  |  |  |   def git_last_commit_date | 
					
						
							|  |  |  |     raise TapUnavailableError, name unless installed? | 
					
						
							| 
									
										
										
										
											2018-09-17 02:45:00 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-02 09:43:12 +02:00
										 |  |  |     path.git_last_commit_date | 
					
						
							| 
									
										
										
										
											2016-03-05 20:03:43 +08:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-28 13:23:22 +01:00
										 |  |  |   # The issues URL of this {Tap}. | 
					
						
							|  |  |  |   # e.g. `https://github.com/user/homebrew-repo/issues` | 
					
						
							|  |  |  |   def issues_url | 
					
						
							| 
									
										
										
										
											2016-09-23 22:02:23 +02:00
										 |  |  |     return unless official? || !custom_remote? | 
					
						
							| 
									
										
										
										
											2018-09-17 02:45:00 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-12 17:30:02 -04:00
										 |  |  |     "#{default_remote}/issues" | 
					
						
							| 
									
										
										
										
											2015-12-28 13:23:22 +01:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-10 15:39:47 +08:00
										 |  |  |   def to_s | 
					
						
							|  |  |  |     name | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-03 16:12:19 +02:00
										 |  |  |   def version_string | 
					
						
							|  |  |  |     return "N/A" unless installed? | 
					
						
							| 
									
										
										
										
											2018-09-17 02:45:00 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-03 16:12:19 +02:00
										 |  |  |     pretty_revision = git_short_head | 
					
						
							|  |  |  |     return "(no git repository)" unless pretty_revision | 
					
						
							| 
									
										
										
										
											2018-09-17 02:45:00 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-03 16:12:19 +02:00
										 |  |  |     "(git revision #{pretty_revision}; last commit #{git_last_commit_date})" | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-13 01:53:55 +08:00
										 |  |  |   # True if this {Tap} is an official Homebrew tap. | 
					
						
							| 
									
										
										
										
											2015-06-10 15:39:47 +08:00
										 |  |  |   def official? | 
					
						
							| 
									
										
										
										
											2015-12-06 20:57:28 +08:00
										 |  |  |     user == "Homebrew" | 
					
						
							| 
									
										
										
										
											2015-06-10 15:39:47 +08:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-13 01:53:55 +08:00
										 |  |  |   # True if the remote of this {Tap} is a private repository. | 
					
						
							| 
									
										
										
										
											2015-06-10 15:39:47 +08:00
										 |  |  |   def private? | 
					
						
							| 
									
										
										
										
											2016-04-12 11:00:23 +01:00
										 |  |  |     return @private if instance_variable_defined?(:@private) | 
					
						
							| 
									
										
										
										
											2018-09-17 02:45:00 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-12 18:51:43 +08:00
										 |  |  |     @private = read_or_set_private_config | 
					
						
							| 
									
										
										
										
											2016-04-12 11:00:23 +01:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-12 18:51:43 +08:00
										 |  |  |   # {TapConfig} of this {Tap} | 
					
						
							| 
									
										
										
										
											2016-04-12 11:00:23 +01:00
										 |  |  |   def config | 
					
						
							|  |  |  |     @config ||= begin | 
					
						
							|  |  |  |       raise TapUnavailableError, name unless installed? | 
					
						
							| 
									
										
										
										
											2018-09-17 02:45:00 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-12 11:00:23 +01:00
										 |  |  |       TapConfig.new(self) | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2015-06-10 15:39:47 +08:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-13 01:53:55 +08:00
										 |  |  |   # True if this {Tap} has been installed. | 
					
						
							| 
									
										
										
										
											2015-06-10 15:39:47 +08:00
										 |  |  |   def installed? | 
					
						
							| 
									
										
										
										
											2015-12-06 20:57:28 +08:00
										 |  |  |     path.directory? | 
					
						
							| 
									
										
										
										
											2015-06-10 15:39:47 +08:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-04 03:18:55 -07:00
										 |  |  |   # True if this {Tap} is not a full clone. | 
					
						
							|  |  |  |   def shallow? | 
					
						
							|  |  |  |     (path/".git/shallow").exist? | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-07 14:12:57 +08:00
										 |  |  |   # @private | 
					
						
							| 
									
										
										
										
											2016-03-07 18:04:25 +08:00
										 |  |  |   def core_tap? | 
					
						
							| 
									
										
										
										
											2015-12-07 14:12:57 +08:00
										 |  |  |     false | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-18 21:42:43 -04:00
										 |  |  |   # Install this {Tap}. | 
					
						
							| 
									
										
										
										
											2015-11-07 16:25:34 +08:00
										 |  |  |   # | 
					
						
							| 
									
										
										
										
											2020-02-05 20:22:21 +00:00
										 |  |  |   # @param clone_target [String] If passed, it will be used as the clone remote. | 
					
						
							|  |  |  |   # @param force_auto_update [Boolean, nil] If present, whether to override the | 
					
						
							| 
									
										
										
										
											2018-04-12 16:14:02 -07:00
										 |  |  |   #   logic that skips non-GitHub repositories during auto-updates. | 
					
						
							| 
									
										
										
										
											2020-02-05 20:22:21 +00:00
										 |  |  |   # @param full_clone [Boolean] If set as true, full clone will be used. If unset/nil, means "no change". | 
					
						
							|  |  |  |   # @param quiet [Boolean] If set, suppress all output. | 
					
						
							|  |  |  |   def install(full_clone: true, quiet: false, clone_target: nil, force_auto_update: nil) | 
					
						
							| 
									
										
										
										
											2015-12-19 19:10:22 +08:00
										 |  |  |     require "descriptions" | 
					
						
							| 
									
										
										
										
											2015-11-07 16:25:34 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-22 16:53:48 +01:00
										 |  |  |     if official? && DEPRECATED_OFFICIAL_TAPS.include?(repo) | 
					
						
							| 
									
										
										
										
											2018-01-28 19:07:01 +00:00
										 |  |  |       odie "#{name} was deprecated. This tap is now empty as all its formulae were migrated." | 
					
						
							| 
									
										
										
										
											2019-10-02 23:30:38 +02:00
										 |  |  |     elsif user == "caskroom" | 
					
						
							|  |  |  |       odie "#{name} was moved. Tap homebrew/cask-#{repo} instead." | 
					
						
							| 
									
										
										
										
											2017-04-22 16:53:48 +01:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-05 20:22:21 +00:00
										 |  |  |     requested_remote = clone_target || default_remote | 
					
						
							| 
									
										
										
										
											2020-02-02 16:36:01 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-05 20:22:21 +00:00
										 |  |  |     if installed? | 
					
						
							|  |  |  |       raise TapRemoteMismatchError.new(name, @remote, requested_remote) if clone_target && requested_remote != remote | 
					
						
							| 
									
										
										
										
											2020-02-02 16:36:01 +01:00
										 |  |  |       raise TapAlreadyTappedError, name if force_auto_update.nil? | 
					
						
							| 
									
										
										
										
											2016-04-04 03:18:55 -07:00
										 |  |  |     end | 
					
						
							| 
									
										
										
										
											2016-02-25 21:09:50 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-07 16:25:34 +08:00
										 |  |  |     # ensure git is installed | 
					
						
							|  |  |  |     Utils.ensure_git_installed! | 
					
						
							| 
									
										
										
										
											2016-04-04 03:18:55 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if installed? | 
					
						
							| 
									
										
										
										
											2018-04-12 16:14:02 -07:00
										 |  |  |       unless force_auto_update.nil? | 
					
						
							|  |  |  |         config["forceautoupdate"] = force_auto_update | 
					
						
							|  |  |  |         return if !full_clone || !shallow? | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-04 03:18:55 -07:00
										 |  |  |       ohai "Unshallowing #{name}" unless quiet | 
					
						
							| 
									
										
										
										
											2016-10-22 13:32:46 +01:00
										 |  |  |       args = %w[fetch --unshallow] | 
					
						
							| 
									
										
										
										
											2016-04-04 03:18:55 -07:00
										 |  |  |       args << "-q" if quiet | 
					
						
							| 
									
										
										
										
											2018-01-15 07:30:56 +00:00
										 |  |  |       path.cd { safe_system "git", *args } | 
					
						
							| 
									
										
										
										
											2016-04-04 03:18:55 -07:00
										 |  |  |       return | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     clear_cache | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-25 21:09:50 +08:00
										 |  |  |     ohai "Tapping #{name}" unless quiet | 
					
						
							| 
									
										
										
										
											2016-06-20 13:03:27 +01:00
										 |  |  |     args =  %W[clone #{requested_remote} #{path}] | 
					
						
							| 
									
										
										
										
											2016-04-04 03:18:55 -07:00
										 |  |  |     args << "--depth=1" unless full_clone | 
					
						
							| 
									
										
										
										
											2016-02-25 21:09:50 +08:00
										 |  |  |     args << "-q" if quiet | 
					
						
							| 
									
										
										
										
											2015-11-07 16:25:34 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     begin | 
					
						
							| 
									
										
										
										
											2018-01-15 07:30:56 +00:00
										 |  |  |       safe_system "git", *args | 
					
						
							| 
									
										
										
										
											2016-09-17 15:32:44 +01:00
										 |  |  |       unless Readall.valid_tap?(self, aliases: true) | 
					
						
							| 
									
										
										
										
											2019-02-19 13:11:32 +00:00
										 |  |  |         raise "Cannot tap #{name}: invalid syntax in tap!" unless ARGV.homebrew_developer? | 
					
						
							| 
									
										
										
										
											2016-07-09 13:51:19 +01:00
										 |  |  |       end | 
					
						
							| 
									
										
										
										
											2018-09-02 23:30:07 +02:00
										 |  |  |     rescue Interrupt, RuntimeError | 
					
						
							| 
									
										
										
										
											2015-11-07 16:25:34 +08:00
										 |  |  |       ignore_interrupts do | 
					
						
							| 
									
										
										
										
											2016-07-09 13:51:19 +01:00
										 |  |  |         # wait for git to possibly cleanup the top directory when interrupt happens. | 
					
						
							|  |  |  |         sleep 0.1
 | 
					
						
							|  |  |  |         FileUtils.rm_rf path | 
					
						
							| 
									
										
										
										
											2015-12-06 20:57:28 +08:00
										 |  |  |         path.parent.rmdir_if_possible | 
					
						
							| 
									
										
										
										
											2015-11-07 16:25:34 +08:00
										 |  |  |       end | 
					
						
							|  |  |  |       raise | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-12 16:14:02 -07:00
										 |  |  |     config["forceautoupdate"] = force_auto_update unless force_auto_update.nil? | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-30 18:22:53 -05:00
										 |  |  |     link_completions_and_manpages | 
					
						
							| 
									
										
										
										
											2015-12-08 17:26:53 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-17 20:11:11 +02:00
										 |  |  |     formatted_contents = contents.presence&.to_sentence&.dup&.prepend(" ") | 
					
						
							| 
									
										
										
										
											2018-06-20 20:35:24 +02:00
										 |  |  |     puts "Tapped#{formatted_contents} (#{path.abv})." unless quiet | 
					
						
							| 
									
										
										
										
											2018-10-13 08:22:51 -07:00
										 |  |  |     CacheStoreDatabase.use(:descriptions) do |db| | 
					
						
							|  |  |  |       DescriptionCacheStore.new(db) | 
					
						
							|  |  |  |                            .update_from_formula_names!(formula_names) | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2015-11-07 16:25:34 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-05 20:22:21 +00:00
										 |  |  |     return if clone_target | 
					
						
							| 
									
										
										
										
											2016-09-23 22:02:23 +02:00
										 |  |  |     return unless private? | 
					
						
							|  |  |  |     return if quiet | 
					
						
							| 
									
										
										
										
											2018-09-17 02:45:00 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-15 02:28:32 +02:00
										 |  |  |     puts <<~EOS | 
					
						
							| 
									
										
										
										
											2016-09-23 22:02:23 +02:00
										 |  |  |       It looks like you tapped a private repository. To avoid entering your | 
					
						
							|  |  |  |       credentials each time you update, you can use git HTTP credential | 
					
						
							|  |  |  |       caching or issue the following command: | 
					
						
							|  |  |  |         cd #{path} | 
					
						
							| 
									
										
										
										
											2017-06-12 17:30:02 -04:00
										 |  |  |         git remote set-url origin git@github.com:#{full_name}.git | 
					
						
							| 
									
										
										
										
											2016-09-23 22:02:23 +02:00
										 |  |  |     EOS | 
					
						
							| 
									
										
										
										
											2015-11-07 16:25:34 +08:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-30 18:22:53 -05:00
										 |  |  |   def link_completions_and_manpages | 
					
						
							|  |  |  |     command = "brew tap --repair" | 
					
						
							|  |  |  |     Utils::Link.link_manpages(path, command) | 
					
						
							|  |  |  |     Utils::Link.link_completions(path, command) | 
					
						
							| 
									
										
										
										
											2015-12-08 17:26:53 +00:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-18 21:42:43 -04:00
										 |  |  |   # Uninstall this {Tap}. | 
					
						
							| 
									
										
										
										
											2015-11-07 16:25:34 +08:00
										 |  |  |   def uninstall | 
					
						
							| 
									
										
										
										
											2015-12-19 19:10:22 +08:00
										 |  |  |     require "descriptions" | 
					
						
							| 
									
										
										
										
											2015-11-07 16:25:34 +08:00
										 |  |  |     raise TapUnavailableError, name unless installed? | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-19 17:59:25 +02:00
										 |  |  |     puts "Untapping #{name}..." | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     abv = path.abv | 
					
						
							| 
									
										
										
										
											2018-09-17 20:11:11 +02:00
										 |  |  |     formatted_contents = contents.presence&.to_sentence&.dup&.prepend(" ") | 
					
						
							| 
									
										
										
										
											2018-06-19 17:59:25 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-07 16:25:34 +08:00
										 |  |  |     unpin if pinned? | 
					
						
							| 
									
										
										
										
											2018-10-13 08:22:51 -07:00
										 |  |  |     CacheStoreDatabase.use(:descriptions) do |db| | 
					
						
							|  |  |  |       DescriptionCacheStore.new(db) | 
					
						
							|  |  |  |                            .delete_from_formula_names!(formula_names) | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2016-09-30 18:22:53 -05:00
										 |  |  |     Utils::Link.unlink_manpages(path) | 
					
						
							|  |  |  |     Utils::Link.unlink_completions(path) | 
					
						
							| 
									
										
										
										
											2015-12-06 20:57:28 +08:00
										 |  |  |     path.rmtree | 
					
						
							| 
									
										
										
										
											2015-12-08 17:26:53 +00:00
										 |  |  |     path.parent.rmdir_if_possible | 
					
						
							| 
									
										
										
										
											2018-06-20 20:35:24 +02:00
										 |  |  |     puts "Untapped#{formatted_contents} (#{abv})." | 
					
						
							| 
									
										
										
										
											2016-02-06 03:50:06 +08:00
										 |  |  |     clear_cache | 
					
						
							| 
									
										
										
										
											2015-11-07 16:25:34 +08:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-13 01:53:55 +08:00
										 |  |  |   # True if the {#remote} of {Tap} is customized. | 
					
						
							| 
									
										
										
										
											2015-06-10 15:39:47 +08:00
										 |  |  |   def custom_remote? | 
					
						
							| 
									
										
										
										
											2015-06-13 01:57:00 +08:00
										 |  |  |     return true unless remote | 
					
						
							| 
									
										
										
										
											2018-09-17 02:45:00 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-17 15:17:27 +01:00
										 |  |  |     remote.casecmp(default_remote).nonzero? | 
					
						
							| 
									
										
										
										
											2015-06-10 15:39:47 +08:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-18 21:42:43 -04:00
										 |  |  |   # Path to the directory of all {Formula} files for this {Tap}. | 
					
						
							| 
									
										
										
										
											2015-12-06 20:59:31 +08:00
										 |  |  |   def formula_dir | 
					
						
							| 
									
										
										
										
											2018-09-02 20:14:54 +01:00
										 |  |  |     @formula_dir ||= potential_formula_dirs.find(&:directory?) || path/"Formula" | 
					
						
							| 
									
										
										
										
											2016-12-13 01:53:05 +00:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def potential_formula_dirs | 
					
						
							|  |  |  |     @potential_formula_dirs ||= [path/"Formula", path/"HomebrewFormula", path].freeze | 
					
						
							| 
									
										
										
										
											2015-12-06 20:59:31 +08:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-18 21:42:43 -04:00
										 |  |  |   # Path to the directory of all {Cask} files for this {Tap}. | 
					
						
							| 
									
										
										
										
											2016-08-04 14:37:37 +04:00
										 |  |  |   def cask_dir | 
					
						
							| 
									
										
										
										
											2017-03-12 19:18:41 +01:00
										 |  |  |     @cask_dir ||= path/"Casks" | 
					
						
							| 
									
										
										
										
											2016-08-04 14:37:37 +04:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-20 20:35:24 +02:00
										 |  |  |   def contents | 
					
						
							|  |  |  |     contents = [] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (command_count = command_files.count).positive? | 
					
						
							| 
									
										
										
										
											2018-09-17 20:11:11 +02:00
										 |  |  |       contents << "#{command_count} #{"command".pluralize(command_count)}" | 
					
						
							| 
									
										
										
										
											2018-06-20 20:35:24 +02:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (cask_count = cask_files.count).positive? | 
					
						
							| 
									
										
										
										
											2018-09-17 20:11:11 +02:00
										 |  |  |       contents << "#{cask_count} #{"cask".pluralize(cask_count)}" | 
					
						
							| 
									
										
										
										
											2018-06-20 20:35:24 +02:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (formula_count = formula_files.count).positive? | 
					
						
							| 
									
										
										
										
											2018-09-17 20:11:11 +02:00
										 |  |  |       contents << "#{formula_count} #{"formula".pluralize(formula_count)}" | 
					
						
							| 
									
										
										
										
											2018-06-20 20:35:24 +02:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     contents | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-18 21:42:43 -04:00
										 |  |  |   # An array of all {Formula} files of this {Tap}. | 
					
						
							| 
									
										
										
										
											2015-06-10 15:39:47 +08:00
										 |  |  |   def formula_files | 
					
						
							| 
									
										
										
										
											2017-03-12 19:18:41 +01:00
										 |  |  |     @formula_files ||= if formula_dir.directory? | 
					
						
							| 
									
										
										
										
											2018-10-10 17:16:18 +02:00
										 |  |  |       formula_dir.children.select(&method(:ruby_file?)) | 
					
						
							| 
									
										
										
										
											2016-08-25 05:19:14 +02:00
										 |  |  |     else | 
					
						
							|  |  |  |       [] | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-18 21:42:43 -04:00
										 |  |  |   # An array of all {Cask} files of this {Tap}. | 
					
						
							| 
									
										
										
										
											2016-08-25 05:19:14 +02:00
										 |  |  |   def cask_files | 
					
						
							| 
									
										
										
										
											2017-03-12 19:18:41 +01:00
										 |  |  |     @cask_files ||= if cask_dir.directory? | 
					
						
							| 
									
										
										
										
											2018-10-10 17:16:18 +02:00
										 |  |  |       cask_dir.children.select(&method(:ruby_file?)) | 
					
						
							| 
									
										
										
										
											2015-09-27 16:52:14 +08:00
										 |  |  |     else | 
					
						
							|  |  |  |       [] | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2015-06-10 15:39:47 +08:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-10 17:16:18 +02:00
										 |  |  |   # returns true if the file has a Ruby extension | 
					
						
							|  |  |  |   # @private | 
					
						
							|  |  |  |   def ruby_file?(file) | 
					
						
							|  |  |  |     file.extname == ".rb" | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-15 22:31:47 +08:00
										 |  |  |   # return true if given path would present a {Formula} file in this {Tap}. | 
					
						
							|  |  |  |   # accepts both absolute path and relative path (relative to this {Tap}'s path) | 
					
						
							|  |  |  |   # @private | 
					
						
							|  |  |  |   def formula_file?(file) | 
					
						
							|  |  |  |     file = Pathname.new(file) unless file.is_a? Pathname | 
					
						
							|  |  |  |     file = file.expand_path(path) | 
					
						
							| 
									
										
										
										
											2018-10-10 17:16:18 +02:00
										 |  |  |     ruby_file?(file) && file.parent == formula_dir | 
					
						
							| 
									
										
										
										
											2016-02-15 22:31:47 +08:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-25 05:19:14 +02:00
										 |  |  |   # return true if given path would present a {Cask} file in this {Tap}. | 
					
						
							| 
									
										
										
										
											2016-08-04 14:37:37 +04:00
										 |  |  |   # accepts both absolute path and relative path (relative to this {Tap}'s path) | 
					
						
							|  |  |  |   # @private | 
					
						
							|  |  |  |   def cask_file?(file) | 
					
						
							|  |  |  |     file = Pathname.new(file) unless file.is_a? Pathname | 
					
						
							|  |  |  |     file = file.expand_path(path) | 
					
						
							| 
									
										
										
										
											2018-10-10 17:16:18 +02:00
										 |  |  |     ruby_file?(file) && file.parent == cask_dir | 
					
						
							| 
									
										
										
										
											2016-08-04 14:37:37 +04:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-18 21:42:43 -04:00
										 |  |  |   # An array of all {Formula} names of this {Tap}. | 
					
						
							| 
									
										
										
										
											2015-06-10 15:39:47 +08:00
										 |  |  |   def formula_names | 
					
						
							| 
									
										
										
										
											2015-12-06 21:30:23 +08:00
										 |  |  |     @formula_names ||= formula_files.map { |f| formula_file_to_name(f) } | 
					
						
							| 
									
										
										
										
											2015-06-10 15:39:47 +08:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-06 21:15:43 +08:00
										 |  |  |   # path to the directory of all alias files for this {Tap}. | 
					
						
							|  |  |  |   # @private | 
					
						
							|  |  |  |   def alias_dir | 
					
						
							| 
									
										
										
										
											2016-03-23 14:55:42 +08:00
										 |  |  |     @alias_dir ||= path/"Aliases" | 
					
						
							| 
									
										
										
										
											2015-12-06 21:15:43 +08:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-12 18:21:22 +08:00
										 |  |  |   # an array of all alias files of this {Tap}. | 
					
						
							|  |  |  |   # @private | 
					
						
							|  |  |  |   def alias_files | 
					
						
							| 
									
										
										
										
											2015-12-06 21:15:43 +08:00
										 |  |  |     @alias_files ||= Pathname.glob("#{alias_dir}/*").select(&:file?) | 
					
						
							| 
									
										
										
										
											2015-09-12 18:21:22 +08:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   # an array of all aliases of this {Tap}. | 
					
						
							|  |  |  |   # @private | 
					
						
							|  |  |  |   def aliases | 
					
						
							| 
									
										
										
										
											2015-12-06 21:30:23 +08:00
										 |  |  |     @aliases ||= alias_files.map { |f| alias_file_to_name(f) } | 
					
						
							| 
									
										
										
										
											2015-09-12 18:21:22 +08:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-07 17:54:20 +08:00
										 |  |  |   # a table mapping alias to formula name | 
					
						
							|  |  |  |   # @private | 
					
						
							|  |  |  |   def alias_table | 
					
						
							|  |  |  |     return @alias_table if @alias_table | 
					
						
							| 
									
										
										
										
											2018-09-17 02:45:00 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-17 15:17:27 +01:00
										 |  |  |     @alias_table = {} | 
					
						
							| 
									
										
										
										
											2015-10-07 17:54:20 +08:00
										 |  |  |     alias_files.each do |alias_file| | 
					
						
							| 
									
										
										
										
											2015-12-06 21:30:23 +08:00
										 |  |  |       @alias_table[alias_file_to_name(alias_file)] = formula_file_to_name(alias_file.resolved_path) | 
					
						
							| 
									
										
										
										
											2015-10-07 17:54:20 +08:00
										 |  |  |     end | 
					
						
							|  |  |  |     @alias_table | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   # a table mapping formula name to aliases | 
					
						
							|  |  |  |   # @private | 
					
						
							|  |  |  |   def alias_reverse_table | 
					
						
							|  |  |  |     return @alias_reverse_table if @alias_reverse_table | 
					
						
							| 
									
										
										
										
											2018-09-17 02:45:00 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-17 15:17:27 +01:00
										 |  |  |     @alias_reverse_table = {} | 
					
						
							| 
									
										
										
										
											2015-10-07 17:54:20 +08:00
										 |  |  |     alias_table.each do |alias_name, formula_name| | 
					
						
							|  |  |  |       @alias_reverse_table[formula_name] ||= [] | 
					
						
							|  |  |  |       @alias_reverse_table[formula_name] << alias_name | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |     @alias_reverse_table | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-25 11:38:19 +02:00
										 |  |  |   def command_dir | 
					
						
							|  |  |  |     @command_dir ||= path/"cmd" | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def command_file?(file) | 
					
						
							|  |  |  |     file = Pathname.new(file) unless file.is_a? Pathname | 
					
						
							|  |  |  |     file = file.expand_path(path) | 
					
						
							|  |  |  |     file.parent == command_dir && file.basename.to_s.match?(/^brew(cask)?-/) && | 
					
						
							|  |  |  |       (file.executable? || file.extname == ".rb") | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-18 21:42:43 -04:00
										 |  |  |   # An array of all commands files of this {Tap}. | 
					
						
							| 
									
										
										
										
											2015-06-10 15:39:47 +08:00
										 |  |  |   def command_files | 
					
						
							| 
									
										
										
										
											2018-07-25 11:38:19 +02:00
										 |  |  |     @command_files ||= if command_dir.directory? | 
					
						
							|  |  |  |       command_dir.children.select(&method(:command_file?)) | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |       [] | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2015-06-10 15:39:47 +08:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-07 16:00:45 +08:00
										 |  |  |   # path to the pin record for this {Tap}. | 
					
						
							|  |  |  |   # @private | 
					
						
							| 
									
										
										
										
											2015-08-09 22:42:46 +08:00
										 |  |  |   def pinned_symlink_path | 
					
						
							| 
									
										
										
										
											2015-12-06 20:57:28 +08:00
										 |  |  |     HOMEBREW_LIBRARY/"PinnedTaps/#{name}" | 
					
						
							| 
									
										
										
										
											2015-08-09 22:42:46 +08:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-07 16:00:45 +08:00
										 |  |  |   # True if this {Tap} has been pinned. | 
					
						
							| 
									
										
										
										
											2015-08-09 22:42:46 +08:00
										 |  |  |   def pinned? | 
					
						
							| 
									
										
										
										
											2015-09-27 16:52:14 +08:00
										 |  |  |     return @pinned if instance_variable_defined?(:@pinned) | 
					
						
							| 
									
										
										
										
											2018-09-17 02:45:00 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-27 16:52:14 +08:00
										 |  |  |     @pinned = pinned_symlink_path.directory? | 
					
						
							| 
									
										
										
										
											2015-08-09 22:42:46 +08:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-18 21:42:43 -04:00
										 |  |  |   # Pin this {Tap}. | 
					
						
							| 
									
										
										
										
											2015-08-09 22:42:46 +08:00
										 |  |  |   def pin | 
					
						
							|  |  |  |     raise TapUnavailableError, name unless installed? | 
					
						
							|  |  |  |     raise TapPinStatusError.new(name, true) if pinned? | 
					
						
							| 
									
										
										
										
											2018-09-17 02:45:00 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-06 20:57:28 +08:00
										 |  |  |     pinned_symlink_path.make_relative_symlink(path) | 
					
						
							| 
									
										
										
										
											2015-09-27 16:52:14 +08:00
										 |  |  |     @pinned = true | 
					
						
							| 
									
										
										
										
											2015-08-09 22:42:46 +08:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-18 21:42:43 -04:00
										 |  |  |   # Unpin this {Tap}. | 
					
						
							| 
									
										
										
										
											2015-08-09 22:42:46 +08:00
										 |  |  |   def unpin | 
					
						
							|  |  |  |     raise TapUnavailableError, name unless installed? | 
					
						
							|  |  |  |     raise TapPinStatusError.new(name, false) unless pinned? | 
					
						
							| 
									
										
										
										
											2018-09-17 02:45:00 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-09 22:42:46 +08:00
										 |  |  |     pinned_symlink_path.delete | 
					
						
							| 
									
										
										
										
											2015-12-08 17:26:53 +00:00
										 |  |  |     pinned_symlink_path.parent.rmdir_if_possible | 
					
						
							| 
									
										
										
										
											2015-12-19 20:32:16 +08:00
										 |  |  |     pinned_symlink_path.parent.parent.rmdir_if_possible | 
					
						
							| 
									
										
										
										
											2015-09-27 16:52:14 +08:00
										 |  |  |     @pinned = false | 
					
						
							| 
									
										
										
										
											2015-08-09 22:42:46 +08:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-10 15:39:47 +08:00
										 |  |  |   def to_hash | 
					
						
							| 
									
										
										
										
											2015-08-13 14:56:14 +08:00
										 |  |  |     hash = { | 
					
						
							| 
									
										
										
										
											2018-11-02 17:18:07 +00:00
										 |  |  |       "name"          => name, | 
					
						
							|  |  |  |       "user"          => user, | 
					
						
							|  |  |  |       "repo"          => repo, | 
					
						
							|  |  |  |       "path"          => path.to_s, | 
					
						
							|  |  |  |       "installed"     => installed?, | 
					
						
							|  |  |  |       "official"      => official?, | 
					
						
							| 
									
										
										
										
											2015-06-10 15:39:47 +08:00
										 |  |  |       "formula_names" => formula_names, | 
					
						
							|  |  |  |       "formula_files" => formula_files.map(&:to_s), | 
					
						
							| 
									
										
										
										
											2015-08-09 22:42:46 +08:00
										 |  |  |       "command_files" => command_files.map(&:to_s), | 
					
						
							| 
									
										
										
										
											2018-11-02 17:18:07 +00:00
										 |  |  |       "pinned"        => pinned?, | 
					
						
							| 
									
										
										
										
											2015-06-10 15:39:47 +08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-08-13 14:56:14 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if installed? | 
					
						
							|  |  |  |       hash["remote"] = remote | 
					
						
							|  |  |  |       hash["custom_remote"] = custom_remote? | 
					
						
							| 
									
										
										
										
											2016-07-10 02:27:59 +02:00
										 |  |  |       hash["private"] = private? | 
					
						
							| 
									
										
										
										
											2015-08-13 14:56:14 +08:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     hash | 
					
						
							| 
									
										
										
										
											2015-06-10 15:39:47 +08:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-09 14:39:46 +03:00
										 |  |  |   # Hash with tap formula renames | 
					
						
							|  |  |  |   def formula_renames | 
					
						
							| 
									
										
										
										
											2016-11-20 13:00:01 -05:00
										 |  |  |     require "json" | 
					
						
							| 
									
										
										
										
											2015-12-19 19:10:22 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-09 14:39:46 +03:00
										 |  |  |     @formula_renames ||= if (rename_file = path/"formula_renames.json").file? | 
					
						
							| 
									
										
										
										
											2016-11-20 13:00:01 -05:00
										 |  |  |       JSON.parse(rename_file.read) | 
					
						
							| 
									
										
										
										
											2015-08-09 14:39:46 +03:00
										 |  |  |     else | 
					
						
							|  |  |  |       {} | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-25 14:14:33 +08:00
										 |  |  |   # Hash with tap migrations | 
					
						
							|  |  |  |   def tap_migrations | 
					
						
							| 
									
										
										
										
											2016-11-20 13:00:01 -05:00
										 |  |  |     require "json" | 
					
						
							| 
									
										
										
										
											2016-02-25 14:14:33 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     @tap_migrations ||= if (migration_file = path/"tap_migrations.json").file? | 
					
						
							| 
									
										
										
										
											2016-11-20 13:00:01 -05:00
										 |  |  |       JSON.parse(migration_file.read) | 
					
						
							| 
									
										
										
										
											2016-02-25 14:14:33 +08:00
										 |  |  |     else | 
					
						
							|  |  |  |       {} | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-06 22:21:27 +08:00
										 |  |  |   def ==(other) | 
					
						
							|  |  |  |     other = Tap.fetch(other) if other.is_a?(String) | 
					
						
							| 
									
										
										
										
											2016-09-17 15:17:27 +01:00
										 |  |  |     self.class == other.class && name == other.name | 
					
						
							| 
									
										
										
										
											2015-12-06 22:21:27 +08:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-10 15:39:47 +08:00
										 |  |  |   def self.each | 
					
						
							|  |  |  |     return unless TAP_DIRECTORY.directory? | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-03 17:18:13 -07:00
										 |  |  |     return to_enum unless block_given? | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-10 15:39:47 +08:00
										 |  |  |     TAP_DIRECTORY.subdirs.each do |user| | 
					
						
							|  |  |  |       user.subdirs.each do |repo| | 
					
						
							| 
									
										
										
										
											2015-12-02 14:35:42 +08:00
										 |  |  |         yield fetch(user.basename.to_s, repo.basename.to_s) | 
					
						
							| 
									
										
										
										
											2015-06-10 15:39:47 +08:00
										 |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-18 21:42:43 -04:00
										 |  |  |   # An array of all installed {Tap} names. | 
					
						
							| 
									
										
										
										
											2015-06-10 15:39:47 +08:00
										 |  |  |   def self.names | 
					
						
							| 
									
										
										
										
											2017-10-14 06:13:40 +01:00
										 |  |  |     map(&:name).sort | 
					
						
							| 
									
										
										
										
											2015-06-10 15:39:47 +08:00
										 |  |  |   end | 
					
						
							| 
									
										
										
										
											2015-12-06 21:30:23 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-18 21:42:43 -04:00
										 |  |  |   # An array of all tap cmd directory {Pathname}s | 
					
						
							| 
									
										
										
										
											2017-11-05 15:37:57 +00:00
										 |  |  |   def self.cmd_directories | 
					
						
							|  |  |  |     Pathname.glob TAP_DIRECTORY/"*/*/cmd" | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-15 20:06:15 +08:00
										 |  |  |   # @private | 
					
						
							| 
									
										
										
										
											2015-12-06 21:30:23 +08:00
										 |  |  |   def formula_file_to_name(file) | 
					
						
							|  |  |  |     "#{name}/#{file.basename(".rb")}" | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-15 20:06:15 +08:00
										 |  |  |   # @private | 
					
						
							| 
									
										
										
										
											2015-12-06 21:30:23 +08:00
										 |  |  |   def alias_file_to_name(file) | 
					
						
							|  |  |  |     "#{name}/#{file.basename}" | 
					
						
							|  |  |  |   end | 
					
						
							| 
									
										
										
										
											2016-04-12 18:51:43 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   private | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def read_or_set_private_config | 
					
						
							|  |  |  |     case config["private"] | 
					
						
							|  |  |  |     when "true" then true | 
					
						
							|  |  |  |     when "false" then false | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |       config["private"] = begin | 
					
						
							|  |  |  |         if custom_remote? | 
					
						
							|  |  |  |           true | 
					
						
							|  |  |  |         else | 
					
						
							| 
									
										
										
										
											2017-06-12 17:30:02 -04:00
										 |  |  |           GitHub.private_repo?(full_name) | 
					
						
							| 
									
										
										
										
											2016-04-12 18:51:43 +08:00
										 |  |  |         end | 
					
						
							|  |  |  |       rescue GitHub::HTTPNotFoundError | 
					
						
							|  |  |  |         true | 
					
						
							|  |  |  |       rescue GitHub::Error | 
					
						
							|  |  |  |         false | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							| 
									
										
										
										
											2015-06-10 15:39:47 +08:00
										 |  |  | end | 
					
						
							| 
									
										
										
										
											2016-03-07 18:04:25 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-18 21:42:43 -04:00
										 |  |  | # A specialized {Tap} class for the core formulae. | 
					
						
							| 
									
										
										
										
											2016-03-07 18:04:25 +08:00
										 |  |  | class CoreTap < Tap | 
					
						
							|  |  |  |   # @private | 
					
						
							|  |  |  |   def initialize | 
					
						
							| 
									
										
										
										
											2016-03-09 17:55:35 +08:00
										 |  |  |     super "Homebrew", "core" | 
					
						
							| 
									
										
										
										
											2016-03-07 18:04:25 +08:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def self.instance | 
					
						
							| 
									
										
										
										
											2016-10-03 16:12:19 +02:00
										 |  |  |     @instance ||= new | 
					
						
							| 
									
										
										
										
											2016-03-07 18:04:25 +08:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-07 12:09:52 +01:00
										 |  |  |   def self.ensure_installed! | 
					
						
							| 
									
										
										
										
											2016-03-09 17:55:35 +08:00
										 |  |  |     return if instance.installed? | 
					
						
							| 
									
										
										
										
											2018-09-17 02:45:00 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-07 12:09:52 +01:00
										 |  |  |     safe_system HOMEBREW_BREW_FILE, "tap", instance.name | 
					
						
							| 
									
										
										
										
											2016-03-09 17:55:35 +08:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-05 20:22:21 +00:00
										 |  |  |   def install(full_clone: true, quiet: false, clone_target: nil, force_auto_update: nil) | 
					
						
							| 
									
										
										
										
											2020-01-13 09:43:02 +00:00
										 |  |  |     if HOMEBREW_CORE_GIT_REMOTE != default_remote | 
					
						
							|  |  |  |       puts "HOMEBREW_CORE_GIT_REMOTE set: using #{HOMEBREW_CORE_GIT_REMOTE} " \ | 
					
						
							|  |  |  |            "for Homebrew/core Git remote URL." | 
					
						
							| 
									
										
										
										
											2020-02-05 20:22:21 +00:00
										 |  |  |       clone_target ||= HOMEBREW_CORE_GIT_REMOTE | 
					
						
							| 
									
										
										
										
											2020-01-13 09:43:02 +00:00
										 |  |  |     end | 
					
						
							| 
									
										
										
										
											2020-02-05 20:22:21 +00:00
										 |  |  |     super(full_clone: full_clone, quiet: quiet, clone_target: clone_target, force_auto_update: force_auto_update) | 
					
						
							| 
									
										
										
										
											2020-01-13 09:43:02 +00:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-07 18:04:25 +08:00
										 |  |  |   # @private | 
					
						
							|  |  |  |   def uninstall | 
					
						
							|  |  |  |     raise "Tap#uninstall is not available for CoreTap" | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   # @private | 
					
						
							|  |  |  |   def pin | 
					
						
							|  |  |  |     raise "Tap#pin is not available for CoreTap" | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   # @private | 
					
						
							|  |  |  |   def unpin | 
					
						
							|  |  |  |     raise "Tap#unpin is not available for CoreTap" | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   # @private | 
					
						
							|  |  |  |   def pinned? | 
					
						
							|  |  |  |     false | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   # @private | 
					
						
							|  |  |  |   def core_tap? | 
					
						
							|  |  |  |     true | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   # @private | 
					
						
							|  |  |  |   def formula_dir | 
					
						
							| 
									
										
										
										
											2016-03-09 17:55:35 +08:00
										 |  |  |     @formula_dir ||= begin | 
					
						
							|  |  |  |       self.class.ensure_installed! | 
					
						
							|  |  |  |       super | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2016-03-07 18:04:25 +08:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   # @private | 
					
						
							|  |  |  |   def alias_dir | 
					
						
							| 
									
										
										
										
											2016-03-09 17:55:35 +08:00
										 |  |  |     @alias_dir ||= begin | 
					
						
							|  |  |  |       self.class.ensure_installed! | 
					
						
							|  |  |  |       super | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2016-03-07 18:04:25 +08:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   # @private | 
					
						
							|  |  |  |   def formula_renames | 
					
						
							| 
									
										
										
										
											2016-03-09 17:55:35 +08:00
										 |  |  |     @formula_renames ||= begin | 
					
						
							|  |  |  |       self.class.ensure_installed! | 
					
						
							|  |  |  |       super | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2016-03-07 18:04:25 +08:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   # @private | 
					
						
							|  |  |  |   def tap_migrations | 
					
						
							| 
									
										
										
										
											2016-03-09 17:55:35 +08:00
										 |  |  |     @tap_migrations ||= begin | 
					
						
							|  |  |  |       self.class.ensure_installed! | 
					
						
							|  |  |  |       super | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2016-03-07 18:04:25 +08:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   # @private | 
					
						
							|  |  |  |   def formula_file_to_name(file) | 
					
						
							|  |  |  |     file.basename(".rb").to_s | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   # @private | 
					
						
							|  |  |  |   def alias_file_to_name(file) | 
					
						
							|  |  |  |     file.basename.to_s | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | end | 
					
						
							| 
									
										
										
										
											2016-04-12 11:00:23 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-18 21:42:43 -04:00
										 |  |  | # Permanent configuration per {Tap} using `git-config(1)`. | 
					
						
							| 
									
										
										
										
											2016-04-12 11:00:23 +01:00
										 |  |  | class TapConfig | 
					
						
							|  |  |  |   attr_reader :tap | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def initialize(tap) | 
					
						
							|  |  |  |     @tap = tap | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def [](key) | 
					
						
							|  |  |  |     return unless tap.git? | 
					
						
							|  |  |  |     return unless Utils.git_available? | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     tap.path.cd do | 
					
						
							| 
									
										
										
										
											2019-11-16 09:39:18 +00:00
										 |  |  |       Utils.popen_read("git", "config", "--get", "homebrew.#{key}").chomp.presence | 
					
						
							| 
									
										
										
										
											2016-04-12 11:00:23 +01:00
										 |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def []=(key, value) | 
					
						
							|  |  |  |     return unless tap.git? | 
					
						
							|  |  |  |     return unless Utils.git_available? | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     tap.path.cd do | 
					
						
							| 
									
										
										
										
											2019-11-16 09:39:18 +00:00
										 |  |  |       safe_system "git", "config", "--replace-all", "homebrew.#{key}", value.to_s | 
					
						
							| 
									
										
										
										
											2016-04-12 11:00:23 +01:00
										 |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | end | 
					
						
							| 
									
										
										
										
											2018-10-02 15:43:16 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | require "extend/os/tap" |