Skip to content

formulary: find racks under aliases and old names - #24527

Merged
HaraldNordgren merged 7 commits into
mainfrom
to-rack-possible-names
Nov 7, 2026
Merged

HaraldNordgren merged 7 commits into
mainfrom
to-rack-possible-names

Conversation

@HaraldNordgren

@HaraldNordgren HaraldNordgren commented Nov 7, 2026 •

Copy link
Copy Markdown
Member

brew info postgres shows my postgresql keg from 2022, but brew uninstall, brew link, brew unlink and brew list can't find it as postgres or postgresql@18. postgresql was its own formula when I installed it. It's now an alias of postgresql@18, and the keg is still in Cellar/postgresql/14.2_1.

To reproduce, you need a keg installed before its formula became an alias:

$ brew info -v postgres
==> postgresql@18: 14.2_1 → stable 18.6_1 [keg-only]
...
==> Installed Kegs and Versions
postgresql@18 14.2_1 → 18.6_1 (3,305 files, 46.5MB) [Linked]
  Cellar: /usr/local/Cellar/postgresql/14.2_1
...
$ brew uninstall postgres
Error: No such keg: /usr/local/Cellar/postgres
$ brew uninstall postgresql@18
Error: No such keg: /usr/local/Cellar/postgresql@18
$ brew list --versions postgres
$ brew list --versions postgresql
postgresql 14.2_1

brew info, brew outdated and brew upgrade already find the keg by checking every name in Formula#possible_names. brew uninstall, brew link, brew unlink and brew list use Formulary.to_rack, which previously checked only the requested and canonical rack names.

Formulary.to_rack now searches candidate racks for the formula's possible names when neither rack exists. It ignores symlinked rack names and selects a rack only when exactly one qualifies and every keg receipt is from the formula's tap. This lets postgres and postgresql@18 find Cellar/postgresql. Missing or ambiguous matches retain the old behavior. Formulary.resolve also loads the formula from that keg's receipt.

The only output change found is that brew upgrade --dry-run postgresql@18 now displays postgresql, the installed name. Output from brew outdated, brew --prefix, brew --cellar, brew missing, brew deps --installed and brew info remains unchanged for postgres, postgresql@18 and icu4c@79.


  • Have you followed our Contributing guidelines?
  • Have you checked for other open Pull Requests for the same change?
  • Have you explained what your changes do? Performance claims (e.g. "this is faster") must include brew benchmark results.
  • Have you explained why you'd like these changes included, not just what they do?
  • For bug fixes, have you given step-by-step brew commands to reproduce the bug?
  • Have you written new tests (excluding integration tests)? Here's an example.
  • Have you successfully run brew lgtm (style, typechecking and tests) locally?

  • I did not use AI/LLM to create this PR, or I disclosed the tool/model below and reviewed its output. I did not attribute commits to AI and will answer maintainer questions and review comments myself without AI/LLM.

Claude Code helped implement the initial fix and earlier review changes. We migrated to Copilot mid-work, which fixed the symlink-dedup case, added its regression spec, and ran ./bin/brew lgtm --online.

- `brew info postgres` shows `Cellar/postgresql/14.2_1`, installed when
  `postgresql` was its own formula, but `uninstall`, `link`, `unlink`
  and `list` fail with `No such keg` for `postgres` and `postgresql@18`.
- `Formula#installed_kegs` checks every name in `possible_names`, while
  `Formulary.to_rack` only checks the given and canonical names.
- Fall back to the rack of the first installed keg when neither exists.
@coderabbitai

coderabbitai Bot commented Nov 7, 2026 •

Copy link
Copy Markdown
Contributor

Explain Change →

No actionable comments were generated in the recent review.

Summary

Summary by CodeRabbit

  • Bug Fixes
    • Formula references now resolve to an installed alias when exactly one suitable alias is available, including when an earlier alias links to it.
    • When alias installations are ambiguous, belong to another tap, or link to another formula, resolution falls back to the formula’s own installation.
    • If no suitable installed alias can be identified, the formula’s canonical-name installation remains the fallback.
    • Pinned formula listings now include formulas with an invalid receipt without producing an error message.

When no canonical-name rack exists, Formulary.to_rack searches installed formula names and selects a rack only when one qualifying candidate remains. Formula methods now accept explicit formula names for installed keg lookup. Tests cover alias rack selection and exclusions, plus pinned cask listing with a malformed receipt.

Changes: Formula rack lookup

Layer / File(s) Summary
Rack resolution and alias tests
Library/Homebrew/formula.rb, Library/Homebrew/formulary.rb, Library/Homebrew/test/formulary_spec.rb
installed_prefixes and installed_kegs accept optional formula names. When no canonical rack exists, to_rack searches installed formula names for a unique qualifying rack. Tests cover alias selection, multiple candidates, mismatched tap receipts and symlinked racks.
Pinned cask listing regression
Library/Homebrew/test/cmd/list_spec.rb
A regression test checks that listing a pinned cask prints its name without stderr when a receipt for an older formula name is malformed.
Merge Risk: Minimal · up to 66046

The change lets commands find kegs installed under a formula's old name. No remaining merge-blocking risk was found in the reviewed changes.

Pre-merge checks: Passed 4

