Skip to content

Commit

Permalink
Merge pull request #19251 from Homebrew/revert-json-v3-logic
Browse files Browse the repository at this point in the history
Revert json v3 logic
  • Loading branch information
MikeMcQuaid authored Feb 7, 2025
2 parents 91acde3 + f916f27 commit 9e3ae9f
Show file tree
Hide file tree
Showing 18 changed files with 66 additions and 875 deletions.
5 changes: 0 additions & 5 deletions Library/Homebrew/api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -184,11 +184,6 @@ def self.tap_from_source_download(path)

Tap.fetch(org, repo)
end

sig { returns(T::Boolean) }
def self.internal_json_v3?
ENV["HOMEBREW_INTERNAL_JSON_V3"].present?
end
end

sig { params(block: T.proc.returns(T.untyped)).returns(T.untyped) }
Expand Down
36 changes: 13 additions & 23 deletions Library/Homebrew/api/formula.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ module Formula
extend Cachable

DEFAULT_API_FILENAME = "formula.jws.json"
INTERNAL_V3_API_FILENAME = "internal/v3/homebrew-core.jws.json"

private_class_method :cache

Expand Down Expand Up @@ -43,33 +42,24 @@ def self.source_download(formula)

sig { returns(Pathname) }
def self.cached_json_file_path
if Homebrew::API.internal_json_v3?
HOMEBREW_CACHE_API/INTERNAL_V3_API_FILENAME
else
HOMEBREW_CACHE_API/DEFAULT_API_FILENAME
end
HOMEBREW_CACHE_API/DEFAULT_API_FILENAME
end

sig { returns(T::Boolean) }
def self.download_and_cache_data!
if Homebrew::API.internal_json_v3?
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["renames"] = {}
cache["formulae"] = json_formulae.to_h do |json_formula|
json_formula["aliases"].each do |alias_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")]
json_formulae, updated = Homebrew::API.fetch_json_api_file DEFAULT_API_FILENAME

cache["aliases"] = {}
cache["renames"] = {}
cache["formulae"] = json_formulae.to_h do |json_formula|
json_formula["aliases"].each do |alias_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

updated
Expand Down
65 changes: 8 additions & 57 deletions Library/Homebrew/cask/cask.rb
Original file line number Diff line number Diff line change
Expand Up @@ -400,63 +400,15 @@ def to_h
}
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
private_constant :HASH_KEYS_TO_SKIP

def to_hash_with_variations(hash_method: :to_h)
case hash_method
when :to_h
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}"
def to_hash_with_variations
if loaded_from_api? && !Homebrew::EnvConfig.no_install_from_api?
return api_to_local_hash(Homebrew::API::Cask.all_casks[token].dup)
end

hash = public_send(hash_method)
hash = to_h
variations = {}

if @dsl.on_system_blocks_exist?
Expand All @@ -471,7 +423,7 @@ def to_hash_with_variations(hash_method: :to_h)
Homebrew::SimulateSystem.with(os:, arch:) do
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 value.to_s == hash[key].to_s

Expand All @@ -485,11 +437,11 @@ def to_hash_with_variations(hash_method: :to_h)
end
end

hash["variations"] = variations if hash_method != :to_internal_api_hash || variations.present?
hash["variations"] = variations
hash
end

def artifacts_list(compact: false, uninstall_only: false)
def artifacts_list(uninstall_only: false)
artifacts.filter_map do |artifact|
case artifact
when Artifact::AbstractFlightBlock
Expand All @@ -498,8 +450,7 @@ def artifacts_list(compact: false, uninstall_only: false)
next if uninstall_only && !uninstall_flight_block

