Review follow-up on F-005. The basename-collision check only ran in ResolverState::into_plan, which covers fresh resolves and UpdateOne — but UpdatePolicy::Frozen returns Lockfile::to_resolve_plan(...) directly, building a ResolvePlan without the check. A pre-existing or hand-edited lockfile containing two distinct packages that share an install basename (e.g. owner/magit and other/magit) would produce one plan and install both to <root>/<basename>, silently colliding. Make find_basename_collision (and its message helper) pub(crate) and apply it in Lockfile::to_resolve_plan too — up front, before any fetch, so a colliding lockfile fails fast via a new LockfileError::BasenameCollision (surfaced through the Frozen path as ResolveError::Lockfile). Both plan-construction sites now reject; to_resolve_plan is pub and has direct callers, so guarding the method (not just the resolve_with_policy branch) covers them all. New unit test builds a two-entry colliding lockfile and asserts to_resolve_plan rejects it before touching the fetcher. Validated: fmt clean; clippy --all-targets clean under both Lua flavors; 1437 lib tests pass (incl. the new frozen-path test). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014TXbAwk27agwhrNNrhLi2U |
||
|---|---|---|
| .. | ||
| address.rs | ||
| fetcher.rs | ||
| installer.rs | ||
| loader.rs | ||
| lockfile.rs | ||
| manifest.rs | ||
| mod.rs | ||
| resolver.rs | ||