fix(pm): reconcile install-node runtime deps in outdated check#2812
Merged
fix(pm): reconcile install-node runtime deps in outdated check#2812
Conversation
`Context::build_deps` injects synthetic `node-bin-*` optionalDependencies into the root lock entry from `engines.install-node`, but `is_pkg_lock_outdated` only compared against package.json (which never carries them). Any project using `install-node` was judged outdated on every install, triggering an endless re-resolve loop. Mirror the same injection at comparison time via `root_optional_with_runtime`. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
Code Review
This pull request modifies the lockfile validation logic to correctly handle synthetic node-bin-* dependencies injected via the engines.install-node configuration. By introducing the root_optional_with_runtime helper, the system now merges these dependencies into the root package's optional dependencies before comparison, ensuring that projects using install-node are not incorrectly flagged as outdated. Feedback suggests exploring more efficient ways to merge these dependencies to avoid cloning the optional_dependencies map.
Assert `package-lock.json` inode stays constant across two consecutive `utoo install` runs on an `engines.install-node` project. `save_package_lock` writes tmp + rename, so any rewrite changes the inode — identical inode is the strongest signal that the cached lock was reused. Also pattern-match the 'package-lock.json is outdated' tracing warning to catch subtler regressions. Regression guard for the `is_pkg_lock_outdated` / `Context::build_deps` optionalDependencies asymmetry fixed in the previous commit. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
fireairforce
approved these changes
Apr 20, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Context::build_depsfolds syntheticnode-bin-*optionalDependencies into the root lock entry fromengines.install-node, butis_pkg_lock_outdatedonly compared againstpackage.json(which never carries them). Any project usinginstall-nodewas judged outdated on every install → endless re-resolve loop.root_optional_with_runtimehelper incrates/pm/src/helper/lock.rs.test_is_pkg_lock_outdated_install_node_in_syncto pin the behavior.Test plan
cargo test -p utoo-pm helper::lock::tests— 13/13 pass, including the new casecargo fmt+cargo clippy -p utoo-pm --all-targets -- -D warnings --no-depscleanut installtwice on a project with"engines": { "install-node": "16" }— second invocation should load the cached lock instead of re-resolving🤖 Generated with Claude Code