Merge pull request #19251 from Homebrew/revert-json-v3-logic

Revert json v3 logic
This commit is contained in:
Mike McQuaid 2025-02-07 08:32:22 +00:00 committed by GitHub
commit 9e3ae9f3f9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
18 changed files with 64 additions and 873 deletions

View File

@ -184,11 +184,6 @@ module Homebrew
Tap.fetch(org, repo) Tap.fetch(org, repo)
end end
sig { returns(T::Boolean) }
def self.internal_json_v3?
ENV["HOMEBREW_INTERNAL_JSON_V3"].present?
end
end end
sig { params(block: T.proc.returns(T.untyped)).returns(T.untyped) } sig { params(block: T.proc.returns(T.untyped)).returns(T.untyped) }

View File

@ -11,7 +11,6 @@ module Homebrew
extend Cachable extend Cachable
DEFAULT_API_FILENAME = "formula.jws.json" DEFAULT_API_FILENAME = "formula.jws.json"
INTERNAL_V3_API_FILENAME = "internal/v3/homebrew-core.jws.json"
private_class_method :cache private_class_method :cache
@ -43,33 +42,24 @@ module Homebrew
sig { returns(Pathname) } sig { returns(Pathname) }
def self.cached_json_file_path def self.cached_json_file_path
if Homebrew::API.internal_json_v3? HOMEBREW_CACHE_API/DEFAULT_API_FILENAME
HOMEBREW_CACHE_API/INTERNAL_V3_API_FILENAME
else
HOMEBREW_CACHE_API/DEFAULT_API_FILENAME
end
end end
sig { returns(T::Boolean) } sig { returns(T::Boolean) }
def self.download_and_cache_data! def self.download_and_cache_data!
if Homebrew::API.internal_json_v3? json_formulae, updated = Homebrew::API.fetch_json_api_file DEFAULT_API_FILENAME
json_formulae, updated = Homebrew::API.fetch_json_api_file INTERNAL_V3_API_FILENAME
overwrite_cache! T.cast(json_formulae, T::Hash[String, T.untyped])
else
json_formulae, updated = Homebrew::API.fetch_json_api_file DEFAULT_API_FILENAME
cache["aliases"] = {} cache["aliases"] = {}
cache["renames"] = {} cache["renames"] = {}
cache["formulae"] = json_formulae.to_h do |json_formula| cache["formulae"] = json_formulae.to_h do |json_formula|
json_formula["aliases"].each do |alias_name| json_formula["aliases"].each do |alias_name|
cache["aliases"][alias_name] = json_formula["name"] cache["aliases"][alias_name] = json_formula["name"]
end
(json_formula["oldnames"] || [json_formula["oldname"]].compact).each do |oldname|
cache["renames"][oldname] = json_formula["name"]
end
[json_formula["name"], json_formula.except("name")]
end end
(json_formula["oldnames"] || [json_formula["oldname"]].compact).each do |oldname|
cache["renames"][oldname] = json_formula["name"]
end
[json_formula["name"], json_formula.except("name")]
end end
updated updated

View File

@ -400,63 +400,15 @@ module Cask
} }
end end
def to_internal_api_hash
api_hash = {
"token" => token,
"name" => name,
"desc" => desc,
"homepage" => homepage,
"url" => url,
"version" => version,
"sha256" => sha256,
"artifacts" => artifacts_list(compact: true),
"ruby_source_path" => ruby_source_path,
"ruby_source_sha256" => ruby_source_checksum.fetch(:sha256),
}
if deprecation_date
api_hash["deprecation_date"] = deprecation_date
api_hash["deprecation_reason"] = deprecation_reason
api_hash["deprecation_replacement"] = deprecation_replacement
end
if disable_date
api_hash["disable_date"] = disable_date
api_hash["disable_reason"] = disable_reason
api_hash["disable_replacement"] = disable_replacement
end
if (url_specs_hash = url_specs).present?
api_hash["url_specs"] = url_specs_hash
end
api_hash["caskfile_only"] = true if caskfile_only?
api_hash["conflicts_with"] = conflicts_with if conflicts_with.present?
api_hash["depends_on"] = depends_on if depends_on.present?
api_hash["container"] = container.pairs if container
api_hash["caveats"] = caveats if caveats.present?
api_hash["auto_updates"] = auto_updates if auto_updates
api_hash["languages"] = languages if languages.present?
api_hash
end
HASH_KEYS_TO_SKIP = %w[outdated installed versions].freeze HASH_KEYS_TO_SKIP = %w[outdated installed versions].freeze
private_constant :HASH_KEYS_TO_SKIP private_constant :HASH_KEYS_TO_SKIP
def to_hash_with_variations(hash_method: :to_h) def to_hash_with_variations
case hash_method if loaded_from_api? && !Homebrew::EnvConfig.no_install_from_api?
when :to_h return api_to_local_hash(Homebrew::API::Cask.all_casks[token].dup)
if loaded_from_api? && !Homebrew::EnvConfig.no_install_from_api?
return api_to_local_hash(Homebrew::API::Cask.all_casks[token].dup)
end
when :to_internal_api_hash
raise ArgumentError, "API Hash must be generated from Ruby source files" if loaded_from_api?
else
raise ArgumentError, "Unknown hash method #{hash_method.inspect}"
end end
hash = public_send(hash_method) hash = to_h
variations = {} variations = {}
if @dsl.on_system_blocks_exist? if @dsl.on_system_blocks_exist?
@ -471,7 +423,7 @@ module Cask
Homebrew::SimulateSystem.with(os:, arch:) do Homebrew::SimulateSystem.with(os:, arch:) do
refresh refresh
public_send(hash_method).each do |key, value| to_h.each do |key, value|
next if HASH_KEYS_TO_SKIP.include? key next if HASH_KEYS_TO_SKIP.include? key
next if value.to_s == hash[key].to_s next if value.to_s == hash[key].to_s
@ -485,11 +437,11 @@ module Cask
end end
end end
hash["variations"] = variations if hash_method != :to_internal_api_hash || variations.present? hash["variations"] = variations
hash hash
end end
def artifacts_list(compact: false, uninstall_only: false) def artifacts_list(uninstall_only: false)
artifacts.filter_map do |artifact| artifacts.filter_map do |artifact|
case artifact case artifact
when Artifact::AbstractFlightBlock when Artifact::AbstractFlightBlock
@ -498,8 +450,7 @@ module Cask
next if uninstall_only && !uninstall_flight_block next if uninstall_only && !uninstall_flight_block
# Only indicate whether this block is used as we don't load it from the API # Only indicate whether this block is used as we don't load it from the API
# We can skip this entirely once we move to internal JSON v3. { artifact.summarize.to_sym => nil }
{ artifact.summarize.to_sym => nil } unless compact
else else
zap_artifact = artifact.is_a?(Artifact::Zap) zap_artifact = artifact.is_a?(Artifact::Zap)
uninstall_artifact = artifact.respond_to?(:uninstall_phase) || artifact.respond_to?(:post_uninstall_phase) uninstall_artifact = artifact.respond_to?(:uninstall_phase) || artifact.respond_to?(:post_uninstall_phase)

