Files
pnpm/engine/pm/commands/package.json
Zoltan Kochan 9af708a613 feat: add pnpm with <version|current> command (#11275)
## Summary

- **New command `pnpm with <version|current> <args...>`** — runs pnpm at a specific version (or the currently active one) for a single invocation, bypassing the project's `packageManager` and `devEngines.packageManager` pins. Uses the same install mechanism as `pnpm self-update`, caching the downloaded pnpm in the global virtual store for reuse.
- **New config setting `pmOnFail`** — overrides the `onFail` behavior of both `packageManager` and `devEngines.packageManager`. Accepted values: `download`, `error`, `warn`, `ignore`. Readable from CLI flag, env var, `pnpm-workspace.yaml`, or `.npmrc` — useful when version management is handled by an external tool (asdf, mise, Volta, etc.) and the project wants pnpm itself to skip the check.

```
pnpm with current install                    # one-shot, use running pnpm
pnpm with 11.0.0-rc.1 install                # one-shot, use specific version
pnpm install --pm-on-fail=ignore             # direct CLI flag
pnpm install --config.pm-on-fail=ignore      # equivalent via --config.* sugar
pnpm_config_pm_on_fail=ignore pnpm install   # env var
# or in pnpm-workspace.yaml: pmOnFail: ignore
```

## Implementation notes

- Command handler lives in `@pnpm/engine.pm.commands` (next to `self-update` and `setup`).
- `'with'` added to `SPECIALLY_ESCAPED_CMDS` in `cli/parse-cli-args` so args after `<spec>` pass through opaquely like `dlx`/`run`.
- `pnpm with current <cmd> [args]` is rewritten in `pnpm/src/parseCliArgs.ts` to an in-process dispatch — argv is rebuilt in place so any global flags the user put before `with` (e.g. `--dir`, `--filter`) are preserved. `process.env.pnpm_config_pm_on_fail=ignore` is set so the override survives `parseCliArgsLib`'s `-v` / `--help` short-circuits (which discard other parsed options).
- `main.ts` treats `skipPackageManagerCheck: true` as bypassing both the auto-download and the warn/error check (previously only the check). Also skips when `cmd='help'` and the help target is itself a skip-check command, so `pnpm with -h` works in pinned projects without downloading the pinned version first.
- Errors reported to stderr for `with` (aligned with `dlx`/`create`/`sbom`).
- `pmOnFail` wired in `config/reader/src/index.ts`: added to `types`, `Config`, and `pnpmConfigFileKeys`; applied as an override in the `onFail` resolution block.
- The `with <version>` child process sets both `COREPACK_ROOT` (honored by every pnpm release via `isExecutedByCorepack()`) and `pnpm_config_pm_on_fail=ignore` (principled override on new releases that ship the setting). This gives graceful behavior when `pnpm with 9.3.0 install` spawns an older pnpm that predates the new setting.
- Store controller lifecycle in the handler wrapped in `try/finally` to prevent leaks on install errors. Signal-induced child exits return a non-zero exit code so interrupted runs aren't masked as success.
2026-04-16 22:34:34 +02:00

83 lines
2.6 KiB
JSON

{
"name": "@pnpm/engine.pm.commands",
"version": "1100.0.1",
"description": "pnpm commands for self-updating and setting up pnpm",
"keywords": [
"pnpm",
"pnpm11"
],
"license": "MIT",
"funding": "https://opencollective.com/pnpm",
"repository": "https://github.com/pnpm/pnpm/tree/main/engine/pm/commands",
"homepage": "https://github.com/pnpm/pnpm/tree/main/engine/pm/commands#readme",
"bugs": {
"url": "https://github.com/pnpm/pnpm/issues"
},
"type": "module",
"main": "lib/index.js",
"types": "lib/index.d.ts",
"exports": {
".": "./lib/index.js"
},
"files": [
"lib",
"!*.map"
],
"scripts": {
"lint": "eslint \"src/**/*.ts\" \"test/**/*.ts\"",
"prepublishOnly": "pn compile",
"test": "pn compile && pn .test",
"compile": "tsgo --build && pn lint --fix",
".test": "cross-env NODE_OPTIONS=\"$NODE_OPTIONS --experimental-vm-modules --disable-warning=ExperimentalWarning --disable-warning=DEP0169\" jest"
},
"dependencies": {
"@pnpm/bins.linker": "workspace:*",
"@pnpm/building.policy": "workspace:*",
"@pnpm/cli.meta": "workspace:*",
"@pnpm/cli.utils": "workspace:*",
"@pnpm/config.reader": "workspace:*",
"@pnpm/deps.graph-hasher": "workspace:*",
"@pnpm/error": "workspace:*",
"@pnpm/global.commands": "workspace:*",
"@pnpm/global.packages": "workspace:*",
"@pnpm/installing.client": "workspace:*",
"@pnpm/installing.deps-restorer": "workspace:*",
"@pnpm/installing.env-installer": "workspace:*",
"@pnpm/lockfile.types": "workspace:*",
"@pnpm/os.env.path-extender": "catalog:",
"@pnpm/resolving.npm-resolver": "workspace:*",
"@pnpm/shell.path": "workspace:*",
"@pnpm/store.connection-manager": "workspace:*",
"@pnpm/store.controller": "workspace:*",
"@pnpm/types": "workspace:*",
"@pnpm/workspace.project-manifest-reader": "workspace:*",
"cross-spawn": "catalog:",
"path-name": "catalog:",
"ramda": "catalog:",
"render-help": "catalog:",
"semver": "catalog:",
"symlink-dir": "catalog:"
},
"peerDependencies": {
"@pnpm/logger": "catalog:"
},
"devDependencies": {
"@jest/globals": "catalog:",
"@pnpm/constants": "workspace:*",
"@pnpm/engine.pm.commands": "workspace:*",
"@pnpm/error": "workspace:*",
"@pnpm/logger": "workspace:*",
"@pnpm/prepare": "workspace:*",
"@pnpm/testing.mock-agent": "workspace:*",
"@types/cross-spawn": "catalog:",
"@types/ramda": "catalog:",
"@types/semver": "catalog:"
},
"engines": {
"node": ">=22.13"
},
"jest": {
"preset": "@pnpm/jest-config"
}
}