| 
									
										
										
										
											2020-10-10 14:16:11 +02:00
										 |  |  | # typed: false | 
					
						
							| 
									
										
										
										
											2019-04-19 15:38:03 +09:00
										 |  |  | # frozen_string_literal: true | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-02 20:51:16 -04:00
										 |  |  | require "digest/md5" | 
					
						
							| 
									
										
										
										
											2017-10-07 00:31:28 +02:00
										 |  |  | require "extend/cachable" | 
					
						
							| 
									
										
										
										
											2020-08-18 00:23:23 +01:00
										 |  |  | require "tab" | 
					
						
							| 
									
										
										
										
											2015-06-02 20:51:16 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-05 17:17:03 -05:00
										 |  |  | # The {Formulary} is responsible for creating instances of {Formula}. | 
					
						
							| 
									
										
										
										
											2016-05-22 21:29:22 +01:00
										 |  |  | # It is not meant to be used directly from formulae. | 
					
						
							| 
									
										
										
										
											2020-08-17 06:10:42 +02:00
										 |  |  | # | 
					
						
							|  |  |  | # @api private | 
					
						
							| 
									
										
										
										
											2017-02-20 13:06:23 +01:00
										 |  |  | module Formulary | 
					
						
							| 
									
										
										
										
											2020-10-20 12:03:48 +02:00
										 |  |  |   extend T::Sig | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-07 00:31:28 +02:00
										 |  |  |   extend Cachable | 
					
						
							| 
									
										
										
										
											2015-01-01 01:21:59 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-29 13:15:08 +01:00
										 |  |  |   URL_START_REGEX = %r{(https?|ftp|file)://}.freeze | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-20 12:03:48 +02:00
										 |  |  |   sig { void } | 
					
						
							| 
									
										
										
										
											2019-11-06 10:03:44 +00:00
										 |  |  |   def self.enable_factory_cache! | 
					
						
							|  |  |  |     @factory_cache = true | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def self.factory_cached? | 
					
						
							|  |  |  |     !@factory_cache.nil? | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-01 19:20:11 -04:00
										 |  |  |   def self.formula_class_defined?(path) | 
					
						
							| 
									
										
										
										
											2017-10-07 00:31:28 +02:00
										 |  |  |     cache.key?(path) | 
					
						
							| 
									
										
										
										
											2013-06-18 10:11:06 -07:00
										 |  |  |   end | 
					
						
							| 
									
										
										
										
											2013-06-08 20:58:43 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-01 19:20:11 -04:00
										 |  |  |   def self.formula_class_get(path) | 
					
						
							| 
									
										
										
										
											2017-10-07 00:31:28 +02:00
										 |  |  |     cache.fetch(path) | 
					
						
							| 
									
										
										
										
											2013-06-18 10:11:06 -07:00
										 |  |  |   end | 
					
						
							| 
									
										
										
										
											2013-06-08 20:58:43 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-26 07:24:14 +02:00
										 |  |  |   def self.load_formula(name, path, contents, namespace, flags:) | 
					
						
							| 
									
										
										
										
											2020-04-05 15:44:50 +01:00
										 |  |  |     raise "Formula loading disabled by HOMEBREW_DISABLE_LOAD_FORMULA!" if Homebrew::EnvConfig.disable_load_formula? | 
					
						
							| 
									
										
										
										
											2016-05-28 15:54:05 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-18 00:23:23 +01:00
										 |  |  |     require "formula" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-01 19:20:11 -04:00
										 |  |  |     mod = Module.new | 
					
						
							| 
									
										
										
										
											2015-09-02 16:12:26 +08:00
										 |  |  |     const_set(namespace, mod) | 
					
						
							| 
									
										
										
										
											2020-07-26 07:24:14 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-01 18:30:55 +00:00
										 |  |  |     begin | 
					
						
							| 
									
										
										
										
											2020-07-30 10:10:42 +02:00
										 |  |  |       # Set `BUILD_FLAGS` in the formula's namespace so we can | 
					
						
							|  |  |  |       # access them from within the formula's class scope. | 
					
						
							| 
									
										
										
										
											2020-07-26 07:24:14 +02:00
										 |  |  |       mod.const_set(:BUILD_FLAGS, flags) | 
					
						
							| 
									
										
										
										
											2017-02-01 18:30:55 +00:00
										 |  |  |       mod.module_eval(contents, path) | 
					
						
							| 
									
										
										
										
											2020-09-03 19:34:25 +02:00
										 |  |  |     rescue NameError, ArgumentError, ScriptError, MethodDeprecatedError => e | 
					
						
							| 
									
										
										
										
											2017-02-01 18:30:55 +00:00
										 |  |  |       raise FormulaUnreadableError.new(name, e) | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2015-06-01 19:20:11 -04:00
										 |  |  |     class_name = class_s(name) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     begin | 
					
						
							| 
									
										
										
										
											2015-09-02 16:12:26 +08:00
										 |  |  |       mod.const_get(class_name) | 
					
						
							| 
									
										
										
										
											2019-04-30 08:44:35 +01:00
										 |  |  |     rescue NameError => e | 
					
						
							| 
									
										
										
										
											2016-09-17 15:17:27 +01:00
										 |  |  |       class_list = mod.constants | 
					
						
							|  |  |  |                       .map { |const_name| mod.const_get(const_name) } | 
					
						
							|  |  |  |                       .select { |const| const.is_a?(Class) } | 
					
						
							| 
									
										
										
										
											2019-04-30 08:44:35 +01:00
										 |  |  |       new_exception = FormulaClassUnavailableError.new(name, path, class_name, class_list) | 
					
						
							|  |  |  |       raise new_exception, "", e.backtrace | 
					
						
							| 
									
										
										
										
											2015-06-01 19:20:11 -04:00
										 |  |  |     end | 
					
						
							| 
									
										
										
										
											2013-12-09 21:10:32 -06:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-26 07:24:14 +02:00
										 |  |  |   def self.load_formula_from_path(name, path, flags:) | 
					
						
							| 
									
										
										
										
											2016-09-24 17:59:14 +02:00
										 |  |  |     contents = path.open("r") { |f| ensure_utf8_encoding(f).read } | 
					
						
							| 
									
										
										
										
											2015-09-02 16:12:26 +08:00
										 |  |  |     namespace = "FormulaNamespace#{Digest::MD5.hexdigest(path.to_s)}" | 
					
						
							| 
									
										
										
										
											2020-07-26 07:24:14 +02:00
										 |  |  |     klass = load_formula(name, path, contents, namespace, flags: flags) | 
					
						
							| 
									
										
										
										
											2017-10-07 00:31:28 +02:00
										 |  |  |     cache[path] = klass | 
					
						
							| 
									
										
										
										
											2015-09-02 16:12:26 +08:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-26 07:24:14 +02:00
										 |  |  |   def self.resolve(name, spec: nil, force_bottle: false, flags: []) | 
					
						
							| 
									
										
										
										
											2018-09-11 17:44:18 +02:00
										 |  |  |     if name.include?("/") || File.exist?(name) | 
					
						
							| 
									
										
										
										
											2020-07-26 07:24:14 +02:00
										 |  |  |       f = factory(name, *spec, force_bottle: force_bottle, flags: flags) | 
					
						
							| 
									
										
										
										
											2018-09-11 17:44:18 +02:00
										 |  |  |       if f.any_version_installed? | 
					
						
							|  |  |  |         tab = Tab.for_formula(f) | 
					
						
							|  |  |  |         resolved_spec = spec || tab.spec | 
					
						
							|  |  |  |         f.active_spec = resolved_spec if f.send(resolved_spec) | 
					
						
							|  |  |  |         f.build = tab | 
					
						
							|  |  |  |         if f.head? && tab.tabfile | 
					
						
							|  |  |  |           k = Keg.new(tab.tabfile.parent) | 
					
						
							|  |  |  |           f.version.update_commit(k.version.version.commit) if k.version.head? | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |       rack = to_rack(name) | 
					
						
							| 
									
										
										
										
											2020-07-26 07:24:14 +02:00
										 |  |  |       alias_path = factory(name, force_bottle: force_bottle, flags: flags).alias_path | 
					
						
							|  |  |  |       f = from_rack(rack, *spec, alias_path: alias_path, force_bottle: force_bottle, flags: flags) | 
					
						
							| 
									
										
										
										
											2018-09-11 17:44:18 +02:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # If this formula was installed with an alias that has since changed, | 
					
						
							|  |  |  |     # then it was specified explicitly in ARGV. (Using the alias would | 
					
						
							|  |  |  |     # instead have found the new formula.) | 
					
						
							|  |  |  |     # | 
					
						
							|  |  |  |     # Because of this, the user is referring to this specific formula, | 
					
						
							| 
									
										
										
										
											2019-08-19 14:27:29 +10:00
										 |  |  |     # not any formula targeted by the same alias, so in this context | 
					
						
							| 
									
										
										
										
											2018-09-11 17:44:18 +02:00
										 |  |  |     # the formula shouldn't be considered outdated if the alias used to | 
					
						
							|  |  |  |     # install it has changed. | 
					
						
							|  |  |  |     f.follow_installed_alias = false | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     f | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-09 15:29:40 +01:00
										 |  |  |   def self.ensure_utf8_encoding(io) | 
					
						
							|  |  |  |     io.set_encoding(Encoding::UTF_8) | 
					
						
							| 
									
										
										
										
											2015-06-06 18:10:47 -04:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-03 13:09:07 +01:00
										 |  |  |   def self.class_s(name) | 
					
						
							| 
									
										
										
										
											2014-04-03 22:40:40 -05:00
										 |  |  |     class_name = name.capitalize | 
					
						
							| 
									
										
										
										
											2017-06-10 20:23:20 +03:00
										 |  |  |     class_name.gsub!(/[-_.\s]([a-zA-Z0-9])/) { Regexp.last_match(1).upcase } | 
					
						
							| 
									
										
										
										
											2015-08-06 15:45:52 +08:00
										 |  |  |     class_name.tr!("+", "x") | 
					
						
							| 
									
										
										
										
											2016-08-29 16:00:40 +01:00
										 |  |  |     class_name.sub!(/(.)@(\d)/, "\\1AT\\2") | 
					
						
							| 
									
										
										
										
											2014-04-03 22:40:40 -05:00
										 |  |  |     class_name | 
					
						
							| 
									
										
										
										
											2014-02-21 00:43:58 -05:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-05 17:17:03 -05:00
										 |  |  |   # A {FormulaLoader} returns instances of formulae. | 
					
						
							| 
									
										
										
										
											2013-06-18 10:11:06 -07:00
										 |  |  |   # Subclasses implement loaders for particular sources of formulae. | 
					
						
							|  |  |  |   class FormulaLoader | 
					
						
							| 
									
										
										
										
											2020-08-02 14:32:31 +02:00
										 |  |  |     include Context | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-18 10:11:06 -07:00
										 |  |  |     # The formula's name | 
					
						
							|  |  |  |     attr_reader :name | 
					
						
							|  |  |  |     # The formula's ruby file's path or filename | 
					
						
							|  |  |  |     attr_reader :path | 
					
						
							| 
									
										
										
										
											2016-09-03 21:10:44 +01:00
										 |  |  |     # The name used to install the formula | 
					
						
							| 
									
										
										
										
											2016-09-05 01:11:36 +01:00
										 |  |  |     attr_reader :alias_path | 
					
						
							| 
									
										
										
										
											2014-04-03 22:40:40 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def initialize(name, path) | 
					
						
							|  |  |  |       @name = name | 
					
						
							| 
									
										
										
										
											2014-04-06 00:31:07 -05:00
										 |  |  |       @path = path.resolved_path | 
					
						
							| 
									
										
										
										
											2014-04-03 22:40:40 -05:00
										 |  |  |     end | 
					
						
							| 
									
										
										
										
											2013-06-18 10:11:06 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # Gets the formula instance. | 
					
						
							| 
									
										
										
										
											2016-09-15 16:01:18 +01:00
										 |  |  |     # `alias_path` can be overridden here in case an alias was used to refer to | 
					
						
							|  |  |  |     # a formula that was loaded in another way. | 
					
						
							| 
									
										
										
										
											2020-07-26 07:24:14 +02:00
										 |  |  |     def get_formula(spec, alias_path: nil, force_bottle: false, flags: []) | 
					
						
							| 
									
										
										
										
											2020-07-30 03:24:37 +02:00
										 |  |  |       alias_path ||= self.alias_path | 
					
						
							|  |  |  |       klass(flags: flags).new(name, path, spec, alias_path: alias_path, force_bottle: force_bottle) | 
					
						
							| 
									
										
										
										
											2014-03-07 17:23:44 -06:00
										 |  |  |     end | 
					
						
							| 
									
										
										
										
											2013-06-18 10:11:06 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-26 07:24:14 +02:00
										 |  |  |     def klass(flags:) | 
					
						
							|  |  |  |       load_file(flags: flags) unless Formulary.formula_class_defined?(path) | 
					
						
							| 
									
										
										
										
											2015-06-01 19:20:11 -04:00
										 |  |  |       Formulary.formula_class_get(path) | 
					
						
							| 
									
										
										
										
											2013-06-18 10:11:06 -07:00
										 |  |  |     end | 
					
						
							| 
									
										
										
										
											2014-12-29 14:53:22 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     private | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-26 07:24:14 +02:00
										 |  |  |     def load_file(flags:) | 
					
						
							| 
									
										
										
										
											2020-08-02 14:32:31 +02:00
										 |  |  |       $stderr.puts "#{$PROGRAM_NAME} (#{self.class.name}): loading #{path}" if debug? | 
					
						
							| 
									
										
										
										
											2016-09-17 15:17:27 +01:00
										 |  |  |       raise FormulaUnavailableError, name unless path.file? | 
					
						
							| 
									
										
										
										
											2018-09-17 02:45:00 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-26 07:24:14 +02:00
										 |  |  |       Formulary.load_formula_from_path(name, path, flags: flags) | 
					
						
							| 
									
										
										
										
											2014-12-29 14:53:22 -05:00
										 |  |  |     end | 
					
						
							| 
									
										
										
										
											2013-06-18 10:11:06 -07:00
										 |  |  |   end | 
					
						
							| 
									
										
										
										
											2013-06-08 20:58:43 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-17 06:10:42 +02:00
										 |  |  |   # Loads a formula from a bottle. | 
					
						
							| 
									
										
										
										
											2013-06-18 10:11:06 -07:00
										 |  |  |   class BottleLoader < FormulaLoader | 
					
						
							| 
									
										
										
										
											2015-08-03 13:09:07 +01:00
										 |  |  |     def initialize(bottle_name) | 
					
						
							| 
									
										
										
										
											2016-07-13 13:51:44 -05:00
										 |  |  |       case bottle_name | 
					
						
							| 
									
										
										
										
											2020-05-29 13:15:08 +01:00
										 |  |  |       when URL_START_REGEX | 
					
						
							| 
									
										
										
										
											2016-07-13 13:51:44 -05:00
										 |  |  |         # The name of the formula is found between the last slash and the last hyphen. | 
					
						
							| 
									
										
										
										
											2017-06-09 11:44:25 -07:00
										 |  |  |         formula_name = File.basename(bottle_name)[/(.+)-/, 1] | 
					
						
							|  |  |  |         resource = Resource.new(formula_name) { url bottle_name } | 
					
						
							| 
									
										
										
										
											2018-03-24 10:53:49 +00:00
										 |  |  |         resource.specs[:bottle] = true | 
					
						
							| 
									
										
										
										
											2018-08-01 05:33:03 +02:00
										 |  |  |         downloader = resource.downloader | 
					
						
							| 
									
										
										
										
											2018-07-05 11:53:29 +02:00
										 |  |  |         cached = downloader.cached_location.exist? | 
					
						
							| 
									
										
										
										
											2016-07-13 13:51:44 -05:00
										 |  |  |         downloader.fetch | 
					
						
							|  |  |  |         ohai "Pouring the cached bottle" if cached | 
					
						
							| 
									
										
										
										
											2018-07-05 11:53:29 +02:00
										 |  |  |         @bottle_filename = downloader.cached_location | 
					
						
							| 
									
										
										
										
											2016-07-13 13:51:44 -05:00
										 |  |  |       else | 
					
						
							|  |  |  |         @bottle_filename = Pathname(bottle_name).realpath | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2016-04-25 17:57:51 +01:00
										 |  |  |       name, full_name = Utils::Bottles.resolve_formula_names @bottle_filename | 
					
						
							| 
									
										
										
										
											2015-05-27 22:49:18 +08:00
										 |  |  |       super name, Formulary.path(full_name) | 
					
						
							| 
									
										
										
										
											2013-06-18 10:11:06 -07:00
										 |  |  |     end | 
					
						
							| 
									
										
										
										
											2013-06-08 20:58:43 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-26 07:24:14 +02:00
										 |  |  |     def get_formula(spec, force_bottle: false, flags: [], **) | 
					
						
							| 
									
										
										
										
											2017-09-19 12:22:32 -07:00
										 |  |  |       contents = Utils::Bottles.formula_contents @bottle_filename, name: name | 
					
						
							| 
									
										
										
										
											2017-10-04 10:14:06 +01:00
										 |  |  |       formula = begin | 
					
						
							| 
									
										
										
										
											2020-08-28 20:23:47 -07:00
										 |  |  |         Formulary.from_contents(name, path, contents, spec, force_bottle: force_bottle, flags: flags) | 
					
						
							| 
									
										
										
										
											2017-10-04 10:14:06 +01:00
										 |  |  |       rescue FormulaUnreadableError => e | 
					
						
							| 
									
										
										
										
											2017-10-15 02:28:32 +02:00
										 |  |  |         opoo <<~EOS | 
					
						
							| 
									
										
										
										
											2017-10-04 10:14:06 +01:00
										 |  |  |           Unreadable formula in #{@bottle_filename}: | 
					
						
							|  |  |  |           #{e} | 
					
						
							|  |  |  |         EOS | 
					
						
							|  |  |  |         super | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2013-09-25 18:51:30 -05:00
										 |  |  |       formula.local_bottle_path = @bottle_filename | 
					
						
							| 
									
										
										
										
											2014-03-07 17:23:44 -06:00
										 |  |  |       formula | 
					
						
							| 
									
										
										
										
											2013-06-18 10:11:06 -07:00
										 |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							| 
									
										
										
										
											2013-06-08 20:58:43 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-17 06:10:42 +02:00
										 |  |  |   # Loads a formula from a path to an alias. | 
					
						
							| 
									
										
										
										
											2014-04-05 22:03:34 -05:00
										 |  |  |   class AliasLoader < FormulaLoader | 
					
						
							| 
									
										
										
										
											2015-08-03 13:09:07 +01:00
										 |  |  |     def initialize(alias_path) | 
					
						
							| 
									
										
										
										
											2014-04-05 22:03:34 -05:00
										 |  |  |       path = alias_path.resolved_path | 
					
						
							|  |  |  |       name = path.basename(".rb").to_s | 
					
						
							|  |  |  |       super name, path | 
					
						
							| 
									
										
										
										
											2016-09-15 16:01:18 +01:00
										 |  |  |       @alias_path = alias_path.to_s | 
					
						
							| 
									
										
										
										
											2014-04-05 22:03:34 -05:00
										 |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-18 21:42:43 -04:00
										 |  |  |   # Loads formulae from disk using a path. | 
					
						
							| 
									
										
										
										
											2013-06-18 10:11:06 -07:00
										 |  |  |   class FromPathLoader < FormulaLoader | 
					
						
							| 
									
										
										
										
											2015-08-03 13:09:07 +01:00
										 |  |  |     def initialize(path) | 
					
						
							| 
									
										
										
										
											2014-04-03 22:40:40 -05:00
										 |  |  |       path = Pathname.new(path).expand_path | 
					
						
							| 
									
										
										
										
											2014-04-05 22:03:34 -05:00
										 |  |  |       super path.basename(".rb").to_s, path | 
					
						
							| 
									
										
										
										
											2013-06-18 10:11:06 -07:00
										 |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-18 21:42:43 -04:00
										 |  |  |   # Loads formulae from URLs. | 
					
						
							| 
									
										
										
										
											2013-06-18 10:11:06 -07:00
										 |  |  |   class FromUrlLoader < FormulaLoader | 
					
						
							| 
									
										
										
										
											2020-10-20 12:03:48 +02:00
										 |  |  |     extend T::Sig | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-18 10:11:06 -07:00
										 |  |  |     attr_reader :url | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-20 12:03:48 +02:00
										 |  |  |     sig { params(url: T.any(URI::Generic, String)).void } | 
					
						
							| 
									
										
										
										
											2015-08-03 13:09:07 +01:00
										 |  |  |     def initialize(url) | 
					
						
							| 
									
										
										
										
											2013-06-18 10:11:06 -07:00
										 |  |  |       @url = url | 
					
						
							| 
									
										
										
										
											2014-04-10 18:58:09 -04:00
										 |  |  |       uri = URI(url) | 
					
						
							|  |  |  |       formula = File.basename(uri.path, ".rb") | 
					
						
							|  |  |  |       super formula, HOMEBREW_CACHE_FORMULA/File.basename(uri.path) | 
					
						
							| 
									
										
										
										
											2013-06-18 10:11:06 -07:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-26 07:24:14 +02:00
										 |  |  |     def load_file(flags:) | 
					
						
							| 
									
										
										
										
											2020-10-09 11:12:06 +02:00
										 |  |  |       if %r{githubusercontent.com/[\w-]+/[\w-]+/[a-f0-9]{40}(?:/Formula)?/(?<formula_name>[\w+-.@]+).rb} =~ url # rubocop:disable Style/CaseLikeIf | 
					
						
							| 
									
										
										
										
											2020-11-24 16:44:02 +00:00
										 |  |  |         raise UsageError, "Installation of #{formula_name} from a GitHub commit URL is unsupported! " \ | 
					
						
							|  |  |  |                   "'brew extract #{formula_name}' to stable tap on GitHub instead." | 
					
						
							| 
									
										
										
										
											2020-05-29 13:15:08 +01:00
										 |  |  |       elsif url.match?(%r{^(https?|ftp)://}) | 
					
						
							| 
									
										
										
										
											2020-11-24 16:44:02 +00:00
										 |  |  |         raise UsageError, "Non-checksummed download of #{name} formula file from an arbitrary URL is unsupported! ", | 
					
						
							|  |  |  |               "'brew extract' or 'brew create' and 'brew tap-new' to create a "\ | 
					
						
							|  |  |  |               "formula file in a tap on GitHub instead." | 
					
						
							| 
									
										
										
										
											2019-05-07 10:50:19 +01:00
										 |  |  |       end | 
					
						
							| 
									
										
										
										
											2014-12-29 14:53:22 -05:00
										 |  |  |       HOMEBREW_CACHE_FORMULA.mkpath | 
					
						
							|  |  |  |       FileUtils.rm_f(path) | 
					
						
							| 
									
										
										
										
											2017-08-08 18:10:13 +02:00
										 |  |  |       curl_download url, to: path | 
					
						
							| 
									
										
										
										
											2014-03-07 17:23:44 -06:00
										 |  |  |       super | 
					
						
							| 
									
										
										
										
											2016-12-10 13:04:14 +00:00
										 |  |  |     rescue MethodDeprecatedError => e | 
					
						
							| 
									
										
										
										
											2020-10-09 11:12:06 +02:00
										 |  |  |       if %r{github.com/(?<user>[\w-]+)/(?<repo>[\w-]+)/} =~ url | 
					
						
							|  |  |  |         e.issues_url = "https://github.com/#{user}/#{repo}/issues/new" | 
					
						
							| 
									
										
										
										
											2016-12-10 13:04:14 +00:00
										 |  |  |       end | 
					
						
							|  |  |  |       raise | 
					
						
							| 
									
										
										
										
											2013-06-08 20:58:43 -07:00
										 |  |  |     end | 
					
						
							| 
									
										
										
										
											2013-06-18 10:11:06 -07:00
										 |  |  |   end | 
					
						
							| 
									
										
										
										
											2013-06-08 20:58:43 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-18 10:11:06 -07:00
										 |  |  |   # Loads tapped formulae. | 
					
						
							|  |  |  |   class TapLoader < FormulaLoader | 
					
						
							| 
									
										
										
										
											2015-07-14 21:33:29 +08:00
										 |  |  |     attr_reader :tap | 
					
						
							| 
									
										
										
										
											2014-04-05 22:03:33 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-11 16:42:29 +00:00
										 |  |  |     def initialize(tapped_name, from: nil) | 
					
						
							| 
									
										
										
										
											2020-12-01 17:04:59 +00:00
										 |  |  |       warn = [:keg, :rack].exclude?(from) | 
					
						
							| 
									
										
										
										
											2016-11-11 16:42:29 +00:00
										 |  |  |       name, path = formula_name_path(tapped_name, warn: warn) | 
					
						
							| 
									
										
										
										
											2016-11-02 14:47:24 -04:00
										 |  |  |       super name, path | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def formula_name_path(tapped_name, warn: true) | 
					
						
							| 
									
										
										
										
											2014-04-05 22:03:33 -05:00
										 |  |  |       user, repo, name = tapped_name.split("/", 3).map(&:downcase) | 
					
						
							| 
									
										
										
										
											2015-12-02 14:35:42 +08:00
										 |  |  |       @tap = Tap.fetch user, repo | 
					
						
							| 
									
										
										
										
											2016-02-24 20:06:33 +08:00
										 |  |  |       formula_dir = @tap.formula_dir || @tap.path | 
					
						
							|  |  |  |       path = formula_dir/"#{name}.rb" | 
					
						
							| 
									
										
										
										
											2015-09-12 18:04:06 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-24 20:06:33 +08:00
										 |  |  |       unless path.file? | 
					
						
							| 
									
										
										
										
											2015-12-06 21:44:18 +08:00
										 |  |  |         if (possible_alias = @tap.alias_dir/name).file? | 
					
						
							| 
									
										
										
										
											2015-09-12 18:04:06 +08:00
										 |  |  |           path = possible_alias.resolved_path | 
					
						
							|  |  |  |           name = path.basename(".rb").to_s | 
					
						
							| 
									
										
										
										
											2016-02-24 20:06:33 +08:00
										 |  |  |         elsif (new_name = @tap.formula_renames[name]) && | 
					
						
							|  |  |  |               (new_path = formula_dir/"#{new_name}.rb").file? | 
					
						
							| 
									
										
										
										
											2016-11-02 14:47:24 -04:00
										 |  |  |           old_name = name | 
					
						
							| 
									
										
										
										
											2016-02-24 20:06:33 +08:00
										 |  |  |           path = new_path | 
					
						
							|  |  |  |           name = new_name | 
					
						
							| 
									
										
										
										
											2016-11-02 14:47:24 -04:00
										 |  |  |           new_name = @tap.core_tap? ? name : "#{@tap}/#{name}" | 
					
						
							|  |  |  |         elsif (new_tap_name = @tap.tap_migrations[name]) | 
					
						
							| 
									
										
										
										
											2016-12-18 13:18:46 -08:00
										 |  |  |           new_tap_user, new_tap_repo, = new_tap_name.split("/") | 
					
						
							|  |  |  |           new_tap_name = "#{new_tap_user}/#{new_tap_repo}" | 
					
						
							| 
									
										
										
										
											2016-11-02 14:47:24 -04:00
										 |  |  |           new_tap = Tap.fetch new_tap_name | 
					
						
							|  |  |  |           new_tap.install unless new_tap.installed? | 
					
						
							|  |  |  |           new_tapped_name = "#{new_tap_name}/#{name}" | 
					
						
							|  |  |  |           name, path = formula_name_path(new_tapped_name, warn: false) | 
					
						
							|  |  |  |           old_name = tapped_name | 
					
						
							|  |  |  |           new_name = new_tap.core_tap? ? name : new_tapped_name | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-19 13:11:32 +00:00
										 |  |  |         opoo "Use #{new_name} instead of deprecated #{old_name}" if warn && old_name && new_name | 
					
						
							| 
									
										
										
										
											2015-09-12 18:04:06 +08:00
										 |  |  |       end | 
					
						
							| 
									
										
										
										
											2014-04-07 18:44:29 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-02 14:47:24 -04:00
										 |  |  |       [name, path] | 
					
						
							| 
									
										
										
										
											2013-06-08 20:58:43 -07:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-26 07:24:14 +02:00
										 |  |  |     def get_formula(spec, alias_path: nil, force_bottle: false, flags: []) | 
					
						
							| 
									
										
										
										
											2014-03-07 17:23:44 -06:00
										 |  |  |       super | 
					
						
							| 
									
										
										
										
											2017-04-18 08:43:39 +01:00
										 |  |  |     rescue FormulaUnreadableError => e | 
					
						
							|  |  |  |       raise TapFormulaUnreadableError.new(tap, name, e.formula_error), "", e.backtrace | 
					
						
							|  |  |  |     rescue FormulaClassUnavailableError => e | 
					
						
							|  |  |  |       raise TapFormulaClassUnavailableError.new(tap, name, e.path, e.class_name, e.class_list), "", e.backtrace | 
					
						
							| 
									
										
										
										
											2014-12-29 15:23:01 -05:00
										 |  |  |     rescue FormulaUnavailableError => e | 
					
						
							| 
									
										
										
										
											2015-07-14 21:33:29 +08:00
										 |  |  |       raise TapFormulaUnavailableError.new(tap, name), "", e.backtrace | 
					
						
							| 
									
										
										
										
											2013-06-18 10:11:06 -07:00
										 |  |  |     end | 
					
						
							| 
									
										
										
										
											2016-12-10 13:04:14 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-26 07:24:14 +02:00
										 |  |  |     def load_file(flags:) | 
					
						
							| 
									
										
										
										
											2016-12-10 13:04:14 +00:00
										 |  |  |       super | 
					
						
							|  |  |  |     rescue MethodDeprecatedError => e | 
					
						
							| 
									
										
										
										
											2016-12-14 05:07:54 +03:00
										 |  |  |       e.issues_url = tap.issues_url || tap.to_s | 
					
						
							| 
									
										
										
										
											2016-12-10 13:04:14 +00:00
										 |  |  |       raise | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2013-06-18 10:11:06 -07:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-05 17:17:03 -05:00
										 |  |  |   # Pseudo-loader which will raise a {FormulaUnavailableError} when trying to load the corresponding formula. | 
					
						
							| 
									
										
										
										
											2015-01-01 01:21:59 -05:00
										 |  |  |   class NullLoader < FormulaLoader | 
					
						
							|  |  |  |     def initialize(name) | 
					
						
							| 
									
										
										
										
											2015-05-08 18:59:08 +08:00
										 |  |  |       super name, Formulary.core_path(name) | 
					
						
							| 
									
										
										
										
											2015-01-01 01:21:59 -05:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-19 16:28:28 +01:00
										 |  |  |     def get_formula(*) | 
					
						
							| 
									
										
										
										
											2016-09-17 15:17:27 +01:00
										 |  |  |       raise FormulaUnavailableError, name | 
					
						
							| 
									
										
										
										
											2015-01-01 01:21:59 -05:00
										 |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-18 21:42:43 -04:00
										 |  |  |   # Load formulae directly from their contents. | 
					
						
							| 
									
										
										
										
											2015-09-02 16:25:46 +08:00
										 |  |  |   class FormulaContentsLoader < FormulaLoader | 
					
						
							| 
									
										
										
										
											2020-11-05 17:17:03 -05:00
										 |  |  |     # The formula's contents. | 
					
						
							| 
									
										
										
										
											2015-09-02 16:25:46 +08:00
										 |  |  |     attr_reader :contents | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def initialize(name, path, contents) | 
					
						
							|  |  |  |       @contents = contents | 
					
						
							|  |  |  |       super name, path | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-26 07:24:14 +02:00
										 |  |  |     def klass(flags:) | 
					
						
							| 
									
										
										
										
											2020-08-02 14:32:31 +02:00
										 |  |  |       $stderr.puts "#{$PROGRAM_NAME} (#{self.class.name}): loading #{path}" if debug? | 
					
						
							| 
									
										
										
										
											2020-07-26 07:24:14 +02:00
										 |  |  |       namespace = "FormulaNamespace#{Digest::MD5.hexdigest(contents.to_s)}" | 
					
						
							|  |  |  |       Formulary.load_formula(name, path, contents, namespace, flags: flags) | 
					
						
							| 
									
										
										
										
											2015-09-02 16:25:46 +08:00
										 |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-05 17:17:03 -05:00
										 |  |  |   # Return a {Formula} instance for the given reference. | 
					
						
							| 
									
										
										
										
											2018-10-18 21:42:43 -04:00
										 |  |  |   # `ref` is a string containing: | 
					
						
							|  |  |  |   # | 
					
						
							| 
									
										
										
										
											2013-06-23 12:47:10 -07:00
										 |  |  |   # * a formula name | 
					
						
							|  |  |  |   # * a formula pathname | 
					
						
							|  |  |  |   # * a formula URL | 
					
						
							|  |  |  |   # * a local bottle reference | 
					
						
							| 
									
										
										
										
											2020-07-26 07:24:14 +02:00
										 |  |  |   def self.factory(ref, spec = :stable, alias_path: nil, from: nil, force_bottle: false, flags: []) | 
					
						
							| 
									
										
										
										
											2018-06-01 19:22:33 +01:00
										 |  |  |     raise ArgumentError, "Formulae must have a ref!" unless ref | 
					
						
							| 
									
										
										
										
											2018-09-17 02:45:00 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-06 10:03:44 +00:00
										 |  |  |     cache_key = "#{ref}-#{spec}-#{alias_path}-#{from}" | 
					
						
							|  |  |  |     if factory_cached? && cache[:formulary_factory] && | 
					
						
							|  |  |  |        cache[:formulary_factory][cache_key] | 
					
						
							|  |  |  |       return cache[:formulary_factory][cache_key] | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-26 07:24:14 +02:00
										 |  |  |     formula = loader_for(ref, from: from).get_formula(spec, alias_path: alias_path, | 
					
						
							|  |  |  |                                                       force_bottle: force_bottle, flags: flags) | 
					
						
							| 
									
										
										
										
											2019-11-06 10:03:44 +00:00
										 |  |  |     if factory_cached? | 
					
						
							|  |  |  |       cache[:formulary_factory] ||= {} | 
					
						
							|  |  |  |       cache[:formulary_factory][cache_key] ||= formula | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |     formula | 
					
						
							| 
									
										
										
										
											2014-04-05 22:03:33 -05:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-05 17:17:03 -05:00
										 |  |  |   # Return a {Formula} instance for the given rack. | 
					
						
							| 
									
										
										
										
											2016-09-15 16:01:18 +01:00
										 |  |  |   # | 
					
						
							| 
									
										
										
										
											2020-11-05 15:19:56 -05:00
										 |  |  |   # @param spec when nil, will auto resolve the formula's spec. | 
					
						
							|  |  |  |   # @param :alias_path will be used if the formula is found not to be | 
					
						
							|  |  |  |   #   installed, and discarded if it is installed because the `alias_path` used | 
					
						
							|  |  |  |   #   to install the formula will be set instead. | 
					
						
							| 
									
										
										
										
											2020-07-26 07:24:14 +02:00
										 |  |  |   def self.from_rack(rack, spec = nil, alias_path: nil, force_bottle: false, flags: []) | 
					
						
							| 
									
										
										
										
											2015-05-16 11:26:26 +08:00
										 |  |  |     kegs = rack.directory? ? rack.subdirs.map { |d| Keg.new(d) } : [] | 
					
						
							| 
									
										
										
										
											2018-09-02 20:14:54 +01:00
										 |  |  |     keg = kegs.find(&:linked?) || kegs.find(&:optlinked?) || kegs.max_by(&:version) | 
					
						
							| 
									
										
										
										
											2015-05-16 11:26:26 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-15 17:45:21 +08:00
										 |  |  |     if keg | 
					
						
							| 
									
										
										
										
											2016-09-19 16:04:32 +01:00
										 |  |  |       from_keg(keg, spec, alias_path: alias_path) | 
					
						
							| 
									
										
										
										
											2016-07-15 17:45:21 +08:00
										 |  |  |     else | 
					
						
							| 
									
										
										
										
											2020-07-26 07:24:14 +02:00
										 |  |  |       factory(rack.basename.to_s, spec || :stable, alias_path: alias_path, from: :rack, | 
					
						
							|  |  |  |               force_bottle: force_bottle, flags: flags) | 
					
						
							| 
									
										
										
										
											2016-07-15 17:45:21 +08:00
										 |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							| 
									
										
										
										
											2018-06-05 23:19:18 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-05 17:17:03 -05:00
										 |  |  |   # Return whether given rack is keg-only. | 
					
						
							| 
									
										
										
										
											2018-06-05 23:19:18 -04:00
										 |  |  |   def self.keg_only?(rack) | 
					
						
							|  |  |  |     Formulary.from_rack(rack).keg_only? | 
					
						
							|  |  |  |   rescue FormulaUnavailableError, TapFormulaAmbiguityError, TapFormulaWithOldnameAmbiguityError | 
					
						
							|  |  |  |     false | 
					
						
							|  |  |  |   end | 
					
						
							| 
									
										
										
										
											2016-07-15 17:45:21 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-05 15:19:56 -05:00
										 |  |  |   # Return a {Formula} instance for the given keg. | 
					
						
							|  |  |  |   # | 
					
						
							|  |  |  |   # @param spec when nil, will auto resolve the formula's spec. | 
					
						
							| 
									
										
										
										
											2020-07-26 07:24:14 +02:00
										 |  |  |   def self.from_keg(keg, spec = nil, alias_path: nil, force_bottle: false, flags: []) | 
					
						
							| 
									
										
										
										
											2015-07-30 16:33:19 +08:00
										 |  |  |     tab = Tab.for_keg(keg) | 
					
						
							|  |  |  |     tap = tab.tap | 
					
						
							|  |  |  |     spec ||= tab.spec | 
					
						
							| 
									
										
										
										
											2015-05-16 11:26:26 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-15 15:03:58 +08:00
										 |  |  |     f = if tap.nil? | 
					
						
							| 
									
										
										
										
											2020-07-26 07:24:14 +02:00
										 |  |  |       factory(keg.rack.basename.to_s, spec, alias_path: alias_path, from: :keg, | 
					
						
							|  |  |  |               force_bottle: force_bottle, flags: flags) | 
					
						
							| 
									
										
										
										
											2015-05-16 11:26:26 +08:00
										 |  |  |     else | 
					
						
							| 
									
										
										
										
											2015-10-09 15:27:59 +08:00
										 |  |  |       begin | 
					
						
							| 
									
										
										
										
											2020-07-26 07:24:14 +02:00
										 |  |  |         factory("#{tap}/#{keg.rack.basename}", spec, alias_path: alias_path, from: :keg, | 
					
						
							|  |  |  |                 force_bottle: force_bottle, flags: flags) | 
					
						
							| 
									
										
										
										
											2015-10-09 15:27:59 +08:00
										 |  |  |       rescue FormulaUnavailableError | 
					
						
							|  |  |  |         # formula may be migrated to different tap. Try to search in core and all taps. | 
					
						
							| 
									
										
										
										
											2020-07-26 07:24:14 +02:00
										 |  |  |         factory(keg.rack.basename.to_s, spec, alias_path: alias_path, from: :keg, | 
					
						
							|  |  |  |                 force_bottle: force_bottle, flags: flags) | 
					
						
							| 
									
										
										
										
											2015-10-09 15:27:59 +08:00
										 |  |  |       end | 
					
						
							| 
									
										
										
										
											2015-05-16 11:26:26 +08:00
										 |  |  |     end | 
					
						
							| 
									
										
										
										
											2016-07-15 15:03:58 +08:00
										 |  |  |     f.build = tab | 
					
						
							| 
									
										
										
										
											2016-12-09 17:59:08 +00:00
										 |  |  |     f.build.used_options = Tab.remap_deprecated_options(f.deprecated_options, tab.used_options).as_flags | 
					
						
							| 
									
										
										
										
											2016-08-06 11:22:12 +03:00
										 |  |  |     f.version.update_commit(keg.version.version.commit) if f.head? && keg.version.head? | 
					
						
							| 
									
										
										
										
											2016-07-15 15:03:58 +08:00
										 |  |  |     f | 
					
						
							| 
									
										
										
										
											2015-05-16 11:26:26 +08:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-05 17:17:03 -05:00
										 |  |  |   # Return a {Formula} instance directly from contents. | 
					
						
							| 
									
										
										
										
											2020-07-26 07:24:14 +02:00
										 |  |  |   def self.from_contents(name, path, contents, spec = :stable, alias_path: nil, force_bottle: false, flags: []) | 
					
						
							|  |  |  |     FormulaContentsLoader.new(name, path, contents) | 
					
						
							|  |  |  |                          .get_formula(spec, alias_path: alias_path, force_bottle: force_bottle, flags: flags) | 
					
						
							| 
									
										
										
										
											2015-09-02 16:25:46 +08:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-09 14:56:01 +03:00
										 |  |  |   def self.to_rack(ref) | 
					
						
							| 
									
										
										
										
											2016-08-10 08:48:30 +01:00
										 |  |  |     # If using a fully-scoped reference, check if the formula can be resolved. | 
					
						
							|  |  |  |     factory(ref) if ref.include? "/" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Check whether the rack with the given name exists. | 
					
						
							| 
									
										
										
										
											2015-08-10 21:35:59 +08:00
										 |  |  |     if (rack = HOMEBREW_CELLAR/File.basename(ref, ".rb")).directory? | 
					
						
							| 
									
										
										
										
											2015-08-15 16:12:42 +08:00
										 |  |  |       return rack.resolved_path | 
					
						
							| 
									
										
										
										
											2015-08-09 14:56:01 +03:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-10 08:48:30 +01:00
										 |  |  |     # Use canonical name to locate rack. | 
					
						
							| 
									
										
										
										
											2015-08-15 16:12:42 +08:00
										 |  |  |     (HOMEBREW_CELLAR/canonical_name(ref)).resolved_path | 
					
						
							| 
									
										
										
										
											2015-08-09 14:56:01 +03:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-05 22:03:34 -05:00
										 |  |  |   def self.canonical_name(ref) | 
					
						
							|  |  |  |     loader_for(ref).name | 
					
						
							| 
									
										
										
										
											2015-05-15 19:41:31 +08:00
										 |  |  |   rescue TapFormulaAmbiguityError | 
					
						
							|  |  |  |     # If there are multiple tap formulae with the name of ref, | 
					
						
							|  |  |  |     # then ref is the canonical name | 
					
						
							|  |  |  |     ref.downcase | 
					
						
							| 
									
										
										
										
											2014-04-05 22:03:34 -05:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-08 13:48:36 +08:00
										 |  |  |   def self.path(ref) | 
					
						
							|  |  |  |     loader_for(ref).path | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-11 16:42:29 +00:00
										 |  |  |   def self.loader_for(ref, from: nil) | 
					
						
							| 
									
										
										
										
											2014-04-05 22:03:33 -05:00
										 |  |  |     case ref | 
					
						
							|  |  |  |     when Pathname::BOTTLE_EXTNAME_RX | 
					
						
							|  |  |  |       return BottleLoader.new(ref) | 
					
						
							| 
									
										
										
										
											2020-05-29 13:15:08 +01:00
										 |  |  |     when URL_START_REGEX | 
					
						
							| 
									
										
										
										
											2016-07-13 13:51:44 -05:00
										 |  |  |       return FromUrlLoader.new(ref) | 
					
						
							| 
									
										
										
										
											2014-04-05 22:03:33 -05:00
										 |  |  |     when HOMEBREW_TAP_FORMULA_REGEX | 
					
						
							| 
									
										
										
										
											2016-11-11 16:42:29 +00:00
										 |  |  |       return TapLoader.new(ref, from: from) | 
					
						
							| 
									
										
										
										
											2013-06-08 20:58:43 -07:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-19 13:11:32 +00:00
										 |  |  |     return FromPathLoader.new(ref) if File.extname(ref) == ".rb" && Pathname.new(ref).expand_path.exist? | 
					
						
							| 
									
										
										
										
											2014-04-05 22:03:33 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-08 18:59:08 +08:00
										 |  |  |     formula_with_that_name = core_path(ref) | 
					
						
							| 
									
										
										
										
											2019-02-19 13:11:32 +00:00
										 |  |  |     return FormulaLoader.new(ref, formula_with_that_name) if formula_with_that_name.file? | 
					
						
							| 
									
										
										
										
											2014-04-05 22:03:33 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-07 18:04:25 +08:00
										 |  |  |     possible_alias = CoreTap.instance.alias_dir/ref | 
					
						
							| 
									
										
										
										
											2016-09-23 11:01:40 +02:00
										 |  |  |     return AliasLoader.new(possible_alias) if possible_alias.file? | 
					
						
							| 
									
										
										
										
											2014-04-05 22:03:33 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-22 13:15:33 +08:00
										 |  |  |     possible_tap_formulae = tap_paths(ref) | 
					
						
							| 
									
										
										
										
											2019-02-19 13:11:32 +00:00
										 |  |  |     raise TapFormulaAmbiguityError.new(ref, possible_tap_formulae) if possible_tap_formulae.size > 1
 | 
					
						
							| 
									
										
										
										
											2016-09-23 22:02:23 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if possible_tap_formulae.size == 1
 | 
					
						
							| 
									
										
										
										
											2015-09-12 18:04:06 +08:00
										 |  |  |       path = possible_tap_formulae.first.resolved_path | 
					
						
							|  |  |  |       name = path.basename(".rb").to_s | 
					
						
							|  |  |  |       return FormulaLoader.new(name, path) | 
					
						
							| 
									
										
										
										
											2015-05-08 19:16:06 +08:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-07 18:04:25 +08:00
										 |  |  |     if newref = CoreTap.instance.formula_renames[ref] | 
					
						
							| 
									
										
										
										
											2015-08-09 14:52:49 +03:00
										 |  |  |       formula_with_that_oldname = core_path(newref) | 
					
						
							| 
									
										
										
										
											2019-02-19 13:11:32 +00:00
										 |  |  |       return FormulaLoader.new(newref, formula_with_that_oldname) if formula_with_that_oldname.file? | 
					
						
							| 
									
										
										
										
											2015-08-09 14:52:49 +03:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     possible_tap_newname_formulae = [] | 
					
						
							|  |  |  |     Tap.each do |tap| | 
					
						
							|  |  |  |       if newref = tap.formula_renames[ref] | 
					
						
							|  |  |  |         possible_tap_newname_formulae << "#{tap.name}/#{newref}" | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if possible_tap_newname_formulae.size > 1
 | 
					
						
							|  |  |  |       raise TapFormulaWithOldnameAmbiguityError.new(ref, possible_tap_newname_formulae) | 
					
						
							| 
									
										
										
										
											2016-09-23 22:02:23 +02:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-19 13:11:32 +00:00
										 |  |  |     return TapLoader.new(possible_tap_newname_formulae.first, from: from) unless possible_tap_newname_formulae.empty? | 
					
						
							| 
									
										
										
										
											2015-08-09 14:52:49 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-09 21:42:09 +00:00
										 |  |  |     possible_keg_formula = Pathname.new("#{HOMEBREW_PREFIX}/opt/#{ref}/.brew/#{ref}.rb") | 
					
						
							| 
									
										
										
										
											2019-02-19 13:11:32 +00:00
										 |  |  |     return FormulaLoader.new(ref, possible_keg_formula) if possible_keg_formula.file? | 
					
						
							| 
									
										
										
										
											2017-01-09 21:42:09 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-05 22:03:33 -05:00
										 |  |  |     possible_cached_formula = Pathname.new("#{HOMEBREW_CACHE_FORMULA}/#{ref}.rb") | 
					
						
							| 
									
										
										
										
											2019-02-19 13:11:32 +00:00
										 |  |  |     return FormulaLoader.new(ref, possible_cached_formula) if possible_cached_formula.file? | 
					
						
							| 
									
										
										
										
											2014-04-05 22:03:33 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-03 13:09:07 +01:00
										 |  |  |     NullLoader.new(ref) | 
					
						
							| 
									
										
										
										
											2013-06-08 20:58:43 -07:00
										 |  |  |   end | 
					
						
							| 
									
										
										
										
											2015-05-08 18:59:08 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   def self.core_path(name) | 
					
						
							| 
									
										
										
										
											2016-09-15 16:01:18 +01:00
										 |  |  |     CoreTap.instance.formula_dir/"#{name.to_s.downcase}.rb" | 
					
						
							| 
									
										
										
										
											2015-05-08 18:59:08 +08:00
										 |  |  |   end | 
					
						
							| 
									
										
										
										
											2015-05-08 19:16:06 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-21 19:57:01 +02:00
										 |  |  |   def self.tap_paths(name, taps = Dir[HOMEBREW_LIBRARY/"Taps/*/*/"]) | 
					
						
							| 
									
										
										
										
											2017-04-07 10:26:00 +09:00
										 |  |  |     name = name.to_s.downcase | 
					
						
							| 
									
										
										
										
											2015-08-09 22:43:01 +08:00
										 |  |  |     taps.map do |tap| | 
					
						
							| 
									
										
										
										
											2015-06-12 13:26:46 +08:00
										 |  |  |       Pathname.glob([ | 
					
						
							| 
									
										
										
										
											2016-09-17 15:17:27 +01:00
										 |  |  |                       "#{tap}Formula/#{name}.rb", | 
					
						
							|  |  |  |                       "#{tap}HomebrewFormula/#{name}.rb", | 
					
						
							|  |  |  |                       "#{tap}#{name}.rb", | 
					
						
							|  |  |  |                       "#{tap}Aliases/#{name}", | 
					
						
							| 
									
										
										
										
											2018-09-02 20:14:54 +01:00
										 |  |  |                     ]).find(&:file?) | 
					
						
							| 
									
										
										
										
											2015-06-12 13:26:46 +08:00
										 |  |  |     end.compact | 
					
						
							| 
									
										
										
										
											2015-05-08 19:16:06 +08:00
										 |  |  |   end | 
					
						
							| 
									
										
										
										
											2013-06-08 20:58:43 -07:00
										 |  |  | end |