View File

@ -62,8 +62,6 @@ module Homebrew
raise raise
end end
homebrew_cask_tap_json = JSON.generate(tap.to_internal_api_hash)
File.write("api/internal/v3/homebrew-cask.json", homebrew_cask_tap_json) unless args.dry_run?
canonical_json = JSON.pretty_generate(tap.cask_renames) canonical_json = JSON.pretty_generate(tap.cask_renames)
File.write("_data/cask_canonical.json", "#{canonical_json}\n") unless args.dry_run? File.write("_data/cask_canonical.json", "#{canonical_json}\n") unless args.dry_run?
end end

View File

@ -60,8 +60,6 @@ module Homebrew
raise raise
end end
homebrew_core_tap_json = JSON.generate(tap.to_internal_api_hash)
File.write("api/internal/v3/homebrew-core.json", homebrew_core_tap_json) unless args.dry_run?
canonical_json = JSON.pretty_generate(tap.formula_renames.merge(tap.alias_table)) 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? File.write("_data/formula_canonical.json", "#{canonical_json}\n") unless args.dry_run?
end end

View File

@ -219,7 +219,6 @@ module Homebrew
# TODO: remove this and fix tests when possible. # TODO: remove this and fix tests when possible.
ENV["HOMEBREW_NO_INSTALL_FROM_API"] = "1" ENV["HOMEBREW_NO_INSTALL_FROM_API"] = "1"
ENV.delete("HOMEBREW_INTERNAL_JSON_V3")
ENV["USER"] ||= system_command!("id", args: ["-nu"]).stdout.chomp ENV["USER"] ||= system_command!("id", args: ["-nu"]).stdout.chomp

View File

@ -7,16 +7,8 @@ module Cachable
@cache ||= T.let({}, T.nilable(T::Hash[T.untyped, T.untyped])) @cache ||= T.let({}, T.nilable(T::Hash[T.untyped, T.untyped]))
end end
# NOTE: We overwrite here instead of using `Hash#clear` to handle frozen hashes.
sig { void } sig { void }
def clear_cache def clear_cache
overwrite_cache!({}) cache.clear
end
private
sig { params(hash: T::Hash[T.untyped, T.untyped]).void }
def overwrite_cache!(hash)
@cache = hash
end end
end end

View File

