| 
									
										
										
										
											2023-03-14 22:47:25 -07:00
										 |  |  | # typed: true | 
					
						
							| 
									
										
										
										
											2019-04-19 15:38:03 +09:00
										 |  |  | # frozen_string_literal: true | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-03 13:09:07 +01:00
										 |  |  | require "cxxstdlib" | 
					
						
							|  |  |  | require "options" | 
					
						
							| 
									
										
										
										
											2016-11-20 13:00:01 -05:00
										 |  |  | require "json" | 
					
						
							| 
									
										
										
										
											2016-07-29 20:31:32 -06:00
										 |  |  | require "development_tools" | 
					
						
							| 
									
										
										
										
											2017-10-07 00:31:28 +02:00
										 |  |  | require "extend/cachable" | 
					
						
							| 
									
										
										
										
											2011-09-22 20:07:39 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-14 22:47:25 -07:00
										 |  |  | # Rather than calling `new` directly, use one of the class methods like {Tab.create}. | 
					
						
							|  |  |  | class Tab | 
					
						
							| 
									
										
										
										
											2017-10-07 00:31:28 +02:00
										 |  |  |   extend Cachable | 
					
						
							| 
									
										
										
										
											2015-11-27 16:40:16 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-19 15:38:03 +09:00
										 |  |  |   FILENAME = "INSTALL_RECEIPT.json" | 
					
						
							| 
									
										
										
										
											2013-01-23 00:26:20 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-26 20:55:51 +02:00
										 |  |  |   # Check whether the formula was installed as a dependency. | 
					
						
							|  |  |  |   # | 
					
						
							| 
									
										
										
										
											2024-04-22 21:05:48 +02:00
										 |  |  |   # @api internal | 
					
						
							|  |  |  |   attr_accessor :installed_as_dependency | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-26 20:55:51 +02:00
										 |  |  |   # Check whether the formula was installed on request. | 
					
						
							|  |  |  |   # | 
					
						
							| 
									
										
										
										
											2024-04-22 21:05:48 +02:00
										 |  |  |   # @api internal | 
					
						
							|  |  |  |   attr_accessor :installed_on_request | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-26 20:55:51 +02:00
										 |  |  |   # Check whether the formula was poured from a bottle. | 
					
						
							|  |  |  |   # | 
					
						
							| 
									
										
										
										
											2024-04-22 21:05:48 +02:00
										 |  |  |   # @api internal | 
					
						
							|  |  |  |   attr_accessor :poured_from_bottle | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   attr_accessor :homebrew_version, :tabfile, :built_as_bottle, | 
					
						
							|  |  |  |                 :changed_files, :loaded_from_api, :time, :stdlib, :aliases, :arch, :source, | 
					
						
							| 
									
										
										
										
											2023-03-14 22:56:32 -07:00
										 |  |  |                 :built_on | 
					
						
							| 
									
										
										
										
											2024-04-22 21:05:48 +02:00
										 |  |  |   attr_writer :used_options, :unused_options, :compiler, :source_modified_time | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-26 20:55:51 +02:00
										 |  |  |   # Returns the formula's runtime dependencies. | 
					
						
							|  |  |  |   # | 
					
						
							| 
									
										
										
										
											2024-04-22 21:05:48 +02:00
										 |  |  |   # @api internal | 
					
						
							|  |  |  |   attr_writer :runtime_dependencies | 
					
						
							| 
									
										
										
										
											2023-03-14 22:47:25 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-08 14:46:15 -04:00
										 |  |  |   # Instantiates a {Tab} for a new installation of a formula. | 
					
						
							| 
									
										
										
										
											2016-07-08 01:14:34 +02:00
										 |  |  |   def self.create(formula, compiler, stdlib) | 
					
						
							|  |  |  |     build = formula.build | 
					
						
							| 
									
										
										
										
											2018-07-16 16:46:39 +01:00
										 |  |  |     runtime_deps = formula.runtime_dependencies(undeclared: false) | 
					
						
							| 
									
										
										
										
											2015-02-18 20:05:50 -05:00
										 |  |  |     attributes = { | 
					
						
							| 
									
										
										
										
											2018-11-02 17:18:07 +00:00
										 |  |  |       "homebrew_version"        => HOMEBREW_VERSION, | 
					
						
							|  |  |  |       "used_options"            => build.used_options.as_flags, | 
					
						
							|  |  |  |       "unused_options"          => build.unused_options.as_flags, | 
					
						
							|  |  |  |       "tabfile"                 => formula.prefix/FILENAME, | 
					
						
							|  |  |  |       "built_as_bottle"         => build.bottle?, | 
					
						
							| 
									
										
										
										
											2017-01-09 21:05:27 +00:00
										 |  |  |       "installed_as_dependency" => false, | 
					
						
							| 
									
										
										
										
											2021-02-23 10:19:45 +00:00
										 |  |  |       "installed_on_request"    => false, | 
					
						
							| 
									
										
										
										
											2018-11-02 17:18:07 +00:00
										 |  |  |       "poured_from_bottle"      => false, | 
					
						
							| 
									
										
										
										
											2022-09-10 20:28:21 -04:00
										 |  |  |       "loaded_from_api"         => false, | 
					
						
							| 
									
										
										
										
											2018-11-02 17:18:07 +00:00
										 |  |  |       "time"                    => Time.now.to_i, | 
					
						
							|  |  |  |       "source_modified_time"    => formula.source_modified_time.to_i, | 
					
						
							|  |  |  |       "compiler"                => compiler, | 
					
						
							|  |  |  |       "stdlib"                  => stdlib, | 
					
						
							|  |  |  |       "aliases"                 => formula.aliases, | 
					
						
							| 
									
										
										
										
											2021-04-29 17:51:13 +01:00
										 |  |  |       "runtime_dependencies"    => Tab.runtime_deps_hash(formula, runtime_deps), | 
					
						
							| 
									
										
										
										
											2020-04-06 13:04:48 +01:00
										 |  |  |       "arch"                    => Hardware::CPU.arch, | 
					
						
							| 
									
										
										
										
											2018-11-02 17:18:07 +00:00
										 |  |  |       "source"                  => { | 
					
						
							| 
									
										
										
										
											2021-03-30 17:35:13 +01:00
										 |  |  |         "path"         => formula.specified_path.to_s, | 
					
						
							|  |  |  |         "tap"          => formula.tap&.name, | 
					
						
							| 
									
										
										
										
											2021-09-12 02:09:11 -04:00
										 |  |  |         "tap_git_head" => nil, # Filled in later if possible | 
					
						
							| 
									
										
										
										
											2021-03-30 17:35:13 +01:00
										 |  |  |         "spec"         => formula.active_spec_sym.to_s, | 
					
						
							|  |  |  |         "versions"     => { | 
					
						
							| 
									
										
										
										
											2023-05-11 02:25:04 +01:00
										 |  |  |           "stable"         => formula.stable&.version&.to_s, | 
					
						
							|  |  |  |           "head"           => formula.head&.version&.to_s, | 
					
						
							| 
									
										
										
										
											2016-08-11 10:00:39 +02:00
										 |  |  |           "version_scheme" => formula.version_scheme, | 
					
						
							| 
									
										
										
										
											2016-09-17 15:17:27 +01:00
										 |  |  |         }, | 
					
						
							|  |  |  |       }, | 
					
						
							| 
									
										
										
										
											2020-04-06 13:04:48 +01:00
										 |  |  |       "built_on"                => DevelopmentTools.build_system_info, | 
					
						
							| 
									
										
										
										
											2015-02-18 20:05:50 -05:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-12 02:09:11 -04:00
										 |  |  |     # We can only get `tap_git_head` if the tap is installed locally | 
					
						
							|  |  |  |     attributes["source"]["tap_git_head"] = formula.tap.git_head if formula.tap&.installed? | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-18 20:05:50 -05:00
										 |  |  |     new(attributes) | 
					
						
							| 
									
										
										
										
											2011-09-22 20:07:39 -07:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-05 17:17:03 -05:00
										 |  |  |   # Returns the {Tab} for an install receipt at `path`. | 
					
						
							| 
									
										
										
										
											2024-04-26 20:55:51 +02:00
										 |  |  |   # | 
					
						
							|  |  |  |   # NOTE: Results are cached. | 
					
						
							| 
									
										
										
										
											2015-08-03 13:09:07 +01:00
										 |  |  |   def self.from_file(path) | 
					
						
							| 
									
										
										
										
											2021-01-14 16:26:17 +00:00
										 |  |  |     cache.fetch(path) do |p| | 
					
						
							|  |  |  |       content = File.read(p) | 
					
						
							|  |  |  |       return empty if content.blank? | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       cache[p] = from_file_content(content, p) | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2015-05-23 18:08:07 +08:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-05 17:17:03 -05:00
										 |  |  |   # Like {from_file}, but bypass the cache. | 
					
						
							| 
									
										
										
										
											2015-08-03 13:09:07 +01:00
										 |  |  |   def self.from_file_content(content, path) | 
					
						
							| 
									
										
										
										
											2018-07-10 09:29:26 +01:00
										 |  |  |     attributes = begin | 
					
						
							|  |  |  |       JSON.parse(content) | 
					
						
							|  |  |  |     rescue JSON::ParserError => e | 
					
						
							|  |  |  |       raise e, "Cannot parse #{path}: #{e}", e.backtrace | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2015-02-21 18:32:52 -05:00
										 |  |  |     attributes["tabfile"] = path | 
					
						
							| 
									
										
										
										
											2016-01-14 18:55:47 +08:00
										 |  |  |     attributes["source_modified_time"] ||= 0
 | 
					
						
							| 
									
										
										
										
											2015-03-13 00:41:10 -04:00
										 |  |  |     attributes["source"] ||= {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     tapped_from = attributes["tapped_from"] | 
					
						
							| 
									
										
										
										
											2018-03-21 12:42:48 +00:00
										 |  |  |     if !tapped_from.nil? && tapped_from != "path or URL" | 
					
						
							| 
									
										
										
										
											2015-03-13 00:41:10 -04:00
										 |  |  |       attributes["source"]["tap"] = attributes.delete("tapped_from") | 
					
						
							| 
									
										
										
										
											2015-08-02 16:34:45 +08:00
										 |  |  |     end | 
					
						
							| 
									
										
										
										
											2015-08-02 16:12:14 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-06 14:50:33 +08:00
										 |  |  |     if attributes["source"]["tap"] == "mxcl/master" || | 
					
						
							| 
									
										
										
										
											2016-09-17 15:17:27 +01:00
										 |  |  |        attributes["source"]["tap"] == "Homebrew/homebrew" | 
					
						
							| 
									
										
										
										
											2016-03-06 14:50:33 +08:00
										 |  |  |       attributes["source"]["tap"] = "homebrew/core" | 
					
						
							| 
									
										
										
										
											2015-03-13 00:41:10 -04:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-28 15:33:07 +08:00
										 |  |  |     if attributes["source"]["spec"].nil? | 
					
						
							| 
									
										
										
										
											2024-01-11 20:03:06 -08:00
										 |  |  |       version = PkgVersion.parse(File.basename(File.dirname(path))) | 
					
						
							| 
									
										
										
										
											2020-03-13 21:15:06 +00:00
										 |  |  |       attributes["source"]["spec"] = if version.head? | 
					
						
							|  |  |  |         "head" | 
					
						
							| 
									
										
										
										
											2015-07-28 15:33:07 +08:00
										 |  |  |       else | 
					
						
							| 
									
										
										
										
											2020-03-13 21:15:06 +00:00
										 |  |  |         "stable" | 
					
						
							| 
									
										
										
										
											2015-07-28 15:33:07 +08:00
										 |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-04 12:39:08 +03:00
										 |  |  |     if attributes["source"]["versions"].nil? | 
					
						
							|  |  |  |       attributes["source"]["versions"] = { | 
					
						
							| 
									
										
										
										
											2018-11-02 17:18:07 +00:00
										 |  |  |         "stable"         => nil, | 
					
						
							|  |  |  |         "head"           => nil, | 
					
						
							| 
									
										
										
										
											2016-08-11 10:00:39 +02:00
										 |  |  |         "version_scheme" => 0, | 
					
						
							| 
									
										
										
										
											2016-07-04 12:39:08 +03:00
										 |  |  |       } | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-11 02:25:04 +01:00
										 |  |  |     # Tabs created with Homebrew 1.5.13 through 4.0.17 inclusive created empty string versions in some cases. | 
					
						
							|  |  |  |     ["stable", "head"].each do |spec| | 
					
						
							|  |  |  |       attributes["source"]["versions"][spec] = attributes["source"]["versions"][spec].presence | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-29 23:15:13 -05:00
										 |  |  |     new(attributes) | 
					
						
							| 
									
										
										
										
											2011-09-23 08:36:40 -07:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-28 03:23:21 +02:00
										 |  |  |   # Get the {Tab} for the given {Keg}, | 
					
						
							|  |  |  |   # or a fake one if the formula is not installed. | 
					
						
							|  |  |  |   # | 
					
						
							| 
									
										
										
										
											2024-04-22 21:05:48 +02:00
										 |  |  |   # @api internal | 
					
						
							| 
									
										
										
										
											2024-04-28 03:23:21 +02:00
										 |  |  |   sig { params(keg: T.any(Keg, Pathname)).returns(T.attached_class) } | 
					
						
							| 
									
										
										
										
											2015-08-03 13:09:07 +01:00
										 |  |  |   def self.for_keg(keg) | 
					
						
							| 
									
										
										
										
											2017-06-01 16:06:51 +02:00
										 |  |  |     path = keg/FILENAME | 
					
						
							| 
									
										
										
										
											2012-01-01 15:22:36 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-02 17:02:56 +01:00
										 |  |  |     tab = if path.exist? | 
					
						
							| 
									
										
										
										
											2014-06-29 22:26:14 -05:00
										 |  |  |       from_file(path) | 
					
						
							| 
									
										
										
										
											2012-01-01 15:22:36 -06:00
										 |  |  |     else | 
					
						
							| 
									
										
										
										
											2015-02-21 12:15:39 -05:00
										 |  |  |       empty | 
					
						
							| 
									
										
										
										
											2012-01-01 15:22:36 -06:00
										 |  |  |     end | 
					
						
							| 
									
										
										
										
											2017-04-02 17:02:56 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-14 22:47:25 -07:00
										 |  |  |     tab.tabfile = path | 
					
						
							| 
									
										
										
										
											2017-04-02 17:02:56 +01:00
										 |  |  |     tab | 
					
						
							| 
									
										
										
										
											2012-01-01 15:22:36 -06:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-05 17:17:03 -05:00
										 |  |  |   # Returns a {Tab} for the named formula's installation, | 
					
						
							| 
									
										
										
										
											2016-09-07 23:17:19 +01:00
										 |  |  |   # or a fake one if the formula is not installed. | 
					
						
							| 
									
										
										
										
											2015-08-03 13:09:07 +01:00
										 |  |  |   def self.for_name(name) | 
					
						
							| 
									
										
										
										
											2014-06-22 15:00:15 -05:00
										 |  |  |     for_formula(Formulary.factory(name)) | 
					
						
							| 
									
										
										
										
											2013-06-26 10:37:09 -07:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-03 13:09:07 +01:00
										 |  |  |   def self.remap_deprecated_options(deprecated_options, options) | 
					
						
							| 
									
										
										
										
											2014-10-16 13:01:48 +01:00
										 |  |  |     deprecated_options.each do |deprecated_option| | 
					
						
							| 
									
										
										
										
											2014-12-26 11:58:09 -05:00
										 |  |  |       option = options.find { |o| o.name == deprecated_option.old } | 
					
						
							| 
									
										
										
										
											2014-10-16 13:01:48 +01:00
										 |  |  |       next unless option | 
					
						
							| 
									
										
										
										
											2018-09-17 02:45:00 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-16 13:01:48 +01:00
										 |  |  |       options -= [option] | 
					
						
							|  |  |  |       options << Option.new(deprecated_option.current, option.description) | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |     options | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-05 17:17:03 -05:00
										 |  |  |   # Returns a {Tab} for an already installed formula, | 
					
						
							| 
									
										
										
										
											2016-09-07 23:04:49 +01:00
										 |  |  |   # or a fake one if the formula is not installed. | 
					
						
							| 
									
										
										
										
											2023-03-10 23:46:07 +00:00
										 |  |  |   def self.for_formula(formula) | 
					
						
							| 
									
										
										
										
											2014-06-29 19:19:24 -05:00
										 |  |  |     paths = [] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-10 23:46:07 +00:00
										 |  |  |     paths << formula.opt_prefix.resolved_path if formula.opt_prefix.symlink? && formula.opt_prefix.directory? | 
					
						
							| 
									
										
										
										
											2014-06-29 19:19:24 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-10 23:46:07 +00:00
										 |  |  |     paths << formula.linked_keg.resolved_path if formula.linked_keg.symlink? && formula.linked_keg.directory? | 
					
						
							| 
									
										
										
										
											2014-03-22 11:34:26 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-10 23:46:07 +00:00
										 |  |  |     if (dirs = formula.installed_prefixes).length == 1
 | 
					
						
							| 
									
										
										
										
											2014-03-22 11:34:26 -05:00
										 |  |  |       paths << dirs.first | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-10 23:46:07 +00:00
										 |  |  |     paths << formula.latest_installed_prefix | 
					
						
							| 
									
										
										
										
											2014-03-22 11:34:26 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-10 23:46:07 +00:00
										 |  |  |     path = paths.map { |pathname| pathname/FILENAME }.find(&:file?) | 
					
						
							| 
									
										
										
										
											2014-03-22 11:34:26 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if path | 
					
						
							| 
									
										
										
										
											2014-10-16 13:01:48 +01:00
										 |  |  |       tab = from_file(path) | 
					
						
							| 
									
										
										
										
											2023-03-10 23:46:07 +00:00
										 |  |  |       used_options = remap_deprecated_options(formula.deprecated_options, tab.used_options) | 
					
						
							| 
									
										
										
										
											2014-10-16 13:01:48 +01:00
										 |  |  |       tab.used_options = used_options.as_flags | 
					
						
							| 
									
										
										
										
											2014-03-22 11:34:26 -05:00
										 |  |  |     else | 
					
						
							| 
									
										
										
										
											2016-09-07 23:04:49 +01:00
										 |  |  |       # Formula is not installed. Return a fake tab. | 
					
						
							| 
									
										
										
										
											2015-02-21 12:15:39 -05:00
										 |  |  |       tab = empty | 
					
						
							| 
									
										
										
										
											2023-03-10 23:46:07 +00:00
										 |  |  |       tab.unused_options = formula.options.as_flags | 
					
						
							| 
									
										
										
										
											2015-12-06 22:33:41 +08:00
										 |  |  |       tab.source = { | 
					
						
							| 
									
										
										
										
											2023-03-10 23:46:07 +00:00
										 |  |  |         "path"     => formula.specified_path.to_s, | 
					
						
							|  |  |  |         "tap"      => formula.tap&.name, | 
					
						
							|  |  |  |         "spec"     => formula.active_spec_sym.to_s, | 
					
						
							| 
									
										
										
										
											2016-08-13 15:26:21 +02:00
										 |  |  |         "versions" => { | 
					
						
							| 
									
										
										
										
											2023-05-11 02:25:04 +01:00
										 |  |  |           "stable"         => formula.stable&.version&.to_s, | 
					
						
							|  |  |  |           "head"           => formula.head&.version&.to_s, | 
					
						
							| 
									
										
										
										
											2023-03-10 23:46:07 +00:00
										 |  |  |           "version_scheme" => formula.version_scheme, | 
					
						
							| 
									
										
										
										
											2016-09-17 15:17:27 +01:00
										 |  |  |         }, | 
					
						
							| 
									
										
										
										
											2015-12-06 22:33:41 +08:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2014-03-22 11:34:26 -05:00
										 |  |  |     end | 
					
						
							| 
									
										
										
										
											2015-02-21 12:15:39 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     tab | 
					
						
							| 
									
										
										
										
											2011-09-23 08:36:40 -07:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-21 12:15:39 -05:00
										 |  |  |   def self.empty | 
					
						
							| 
									
										
										
										
											2015-02-18 20:05:50 -05:00
										 |  |  |     attributes = { | 
					
						
							| 
									
										
										
										
											2018-11-02 17:18:07 +00:00
										 |  |  |       "homebrew_version"        => HOMEBREW_VERSION, | 
					
						
							|  |  |  |       "used_options"            => [], | 
					
						
							|  |  |  |       "unused_options"          => [], | 
					
						
							|  |  |  |       "built_as_bottle"         => false, | 
					
						
							| 
									
										
										
										
											2017-01-09 21:05:27 +00:00
										 |  |  |       "installed_as_dependency" => false, | 
					
						
							| 
									
										
										
										
											2021-02-23 10:19:45 +00:00
										 |  |  |       "installed_on_request"    => false, | 
					
						
							| 
									
										
										
										
											2018-11-02 17:18:07 +00:00
										 |  |  |       "poured_from_bottle"      => false, | 
					
						
							| 
									
										
										
										
											2022-09-10 20:28:21 -04:00
										 |  |  |       "loaded_from_api"         => false, | 
					
						
							| 
									
										
										
										
											2018-11-02 17:18:07 +00:00
										 |  |  |       "time"                    => nil, | 
					
						
							|  |  |  |       "source_modified_time"    => 0, | 
					
						
							|  |  |  |       "stdlib"                  => nil, | 
					
						
							|  |  |  |       "compiler"                => DevelopmentTools.default_compiler, | 
					
						
							|  |  |  |       "aliases"                 => [], | 
					
						
							|  |  |  |       "runtime_dependencies"    => nil, | 
					
						
							| 
									
										
										
										
											2020-11-12 17:06:47 +00:00
										 |  |  |       "arch"                    => nil, | 
					
						
							| 
									
										
										
										
											2018-11-02 17:18:07 +00:00
										 |  |  |       "source"                  => { | 
					
						
							| 
									
										
										
										
											2021-03-30 17:35:13 +01:00
										 |  |  |         "path"         => nil, | 
					
						
							|  |  |  |         "tap"          => nil, | 
					
						
							|  |  |  |         "tap_git_head" => nil, | 
					
						
							|  |  |  |         "spec"         => "stable", | 
					
						
							|  |  |  |         "versions"     => { | 
					
						
							| 
									
										
										
										
											2018-11-02 17:18:07 +00:00
										 |  |  |           "stable"         => nil, | 
					
						
							|  |  |  |           "head"           => nil, | 
					
						
							| 
									
										
										
										
											2016-08-11 10:00:39 +02:00
										 |  |  |           "version_scheme" => 0, | 
					
						
							| 
									
										
										
										
											2016-09-17 15:17:27 +01:00
										 |  |  |         }, | 
					
						
							|  |  |  |       }, | 
					
						
							| 
									
										
										
										
											2020-04-06 13:04:48 +01:00
										 |  |  |       "built_on"                => DevelopmentTools.generic_build_system_info, | 
					
						
							| 
									
										
										
										
											2015-02-18 20:05:50 -05:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     new(attributes) | 
					
						
							| 
									
										
										
										
											2012-01-01 15:22:36 -06:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-29 17:51:13 +01:00
										 |  |  |   def self.runtime_deps_hash(formula, deps) | 
					
						
							| 
									
										
										
										
											2018-06-01 19:53:26 +01:00
										 |  |  |     deps.map do |dep| | 
					
						
							|  |  |  |       f = dep.to_formula | 
					
						
							| 
									
										
										
										
											2021-04-29 17:51:13 +01:00
										 |  |  |       { | 
					
						
							|  |  |  |         "full_name"         => f.full_name, | 
					
						
							|  |  |  |         "version"           => f.version.to_s, | 
					
						
							| 
									
										
										
										
											2023-11-10 17:17:24 +00:00
										 |  |  |         "revision"          => f.revision, | 
					
						
							|  |  |  |         "pkg_version"       => f.pkg_version.to_s, | 
					
						
							| 
									
										
										
										
											2021-04-29 17:51:13 +01:00
										 |  |  |         "declared_directly" => formula.deps.include?(dep), | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2018-06-01 19:53:26 +01:00
										 |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-14 22:47:25 -07:00
										 |  |  |   def initialize(attributes = {}) | 
					
						
							| 
									
										
										
										
											2023-12-18 09:34:01 -08:00
										 |  |  |     attributes.each { |key, value| instance_variable_set(:"@#{key}", value) } | 
					
						
							| 
									
										
										
										
											2023-03-14 22:47:25 -07:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-23 19:58:39 +01:00
										 |  |  |   def any_args_or_options? | 
					
						
							|  |  |  |     !used_options.empty? || !unused_options.empty? | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-03 13:09:07 +01:00
										 |  |  |   def with?(val) | 
					
						
							| 
									
										
										
										
											2015-12-14 19:47:19 +00:00
										 |  |  |     option_names = val.respond_to?(:option_names) ? val.option_names : [val] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     option_names.any? do |name| | 
					
						
							|  |  |  |       include?("with-#{name}") || unused_options.include?("without-#{name}") | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2013-01-23 00:26:24 -06:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-14 19:47:19 +00:00
										 |  |  |   def without?(val) | 
					
						
							|  |  |  |     !with?(val) | 
					
						
							| 
									
										
										
										
											2014-07-30 21:04:17 -05:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-03 13:09:07 +01:00
										 |  |  |   def include?(opt) | 
					
						
							| 
									
										
										
										
											2011-09-23 08:36:40 -07:00
										 |  |  |     used_options.include? opt | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-15 15:12:05 +08:00
										 |  |  |   def head? | 
					
						
							|  |  |  |     spec == :head | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def stable? | 
					
						
							|  |  |  |     spec == :stable | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-26 20:55:51 +02:00
										 |  |  |   # The options used to install the formula. | 
					
						
							|  |  |  |   # | 
					
						
							| 
									
										
										
										
											2024-04-22 21:05:48 +02:00
										 |  |  |   # @api internal | 
					
						
							| 
									
										
										
										
											2024-04-26 20:55:51 +02:00
										 |  |  |   sig { returns(Options) } | 
					
						
							| 
									
										
										
										
											2013-01-23 00:26:23 -06:00
										 |  |  |   def used_options | 
					
						
							| 
									
										
										
										
											2023-03-14 22:47:25 -07:00
										 |  |  |     Options.create(@used_options) | 
					
						
							| 
									
										
										
										
											2013-01-23 00:26:23 -06:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def unused_options | 
					
						
							| 
									
										
										
										
											2023-03-14 22:47:25 -07:00
										 |  |  |     Options.create(@unused_options) | 
					
						
							| 
									
										
										
										
											2013-01-23 00:26:23 -06:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-27 20:04:45 -04:00
										 |  |  |   def compiler | 
					
						
							| 
									
										
										
										
											2023-03-14 22:47:25 -07:00
										 |  |  |     @compiler || DevelopmentTools.default_compiler | 
					
						
							| 
									
										
										
										
											2015-06-27 20:04:45 -04:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-30 16:16:28 +00:00
										 |  |  |   def parsed_homebrew_version | 
					
						
							|  |  |  |     return Version::NULL if homebrew_version.nil? | 
					
						
							| 
									
										
										
										
											2018-09-17 02:45:00 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-30 18:15:35 +00:00
										 |  |  |     Version.new(homebrew_version) | 
					
						
							| 
									
										
										
										
											2016-12-30 16:16:28 +00:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-30 20:34:14 +00:00
										 |  |  |   def runtime_dependencies | 
					
						
							| 
									
										
										
										
											2016-12-30 16:16:28 +00:00
										 |  |  |     # Homebrew versions prior to 1.1.6 generated incorrect runtime dependency | 
					
						
							|  |  |  |     # lists. | 
					
						
							| 
									
										
										
										
											2023-04-18 15:06:50 -07:00
										 |  |  |     @runtime_dependencies if parsed_homebrew_version >= "1.1.6" | 
					
						
							| 
									
										
										
										
											2016-12-30 16:16:28 +00:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-27 00:11:45 -07:00
										 |  |  |   def cxxstdlib | 
					
						
							|  |  |  |     # Older tabs won't have these values, so provide sensible defaults | 
					
						
							| 
									
										
										
										
											2013-10-07 00:25:26 -07:00
										 |  |  |     lib = stdlib.to_sym if stdlib | 
					
						
							| 
									
										
										
										
											2015-06-27 20:04:45 -04:00
										 |  |  |     CxxStdlib.create(lib, compiler.to_sym) | 
					
						
							| 
									
										
										
										
											2013-07-27 00:11:45 -07:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-25 14:01:50 -07:00
										 |  |  |   def built_bottle? | 
					
						
							| 
									
										
										
										
											2014-10-15 00:52:57 -05:00
										 |  |  |     built_as_bottle && !poured_from_bottle | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-11 20:23:22 -07:00
										 |  |  |   def bottle? | 
					
						
							|  |  |  |     built_as_bottle | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-26 20:55:51 +02:00
										 |  |  |   sig { returns(T.nilable(Tap)) } | 
					
						
							| 
									
										
										
										
											2015-03-13 00:41:10 -04:00
										 |  |  |   def tap | 
					
						
							| 
									
										
										
										
											2015-12-06 22:33:41 +08:00
										 |  |  |     tap_name = source["tap"] | 
					
						
							|  |  |  |     Tap.fetch(tap_name) if tap_name | 
					
						
							| 
									
										
										
										
											2015-03-13 00:41:10 -04:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-27 09:57:41 +01:00
										 |  |  |   def tap=(tap) | 
					
						
							| 
									
										
										
										
											2015-12-06 22:33:41 +08:00
										 |  |  |     tap_name = tap.respond_to?(:name) ? tap.name : tap | 
					
						
							|  |  |  |     source["tap"] = tap_name | 
					
						
							| 
									
										
										
										
											2015-05-27 09:57:41 +01:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-28 15:33:07 +08:00
										 |  |  |   def spec | 
					
						
							|  |  |  |     source["spec"].to_sym | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-04 12:39:08 +03:00
										 |  |  |   def versions | 
					
						
							|  |  |  |     source["versions"] | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def stable_version | 
					
						
							| 
									
										
										
										
											2024-03-03 18:55:56 -08:00
										 |  |  |     versions["stable"]&.then { Version.new(_1) } | 
					
						
							| 
									
										
										
										
											2016-07-04 12:39:08 +03:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def head_version | 
					
						
							| 
									
										
										
										
											2024-03-03 18:55:56 -08:00
										 |  |  |     versions["head"]&.then { Version.new(_1) } | 
					
						
							| 
									
										
										
										
											2016-07-04 12:39:08 +03:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-11 10:00:39 +02:00
										 |  |  |   def version_scheme | 
					
						
							|  |  |  |     versions["version_scheme"] || 0
 | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-20 12:03:48 +02:00
										 |  |  |   sig { returns(Time) } | 
					
						
							| 
									
										
										
										
											2016-01-14 18:55:47 +08:00
										 |  |  |   def source_modified_time | 
					
						
							| 
									
										
										
										
											2023-03-14 22:47:25 -07:00
										 |  |  |     Time.at(@source_modified_time || 0) | 
					
						
							| 
									
										
										
										
											2016-01-14 18:55:47 +08:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-18 15:04:37 +00:00
										 |  |  |   def to_json(options = nil) | 
					
						
							| 
									
										
										
										
											2015-02-18 20:05:50 -05:00
										 |  |  |     attributes = { | 
					
						
							| 
									
										
										
										
											2018-11-02 17:18:07 +00:00
										 |  |  |       "homebrew_version"        => homebrew_version, | 
					
						
							|  |  |  |       "used_options"            => used_options.as_flags, | 
					
						
							|  |  |  |       "unused_options"          => unused_options.as_flags, | 
					
						
							|  |  |  |       "built_as_bottle"         => built_as_bottle, | 
					
						
							|  |  |  |       "poured_from_bottle"      => poured_from_bottle, | 
					
						
							| 
									
										
										
										
											2022-09-10 20:28:21 -04:00
										 |  |  |       "loaded_from_api"         => loaded_from_api, | 
					
						
							| 
									
										
										
										
											2017-01-09 21:05:27 +00:00
										 |  |  |       "installed_as_dependency" => installed_as_dependency, | 
					
						
							| 
									
										
										
										
											2018-11-02 17:18:07 +00:00
										 |  |  |       "installed_on_request"    => installed_on_request, | 
					
						
							|  |  |  |       "changed_files"           => changed_files&.map(&:to_s), | 
					
						
							|  |  |  |       "time"                    => time, | 
					
						
							|  |  |  |       "source_modified_time"    => source_modified_time.to_i, | 
					
						
							| 
									
										
										
										
											2019-11-28 15:10:50 +00:00
										 |  |  |       "stdlib"                  => stdlib&.to_s, | 
					
						
							|  |  |  |       "compiler"                => compiler&.to_s, | 
					
						
							| 
									
										
										
										
											2018-11-02 17:18:07 +00:00
										 |  |  |       "aliases"                 => aliases, | 
					
						
							|  |  |  |       "runtime_dependencies"    => runtime_dependencies, | 
					
						
							|  |  |  |       "source"                  => source, | 
					
						
							| 
									
										
										
										
											2021-03-30 17:35:13 +01:00
										 |  |  |       "arch"                    => arch, | 
					
						
							| 
									
										
										
										
											2020-04-06 13:04:48 +01:00
										 |  |  |       "built_on"                => built_on, | 
					
						
							| 
									
										
										
										
											2015-02-18 20:05:50 -05:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-03-30 17:35:13 +01:00
										 |  |  |     attributes.delete("stdlib") if attributes["stdlib"].blank? | 
					
						
							| 
									
										
										
										
											2015-02-18 20:05:50 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-30 17:35:13 +01:00
										 |  |  |     JSON.pretty_generate(attributes, options) | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-08 14:46:15 -04:00
										 |  |  |   # A subset of to_json that we care about for bottles. | 
					
						
							| 
									
										
										
										
											2021-03-30 17:35:13 +01:00
										 |  |  |   def to_bottle_hash | 
					
						
							|  |  |  |     attributes = { | 
					
						
							|  |  |  |       "homebrew_version"     => homebrew_version, | 
					
						
							|  |  |  |       "changed_files"        => changed_files&.map(&:to_s), | 
					
						
							|  |  |  |       "source_modified_time" => source_modified_time.to_i, | 
					
						
							|  |  |  |       "stdlib"               => stdlib&.to_s, | 
					
						
							|  |  |  |       "compiler"             => compiler&.to_s, | 
					
						
							|  |  |  |       "runtime_dependencies" => runtime_dependencies, | 
					
						
							|  |  |  |       "arch"                 => arch, | 
					
						
							|  |  |  |       "built_on"             => built_on, | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     attributes.delete("stdlib") if attributes["stdlib"].blank? | 
					
						
							|  |  |  |     attributes | 
					
						
							| 
									
										
										
										
											2011-09-22 20:07:39 -07:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def write | 
					
						
							| 
									
										
										
										
											2016-11-15 17:44:02 +00:00
										 |  |  |     # If this is a new installation, the cache of installed formulae | 
					
						
							|  |  |  |     # will no longer be valid. | 
					
						
							| 
									
										
										
										
											2020-10-29 08:31:04 +00:00
										 |  |  |     Formula.clear_cache unless tabfile.exist? | 
					
						
							| 
									
										
										
										
											2016-11-15 17:44:02 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-07 00:31:28 +02:00
										 |  |  |     self.class.cache[tabfile] = self | 
					
						
							| 
									
										
										
										
											2014-03-22 11:13:33 -05:00
										 |  |  |     tabfile.atomic_write(to_json) | 
					
						
							| 
									
										
										
										
											2011-09-22 20:07:39 -07:00
										 |  |  |   end | 
					
						
							| 
									
										
										
										
											2013-03-27 23:07:25 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-20 12:03:48 +02:00
										 |  |  |   sig { returns(String) } | 
					
						
							| 
									
										
										
										
											2013-03-27 23:07:25 -05:00
										 |  |  |   def to_s | 
					
						
							|  |  |  |     s = [] | 
					
						
							| 
									
										
										
										
											2020-03-13 21:15:06 +00:00
										 |  |  |     s << if poured_from_bottle | 
					
						
							|  |  |  |       "Poured from bottle" | 
					
						
							| 
									
										
										
										
											2016-05-03 16:52:00 -07:00
										 |  |  |     else | 
					
						
							| 
									
										
										
										
											2020-03-13 21:15:06 +00:00
										 |  |  |       "Built from source" | 
					
						
							| 
									
										
										
										
											2016-05-03 16:52:00 -07:00
										 |  |  |     end | 
					
						
							| 
									
										
										
										
											2016-09-23 11:01:40 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-10 20:28:21 -04:00
										 |  |  |     s << "using the formulae.brew.sh API" if loaded_from_api | 
					
						
							| 
									
										
										
										
											2016-09-23 11:01:40 +02:00
										 |  |  |     s << Time.at(time).strftime("on %Y-%m-%d at %H:%M:%S") if time | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-03-27 23:07:25 -05:00
										 |  |  |     unless used_options.empty? | 
					
						
							|  |  |  |       s << "with:" | 
					
						
							| 
									
										
										
										
											2015-06-26 10:08:41 +01:00
										 |  |  |       s << used_options.to_a.join(" ") | 
					
						
							| 
									
										
										
										
											2013-03-27 23:07:25 -05:00
										 |  |  |     end | 
					
						
							|  |  |  |     s.join(" ") | 
					
						
							|  |  |  |   end | 
					
						
							| 
									
										
										
										
											2011-09-22 20:07:39 -07:00
										 |  |  | end |