Shard JSON API by OS/Arch combination

This commit is contained in:
Rylan Polster 2025-06-02 22:15:28 -04:00
parent a0c89e4a7f
commit 0f03757e8f
No known key found for this signature in database
4 changed files with 120 additions and 9 deletions

View File

@ -122,14 +122,15 @@ module Homebrew
end
end
sig { params(json: Hash).returns(Hash) }
def self.merge_variations(json)
sig { params(json: Hash, bottle_tag: T.nilable(::Utils::Bottles::Tag)).returns(Hash) }
def self.merge_variations(json, bottle_tag: nil)
return json unless json.key?("variations")
bottle_tag = ::Utils::Bottles::Tag.new(system: Homebrew::SimulateSystem.current_os,
arch: Homebrew::SimulateSystem.current_arch)
bottle_tag ||= ::Utils::Bottles::Tag.new(system: Homebrew::SimulateSystem.current_os,
arch: Homebrew::SimulateSystem.current_arch)
if (variation = json.dig("variations", bottle_tag.to_s).presence)
if (variation = json.dig("variations", bottle_tag.to_s).presence) ||
(variation = json.dig("variations", bottle_tag.to_sym).presence)
json = json.merge(variation)
end

View File

@ -33,7 +33,7 @@ module Homebrew
raise TapUnavailableError, tap.name unless tap.installed?
unless args.dry_run?
directories = ["_data/cask", "api/cask", "api/cask-source", "cask", "api/internal/v3"].freeze
directories = ["_data/cask", "api/cask", "api/cask-source", "cask", "api/internal"].freeze
FileUtils.rm_rf directories
FileUtils.mkdir_p directories
end
@ -44,12 +44,14 @@ module Homebrew
Cask::Cask.generating_hash!
all_casks = {}
latest_macos = MacOSVersion.new((HOMEBREW_MACOS_NEWEST_UNSUPPORTED.to_i - 1).to_s).to_sym
Homebrew::SimulateSystem.with(os: latest_macos, arch: :arm) do
tap.cask_files.each do |path|
cask = Cask::CaskLoader.load(path)
name = cask.token
json = JSON.pretty_generate(cask.to_hash_with_variations)
all_casks[name] = cask.to_hash_with_variations
json = JSON.pretty_generate(all_casks[name])
cask_source = path.read
html_template_name = html_template(name)
@ -67,6 +69,19 @@ module Homebrew
canonical_json = JSON.pretty_generate(tap.cask_renames)
File.write("_data/cask_canonical.json", "#{canonical_json}\n") unless args.dry_run?
OnSystem::ALL_OS_ARCH_COMBINATIONS.filter_map do |os, arch|
bottle_tag = Utils::Bottles::Tag.new(system: os, arch:)
next unless bottle_tag.valid_combination?
variation_casks = all_casks.transform_values do |cask|
Homebrew::API.merge_variations(cask, bottle_tag:)
end
unless args.dry_run?
File.write("api/internal/cask.#{bottle_tag}.json", JSON.pretty_generate(variation_casks))
end
end
end
end

View File

@ -32,7 +32,7 @@ module Homebrew
raise TapUnavailableError, tap.name unless tap.installed?
unless args.dry_run?
directories = ["_data/formula", "api/formula", "formula", "api/internal/v3"]
directories = ["_data/formula", "api/formula", "formula", "api/internal"]
FileUtils.rm_rf directories + ["_data/formula_canonical.json"]
FileUtils.mkdir_p directories
end
@ -44,12 +44,14 @@ module Homebrew
Formulary.enable_factory_cache!
Formula.generating_hash!
all_formulae = {}
latest_macos = MacOSVersion.new((HOMEBREW_MACOS_NEWEST_UNSUPPORTED.to_i - 1).to_s).to_sym
Homebrew::SimulateSystem.with(os: latest_macos, arch: :arm) do
tap.formula_names.each do |name|
formula = Formulary.factory(name)
name = formula.name
json = JSON.pretty_generate(formula.to_hash_with_variations)
all_formulae[name] = formula.to_hash_with_variations
json = JSON.pretty_generate(all_formulae[name])
html_template_name = html_template(name)
unless args.dry_run?
@ -65,6 +67,19 @@ module Homebrew
canonical_json = JSON.pretty_generate(tap.formula_renames.merge(tap.alias_table))
File.write("_data/formula_canonical.json", "#{canonical_json}\n") unless args.dry_run?
OnSystem::ALL_OS_ARCH_COMBINATIONS.filter_map do |os, arch|
bottle_tag = Utils::Bottles::Tag.new(system: os, arch:)
next unless bottle_tag.valid_combination?
variation_formulae = all_formulae.transform_values do |formula|
Homebrew::API.merge_variations(formula, bottle_tag:)
end
unless args.dry_run?
File.write("api/internal/formula.#{bottle_tag}.json", JSON.pretty_generate(variation_formulae))
end
end
end
end

View File

@ -90,4 +90,84 @@ RSpec.describe Homebrew::API do
end
end
end
describe "::merge_variations" do
let(:arm64_sequoia_tag) { Utils::Bottles::Tag.new(system: :sequoia, arch: :arm) }
let(:sonoma_tag) { Utils::Bottles::Tag.new(system: :sonoma, arch: :intel) }
let(:x86_64_linux_tag) { Utils::Bottles::Tag.new(system: :linux, arch: :intel) }
let(:json) do
{
"name" => "foo",
"foo" => "bar",
"baz" => ["test1", "test2"],
"variations" => {
"arm64_sequoia" => { "foo" => "new" },
:sonoma => { "baz" => ["new1", "new2", "new3"] },
},
}
end
let(:arm64_sequoia_result) do
{
"name" => "foo",
"foo" => "new",
"baz" => ["test1", "test2"],
}
end
let(:sonoma_result) do
{
"name" => "foo",
"foo" => "bar",
"baz" => ["new1", "new2", "new3"],
}
end
it "returns the original JSON if no variations are found" do
result = described_class.merge_variations(arm64_sequoia_result, bottle_tag: arm64_sequoia_tag)
expect(result).to eq arm64_sequoia_result
end
it "returns the original JSON if no variations are found for the current system" do
result = described_class.merge_variations(arm64_sequoia_result)
expect(result).to eq arm64_sequoia_result
end
it "returns the original JSON without the variations if no matching variation is found" do
result = described_class.merge_variations(json, bottle_tag: x86_64_linux_tag)
expect(result).to eq json.except("variations")
end
it "returns the original JSON without the variations if no matching variation is found for the current system" do
Homebrew::SimulateSystem.with(os: :linux, arch: :intel) do
result = described_class.merge_variations(json)
expect(result).to eq json.except("variations")
end
end
it "returns the JSON with the matching variation applied from a string key" do
result = described_class.merge_variations(json, bottle_tag: arm64_sequoia_tag)
expect(result).to eq arm64_sequoia_result
end
it "returns the JSON with the matching variation applied from a string key for the current system" do
Homebrew::SimulateSystem.with(os: :sequoia, arch: :arm) do
result = described_class.merge_variations(json)
expect(result).to eq arm64_sequoia_result
end
end
it "returns the JSON with the matching variation applied from a symbol key" do
result = described_class.merge_variations(json, bottle_tag: sonoma_tag)
expect(result).to eq sonoma_result
end
it "returns the JSON with the matching variation applied from a symbol key for the current system" do
Homebrew::SimulateSystem.with(os: :sonoma, arch: :intel) do
result = described_class.merge_variations(json)
expect(result).to eq sonoma_result
end
end
end
end