@ -2572,85 +2572,8 @@ class Formula
hsh hsh
end end
def to_internal_api_hash def to_hash_with_variations
api_hash = { hash = to_hash
"desc" => desc,
"license" => SPDX.license_expression_to_string(license),
"homepage" => homepage,
"urls" => urls_hash.transform_values(&:compact),
"post_install_defined" => post_install_defined?,
"ruby_source_path" => ruby_source_path,
"ruby_source_sha256" => ruby_source_checksum&.hexdigest,
}
# Exclude default values.
api_hash["revision"] = revision unless revision.zero?
api_hash["version_scheme"] = version_scheme unless version_scheme.zero?
# Optional values.
api_hash["keg_only_reason"] = keg_only_reason.to_hash if keg_only_reason
api_hash["pour_bottle_only_if"] = self.class.pour_bottle_only_if.to_s if self.class.pour_bottle_only_if
api_hash["link_overwrite"] = self.class.link_overwrite_paths.to_a if self.class.link_overwrite_paths.present?
api_hash["caveats"] = caveats_with_placeholders if caveats
api_hash["service"] = service.to_hash if service?
if stable
api_hash["version"] = stable&.version&.to_s
api_hash["bottle"] = bottle_hash(compact_for_api: true) if bottle_defined?
end
if (versioned_formulae_list = versioned_formulae.presence)
# Could we just use `versioned_formulae_names` here instead?
api_hash["versioned_formulae"] = versioned_formulae_list.map(&:name)
end
if (dependencies = internal_dependencies_hash(:stable).presence)
api_hash["dependencies"] = dependencies
end
if (head_dependencies = internal_dependencies_hash(:head).presence)
api_hash["head_dependencies"] = head_dependencies
end
if (requirements_array = serialized_requirements.presence)
api_hash["requirements"] = requirements_array
end
if conflicts.present?
api_hash["conflicts_with"] = conflicts.map(&:name)
api_hash["conflicts_with_reasons"] = conflicts.map(&:reason)
end
if deprecation_date
api_hash["deprecation_date"] = deprecation_date
api_hash["deprecation_reason"] = deprecation_reason
api_hash["deprecation_replacement"] = deprecation_replacement
end
if disable_date
api_hash["disable_date"] = disable_date
api_hash["disable_reason"] = disable_reason
api_hash["disable_replacement"] = disable_replacement
end
api_hash
end
def to_hash_with_variations(hash_method: :to_hash)
if loaded_from_api? && hash_method == :to_internal_api_hash
raise ArgumentError, "API Hash must be generated from Ruby source files"
end
namespace_prefix = case hash_method
when :to_hash
"Variations"
when :to_internal_api_hash
"APIVariations"
else
raise ArgumentError, "Unknown hash method #{hash_method.inspect}"
end
hash = public_send(hash_method)
# Take from API, merging in local install status. # Take from API, merging in local install status.
if loaded_from_api? && !Homebrew::EnvConfig.no_install_from_api? if loaded_from_api? && !Homebrew::EnvConfig.no_install_from_api?
@ -2669,13 +2592,13 @@ class Formula
next unless bottle_tag.valid_combination? next unless bottle_tag.valid_combination?
Homebrew::SimulateSystem.with(os:, arch:) do Homebrew::SimulateSystem.with(os:, arch:) do
variations_namespace = Formulary.class_s("#{namespace_prefix}#{bottle_tag.to_sym.capitalize}") variations_namespace = Formulary.class_s("Variations#{bottle_tag.to_sym.capitalize}")
variations_formula_class = Formulary.load_formula(name, path, formula_contents, variations_namespace, variations_formula_class = Formulary.load_formula(name, path, formula_contents, variations_namespace,
flags: self.class.build_flags, ignore_errors: true) flags: self.class.build_flags, ignore_errors: true)
variations_formula = variations_formula_class.new(name, path, :stable, variations_formula = variations_formula_class.new(name, path, :stable,
alias_path:, force_bottle:) alias_path:, force_bottle:)
variations_formula.public_send(hash_method).each do |key, value| variations_formula.to_hash.each do |key, value|
next if value.to_s == hash[key].to_s next if value.to_s == hash[key].to_s
variations[bottle_tag.to_sym] ||= {} variations[bottle_tag.to_sym] ||= {}
@ -2685,12 +2608,12 @@ class Formula
end end
end end
hash["variations"] = variations if hash_method != :to_internal_api_hash || variations.present? hash["variations"] = variations
hash hash
end end
# Returns the bottle information for a formula. # Returns the bottle information for a formula.
def bottle_hash(compact_for_api: false) def bottle_hash
hash = {} hash = {}
stable_spec = stable stable_spec = stable
return hash unless stable_spec return hash unless stable_spec
@ -2698,8 +2621,8 @@ class Formula
bottle_spec = stable_spec.bottle_specification bottle_spec = stable_spec.bottle_specification
hash["rebuild"] = bottle_spec.rebuild if !compact_for_api || !bottle_spec.rebuild.zero? hash["rebuild"] = bottle_spec.rebuild
hash["root_url"] = bottle_spec.root_url unless compact_for_api hash["root_url"] = bottle_spec.root_url
hash["files"] = {} hash["files"] = {}
bottle_spec.collector.each_tag do |tag| bottle_spec.collector.each_tag do |tag|
@ -2710,11 +2633,9 @@ class Formula
file_hash = {} file_hash = {}
file_hash["cellar"] = os_cellar file_hash["cellar"] = os_cellar
unless compact_for_api filename = Bottle::Filename.create(self, tag, bottle_spec.rebuild)
filename = Bottle::Filename.create(self, tag, bottle_spec.rebuild) path, = Utils::Bottles.path_resolved_basename(bottle_spec.root_url, name, checksum, filename)
path, = Utils::Bottles.path_resolved_basename(bottle_spec.root_url, name, checksum, filename) file_hash["url"] = "#{bottle_spec.root_url}/#{path}"
file_hash["url"] = "#{bottle_spec.root_url}/#{path}"
end
file_hash["sha256"] = checksum file_hash["sha256"] = checksum
hash["files"][tag.to_sym] = file_hash hash["files"][tag.to_sym] = file_hash

View File

