Repository navigation
info: align recursive runtime deps with other deps - #24425
Conversation
- `Recursive Runtime` read the installed keg's receipt even when the formula is outdated, while `Required` lists the latest version's dependencies. `brew info git` said "all installed" while `brew upgrade git` wanted to install three new dependencies. - For outdated formulae, count the latest version's recursive runtime dependencies instead. Up-to-date kegs keep using the receipt, so they load no extra formulae. - Upgrading an outdated formula installs its missing dependencies, so count them as "not installed" rather than marking them with a red ✘.
Findings
|
| Layer / File(s) | Summary |
|---|---|
Dependency selection and status reporting Library/Homebrew/cmd/info.rb, Library/Homebrew/test/cmd/info_spec.rb |
Outdated formulas use current runtime dependencies instead of dependencies recorded in the installed tab. Missing dependencies are reported as “not installed” without a red-X marker. Specs cover outdated formulas and set up non-outdated formulas. |
Merge Risk: 
Low · up to 21e42
-
In uncommon cases, brew info can omit or misrepresent recursive dependency counts. The impact is limited to reporting.
Pre-merge checks: 
4
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.
There was a problem hiding this comment.
Actionable comments posted: 2

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:
3927652a-3be7-47b0-aaf6-6feb297b1c33
Files selected for processing: 2-
Library/Homebrew/cmd/info.rbLibrary/Homebrew/test/cmd/info_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.
-
| @@ -580,15 +581,21 @@ def info_formula(formula, shadowed_by: nil) | |||
| puts "Missing libraries (#{missing_library_names.count}): #{decorated}" | |||
| end | |||
| if tab_runtime_deps.present? | |||
There was a problem hiding this comment.
Calculate the latest dependencies when the receipt is empty.
If an outdated keg has no recorded runtime dependencies but the latest formula adds one, this guard skips the new calculation. The Recursive Runtime count is absent. Select the dependency list before testing whether it is present.
| if tab_runtime_deps.present? | ||
| installed_count = tab_runtime_deps.count do |dep| | ||
| runtime_deps = if outdated | ||
| formula.runtime_dependencies(read_from_tab: false, undeclared: false).map { { "full_name" => it.name } } |
There was a problem hiding this comment.
Distinguish an unavailable dependency graph from an empty one.
If a transitive formula is unavailable, runtime_dependencies prints an error and returns []. This branch then reports Recursive Runtime (0): all installed, although the graph could not be calculated. Preserve the failure state and report the count as unavailable instead. (raw.githubusercontent.com)
|
@MikeMcQuaid You're merging these faster than I mark them as ready for review 😃 Not that I really mind, it was ready to go, but now we have some leftover Coderabbit comments. I can handle them as a follow-up! |
|
@HaraldNordgren I was wondering why you were marking them as draft when they were ready to go, I realise now it was for Coderabbit avoidance 🤦🏻. Sorry! |
|
@HaraldNordgren think ideally just open as non-draft so we get the Coderabbit comments nice and early 🙇🏻. I can ignore them easily enough but does help me when reviewing a bit. |
|
@HaraldNordgren as-per maintainer guide we generally prefer Draft for just "this must not be merged" stuff to stop people accidentally hitting the merge button prematurely. |
|
Fair enough, that makes sense 🤝 |
brew info gitsaid all runtime dependencies were installed, butbrew upgrade gitthen wanted to install three new ones:The other dependency lines list the latest version's dependencies, since
brew infodescribes the formula rather than the installed keg (see #23945), butRecursive Runtimecounted the installed keg's receipt. git 2.56.0_2 now depends oncurl(Homebrew/homebrew-core@5af25e90552), so the receipt of my 2.56.0 keg has neithercurlnor anythingcurlneeds.For an outdated formula,
Recursive Runtimenow counts the latest version's recursive runtime dependencies, in line with the other dependency lines. Up-to-date formulae still read the receipt, which already matches the latest version, so they load no extra formulae.Missing dependencies of an outdated formula are counted as "not installed" without a red ✘, because upgrading installs them.
Requiredstill marks a missing dependency with ✘ when the installed keg needs it too (#23960), but a single count can't make that split without a third group (13 installed ✔, 1 missing ✘, 3 not installed), which is too much for one summary line. A broken install still shows up as ✘ inRequiredfor direct dependencies and inMissing libraries.The existing specs that cover the receipt path now stub
outdated?: false, because their test kegs aren't linked and so count as outdated.There is no slowdown:
brew benchmarkresults.brewcommands to reproduce the bug?brew lgtm(style, typechecking and tests) locally?Claude Code (Claude Opus 5.5) traced where each
brew infodependency line gets its data, wrote the change and its spec and verified them. The new spec fails without the change and passes with it. It ranbrew lgtm, which passes, and thebrew info gitoutput above is from my real install.