Repository navigation
Keep compatible outdated runtime dependencies - #24384
MikeMcQuaid merged 2 commits into
Conversation
|
Important Review skippedReview was skipped as selected files did not have any reviewable changes.
|
| Layer / File(s) | Summary |
|---|---|
Dependency retention and re-expansion Library/Homebrew/formula_installer.rb, Library/Homebrew/test/formula_installer_spec.rb |
The expansion method applies retention to build and runtime dependencies, subject to bottle-build and installed-runtime-dependency conditions. It records installed kegs’ runtime dependencies and excludes kept dependencies when those runtime dependencies require upgrades. Tests cover bottle metadata, dependency caching and compatibility-version cases. |
Priority:
Merge Risk: 
Moderate · previous review 3aa27
-
A source build can keep a dependency installed without options it requires and omit the needed rebuild. Check those options before merging.
Pre-merge checks: 
4
- Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
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.
Comment @coderabbitai help to get the list of available commands.
There was a problem hiding this comment.
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:
28f6ed6a-2587-44bf-bb67-0ac0e0caa6fa
Files selected for processing: 2-
Library/Homebrew/formula_installer.rbLibrary/Homebrew/test/formula_installer_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.
-
There was a problem hiding this comment.
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:
b8999f11-e85b-4ace-a0fd-2bc5bbc2282d
Files selected for processing: 2-
Library/Homebrew/formula_installer.rbLibrary/Homebrew/test/formula_installer_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.
-
- Since Homebrew#24273, building from source keeps an outdated build dependency whose installed `compatibility_version` matches. Runtime dependencies are still always upgraded, so e.g. `brew install nmap` on Intel macOS rebuilds `sqlite` although the installed and current versions both have `compatibility_version 1`. - Keep those too when their dependent is built from source, along with the dependencies they were built against. Upgrade them anyway if this install would incompatibly upgrade one of those. - Pouring or building a bottle still upgrades them as before. - `:no_linkage` still only keeps build dependencies whatever their `compatibility_version`.
- `Build` expands each runtime dependency's current formula and fails in `fixopt` when one of the dependencies it finds isn't installed. Keeping a runtime dependency prunes its dependencies from the install plan, so any that its current formula gained since it was installed would be missing. - Upgrade it instead if any of its current recursive runtime dependencies isn't installed. Build dependencies don't need this because `Build` doesn't expand their dependencies.
3aa27f5 to
f40f6ae
Compare
On my MacBook Air (macOS 12.7.6, Xcode 14.2, so no bottles),
brew install nmapwanted to rebuild four dependencies from source to go from nmap 7.991 to 7.993:sqliteis a runtime dependency ofpython@3.15, and the installed 3.54.0 has the samecompatibility_versionas the current formula. By the Formula Cookbook's definition, that means nothing built against 3.54.0 needs rebuilding when it's upgraded, so upgrading it before buildingpython@3.15gains nothing. Since #24273, source builds already keep an outdated build dependency in this case, but runtime dependencies are still always upgraded.This applies the same rule to runtime dependencies: when the dependent is built from source, keep an outdated runtime dependency whose installed
compatibility_versionmatches, along with the dependencies it was built against. As with build dependencies, it's still upgraded if this install would incompatibly upgrade one of those. Pouring a bottle is unchanged, since #15927 already keeps outdated runtime dependencies that the bottle's tab says are new enough. Building a bottle still upgrades everything.With this branch, the plan drops
sqlite:The other three are still upgraded because their formulae don't set
compatibility_version, so there's nothing to compare.One trade-off: if a new version of a dependent needs something newer from a kept runtime dependency, its build fails, just as it would with a kept build dependency, and
brew upgradeon that dependency fixes it.Changes
FormulaInstaller: when the dependent is built from source, an outdated runtime dependency now takes the same keep path as build dependencies.:no_linkagestill only keeps build dependencies whatever theircompatibility_version.kept_build_dependenciesandkeepable_build_dependenciesare renamed to match.compatibility_versionto be upgraded now expects it to be kept, plus a new example for pouring a bottle. Three specs that stubbedinstall_bottle_for?: falseonly to simplify their setup now stubtrue, since they cover bottle tab metadata and satisfaction caching for runtime dependencies.AI usage
Claude Code (Claude Opus 5.5) helped trace the dependency resolution and audit code and write the change and specs. I verified it by running
brew install nmapon my macOS 12 machine with this branch, which droppedsqlitefrom the plan as shown above.brew style,brew typecheckand theformula_installerspecs pass locally.brew benchmarkresults.brewcommands to reproduce the bug?brew lgtm(style, typechecking and tests) locally?