| 
									
										
										
										
											2021-08-06 02:30:44 -04:00
										 |  |  | # typed: false | 
					
						
							|  |  |  | # frozen_string_literal: true | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | require "github_packages" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | module Homebrew | 
					
						
							|  |  |  |   module API | 
					
						
							| 
									
										
										
										
											2021-08-06 04:35:45 -04:00
										 |  |  |     # Helper functions for using the bottle JSON API. | 
					
						
							| 
									
										
										
										
											2021-08-06 02:30:44 -04:00
										 |  |  |     # | 
					
						
							|  |  |  |     # @api private | 
					
						
							|  |  |  |     module Bottle | 
					
						
							| 
									
										
										
										
											2021-08-09 16:48:13 -04:00
										 |  |  |       class << self | 
					
						
							|  |  |  |         extend T::Sig | 
					
						
							| 
									
										
										
										
											2021-08-06 02:30:44 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-09 16:48:13 -04:00
										 |  |  |         sig { returns(String) } | 
					
						
							|  |  |  |         def bottle_api_path | 
					
						
							|  |  |  |           "bottle" | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  |         alias generic_bottle_api_path bottle_api_path | 
					
						
							| 
									
										
										
										
											2021-08-06 02:30:44 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-09 16:48:13 -04:00
										 |  |  |         GITHUB_PACKAGES_SHA256_REGEX = %r{#{GitHubPackages::URL_REGEX}.*/blobs/sha256:(?<sha256>\h{64})$}.freeze | 
					
						
							| 
									
										
										
										
											2021-08-06 02:30:44 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-09 16:48:13 -04:00
										 |  |  |         sig { params(name: String).returns(Hash) } | 
					
						
							|  |  |  |         def fetch(name) | 
					
						
							| 
									
										
										
										
											2021-10-28 01:25:27 -04:00
										 |  |  |           name = name.sub(%r{^homebrew/core/}, "") | 
					
						
							| 
									
										
										
										
											2021-08-09 16:48:13 -04:00
										 |  |  |           Homebrew::API.fetch "#{bottle_api_path}/#{name}.json" | 
					
						
							|  |  |  |         end | 
					
						
							| 
									
										
										
										
											2021-08-06 02:30:44 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-09 16:48:13 -04:00
										 |  |  |         sig { params(name: String).returns(T::Boolean) } | 
					
						
							|  |  |  |         def available?(name) | 
					
						
							|  |  |  |           fetch name | 
					
						
							|  |  |  |           true | 
					
						
							|  |  |  |         rescue ArgumentError | 
					
						
							|  |  |  |           false | 
					
						
							| 
									
										
										
										
											2021-08-06 02:30:44 -04:00
										 |  |  |         end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-09 16:48:13 -04:00
										 |  |  |         sig { params(name: String).void } | 
					
						
							|  |  |  |         def fetch_bottles(name) | 
					
						
							|  |  |  |           hash = fetch(name) | 
					
						
							|  |  |  |           bottle_tag = Utils::Bottles.tag.to_s | 
					
						
							| 
									
										
										
										
											2021-08-06 02:30:44 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-09 16:48:13 -04:00
										 |  |  |           if !hash["bottles"].key?(bottle_tag) && !hash["bottles"].key?("all") | 
					
						
							|  |  |  |             odie "No bottle available for #{name} on the current OS" | 
					
						
							| 
									
										
										
										
											2021-08-06 02:30:44 -04:00
										 |  |  |           end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-09 16:48:13 -04:00
										 |  |  |           download_bottle(hash, bottle_tag) | 
					
						
							| 
									
										
										
										
											2021-08-06 02:30:44 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-09 16:48:13 -04:00
										 |  |  |           hash["dependencies"].each do |dep_hash| | 
					
						
							|  |  |  |             existing_formula = begin | 
					
						
							|  |  |  |               Formulary.factory dep_hash["name"] | 
					
						
							|  |  |  |             rescue FormulaUnavailableError | 
					
						
							|  |  |  |               # The formula might not exist if it's not installed and homebrew/core isn't tapped | 
					
						
							|  |  |  |               nil | 
					
						
							|  |  |  |             end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             next if existing_formula.present? && existing_formula.latest_version_installed? | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             download_bottle(dep_hash, bottle_tag) | 
					
						
							|  |  |  |           end | 
					
						
							| 
									
										
										
										
											2021-08-06 02:30:44 -04:00
										 |  |  |         end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-09 16:48:13 -04:00
										 |  |  |         sig { params(url: String).returns(T.nilable(String)) } | 
					
						
							|  |  |  |         def checksum_from_url(url) | 
					
						
							|  |  |  |           match = url.match GITHUB_PACKAGES_SHA256_REGEX | 
					
						
							|  |  |  |           return if match.blank? | 
					
						
							| 
									
										
										
										
											2021-08-06 02:30:44 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-09 16:48:13 -04:00
										 |  |  |           match[:sha256] | 
					
						
							|  |  |  |         end | 
					
						
							| 
									
										
										
										
											2021-08-06 02:30:44 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-09 17:20:27 -04:00
										 |  |  |         sig { params(hash: Hash, tag: String).void } | 
					
						
							| 
									
										
										
										
											2021-08-09 16:48:13 -04:00
										 |  |  |         def download_bottle(hash, tag) | 
					
						
							|  |  |  |           bottle = hash["bottles"][tag] | 
					
						
							|  |  |  |           bottle ||= hash["bottles"]["all"] | 
					
						
							|  |  |  |           return if bottle.blank? | 
					
						
							| 
									
										
										
										
											2021-08-06 02:30:44 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-09 16:48:13 -04:00
										 |  |  |           sha256 = bottle["sha256"] || checksum_from_url(bottle["url"]) | 
					
						
							|  |  |  |           bottle_filename = ::Bottle::Filename.new(hash["name"], hash["pkg_version"], tag, hash["rebuild"]) | 
					
						
							| 
									
										
										
										
											2021-08-06 02:30:44 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-09 16:48:13 -04:00
										 |  |  |           resource = Resource.new hash["name"] | 
					
						
							|  |  |  |           resource.url bottle["url"] | 
					
						
							|  |  |  |           resource.sha256 sha256 | 
					
						
							|  |  |  |           resource.version hash["pkg_version"] | 
					
						
							|  |  |  |           resource.downloader.resolved_basename = bottle_filename | 
					
						
							| 
									
										
										
										
											2021-08-06 02:30:44 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-09 16:48:13 -04:00
										 |  |  |           resource.fetch | 
					
						
							| 
									
										
										
										
											2021-08-06 02:30:44 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-09 16:48:13 -04:00
										 |  |  |           # Map the name of this formula to the local bottle path to allow the | 
					
						
							|  |  |  |           # formula to be loaded by passing just the name to `Formulary::factory`. | 
					
						
							| 
									
										
										
										
											2021-10-28 01:25:27 -04:00
										 |  |  |           [hash["name"], "homebrew/core/#{hash["name"]}"].each do |name| | 
					
						
							|  |  |  |             Formulary.map_formula_name_to_local_bottle_path name, resource.downloader.cached_location | 
					
						
							|  |  |  |           end | 
					
						
							| 
									
										
										
										
											2021-08-09 16:48:13 -04:00
										 |  |  |         end | 
					
						
							| 
									
										
										
										
											2021-08-06 02:30:44 -04:00
										 |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | end |