From fcaeae92a2a8fef2e4c56d76e9c73eae96b22c92 Mon Sep 17 00:00:00 2001 From: apainintheneck Date: Sun, 23 Jun 2024 19:51:12 -0700 Subject: [PATCH] fix tap migration renames with API We don't load casks and formulae that used to exist in an external tap but have been moved and renamed to an API tap when using the API. Loading works correctly when the core formula or cask tap is tapped locally though. This PR adds some logic to map tap migration renames to the API and check that when loading formulae and casks. --- Library/Homebrew/cask/cask_loader.rb | 18 ++++++++++++++---- Library/Homebrew/formulary.rb | 22 ++++++++++++++++------ Library/Homebrew/tap.rb | 26 ++++++++++++++++++++++++++ 3 files changed, 56 insertions(+), 10 deletions(-) diff --git a/Library/Homebrew/cask/cask_loader.rb b/Library/Homebrew/cask/cask_loader.rb index 5637aadc0e5d5..29bfca4910dc4 100644 --- a/Library/Homebrew/cask/cask_loader.rb +++ b/Library/Homebrew/cask/cask_loader.rb @@ -268,11 +268,13 @@ class FromAPILoader def self.try_new(ref, warn: false) return if Homebrew::EnvConfig.no_install_from_api? return unless ref.is_a?(String) - return unless (token = ref[HOMEBREW_DEFAULT_TAP_CASK_REGEX, :token]) - if !Homebrew::API::Cask.all_casks.key?(token) && - !Homebrew::API::Cask.all_renames.key?(token) - return + + token = parse_token(ref) + token ||= begin + ref = CoreCaskTap.instance.tap_migration_renames[ref] + parse_token(ref) if ref end + return unless token ref = "#{CoreCaskTap.instance}/#{token}" @@ -280,6 +282,14 @@ def self.try_new(ref, warn: false) new("#{tap}/#{token}") end + sig { params(ref: String).returns(T.nilable(String)) } + private_class_method def self.parse_token(ref) + return unless (token = ref[HOMEBREW_DEFAULT_TAP_CASK_REGEX, :token]) + return token if Homebrew::API::Cask.all_casks.key?(token) + + token if Homebrew::API::Cask.all_renames.key?(token) + end + sig { params(token: String, from_json: Hash, path: T.nilable(Pathname)).void } def initialize(token, from_json: T.unsafe(nil), path: nil) @token = token.sub(%r{^homebrew/(?:homebrew-)?cask/}i, "") diff --git a/Library/Homebrew/formulary.rb b/Library/Homebrew/formulary.rb index a5fae52065cea..4fc7b15f6b4c3 100644 --- a/Library/Homebrew/formulary.rb +++ b/Library/Homebrew/formulary.rb @@ -917,12 +917,13 @@ class FromAPILoader < FormulaLoader def self.try_new(ref, from: T.unsafe(nil), warn: false) return if Homebrew::EnvConfig.no_install_from_api? return unless ref.is_a?(String) - return unless (name = ref[HOMEBREW_DEFAULT_TAP_FORMULA_REGEX, :name]) - if !Homebrew::API::Formula.all_formulae.key?(name) && - !Homebrew::API::Formula.all_aliases.key?(name) && - !Homebrew::API::Formula.all_renames.key?(name) - return + + name = parse_name(ref) + name ||= begin + ref = CoreTap.instance.tap_migration_renames[ref] + parse_name(ref) if ref end + return unless name alias_name = name @@ -932,7 +933,7 @@ def self.try_new(ref, from: T.unsafe(nil), warn: false) name, tap, type = name_tap_type - options = if type == :alias + options = if type == :alias { alias_name: alias_name.downcase } else {} @@ -941,6 +942,15 @@ def self.try_new(ref, from: T.unsafe(nil), warn: false) new(name, tap:, **options) end + sig { params(ref: String).returns(T.nilable(String)) } + private_class_method def self.parse_name(ref) + return unless (name = ref[HOMEBREW_DEFAULT_TAP_FORMULA_REGEX, :name]) + return name if Homebrew::API::Formula.all_formulae.key?(name) + return name if Homebrew::API::Formula.all_aliases.key?(name) + + name if Homebrew::API::Formula.all_renames.key?(name) + end + sig { params(name: String, tap: Tap, alias_name: String).void } def initialize(name, tap: T.unsafe(nil), alias_name: T.unsafe(nil)) options = { diff --git a/Library/Homebrew/tap.rb b/Library/Homebrew/tap.rb index d04fdec0c7b9c..b6127a305671e 100644 --- a/Library/Homebrew/tap.rb +++ b/Library/Homebrew/tap.rb @@ -1284,6 +1284,19 @@ def tap_migrations end end + # External formula names to core formula renames + sig { returns(T::Hash[String, String]) } + def tap_migration_renames + @tap_migration_renames ||= Tap.each_with_object({}) do |tap, hash| + tap.tap_migrations.each do |old_name, new_name| + next unless new_name.start_with?("homebrew/core/") + + hash[old_name] = new_name + hash["#{tap}/#{old_name}"] = new_name + end + end + end + sig { returns(T::Array[String]) } def autobump @autobump ||= begin @@ -1456,6 +1469,19 @@ def tap_migrations end end + # External cask names to core cask renames + sig { returns(T::Hash[String, String]) } + def tap_migration_renames + @tap_migration_renames ||= Tap.each_with_object({}) do |tap, hash| + tap.tap_migrations.each do |old_name, new_name| + next unless new_name.start_with?("homebrew/cask/") + + hash[old_name] = new_name + hash["#{tap}/#{old_name}"] = new_name + end + end + end + sig { returns(T::Hash[String, T.untyped]) } def to_internal_api_hash casks_api_hash = cask_tokens.to_h do |token|