@ -213,71 +213,38 @@ module Formulary
end end
end end
add_deps = if Homebrew::API.internal_json_v3? add_deps = lambda do |spec|
lambda do |deps| T.bind(self, SoftwareSpec)
T.bind(self, SoftwareSpec)
deps&.each do |name, info| dep_json = json_formula.fetch("#{spec}_dependencies", json_formula)
tags = case info&.dig("tags")
in Array => tag_list
tag_list.map(&:to_sym)
in String => tag
tag.to_sym
else
nil
end
if info&.key?("uses_from_macos") dep_json["dependencies"]&.each do |dep|
bounds = info["uses_from_macos"].dup || {} # Backwards compatibility check - uses_from_macos used to be a part of dependencies on Linux
bounds.deep_transform_keys!(&:to_sym) next if !json_formula.key?("uses_from_macos_bounds") && uses_from_macos_names.include?(dep) &&
bounds.deep_transform_values!(&:to_sym) !Homebrew::SimulateSystem.simulating_or_running_on_macos?
if tags depends_on dep
uses_from_macos name => tags, **bounds
else
uses_from_macos name, **bounds
end
elsif tags
depends_on name => tags
else
depends_on name
end
end
end end
else
lambda do |spec|
T.bind(self, SoftwareSpec)
dep_json = json_formula.fetch("#{spec}_dependencies", json_formula) [:build, :test, :recommended, :optional].each do |type|
dep_json["#{type}_dependencies"]&.each do |dep|
dep_json["dependencies"]&.each do |dep|
# Backwards compatibility check - uses_from_macos used to be a part of dependencies on Linux # Backwards compatibility check - uses_from_macos used to be a part of dependencies on Linux
next if !json_formula.key?("uses_from_macos_bounds") && uses_from_macos_names.include?(dep) && next if !json_formula.key?("uses_from_macos_bounds") && uses_from_macos_names.include?(dep) &&
!Homebrew::SimulateSystem.simulating_or_running_on_macos? !Homebrew::SimulateSystem.simulating_or_running_on_macos?
depends_on dep depends_on dep => type
end end
end
[:build, :test, :recommended, :optional].each do |type| dep_json["uses_from_macos"]&.each_with_index do |dep, index|
dep_json["#{type}_dependencies"]&.each do |dep| bounds = dep_json.fetch("uses_from_macos_bounds", [])[index].dup || {}
# Backwards compatibility check - uses_from_macos used to be a part of dependencies on Linux bounds.deep_transform_keys!(&:to_sym)
next if !json_formula.key?("uses_from_macos_bounds") && uses_from_macos_names.include?(dep) && bounds.deep_transform_values!(&:to_sym)
!Homebrew::SimulateSystem.simulating_or_running_on_macos?
depends_on dep => type if dep.is_a?(Hash)
end uses_from_macos dep.deep_transform_values(&:to_sym).merge(bounds)
end else
uses_from_macos dep, bounds
dep_json["uses_from_macos"]&.each_with_index do |dep, index|
bounds = dep_json.fetch("uses_from_macos_bounds", [])[index].dup || {}
bounds.deep_transform_keys!(&:to_sym)
bounds.deep_transform_values!(&:to_sym)
if dep.is_a?(Hash)
uses_from_macos dep.deep_transform_values(&:to_sym).merge(bounds)
else
uses_from_macos dep, bounds
end
end end
end end
end end
@ -299,15 +266,10 @@ module Formulary
using: urls_stable["using"]&.to_sym, using: urls_stable["using"]&.to_sym,
}.compact }.compact
url urls_stable["url"], **url_spec url urls_stable["url"], **url_spec
version Homebrew::API.internal_json_v3? ? json_formula["version"] : json_formula["versions"]["stable"] version json_formula["versions"]["stable"]
sha256 urls_stable["checksum"] if urls_stable["checksum"].present? sha256 urls_stable["checksum"] if urls_stable["checksum"].present?
if Homebrew::API.internal_json_v3? instance_exec(:stable, &add_deps)
instance_exec(json_formula["dependencies"], &add_deps)
else
instance_exec(:stable, &add_deps)
end
requirements[:stable]&.each do |req| requirements[:stable]&.each do |req|
depends_on req depends_on req
end end
@ -322,23 +284,14 @@ module Formulary
}.compact }.compact
url urls_head["url"], **url_spec url urls_head["url"], **url_spec
if Homebrew::API.internal_json_v3? instance_exec(:head, &add_deps)
instance_exec(json_formula["head_dependencies"], &add_deps)
else
instance_exec(:head, &add_deps)
end
requirements[:head]&.each do |req| requirements[:head]&.each do |req|
depends_on req depends_on req
end end
end end
end end
bottles_stable = if Homebrew::API.internal_json_v3? bottles_stable = json_formula["bottle"]["stable"].presence
json_formula["bottle"]
else
json_formula["bottle"]["stable"]
end.presence
if bottles_stable if bottles_stable
bottle do bottle do
@ -426,26 +379,20 @@ module Formulary
.gsub(HOMEBREW_HOME_PLACEHOLDER, Dir.home) .gsub(HOMEBREW_HOME_PLACEHOLDER, Dir.home)
end end
@tap_git_head_string = if Homebrew::API.internal_json_v3? @tap_git_head_string = json_formula["tap_git_head"]
Homebrew::API::Formula.tap_git_head
else
json_formula["tap_git_head"]
end
def tap_git_head def tap_git_head
self.class.instance_variable_get(:@tap_git_head_string) self.class.instance_variable_get(:@tap_git_head_string)
end end
unless Homebrew::API.internal_json_v3? @oldnames_array = json_formula["oldnames"] || [json_formula["oldname"]].compact
@oldnames_array = json_formula["oldnames"] || [json_formula["oldname"]].compact def oldnames
def oldnames self.class.instance_variable_get(:@oldnames_array)
self.class.instance_variable_get(:@oldnames_array) end
end
@aliases_array = json_formula.fetch("aliases", []) @aliases_array = json_formula.fetch("aliases", [])
def aliases def aliases
self.class.instance_variable_get(:@aliases_array) self.class.instance_variable_get(:@aliases_array)
end
end end
@versioned_formulae_array = json_formula.fetch("versioned_formulae", []) @versioned_formulae_array = json_formula.fetch("versioned_formulae", [])

View File

@ -1307,8 +1307,6 @@ class CoreTap < AbstractCoreTap
@tap_migrations ||= if Homebrew::EnvConfig.no_install_from_api? @tap_migrations ||= if Homebrew::EnvConfig.no_install_from_api?
ensure_installed! ensure_installed!
super super
elsif Homebrew::API.internal_json_v3?
Homebrew::API::Formula.tap_migrations
else else
migrations, = Homebrew::API.fetch_json_api_file "formula_tap_migrations.jws.json", migrations, = Homebrew::API.fetch_json_api_file "formula_tap_migrations.jws.json",
stale_seconds: TAP_MIGRATIONS_STALE_SECONDS stale_seconds: TAP_MIGRATIONS_STALE_SECONDS
@ -1400,23 +1398,6 @@ class CoreTap < AbstractCoreTap
end end
end end
end end
sig { returns(T::Hash[String, T.untyped]) }
def to_internal_api_hash
formulae_api_hash = formula_names.to_h do |name|
formula = Formulary.factory(name)
formula_hash = formula.to_hash_with_variations(hash_method: :to_internal_api_hash)
[name, formula_hash]
end
{
"tap_git_head" => git_head,
"aliases" => alias_table,
"renames" => formula_renames,
"tap_migrations" => tap_migrations,
"formulae" => formulae_api_hash,
}
end
end end
# A specialized {Tap} class for homebrew-cask. # A specialized {Tap} class for homebrew-cask.
@ -1491,22 +1472,6 @@ class CoreCaskTap < AbstractCoreTap
migrations migrations
end end
end end
sig { returns(T::Hash[String, T.untyped]) }
def to_internal_api_hash
casks_api_hash = cask_tokens.to_h do |token|
cask = Cask::CaskLoader.load(token)
cask_hash = cask.to_hash_with_variations(hash_method: :to_internal_api_hash)
[token, cask_hash]
end
{
"tap_git_head" => git_head,
"renames" => cask_renames,
"tap_migrations" => tap_migrations,
"casks" => casks_api_hash,
}
end
end end
# Permanent configuration per {Tap} using `git-config(1)`. # Permanent configuration per {Tap} using `git-config(1)`.