# 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 } unless compact
{ artifact.summarize.to_sym => nil }
else
zap_artifact = artifact.is_a?(Artifact::Zap)
uninstall_artifact = artifact.respond_to?(:uninstall_phase) || artifact.respond_to?(:post_uninstall_phase)
Expand Down
2 changes: 0 additions & 2 deletions Library/Homebrew/dev-cmd/generate-cask-api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,6 @@ def run
raise
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)
File.write("_data/cask_canonical.json", "#{canonical_json}\n") unless args.dry_run?
end
Expand Down
2 changes: 0 additions & 2 deletions Library/Homebrew/dev-cmd/generate-formula-api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,6 @@ def run
raise
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))
File.write("_data/formula_canonical.json", "#{canonical_json}\n") unless args.dry_run?
end
Expand Down
1 change: 0 additions & 1 deletion Library/Homebrew/dev-cmd/tests.rb
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,6 @@ def setup_environment!

# TODO: remove this and fix tests when possible.
ENV["HOMEBREW_NO_INSTALL_FROM_API"] = "1"
ENV.delete("HOMEBREW_INTERNAL_JSON_V3")

ENV["USER"] ||= system_command!("id", args: ["-nu"]).stdout.chomp

Expand Down
10 changes: 1 addition & 9 deletions Library/Homebrew/extend/cachable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,8 @@ def cache
@cache ||= T.let({}, T.nilable(T::Hash[T.untyped, T.untyped]))
end

# NOTE: We overwrite here instead of using `Hash#clear` to handle frozen hashes.
sig { void }
def clear_cache
overwrite_cache!({})
end

private

sig { params(hash: T::Hash[T.untyped, T.untyped]).void }
def overwrite_cache!(hash)
@cache = hash
cache.clear
end
end
101 changes: 11 additions & 90 deletions Library/Homebrew/formula.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2572,85 +2572,8 @@ def to_hash
hsh
end

def to_internal_api_hash
api_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)
def to_hash_with_variations
hash = to_hash

# Take from API, merging in local install status.
if loaded_from_api? && !Homebrew::EnvConfig.no_install_from_api?
Expand All @@ -2669,13 +2592,13 @@ def to_hash_with_variations(hash_method: :to_hash)
next unless bottle_tag.valid_combination?

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,
flags: self.class.build_flags, ignore_errors: true)
variations_formula = variations_formula_class.new(name, path, :stable,
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

variations[bottle_tag.to_sym] ||= {}
Expand All @@ -2685,21 +2608,21 @@ def to_hash_with_variations(hash_method: :to_hash)
end
end

hash["variations"] = variations if hash_method != :to_internal_api_hash || variations.present?
hash["variations"] = variations
hash
end

# Returns the bottle information for a formula.
def bottle_hash(compact_for_api: false)
def bottle_hash
hash = {}
stable_spec = stable
return hash unless stable_spec
return hash unless bottle_defined?

bottle_spec = stable_spec.bottle_specification

hash["rebuild"] = bottle_spec.rebuild if !compact_for_api || !bottle_spec.rebuild.zero?
hash["root_url"] = bottle_spec.root_url unless compact_for_api
hash["rebuild"] = bottle_spec.rebuild
hash["root_url"] = bottle_spec.root_url
hash["files"] = {}

bottle_spec.collector.each_tag do |tag|
Expand All @@ -2710,11 +2633,9 @@ def bottle_hash(compact_for_api: false)

file_hash = {}
file_hash["cellar"] = os_cellar
unless compact_for_api
filename = Bottle::Filename.create(self, tag, bottle_spec.rebuild)
path, = Utils::Bottles.path_resolved_basename(bottle_spec.root_url, name, checksum, filename)
file_hash["url"] = "#{bottle_spec.root_url}/#{path}"
end
filename = Bottle::Filename.create(self, tag, bottle_spec.rebuild)
path, = Utils::Bottles.path_resolved_basename(bottle_spec.root_url, name, checksum, filename)
file_hash["url"] = "#{bottle_spec.root_url}/#{path}"
file_hash["sha256"] = checksum

hash["files"][tag.to_sym] = file_hash
Expand Down
Loading

0 comments on commit 9e3ae9f

Please sign in to comment.