Skip to content

fix(cli): stamp package-manager lifecycle env for vp run scripts - #2385

Open
tarikermis wants to merge 5 commits into
voidzero-dev:mainfrom
tarikermis:fix/pm-lifecycle-env
Open

fix(cli): stamp package-manager lifecycle env for vp run scripts#2385
tarikermis wants to merge 5 commits into
voidzero-dev:mainfrom
tarikermis:fix/pm-lifecycle-env

Conversation

@tarikermis

@tarikermis tarikermis commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

Closes #2317

What changed

vp run and vpr now set the session-level package-manager lifecycle variables before vt::Session::init snapshots the environment:

  • npm_execpath
  • npm_config_user_agent
  • INIT_CWD
  • npm_node_execpath / NODE

This mirrors the values pnpm, npm, and Yarn set when they run package scripts themselves.

Why

vp run currently adds node_modules/.bin to PATH and sets VP_RUN=1, but leaves the lifecycle environment empty. Child runners such as npm-run-all2 then fall back to npm run inside pnpm projects, which can fail with EBADDEVENGINES when devEngines.packageManager requires pnpm.

The new helper in vp_pm_cli resolves the JS CLI entry used by the package-manager shims and builds the matching user-agent string. The CLI binding stamps those values before the session starts. Node's real process.version and process.execPath are passed through napi so version-manager symlinks are not resolved to the wrong executable.

Per-script fields such as npm_lifecycle_event, npm_lifecycle_script, npm_package_*, and PNPM_SCRIPT_SRC_DIR are deliberately left out because they cannot be set correctly once per session. Bun is also left unchanged because I could not verify its lifecycle contract.

Verification

The repro pins pnpm in devEngines.packageManager, runs npm-run-all2, and places a failing npm stub on PATH.

  • On main, the lifecycle variables are unset and npm-run-all2 invokes the npm stub.
  • With this change, the variables match pnpm's values and the child scripts run through pnpm successfully.
  • cargo test -p vp_pm_cli: 746 passed.
  • cargo test -p vite-plus-cli: 37 passed.
  • Cargo clippy and format checks pass.
  • pnpm fmt and pnpm lint report no findings in changed files. The repo-wide lint still reports 18 existing errors in untouched docs/.vitepress/* files.

Notes

Windows was not available for a local run, but the JS-entry lookup and pnpm native .exe fallback are covered by platform-aware tests. vp and vpr share the same run() call site, so both use the new environment.

Best Regards, Tarik

@netlify

netlify Bot commented Aug 9, 2026

Copy link
Copy Markdown

Deploy Preview for viteplus-preview ready!

Name Link
🔨 Latest commit 28e556a
🔍 Latest deploy log https://app.netlify.com/projects/viteplus-preview/deploys/6a7b4b8f351a0b00088a6880
😎 Deploy Preview https://deploy-preview-2385--viteplus-preview.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

@fengmk2
fengmk2 requested a review from wan9chi August 10, 2026 06:24
@fengmk2 fengmk2 self-assigned this Aug 10, 2026
@fengmk2

fengmk2 commented Aug 10, 2026

Copy link
Copy Markdown
Member

@tarikermis can you also add a new snapshot test to cover this bug fix?

@tarikermis

Copy link
Copy Markdown
Contributor Author

Good call, on it - adding a snapshot test for the fix now. Best Regards, Tarik

Covers voidzero-dev#2317: snapshot the session-constant
lifecycle env computed for fixture package-manager install layouts
(pnpm/npm/yarn JS CLI entries, native pnpm binary, shim fallback, and
bun's empty stamp) so a regression that drops the stamp or changes
exec-path resolution fails the test.
@fengmk2

fengmk2 commented Aug 10, 2026

Copy link
Copy Markdown
Member

@tarikermis I mean this snapshot tests https://github.com/voidzero-dev/vite-plus/tree/main/crates/vp_cli_snapshots/tests/cli_snapshots .
Sorry I didn't explain clearly.

@tarikermis

Copy link
Copy Markdown
Contributor Author

Ah my bad, got it - adding a CLI snapshot test in vp_cli_snapshots now. Best Regards, Tarik

CLI-level regression test for voidzero-dev#2317: a fixture pnpm project runs a
package.json script via vp run that surfaces npm_execpath,
npm_config_user_agent, and INIT_CWD. Pre-fix all three were undefined in
the script process, so child tooling like npm-run-all fell back to npm.
A fake managed pnpm install under VP_HOME keeps the case offline.
---
source: crates/vp_pm_cli/src/lifecycle_env.rs
expression: "render_lifecycle_stamp(PackageManagerType::Pnpm, \"11.20.0\", &[])"
---

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tarikermis can you revert these snapshots?


if let Some(node_execpath) = &context.node_execpath {
vars.push(("npm_node_execpath", node_execpath.as_os_str().to_os_string()));
vars.push(("NODE", node_execpath.as_os_str().to_os_string()));

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there source documentation for the naming of these environment variables? Or reference code? Need to add code comments to explain them.

@tarikermis

Copy link
Copy Markdown
Contributor Author

Sure - reverting the insta snapshots and adding source comments explaining the env var naming. Best Regards, Tarik

Revert the crate-level insta snapshot tests (the CLI-level
vp_cli_snapshots case covers the bug fix end to end), and document where
each lifecycle env var name and format comes from: npm's set-envs.js and
user-agent definition, pnpm's @pnpm/npm-lifecycle and config userAgent,
verified against pnpm 11.21.0 and npm 10.9.8.
# Conflicts:
#	packages/cli/binding/index.d.cts
#	packages/cli/binding/src/cli/mod.rs
#	packages/cli/binding/src/lib.rs
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

vpr appears not to preserve the pnpm lifecycle environment, causing npm-run-all2 to fall back to npm

2 participants