mirror of
https://github.com/Homebrew/brew.git
synced 2025-07-14 16:09:03 +08:00
Load formulae from the internal API with HOMEBREW_USE_INTERNAL_API
This commit is contained in:
parent
0b67caf718
commit
8ec57eab2b
@ -4,6 +4,7 @@
|
||||
require "api/analytics"
|
||||
require "api/cask"
|
||||
require "api/formula"
|
||||
require "api/internal"
|
||||
require "base64"
|
||||
|
||||
module Homebrew
|
||||
|
72
Library/Homebrew/api/internal.rb
Normal file
72
Library/Homebrew/api/internal.rb
Normal file
@ -0,0 +1,72 @@
|
||||
# typed: strict
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "extend/cachable"
|
||||
require "api/download"
|
||||
require "formula_stub"
|
||||
|
||||
module Homebrew
|
||||
module API
|
||||
# Helper functions for using the JSON internal API.
|
||||
module Internal
|
||||
extend Cachable
|
||||
|
||||
private_class_method :cache
|
||||
|
||||
sig { returns(String) }
|
||||
def self.endpoint
|
||||
"internal/formula.#{SimulateSystem.current_tag}.jws.json"
|
||||
end
|
||||
|
||||
sig { params(name: String).returns(T::Hash[String, T.untyped]) }
|
||||
def self.formula(name)
|
||||
tag = Utils::Bottles.tag
|
||||
formula_stub = Homebrew::FormulaStub.from_array formula_stub(name)
|
||||
|
||||
bottle_specification = BottleSpecification.new
|
||||
bottle_specification.tap = Homebrew::DEFAULT_REPOSITORY
|
||||
bottle_specification.rebuild formula_stub.rebuild
|
||||
bottle_specification.sha256 tag.to_sym => formula_stub.sha256
|
||||
|
||||
bottle = Bottle.new(formula_stub, bottle_specification, tag)
|
||||
bottle_manifest_resource = T.must(bottle.github_packages_manifest_resource)
|
||||
|
||||
begin
|
||||
bottle_manifest_resource.fetch
|
||||
bottle_manifest_resource.formula_json
|
||||
rescue Resource::BottleManifest::Error
|
||||
opoo "Falling back to API fetch for #{name}"
|
||||
Homebrew::API.fetch "formula/#{name}.json"
|
||||
end
|
||||
end
|
||||
|
||||
sig { returns(Pathname) }
|
||||
def self.cached_json_file_path
|
||||
HOMEBREW_CACHE_API/endpoint
|
||||
end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def self.download_and_cache_data!
|
||||
json_formula_stubs, updated = Homebrew::API.fetch_json_api_file endpoint
|
||||
cache["formula_stubs"] = {}
|
||||
cache["all_formula_stubs"] = json_formula_stubs
|
||||
updated
|
||||
end
|
||||
private_class_method :download_and_cache_data!
|
||||
|
||||
sig { params(name: String).returns([String, String, Integer, T.nilable(String)]) }
|
||||
def self.formula_stub(name)
|
||||
download_and_cache_data! unless cache.key?("all_formula_stubs")
|
||||
|
||||
return cache["formula_stubs"][name] if cache["formula_stubs"].key?(name)
|
||||
|
||||
cache["all_formula_stubs"].find do |stub|
|
||||
next false if stub["name"] != name
|
||||
|
||||
cache["formula_stubs"][name] = stub
|
||||
true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
@ -7,7 +7,11 @@ class Bottle
|
||||
class Filename
|
||||
attr_reader :name, :version, :tag, :rebuild
|
||||
|
||||
sig { params(formula: Formula, tag: Utils::Bottles::Tag, rebuild: Integer).returns(T.attached_class) }
|
||||
sig {
|
||||
params(formula: T.any(Formula, Homebrew::FormulaStub),
|
||||
tag: Utils::Bottles::Tag,
|
||||
rebuild: Integer).returns(T.attached_class)
|
||||
}
|
||||
def self.create(formula, tag, rebuild)
|
||||
new(formula.name, formula.pkg_version, tag, rebuild)
|
||||
end
|
||||
|
24
Library/Homebrew/formula_stub.rb
Normal file
24
Library/Homebrew/formula_stub.rb
Normal file
@ -0,0 +1,24 @@
|
||||
# typed: strict
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "pkg_version"
|
||||
|
||||
module Homebrew
|
||||
# A stub for a formula, with only the information needed to fetch the bottle manifest.
|
||||
class FormulaStub < T::Struct
|
||||
const :name, String
|
||||
const :pkg_version, PkgVersion
|
||||
const :rebuild, Integer
|
||||
const :sha256, T.nilable(String)
|
||||
|
||||
sig { params(array: [String, String, Integer, T.nilable(String)]).returns(FormulaStub) }
|
||||
def self.from_array(array)
|
||||
new(
|
||||
name: array[0],
|
||||
pkg_version: PkgVersion.parse(array[1]),
|
||||
rebuild: array[2],
|
||||
sha256: array[3],
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
@ -165,7 +165,11 @@ module Formulary
|
||||
mod.const_set(:BUILD_FLAGS, flags)
|
||||
|
||||
class_name = class_s(name)
|
||||
json_formula = Homebrew::API::Formula.all_formulae[name]
|
||||
json_formula = if ENV.fetch("HOMEBREW_USE_INTERNAL_API", false).present?
|
||||
Homebrew::API::Internal.formula(name)
|
||||
else
|
||||
Homebrew::API::Formula.all_formulae[name]
|
||||
end
|
||||
raise FormulaUnavailableError, name if json_formula.nil?
|
||||
|
||||
json_formula = Homebrew::API.merge_variations(json_formula)
|
||||
|
@ -312,6 +312,9 @@ class GitHubPackages
|
||||
SPDX.license_expression_to_string(:cannot_represent)
|
||||
end
|
||||
|
||||
formula_path = HOMEBREW_REPOSITORY/bottle_hash["formula"]["path"]
|
||||
formula = Formulary.factory(formula_path)
|
||||
|
||||
formula_annotations_hash = {
|
||||
"com.github.package.type" => GITHUB_PACKAGE_TYPE,
|
||||
"org.opencontainers.image.created" => created_date,
|
||||
@ -325,6 +328,7 @@ class GitHubPackages
|
||||
"org.opencontainers.image.url" => bottle_hash["formula"]["homepage"],
|
||||
"org.opencontainers.image.vendor" => org,
|
||||
"org.opencontainers.image.version" => version,
|
||||
"sh.brew.formula.json" => formula.to_hash_with_variations,
|
||||
}.compact_blank
|
||||
manifests = []
|
||||
end
|
||||
|
@ -329,6 +329,17 @@ class Resource
|
||||
end
|
||||
end
|
||||
|
||||
def formula_json
|
||||
formula_json = manifest_annotations["sh.brew.formula.json"]
|
||||
raise Error, "Couldn't find formula JSON from manifest." if formula_json.blank?
|
||||
|
||||
begin
|
||||
JSON.parse(formula_json)
|
||||
rescue JSON::ParserError
|
||||
raise Error, "Couldn't parse formula JSON."
|
||||
end
|
||||
end
|
||||
|
||||
sig { returns(T.nilable(Integer)) }
|
||||
def bottle_size
|
||||
manifest_annotations["sh.brew.bottle.size"]&.to_i
|
||||
|
Loading…
x
Reference in New Issue
Block a user