View File

@ -1,170 +0,0 @@
# frozen_string_literal: true
RSpec.describe "Internal Tap JSON -- Formula", type: :system do
include FileUtils
let(:internal_tap_json) { File.read(TEST_FIXTURE_DIR/"internal_tap_json/homebrew-core.json").chomp }
let(:tap_git_head) { "9977471165641744a829d3e494fa563407503297" }
context "when generating JSON", :needs_macos do
before do
cp_r(TEST_FIXTURE_DIR/"internal_tap_json/homebrew-core", HOMEBREW_TAP_DIRECTORY/"homebrew")
# NOTE: Symlinks can't be copied recursively so we create them manually here.
(HOMEBREW_TAP_DIRECTORY/"homebrew/homebrew-core").tap do |core_tap|
mkdir(core_tap/"Aliases")
ln_s(core_tap/"Formula/f/fennel.rb", core_tap/"Aliases/fennel-lang")
ln_s(core_tap/"Formula/p/ponyc.rb", core_tap/"Aliases/ponyc-lang")
end
end
it "creates the expected hash" do
api_hash = CoreTap.instance.to_internal_api_hash
api_hash["tap_git_head"] = tap_git_head # tricky to mock
expect(JSON.pretty_generate(api_hash)).to eq(internal_tap_json)
end
end
context "when loading JSON" do
before do
ENV["HOMEBREW_INTERNAL_JSON_V3"] = "1"
ENV.delete("HOMEBREW_NO_INSTALL_FROM_API")
allow(Homebrew::API).to receive(:fetch_json_api_file)
.with("internal/v3/homebrew-core.jws.json")
.and_return([JSON.parse(internal_tap_json, freeze: true), false])
# `Tap.tap_migration_oldnames` looks for renames in every
# tap so `CoreCaskTap.tap_migrations` gets called and tries to
# fetch stuff from the API. This just avoids errors.
allow(Homebrew::API).to receive(:fetch_json_api_file)
.with("cask_tap_migrations.jws.json", anything)
.and_return([{}, false])
# To allow `formula_names.txt` to be written to the cache.
(HOMEBREW_CACHE/"api").mkdir
end
it "loads tap aliases" do
expect(CoreTap.instance.alias_table).to eq({
"fennel-lang" => "fennel",
"ponyc-lang" => "ponyc",
})
end
it "loads formula renames" do
expect(CoreTap.instance.formula_renames).to eq({
"advancemenu" => "advancemame",
"amtk" => "libgedit-amtk",
"annie" => "lux",
"antlr2" => "antlr@2",
"romanesco" => "fennel",
})
end
it "loads tap migrations" do
expect(CoreTap.instance.tap_migrations).to eq({
"adobe-air-sdk" => "homebrew/cask",
"android-ndk" => "homebrew/cask",
"android-platform-tools" => "homebrew/cask",
"android-sdk" => "homebrew/cask",
"app-engine-go-32" => "homebrew/cask/google-cloud-sdk",
})
end
it "loads tap git head" do
expect(Homebrew::API::Formula.tap_git_head)
.to eq(tap_git_head)
end
context "when loading formulae" do
let(:fennel_metadata) do
{
"dependencies" => ["lua"],
"desc" => "Lua Lisp Language",
"full_name" => "fennel",
"homepage" => "https://fennel-lang.org",
"license" => "MIT",
"name" => "fennel",
"ruby_source_path" => "Formula/f/fennel.rb",
"tap" => "homebrew/core",
"tap_git_head" => tap_git_head,
"versions" => { "bottle"=>true, "head"=>nil, "stable"=>"1.4.0" },
"ruby_source_checksum" => {
"sha256" => "5856e655fd1cea11496d67bc27fb14fee5cfbdea63c697c3773c7f247581197d",
},
}
end
let(:ponyc_metadata) do
{
"desc" => "Object-oriented, actor-model, capabilities-secure programming language",
"full_name" => "ponyc",
"homepage" => "https://www.ponylang.io/",
"license" => "BSD-2-Clause",
"name" => "ponyc",
"ruby_source_path" => "Formula/p/ponyc.rb",
"tap" => "homebrew/core",
"tap_git_head" => tap_git_head,
"uses_from_macos" => [{ "llvm"=>[:build, :test] }, "zlib"],
"uses_from_macos_bounds" => [{}, {}],
"versions" => { "bottle"=>true, "head"=>nil, "stable"=>"0.58.1" },
"ruby_source_checksum" => {
"sha256" => "81d51c25d18710191beb62f9f380bae3d878aad815a65ec1ee2a3b132c1fadb3",
},
}
end
let(:inko_metadata) do
{
"desc" => "Safe and concurrent object-oriented programming language",
"full_name" => "inko",
"homepage" => "https://inko-lang.org/",
"license" => "MPL-2.0",
"name" => "inko",
"ruby_source_path" => "Formula/i/inko.rb",
"tap" => "homebrew/core",
"tap_git_head" => tap_git_head,
"dependencies" => ["llvm@15", "zstd"],
"uses_from_macos" => ["libffi", "ruby"],
"uses_from_macos_bounds" => [{ since: :catalina }, { since: :sierra }],
"versions" => { "bottle"=>true, "head"=>"HEAD", "stable"=>"0.14.0" },
"ruby_source_checksum" => {
"sha256" => "843f6b5652483b971c83876201d68c95d5f32e67e55a75ac7c95d68c4350aa1c",
},
}
end
it "loads fennel" do
fennel = Formulary.factory("fennel")
expect(fennel.to_hash).to include(**fennel_metadata)
end
it "loads fennel from rename" do
fennel = Formulary.factory("romanesco")
expect(fennel.to_hash).to include(**fennel_metadata)
end
it "loads fennel from alias" do
fennel = Formulary.factory("fennel-lang")
expect(fennel.to_hash).to include(**fennel_metadata)
end
it "loads ponyc" do
ponyc = Formulary.factory("ponyc")
expect(ponyc.to_hash).to include(**ponyc_metadata)
end
it "loads ponyc from alias" do
ponyc = Formulary.factory("ponyc-lang")
expect(ponyc.to_hash).to include(**ponyc_metadata)
end
it "loads ink" do
inko = Formulary.factory("inko")
expect(inko.to_hash).to include(**inko_metadata)
end
end
end
end

