Skip to content

doctor: skip removed formulae in deprecated check - #24490

Merged
HaraldNordgren merged 7 commits into
mainfrom
doctor-deprecated-skip-removed
Nov 6, 2026
Merged

HaraldNordgren merged 7 commits into
mainfrom
doctor-deprecated-skip-removed

Conversation

@HaraldNordgren

@HaraldNordgren HaraldNordgren commented Nov 5, 2026 •

Copy link
Copy Markdown
Member

brew doctor told me to find a replacement for openssl@1.1 twice:

Warning: Some installed kegs have no formulae!
This means they were either deleted or installed manually.

You should find replacements for the following formulae:

  terraform
  go@1.14
  grv
  exa
  unrar
  openssl@1.1
  six
  python@3.8
  packer

Warning: Some installed formulae are deprecated or disabled.
You should find replacements for the following formulae:

  openssl@1.1
  pcre
  python@3.9
  qt@5

The formula was removed from homebrew/core on 2025-10-25, so the first warning is the accurate one. The second comes from the keg. Once a formula is gone from its tap, Formula.installed loads the copy saved in the keg's .brew/ directory. My keg is from February 2023 and its copy already had deprecate! date: "2023-09-11", so it counts as deprecated. The copies in my other eight removed kegs have no deprecate! or disable!, so those appear only once. Whether a removed formula is listed twice only depends on when it was installed.

This skips formulae with any keg under the same name that Keg#deleted_formula? flags, because check_deleted_formula already reports them, as #24466 did for check_for_unlinked_but_not_keg_only. A name is no longer listed in both sections. openssl@1.1 drops out of the second list and pcre, python@3.9 and qt@5 stay. Two other cases are now listed under "no formulae" only: deprecated formulae installed from a local file, and deprecated formulae still in a tap that also have an older keg from a removed tap, while that keg is installed.

That leaves the first warning as the only explanation, and "either deleted or installed manually" undersells what we know. A keg's receipt records the tap it came from, and all nine of mine record homebrew/core, so none was installed manually. The warning now groups formulae by that tap. Deleted comes first, then untapped, then kegs with no recorded tap, and within each homebrew/* taps come before others, alphabetically:

Warning: Some installed kegs have no formulae!
You should find replacements for the following formulae.

Deleted from homebrew/core:
  exa
  go@1.14
  grv
  openssl@1.1
  packer
  python@3.8
  six
  terraform
  unrar

Each header only says what's known. "Deleted from" needs the tap to be homebrew/core, installed or in DEPRECATED_OFFICIAL_TAPS, which brew tap already refuses as empty. Any other tap that isn't installed says "From untapped other/tap" instead, because its formula may still exist. A keg with no receipt, such as a leftover from an unfinished install, says "No tap recorded (possibly installed manually)". A formula with several kegs is listed once, under its newest keg that records a tap.

This goes by the keg's tap alone, without also requiring a deprecated copy. Only openssl@1.1 of my nine has one, and they were all deleted the same way.

To reproduce:

keg="$(brew --cellar)/removed-formula/1.0"
mkdir -p "$keg/.brew"
cat > "$keg/.brew/removed-formula.rb" <<'EOS'
class RemovedFormula < Formula
  url "https://brew.sh/removed-formula-1.0.tar.gz"
  deprecate! date: "2020-01-01", because: :unsupported
end
EOS
echo '{"source":{"tap":"homebrew/core","spec":"stable"}}' > "$keg/INSTALL_RECEIPT.json"
ln -s "$keg" "$(brew --prefix)/opt/removed-formula"
brew doctor check_deleted_formula check_deprecated_disabled
rm "$(brew --prefix)/opt/removed-formula"
rm -r "$(brew --cellar)/removed-formula"

  • 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 (Claude Opus 5.5) traced why brew doctor listed the formula twice, wrote the change and its specs and verified them. The new specs for removed formulae fail without the change and pass with it. It ran the reproduction steps before and after the change, ran the new filter against my install and ran brew lgtm on the first commit, which passes, then the specs and brew style on the follow-ups.


@coderabbitai

coderabbitai Bot commented Nov 5, 2026 •

Copy link
Copy Markdown
Contributor

Explain Change →

No actionable comments were generated in the recent review.

Summary

Summary by CodeRabbit

  • Bug Fixes
    • Diagnostics no longer flag deprecated formulae when their only installed copies are deleted-formula kegs.
    • Deleted-formula reports sort affected kegs by scheme and version, and prefer entries with recorded taps when selecting one per formula.
    • Reports group affected formulae by source, distinguishing deleted formulae, untapped sources and kegs with no recorded tap.
    • Source-specific headings replace the generic explanation that missing formulae were deleted or installed manually.

The diagnostic checks now filter deprecated or disabled formulae using installed keg names and deleted-formula status. Deleted-formula findings select the newest keg per name and group remediation by recorded tap.

Changes: Diagnostic findings

Layer / File(s) Summary
Deprecated formula filter
Library/Homebrew/diagnostic.rb, Library/Homebrew/test/diagnostic_checks_spec.rb
The check omits a deprecated or disabled formula when none of its installed kegs has the same name and is a deleted-formula keg. Tests cover formulae still in a tap, removed formulae and taps, and old keg names.
Deleted-formula findings
Library/Homebrew/diagnostic.rb, Library/Homebrew/test/diagnostic_checks_spec.rb
The check selects the newest deleted-formula keg per name, sorts affected names and groups remediation for core or installed taps, untapped taps and kegs without a recorded tap. Tests cover tap sources, manual installs and multiple versions.
Merge Risk: Low · up to bdd44

After a reverse rename, brew doctor may omit the current formula’s deprecation warning. This narrow case is suitable for follow-up and does not block merging.

