From 1d32dc9067ca172a8e1aa77fc7e5a30cb978a48a Mon Sep 17 00:00:00 2001 From: Mike McQuaid Date: Thu, 11 Mar 2021 17:45:44 +0000 Subject: [PATCH] Support downloading bottles from GitHub Packages --- Library/Homebrew/download_strategy.rb | 23 +++++++++++++++++++++++ Library/Homebrew/software_spec.rb | 4 ++++ 2 files changed, 27 insertions(+) diff --git a/Library/Homebrew/download_strategy.rb b/Library/Homebrew/download_strategy.rb index 206962ac74..bf52bc08a2 100644 --- a/Library/Homebrew/download_strategy.rb +++ b/Library/Homebrew/download_strategy.rb @@ -13,6 +13,8 @@ require "mechanize/http/content_disposition_parser" require "utils/curl" +require "github_packages" + # @abstract Abstract superclass for all download strategies. # # @api private @@ -527,6 +529,25 @@ class CurlDownloadStrategy < AbstractFileDownloadStrategy end end +# Strategy for downloading a file from an GitHub Packages URL. +# +# @api public +class CurlGitHubPackagesDownloadStrategy < CurlDownloadStrategy + attr_accessor :checksum, :name + + private + + def _fetch(url:, resolved_url:) + raise "Empty checksum" if checksum.blank? + raise "Empty name" if name.blank? + + _, org, repo, = *url.match(GitHubPackages::URL_REGEX) + + blob_url = "https://ghcr.io/v2/#{org}/#{repo}/#{name}/blobs/sha256:#{checksum}" + curl_download(blob_url, "--header", "Authorization: Bearer", to: temporary_path) + end +end + # Strategy for downloading a file from an Apache Mirror URL. # # @api public @@ -1243,6 +1264,8 @@ class DownloadStrategyDetector def self.detect_from_url(url) case url + when GitHubPackages::URL_REGEX + CurlGitHubPackagesDownloadStrategy when %r{^https?://github\.com/[^/]+/[^/]+\.git$} GitHubGitDownloadStrategy when %r{^https?://.+\.git$}, diff --git a/Library/Homebrew/software_spec.rb b/Library/Homebrew/software_spec.rb index e53bf90728..62fcd9fefd 100644 --- a/Library/Homebrew/software_spec.rb +++ b/Library/Homebrew/software_spec.rb @@ -316,12 +316,16 @@ class Bottle def fetch(verify_download_integrity: true) # add the default bottle domain as a fallback mirror + # TODO: this may need adjusted when if we use GitHub Packages by default if @resource.download_strategy == CurlDownloadStrategy && @resource.url.start_with?(Homebrew::EnvConfig.bottle_domain) fallback_url = @resource.url .sub(/^#{Regexp.escape(Homebrew::EnvConfig.bottle_domain)}/, HOMEBREW_BOTTLE_DEFAULT_DOMAIN) @resource.mirror(fallback_url) if [@resource.url, *@resource.mirrors].exclude?(fallback_url) + elsif @resource.download_strategy == CurlGitHubPackagesDownloadStrategy + @resource.downloader.name = @name + @resource.downloader.checksum = @resource.checksum.hexdigest end @resource.fetch(verify_download_integrity: verify_download_integrity) end