-
-
Notifications
You must be signed in to change notification settings - Fork 9.3k
/
bottle.rb
96 lines (77 loc) 路 2.92 KB
/
bottle.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# typed: false
# frozen_string_literal: true
require "github_packages"
module Homebrew
module API
# Helper functions for using the bottle JSON API.
#
# @api private
module Bottle
class << self
extend T::Sig
sig { returns(String) }
def bottle_api_path
"bottle"
end
alias generic_bottle_api_path bottle_api_path
GITHUB_PACKAGES_SHA256_REGEX = %r{#{GitHubPackages::URL_REGEX}.*/blobs/sha256:(?<sha256>\h{64})$}.freeze
sig { params(name: String).returns(Hash) }
def fetch(name)
name = name.sub(%r{^homebrew/core/}, "")
Homebrew::API.fetch "#{bottle_api_path}/#{name}.json"
end
sig { params(name: String).returns(T::Boolean) }
def available?(name)
fetch name
true
rescue ArgumentError
false
end
sig { params(name: String).void }
def fetch_bottles(name)
hash = fetch(name)
bottle_tag = Utils::Bottles.tag.to_s
if !hash["bottles"].key?(bottle_tag) && !hash["bottles"].key?("all")
odie "No bottle available for #{name} on the current OS"
end
download_bottle(hash, bottle_tag)
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
end
sig { params(url: String).returns(T.nilable(String)) }
def checksum_from_url(url)
match = url.match GITHUB_PACKAGES_SHA256_REGEX
return if match.blank?
match[:sha256]
end
sig { params(hash: Hash, tag: String).void }
def download_bottle(hash, tag)
bottle = hash["bottles"][tag]
bottle ||= hash["bottles"]["all"]
return if bottle.blank?
sha256 = bottle["sha256"] || checksum_from_url(bottle["url"])
bottle_filename = ::Bottle::Filename.new(hash["name"], hash["pkg_version"], tag, hash["rebuild"])
resource = Resource.new hash["name"]
resource.url bottle["url"]
resource.sha256 sha256
resource.version hash["pkg_version"]
resource.downloader.resolved_basename = bottle_filename
resource.fetch
# 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`.
[hash["name"], "homebrew/core/#{hash["name"]}"].each do |name|
Formulary.map_formula_name_to_local_bottle_path name, resource.downloader.cached_location
end
end
end
end
end
end