From 20fb068085af1ec3907771f1bbdecd9c34be2dbd Mon Sep 17 00:00:00 2001
From: Philippe Eberli
Date: Tue, 28 May 2024 20:36:19 +0200
Subject: [PATCH] Fix migrations of formulae and casks to non homebrew taps
---
Library/Homebrew/cask/cask_loader.rb | 1 +
Library/Homebrew/formulary.rb | 1 +
.../Homebrew/test/cask/cask_loader_spec.rb | 35 +++++++++++++++++
Library/Homebrew/test/formulary_spec.rb | 39 +++++++++++++++++++
4 files changed, 76 insertions(+)
diff --git a/Library/Homebrew/cask/cask_loader.rb b/Library/Homebrew/cask/cask_loader.rb
index f088dcf339d4a..5637aadc0e5d5 100644
--- a/Library/Homebrew/cask/cask_loader.rb
+++ b/Library/Homebrew/cask/cask_loader.rb
@@ -458,6 +458,7 @@ def self.try_new(ref, warn: false)
loaders = Tap.select { |tap| tap.installed? && !tap.core_cask_tap? }
.filter_map { |tap| super("#{tap}/#{token}", warn:) }
+ .uniq(&:path)
.select { |tap| tap.path.exist? }
case loaders.count
diff --git a/Library/Homebrew/formulary.rb b/Library/Homebrew/formulary.rb
index 8810dc4e7be50..d25b508a877c3 100644
--- a/Library/Homebrew/formulary.rb
+++ b/Library/Homebrew/formulary.rb
@@ -828,6 +828,7 @@ def self.try_new(ref, from: T.unsafe(nil), warn: false)
loaders = Tap.select { |tap| tap.installed? && !tap.core_tap? }
.filter_map { |tap| super("#{tap}/#{name}", warn:) }
+ .uniq(&:path)
.select { |tap| tap.path.exist? }
case loaders.count
diff --git a/Library/Homebrew/test/cask/cask_loader_spec.rb b/Library/Homebrew/test/cask/cask_loader_spec.rb
index 62be102cea7b3..c867e0b32276c 100644
--- a/Library/Homebrew/test/cask/cask_loader_spec.rb
+++ b/Library/Homebrew/test/cask/cask_loader_spec.rb
@@ -82,6 +82,41 @@
(old_tap.path/"tap_migrations.json").write tap_migrations.to_json
end
+ context "to a cask in an other tap" do
+ # Can't use local-caffeine. It is a fixture in the :core_cask_tap and would take precendence over :new_tap.
+ let(:token) { "some-cask" }
+
+ let(:old_tap) { Tap.fetch("homebrew", "foo") }
+ let(:new_tap) { Tap.fetch("homebrew", "bar") }
+
+ let(:cask_file) { new_tap.cask_dir/"#{token}.rb" }
+
+ before do
+ new_tap.cask_dir.mkpath
+ FileUtils.touch cask_file
+ end
+
+ # FIXME
+ # It would be preferable not to print a warning when installing with the short token
+ it "warns when loading the short token" do
+ expect do
+ described_class.for(token)
+ end.to output(%r{Cask #{old_tap}/#{token} was renamed to #{new_tap}/#{token}\.}).to_stderr
+ end
+
+ it "does not warn when loading the full token in the new tap" do
+ expect do
+ described_class.for("#{new_tap}/#{token}")
+ end.not_to output.to_stderr
+ end
+
+ it "warns when loading the full token in the old tap" do
+ expect do
+ described_class.for("#{old_tap}/#{token}")
+ end.to output(%r{Cask #{old_tap}/#{token} was renamed to #{new_tap}/#{token}\.}).to_stderr
+ end
+ end
+
context "to a formula in the default tap" do
let(:old_tap) { core_cask_tap }
let(:new_tap) { core_tap }
diff --git a/Library/Homebrew/test/formulary_spec.rb b/Library/Homebrew/test/formulary_spec.rb
index 6b53acf40c6e7..e5293ffc7a42c 100644
--- a/Library/Homebrew/test/formulary_spec.rb
+++ b/Library/Homebrew/test/formulary_spec.rb
@@ -641,6 +641,45 @@ def formula_json_contents(extra_items = {})
# end
# end
end
+
+ context "to a third-party tap" do
+ let(:old_tap) { Tap.fetch("another", "foo") }
+ let(:new_tap) { Tap.fetch("another", "bar") }
+ let(:formula_file) { new_tap.formula_dir/"#{token}.rb" }
+
+ before do
+ new_tap.formula_dir.mkpath
+ FileUtils.touch formula_file
+ end
+
+ after do
+ FileUtils.rm_rf Tap::TAP_DIRECTORY/"another"
+ end
+
+ # FIXME
+ # It would be preferable not to print a warning when installing with the short token
+ it "warns when loading the short token" do
+ expect do
+ described_class.loader_for(token)
+ end.to output(
+ a_string_including("Formula #{old_tap}/#{token} was renamed to #{new_tap}/#{token}.").once,
+ ).to_stderr
+ end
+
+ it "does not warn when loading the full token in the new tap" do
+ expect do
+ described_class.loader_for("#{new_tap}/#{token}")
+ end.not_to output.to_stderr
+ end
+
+ it "warns when loading the full token in the old tap" do
+ expect do
+ described_class.loader_for("#{old_tap}/#{token}")
+ end.to output(
+ a_string_including("Formula #{old_tap}/#{token} was renamed to #{new_tap}/#{token}.").once,
+ ).to_stderr
+ end
+ end
end
end
end