zb install used to re-install a package's whole dependency closure at the latest version, so already-installed dependencies got upgraded as a side effect. e.g. zb install nmap with an older openssl@3 installed would upgrade openssl@3. homebrew goes further and also upgrades the dependents of whatever it upgraded, which is how installing nmap ends up upgrading postgres (Homebrew/discussions#57).
install now leaves installed dependencies alone and only installs the missing ones. same for zb upgrade <pkg>, zbx and migrate, since they share the planner.
the tradeoff: a bottle is built against the latest versions of its dependencies. if an installed dependency is too old, the new package fails at runtime with "Library not loaded", and nothing fails at install time. formula json has no minimum versions for dependencies, so the planner can't tell a harmless old dependency from a breaking one.
proposal: let the binaries decide. bottles record the exact libraries they load (e.g. opt/openssl@3/lib/libssl.3.dylib), and we already read those with otool when patching. after a package is unpacked, check that every library it loads under the prefix exists.
- all present: keep the installed dependency
- one missing: that dependency is proven too old. upgrade only that one and say why, naming the missing library
- before upgrading it, run the same check in reverse on the other packages that load from it. if the upgrade would remove a library they load, stop and report instead of cascading
first step is done: zb doctor runs the check on installed kegs and reports broken linkage. report-only, macos only.
todo:
- see how often doctor reports real breakage before install acts on it
- run the check in install and
zb upgrade <pkg>, upgrading only dependencies proven too old - the reverse check, and a clear error when an upgrade would break another package
- linux (elf). DT_NEEDED entries are bare names resolved through rpath, so it needs its own resolver
- say in the install output when an outdated dependency was kept
open questions:
- a missing library catches major version bumps, not a symbol added under the same library name. comparing symbol tables would, but it's slower. worth it?
- interpreted packages (python, node modules) are invisible to this. homebrew's linkage check has the same blind spot
- when an upgrade is needed but would break another package: fail the install, or install and warn?
- an opt-in flag to upgrade dependencies during install, for people who want homebrew's behavior?
zb install <pkg>still upgrades pkg itself when an older version is installed (#331). keep?
Activity
0No activity yet.