Check name Status Explanation
Title check Passed The title describes the change to find installed racks under aliases and old names.
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Description check Passed The description explains the alias rack lookup problem and the changes to Formulary.to_rack.
Recent review info

Run configuration

  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 09cbb499-adbf-49fd-bbf3-34d38eb912b2
Commits

Reviewing files that changed from the base of the PR and between c7a4020 and 6604689.

Files selected for processing: 2

  • Library/Homebrew/formulary.rb
  • Library/Homebrew/test/cmd/list_spec.rb

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 7 remain after this review.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Review info

Run configuration

  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: d9117549-fb0e-40ff-8fbb-ce9bf7c68482
Commits

Reviewing files that changed from the base of the PR and between 47b4277 and c0999f1.

Files selected for processing: 2

  • Library/Homebrew/formulary.rb
  • Library/Homebrew/test/formulary_spec.rb

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 9 remain after this review.

Comment thread Library/Homebrew/formulary.rb Resolved
- A rename in one tap leaves `Cellar/<old name>` linked to the new
  rack, and another tap can make the same name an alias of a different
  formula. `brew uninstall` would then remove the renamed formula's keg.
- Skip symlinked racks and kegs whose receipt names another tap.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Review info

Run configuration

  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 0b572527-6604-4e45-bda8-d63a361d228c
Commits

Reviewing files that changed from the base of the PR and between c0999f1 and 117f1c9.

Files selected for processing: 2

  • Library/Homebrew/formulary.rb
  • Library/Homebrew/test/formulary_spec.rb

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 9 remain after this review.

Comment thread Library/Homebrew/formulary.rb Resolved

@carlocab carlocab left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems fine when CodeRabbit reviews are addressed.

- A rack can hold kegs from several taps. One keg from the formula's
  tap made the whole rack match, and `brew uninstall --force` removes
  every keg in it, including the other tap's.
- Only use a rack when all its kegs come from the formula's tap.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Review info

Run configuration

  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: c17a8ced-ca42-43e0-8676-098076a802bd
Commits

Reviewing files that changed from the base of the PR and between 117f1c9 and 17092bd.

Files selected for processing: 2

  • Library/Homebrew/formulary.rb
  • Library/Homebrew/test/formulary_spec.rb

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 8 remain after this review.

Comment thread Library/Homebrew/formulary.rb Resolved

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Review info

Run configuration

  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: f0cb5164-b62a-4504-8670-b8abd16a1be3
Commits

Reviewing files that changed from the base of the PR and between 17092bd and 07d1c7e.

Files selected for processing: 2

  • Library/Homebrew/formulary.rb
  • Library/Homebrew/test/formulary_spec.rb

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 8 remain after this review.

Comment thread Library/Homebrew/formulary.rb Resolved

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Additional comments: 2

AGENTS.md-37-37: 1

37-37: Major · Functional Correctness · Quick win

Unverified finding
Verification ran but could not confirm this finding. It is shown for review, not as a verified issue.

Require the user's review before opening a ready PR.

If the user asks the agent to open a PR before reviewing its output, this instruction makes the PR ready for human review too early. Homebrew requires the contributor to review AI-generated code and prose before requesting review. Ask the user to review the changes and PR description first. (raw.githubusercontent.com)

AGENTS.md-39-39: 1

39-39: Major · Functional Correctness · Quick win

Unverified finding
Verification ran but could not confirm this finding. It is shown for review, not as a verified issue.

Do not explain feedback for the user's reply.

If the user relies on the agent's explanation to answer a review comment, the reply is AI-assisted. Homebrew requires contributors to answer maintainer questions and review comments without AI. Direct the user to interpret and answer the feedback themselves. (raw.githubusercontent.com)

Review info

Run configuration

  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: a6bd7846-c982-411a-8326-3fa672765956
Commits

Reviewing files that changed from the base of the PR and between 07d1c7e and 19b2ea7.

Files selected for processing: 1

  • AGENTS.md

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 7 remain after this review.

@MikeMcQuaid MikeMcQuaid left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm fine with the change but from your description I'm surprised there's no consolidation/deduplication/etc. with other code here and only adding new code? Is it possible to DRY things up a bit so this path is both shared and used in more places and/or share this new code with the existing functionality?

@HaraldNordgren

Copy link
Copy Markdown
Member Author

@MikeMcQuaid That's a good point and I'll take a look.

I exhausted my weekly Claude limit and thought that would be a good opportunity to switch over to Copilot. So bear with me if this becomes messy.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Review info

Run configuration

  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 64420dfa-dde8-445c-83fd-71b624c4b65f
Commits

Reviewing files that changed from the base of the PR and between 9c14af2 and c7a4020.

Files selected for processing: 2

  • Library/Homebrew/formula.rb
  • Library/Homebrew/formulary.rb

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 8 remain after this review.

Comment thread Library/Homebrew/formulary.rb Resolved
@HaraldNordgren

Copy link
Copy Markdown
Member Author

@MikeMcQuaid I attempted some DRY, but some of this logic is indeed new. Do you want to take another look?

@HaraldNordgren
HaraldNordgren added this pull request to the merge queue Nov 7, 2026
Merged via the queue into main with commit 6dce86e Nov 7, 2026
56 checks passed
@HaraldNordgren
HaraldNordgren deleted the to-rack-possible-names branch November 7, 2026 15:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants