Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 18 additions & 1 deletion Library/Homebrew/formulary.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1242,7 +1242,24 @@ def self.to_rack(ref)
end

# Use canonical name to locate rack.
Utils::Path.resolved_path(HOMEBREW_CELLAR/canonical_name(ref))
rack = Utils::Path.resolved_path(HOMEBREW_CELLAR/canonical_name(ref))
return rack if rack.directory?

possible_rack = begin
formula = factory(ref)
installed_kegs = Utils::Path.formula_installed_prefixes(
formula.possible_names.reject { |name| (HOMEBREW_CELLAR/name).symlink? },
).map { |prefix| Keg.new(prefix) }
matching_racks = installed_kegs.group_by(&:rack).filter_map do |installed_rack, kegs|
next if installed_rack.symlink? || kegs.any? { |keg| keg.tab.tap != formula.tap }

Comment thread
coderabbitai[bot] marked this conversation as resolved.
Resolved
installed_rack
end
matching_racks.first if matching_racks.one?
rescue FormulaUnavailableError, TapFormulaAmbiguityError, Homebrew::UntrustedTapError
nil
end
possible_rack || rack
end

sig { params(ref: String).returns(String) }
Expand Down
59 changes: 59 additions & 0 deletions Library/Homebrew/test/formulary_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1176,6 +1176,65 @@ class #{described_class.class_s(formula_name)} < Formula
end
end

context "when the Formula has an alias", :no_api do
let(:alias_name) { "testball-alias" }
let(:alias_rack_path) { HOMEBREW_CELLAR/alias_name }
let(:later_alias_name) { "testball-alias-later" }
let(:later_alias_rack_path) { HOMEBREW_CELLAR/later_alias_name }

def install_keg(rack, version: "0.1", tap: CoreTap.instance)
keg_path = rack/version
keg_path.mkpath
tab = Tab.empty
tab.tabfile = keg_path/AbstractTab::FILENAME
tab.tap = tap
tab.write
end

before do
formula_path.dirname.mkpath
formula_path.write formula_content
CoreTap.instance.alias_dir.mkpath
FileUtils.ln_s formula_path, CoreTap.instance.alias_dir/alias_name
FileUtils.ln_s formula_path, CoreTap.instance.alias_dir/later_alias_name
end

it "returns the Rack of the alias when only that Rack exists" do
install_keg(alias_rack_path)

expect(described_class.to_rack(formula_name)).to eq(alias_rack_path)
end

it "finds a non-symlink alias after an earlier symlinked alias" do
install_keg(later_alias_rack_path)
alias_rack_path.make_relative_symlink(later_alias_rack_path)

expect(described_class.to_rack(formula_name)).to eq(later_alias_rack_path)
end

it "does not choose between multiple same-tap alias racks" do
install_keg(alias_rack_path)
install_keg(later_alias_rack_path)

expect(described_class.to_rack(formula_name)).to eq(rack_path)
end

it "ignores a Rack of the alias with any keg from another tap" do
install_keg(alias_rack_path)
install_keg(alias_rack_path, version: "0.2", tap: Tap.fetch("homebrew", "other"))

expect(described_class.to_rack(formula_name)).to eq(rack_path)
end

it "ignores a Rack of the alias that links to another Formula's Rack" do
other_rack_path = HOMEBREW_CELLAR/"testball-renamed"
install_keg(other_rack_path)
alias_rack_path.make_relative_symlink(other_rack_path)

expect(described_class.to_rack(formula_name)).to eq(rack_path)
end
end

it "raises an error if the Formula is not available" do
expect do
described_class.to_rack("a/b/#{formula_name}")
Expand Down
Loading