Pre-merge checks: Passed 4

Check name Status Explanation
Title check Passed The title identifies the change to the deprecated formula check.
Description check Passed The description covers the changes. It says any deleted keg triggers exclusion, but the file summary says every installed keg with the same name must be marked deleted.
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.
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: 6ba185b8-60a6-491f-b5dc-d890177b7e11
Commits

Reviewing files that changed from the base of the PR and between b0bc032 and bdd44d7.

Files selected for processing: 1

  • Library/Homebrew/diagnostic.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.

@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: 1

Library/Homebrew/diagnostic.rb-1227-1227: 1

1227-1227: Minor · Functional Correctness · Quick win

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

Preserve a warning when this check runs alone.

brew doctor check_deprecated_disabled does not run check_deleted_formula. If its only installed formula is deprecated and removed, this change makes the command report success without a warning. (raw.githubusercontent.com)

Keep the warning for an individual check, or include the deleted-formula check in that invocation.

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: 481ccd69-68fa-4ce2-9c4a-e60f7ac13dce
Commits

Reviewing files that changed from the base of the PR and between 944ccca and 51f631c.

Files selected for processing: 2

  • Library/Homebrew/diagnostic.rb
  • Library/Homebrew/test/diagnostic_checks_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.

@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: 29a4bbc4-13e1-41bc-b618-4cf58b06d333
Commits

Reviewing files that changed from the base of the PR and between 944ccca and 51f631c.

Files selected for processing: 2

  • Library/Homebrew/diagnostic.rb
  • Library/Homebrew/test/diagnostic_checks_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/diagnostic.rb Resolved
@HaraldNordgren
HaraldNordgren force-pushed the doctor-deprecated-skip-removed branch from 51f631c to 02e0cad Compare November 5, 2026 11:48

@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: 05e22009-71c7-4ace-812b-a57026702457
Commits

Reviewing files that changed from the base of the PR and between 51f631c and 02e0cad.

Files selected for processing: 2

  • Library/Homebrew/diagnostic.rb
  • Library/Homebrew/test/diagnostic_checks_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/diagnostic.rb Resolved

@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 think this is fairly good but might be worth improving the "removed" language to indicate they were deleted by homebrew/core if they were also showing up as deprecated and from homebrew/core.

@HaraldNordgren
HaraldNordgren force-pushed the doctor-deprecated-skip-removed branch 2 times, most recently from 7441212 to 4b7119d Compare November 5, 2026 19:29

@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: 1

Library/Homebrew/diagnostic.rb-1470-1470: 1

1470-1470: Minor · Functional Correctness · Quick win

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

Select the newest keg before preferring a recorded tap.

When a newer untapped keg and an older core keg share a name, this sort selects the older core keg. The warning then places the name under “Deleted from homebrew/core” rather than describing the newest installation. The half-installed fixture confirms this result. Put scheme_and_version before tap presence in the sort key, and update that expectation. (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: 3b0ca642-0fe7-44a6-91e9-4b9e81b26c4f
Commits

Reviewing files that changed from the base of the PR and between 7441212 and 4b7119d.

Files selected for processing: 2

  • Library/Homebrew/diagnostic.rb
  • Library/Homebrew/test/diagnostic_checks_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.

@HaraldNordgren

Copy link
Copy Markdown
Member Author

@MikeMcQuaid Updated it now to spell out where things are from, and if they were deleted on the tap was untapped instead.

@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.

Very nice, one final nit!

Comment thread Library/Homebrew/diagnostic.rb Resolved
- `check_deleted_formula` already lists these kegs, so a removed formula
  could appear in both sections with the same advice
- Their deprecated state comes from the keg's old `.brew/` copy, so the
  overlap only depended on when the formula was installed
- `check_deleted_formula` lists a name if any of its kegs is flagged, so
  a formula with only an older flagged keg could still appear in both
  sections
- `installed_kegs` also holds kegs under old names and aliases, so a
  removed `asciigen` keg hid the deprecation of an installed `glyph`
- `check_deleted_formula` only reports `asciigen`, so `glyph` appeared
  in neither section
- A keg's tab records `homebrew/core`, so it wasn't installed manually
  and "either deleted or installed manually" undersells what we know
- `check_deprecated_disabled` now skips these formulae, so this is the
  only warning left to explain why they went away
- Two findings from one check ran together under one `Warning:`, and
  fixing that meant changing how `doctor` prints every check
- One finding grouped by tap says where each formula went without that
- Sort by type (deleted, untapped, no tap), then `homebrew/*` taps
  before others, then alphabetically
- List a formula once, under the newest keg that records a tap
- Only say "Deleted from" for `homebrew/core` or an installed tap, as
  the formula from an untapped tap may still exist
- A keg with no receipt can be a leftover, not a manual install
- `brew tap` refuses these taps as empty, so we know their formulae are
  gone without needing a network lookup
@HaraldNordgren
HaraldNordgren force-pushed the doctor-deprecated-skip-removed branch from b0bc032 to 5479695 Compare November 6, 2026 10:18
- Hash keys show the order of the types and partitions show the order
  of the taps, so the sort keys no longer need `0`, `1` and `2`
@HaraldNordgren
HaraldNordgren force-pushed the doctor-deprecated-skip-removed branch from 5479695 to bdd44d7 Compare November 6, 2026 10:19

@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.

Thanks!

@HaraldNordgren
HaraldNordgren added this pull request to the merge queue Nov 6, 2026
Merged via the queue into main with commit 7dc473f Nov 6, 2026
58 checks passed
@HaraldNordgren
HaraldNordgren deleted the doctor-deprecated-skip-removed branch November 6, 2026 16:12
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.

2 participants

⌂ 换网址