View File

@ -236,23 +236,6 @@ RSpec.describe Cask::Cask, :cask do
expect(cask.artifacts_list).to eq(expected_artifacts) expect(cask.artifacts_list).to eq(expected_artifacts)
end end
it "skips flight blocks when compact is true" do
expected_artifacts = [
{ uninstall: [{
rmdir: "#{TEST_TMPDIR}/empty_directory_path",
trash: ["#{TEST_TMPDIR}/foo", "#{TEST_TMPDIR}/bar"],
}] },
{ pkg: ["ManyArtifacts/ManyArtifacts.pkg"] },
{ app: ["ManyArtifacts/ManyArtifacts.app"] },
{ zap: [{
rmdir: ["~/Library/Caches/ManyArtifacts", "~/Library/Application Support/ManyArtifacts"],
trash: "~/Library/Logs/ManyArtifacts.log",
}] },
]
expect(cask.artifacts_list(compact: true)).to eq(expected_artifacts)
end
it "returns only uninstall artifacts when uninstall_only is true" do it "returns only uninstall artifacts when uninstall_only is true" do
expected_artifacts = [ expected_artifacts = [
{ uninstall_preflight: nil }, { uninstall_preflight: nil },
@ -270,22 +253,6 @@ RSpec.describe Cask::Cask, :cask do
expect(cask.artifacts_list(uninstall_only: true)).to eq(expected_artifacts) expect(cask.artifacts_list(uninstall_only: true)).to eq(expected_artifacts)
end end
it "skips flight blocks and returns only uninstall artifacts when compact and uninstall_only are true" do
expected_artifacts = [
{ uninstall: [{
rmdir: "#{TEST_TMPDIR}/empty_directory_path",
trash: ["#{TEST_TMPDIR}/foo", "#{TEST_TMPDIR}/bar"],
}] },
{ app: ["ManyArtifacts/ManyArtifacts.app"] },
{ zap: [{
rmdir: ["~/Library/Caches/ManyArtifacts", "~/Library/Application Support/ManyArtifacts"],
trash: "~/Library/Logs/ManyArtifacts.log",
}] },
]
expect(cask.artifacts_list(compact: true, uninstall_only: true)).to eq(expected_artifacts)
end
end end
describe "#uninstall_flight_blocks?" do describe "#uninstall_flight_blocks?" do

View File

@ -1,218 +0,0 @@
{
"tap_git_head": "9977471165641744a829d3e494fa563407503297",
"aliases": {
"fennel-lang": "fennel",
"ponyc-lang": "ponyc"
},
"renames": {
"advancemenu": "advancemame",
"amtk": "libgedit-amtk",
"annie": "lux",
"antlr2": "antlr@2",
"romanesco": "fennel"
},
"tap_migrations": {
"adobe-air-sdk": "homebrew/cask",
"android-ndk": "homebrew/cask",
"android-platform-tools": "homebrew/cask",
"android-sdk": "homebrew/cask",
"app-engine-go-32": "homebrew/cask/google-cloud-sdk"
},
"formulae": {
"fennel": {
"desc": "Lua Lisp Language",
"license": "MIT",
"homepage": "https://fennel-lang.org",
"urls": {
"stable": {
"url": "https://github.com/bakpakin/Fennel/archive/refs/tags/1.4.0.tar.gz",
"checksum": "161eb7f17f86e95de09070214d042fb25372f71ad266f451431f3109e87965c7"
}
},
"post_install_defined": false,
"ruby_source_path": "Formula/f/fennel.rb",
"ruby_source_sha256": "5856e655fd1cea11496d67bc27fb14fee5cfbdea63c697c3773c7f247581197d",
"version": "1.4.0",
"bottle": {
"files": {
"all": {
"cellar": ":any_skip_relocation",
"sha256": "f46028597883cbc38864c61bd3fa402da9cb90ce97415d51a7b5279bc17f7bd0"
}
}
},
"dependencies": {
"lua": null
}
},
"inko": {
"desc": "Safe and concurrent object-oriented programming language",
"license": "MPL-2.0",
"homepage": "https://inko-lang.org/",
"urls": {
"stable": {
"url": "https://releases.inko-lang.org/0.14.0.tar.gz",
"checksum": "4e2c82911d6026f76c42ccc164dc45b1b5e331db2e9557460d9319d682668e65"
},
"head": {
"url": "https://github.com/inko-lang/inko.git",
"branch": "main"
}
},
"post_install_defined": false,
"ruby_source_path": "Formula/i/inko.rb",
"ruby_source_sha256": "843f6b5652483b971c83876201d68c95d5f32e67e55a75ac7c95d68c4350aa1c",
"version": "0.14.0",
"bottle": {
"files": {
"arm64_sonoma": {
"cellar": ":any",
"sha256": "f6ff66fdfb3aac69263c32a8a29d13e9d28a80ae33807f34460e55d8c1b228c6"
},
"arm64_ventura": {
"cellar": ":any",
"sha256": "be59d916d29d85bb8bc4474eb1c7d42a56236835c3c21b0e36fb9e9df0a25e6e"
},
"arm64_monterey": {
"cellar": ":any",
"sha256": "9522c1f89b997dedaa3167ce4dbfa4a2d8c660acddecd32a99a515922e851b52"
},
"sonoma": {
"cellar": ":any",
"sha256": "8e32d823ce9712ae2d5a2b9cbe0c9b727223098b3e66b003da087032be9f6818"
},
"ventura": {
"cellar": ":any",
"sha256": "178865db1e2b60b4085a2465e8a3879794030a6d22c99b58c95e4bdf5418ef1b"
},
"monterey": {
"cellar": ":any",
"sha256": "6ef924939c42d7bb2ec4e0d65cf293147a593f829619928d2580b419ec19b26c"
},
"x86_64_linux": {
"cellar": ":any_skip_relocation",
"sha256": "14a02c119990d6a17062290439ac74e6667b41dcb90b18cd90b36d2a09715e10"
}
}
},
"dependencies": {
"coreutils": {
"tags": [
"build"
]
},
"rust": {
"tags": [
"build"
]
},
"llvm@15": null,
"zstd": null,
"libffi": {
"uses_from_macos": {
"since": "catalina"
}
},
"ruby": {
"uses_from_macos": {
"since": "sierra"
}
}
},
"head_dependencies": {
"coreutils": {
"tags": [
"build"
]
},
"rust": {
"tags": [
"build"
]
},
"llvm@15": null,
"zstd": null,
"libffi": {
"uses_from_macos": {
"since": "catalina"
}
},
"ruby": {
"uses_from_macos": {
"since": "sierra"
}
}
}
},
"ponyc": {
"desc": "Object-oriented, actor-model, capabilities-secure programming language",
"license": "BSD-2-Clause",
"homepage": "https://www.ponylang.io/",
"urls": {
"stable": {
"url": "https://github.com/ponylang/ponyc.git",
"tag": "0.58.1",
"revision": "fe3895eb4af494bf36d7690641bdfb5755db8350"
}
},
"post_install_defined": false,
"ruby_source_path": "Formula/p/ponyc.rb",
"ruby_source_sha256": "81d51c25d18710191beb62f9f380bae3d878aad815a65ec1ee2a3b132c1fadb3",
"version": "0.58.1",
"bottle": {
"files": {
"arm64_sonoma": {
"cellar": ":any_skip_relocation",
"sha256": "e3aecfcf02aea56d53d82691e2ad7a780f771023d7070271bfce96b17439a34d"
},
"arm64_ventura": {
"cellar": ":any_skip_relocation",
"sha256": "6ff83717191e16e4f852fb3be8f838afba312cc39e601bb5cebd2a618a328658"
},
"arm64_monterey": {
"cellar": ":any_skip_relocation",
"sha256": "25c91bce200583a96f4cea34f31393c8f10eadcab363cc7d4d864d15f5f97e25"
},
"sonoma": {
"cellar": ":any_skip_relocation",
"sha256": "5f4c550ce33e2970e0ada18a409755fa62936181289a21c15582ff80343866b6"
},
"ventura": {
"cellar": ":any_skip_relocation",
"sha256": "f26c799f45013685da779bf2008ebe1907f9b3a93d5f260ce271a3f3b628da50"
},
"monterey": {
"cellar": ":any_skip_relocation",
"sha256": "1cff10d068b36b18b253d235424c4f5aef71ff9ee44f2522c4b041dd4383ec30"
},
"x86_64_linux": {
"cellar": ":any_skip_relocation",
"sha256": "ab49318d75eed3ee932c8e5add22f252ec0c852aad94945022877f926e93899f"
}
}
},
"dependencies": {
"cmake": {
"tags": [
"build"
]
},
"python@3.12": {
"tags": [
"build"
]
},
"llvm": {
"tags": [
"build",
"test"
],
"uses_from_macos": null
},
"zlib": {
"uses_from_macos": null
}
}
}
}
}

View File

@ -1,25 +0,0 @@
class Fennel < Formula
desc "Lua Lisp Language"
homepage "https://fennel-lang.org"
url "https://github.com/bakpakin/Fennel/archive/refs/tags/1.4.0.tar.gz"
sha256 "161eb7f17f86e95de09070214d042fb25372f71ad266f451431f3109e87965c7"
license "MIT"
bottle do
sha256 cellar: :any_skip_relocation, all: "f46028597883cbc38864c61bd3fa402da9cb90ce97415d51a7b5279bc17f7bd0"
end
depends_on "lua"
def install
system "make"
bin.install "fennel"
lua = Formula["lua"]
(share/"lua"/lua.version.major_minor).install "fennel.lua"
end
test do
assert_match "hello, world!", shell_output("#{bin}/fennel -e '(print \"hello, world!\")'")
end
end

View File

@ -1,45 +0,0 @@
class Inko < Formula
desc "Safe and concurrent object-oriented programming language"
homepage "https://inko-lang.org/"
url "https://releases.inko-lang.org/0.14.0.tar.gz"
sha256 "4e2c82911d6026f76c42ccc164dc45b1b5e331db2e9557460d9319d682668e65"
license "MPL-2.0"
head "https://github.com/inko-lang/inko.git", branch: "main"
bottle do
sha256 cellar: :any, arm64_sonoma: "f6ff66fdfb3aac69263c32a8a29d13e9d28a80ae33807f34460e55d8c1b228c6"
sha256 cellar: :any, arm64_ventura: "be59d916d29d85bb8bc4474eb1c7d42a56236835c3c21b0e36fb9e9df0a25e6e"
sha256 cellar: :any, arm64_monterey: "9522c1f89b997dedaa3167ce4dbfa4a2d8c660acddecd32a99a515922e851b52"
sha256 cellar: :any, sonoma: "8e32d823ce9712ae2d5a2b9cbe0c9b727223098b3e66b003da087032be9f6818"
sha256 cellar: :any, ventura: "178865db1e2b60b4085a2465e8a3879794030a6d22c99b58c95e4bdf5418ef1b"
sha256 cellar: :any, monterey: "6ef924939c42d7bb2ec4e0d65cf293147a593f829619928d2580b419ec19b26c"
sha256 cellar: :any_skip_relocation, x86_64_linux: "14a02c119990d6a17062290439ac74e6667b41dcb90b18cd90b36d2a09715e10"
end
depends_on "coreutils" => :build
depends_on "rust" => :build
depends_on "llvm@15"
depends_on "zstd"
uses_from_macos "libffi", since: :catalina
uses_from_macos "ruby", since: :sierra
def install
ENV.prepend_path "PATH", Formula["coreutils"].opt_libexec/"gnubin"
system "make", "build", "PREFIX=#{prefix}"
system "make", "install", "PREFIX=#{prefix}"
end
test do
(testpath/"hello.inko").write <<~EOS
import std.stdio.STDOUT
class async Main {
fn async main {
STDOUT.new.print('Hello, world!')
}
}
EOS
assert_equal "Hello, world!\n", shell_output("#{bin}/inko run hello.inko")
end
end

View File

@ -1,60 +0,0 @@
class Ponyc < Formula
desc "Object-oriented, actor-model, capabilities-secure programming language"
homepage "https://www.ponylang.io/"
url "https://github.com/ponylang/ponyc.git",
tag: "0.58.1",
revision: "fe3895eb4af494bf36d7690641bdfb5755db8350"
license "BSD-2-Clause"
bottle do
sha256 cellar: :any_skip_relocation, arm64_sonoma: "e3aecfcf02aea56d53d82691e2ad7a780f771023d7070271bfce96b17439a34d"
sha256 cellar: :any_skip_relocation, arm64_ventura: "6ff83717191e16e4f852fb3be8f838afba312cc39e601bb5cebd2a618a328658"
sha256 cellar: :any_skip_relocation, arm64_monterey: "25c91bce200583a96f4cea34f31393c8f10eadcab363cc7d4d864d15f5f97e25"
sha256 cellar: :any_skip_relocation, sonoma: "5f4c550ce33e2970e0ada18a409755fa62936181289a21c15582ff80343866b6"
sha256 cellar: :any_skip_relocation, ventura: "f26c799f45013685da779bf2008ebe1907f9b3a93d5f260ce271a3f3b628da50"
sha256 cellar: :any_skip_relocation, monterey: "1cff10d068b36b18b253d235424c4f5aef71ff9ee44f2522c4b041dd4383ec30"
sha256 cellar: :any_skip_relocation, x86_64_linux: "ab49318d75eed3ee932c8e5add22f252ec0c852aad94945022877f926e93899f"
end
depends_on "cmake" => :build
depends_on "python@3.12" => :build
uses_from_macos "llvm" => [:build, :test]
uses_from_macos "zlib"
# We use LLVM to work around an error while building bundled `google-benchmark` with GCC
fails_with :gcc do
cause <<-EOS
.../src/gbenchmark/src/thread_manager.h:50:31: error: expected ')' before '(' token
50 | GUARDED_BY(GetBenchmarkMutex()) Result results;
| ^
EOS
end
def install
inreplace "CMakeLists.txt", "PONY_COMPILER=\"${CMAKE_C_COMPILER}\"", "PONY_COMPILER=\"#{ENV.cc}\"" if OS.linux?
ENV["CMAKE_FLAGS"] = "-DCMAKE_OSX_SYSROOT=#{MacOS.sdk_path}" if OS.mac?
ENV["MAKEFLAGS"] = "build_flags=-j#{ENV.make_jobs}"
system "make", "libs"
system "make", "configure"
system "make", "build"
system "make", "install", "DESTDIR=#{prefix}"
end
test do
# ENV["CC"] returns llvm_clang, which does not work in a test block.
ENV.clang
system "#{bin}/ponyc", "-rexpr", "#{prefix}/packages/stdlib"
(testpath/"test/main.pony").write <<~EOS
actor Main
new create(env: Env) =>
env.out.print("Hello World!")
EOS
system "#{bin}/ponyc", "test"
assert_equal "Hello World!", shell_output("./test1").strip
end
end

View File

@ -1,7 +0,0 @@
{
"advancemenu": "advancemame",
"amtk": "libgedit-amtk",
"annie": "lux",
"antlr2": "antlr@2",
"romanesco": "fennel"
}

View File

@ -1,7 +0,0 @@
{
"adobe-air-sdk": "homebrew/cask",
"android-ndk": "homebrew/cask",
"android-platform-tools": "homebrew/cask",
"android-sdk": "homebrew/cask",
"app-engine-go-32": "homebrew/cask/google-cloud-sdk"
}