Download and use tabs from GitHub Packages

This commit is contained in:
Mike McQuaid 2021-03-31 20:55:35 +01:00
parent 8144fdef78
commit d9032ff01a
No known key found for this signature in database
GPG Key ID: 48A898132FD8EE70
4 changed files with 78 additions and 4 deletions

View File

@ -88,6 +88,7 @@ module Homebrew
fetched_bottle = false
if fetch_bottle?(f, args: args)
begin
f.fetch_bottle_tab
fetch_formula(f.bottle, args: args)
rescue Interrupt
raise

View File

@ -2211,6 +2211,20 @@ class Formula
patchlist.select(&:external?).each(&:fetch)
end
sig { void }
def fetch_bottle_tab
return unless bottled?
T.must(bottle).fetch_tab
end
sig { returns(Hash) }
def bottle_tab_attributes
return {} unless bottled?
T.must(bottle).tab_attributes
end
private
def prepare_patches

View File

@ -1100,7 +1100,9 @@ class FormulaInstaller
return if only_deps?
unless pour_bottle?(output_warning: true)
if pour_bottle?(output_warning: true)
formula.fetch_bottle_tab
else
formula.fetch_patches
formula.resources.each(&:fetch)
end
@ -1124,14 +1126,17 @@ class FormulaInstaller
end
keg = Keg.new(formula.prefix)
tab = Tab.for_keg(keg)
Tab.clear_cache
tab = if (tab_attributes = formula.bottle_tab_attributes.presence)
Tab.from_file_content(tab_attributes.to_json, keg/Tab::FILENAME)
else
Tab.for_keg(keg)
end
skip_linkage = formula.bottle_specification.skip_relocation?
keg.replace_placeholders_with_locations tab.changed_files, skip_linkage: skip_linkage
tab = Tab.for_keg(keg)
unless ignore_deps?
CxxStdlib.check_compatibility(
formula, formula.recursive_dependencies,

View File

@ -348,8 +348,62 @@ class Bottle
resource.downloader.stage
end
def fetch_tab
# a checksum is used later identifying the correct tab but we do not have the checksum for the manifest/tab
github_packages_manifest_resource&.fetch(verify_download_integrity: false)
end
def tab_attributes
return {} unless github_packages_manifest_resource&.downloaded?
manifest_json = github_packages_manifest_resource.cached_download.read
json = begin
JSON.parse(manifest_json)
rescue JSON::ParserError
raise ArgumentError, "Couldn't parse manifest JSON."
end
manifests = json["manifests"]
raise ArgumentError, "Missing 'manifests' section." if manifests.blank?
manifests_annotations = manifests.map { |m| m["annotations"] }
raise ArgumentError, "Missing 'annotations' section." if manifests_annotations.blank?
bottle_checksum = @resource.checksum.hexdigest
manifest_annotations = manifests_annotations.find do |m|
m["sh.brew.bottle.checksum"] == bottle_checksum
end
raise ArgumentError, "Couldn't find manifest matching bottle checksum." if manifest_annotations.blank?
tab = manifest_annotations["sh.brew.tab"]
raise ArgumentError, "Couldn't find tab from manifest." if tab.blank?
begin
JSON.parse(tab)
rescue JSON::ParserError
raise ArgumentError, "Couldn't parse tab JSON."
end
end
private
def github_packages_manifest_resource
return if @resource.download_strategy != CurlGitHubPackagesDownloadStrategy
@github_packages_manifest_resource ||= begin
resource = Resource.new("#{name}_bottle_manifest")
version_rebuild = GitHubPackages.version_rebuild(@resource.version, rebuild)
resource.version(version_rebuild)
resource.url("#{@spec.root_url}/#{name}/manifests/#{version_rebuild}",
using: CurlGitHubPackagesDownloadStrategy)
resource.downloader.resolved_basename = "#{name}-#{version_rebuild}.bottle_manifest.json"
resource
end
end
def select_download_strategy(specs)
specs[:using] ||= DownloadStrategyDetector.detect(@spec.root_url)
specs