Commit Graph

111 Commits

Author SHA1 Message Date
zybo
61f94906ea fix: handle verifyDepsBeforeRun prompt in non-TTY environments (#10903)
* fix: handle verifyDepsBeforeRun prompt in non-TTY environments

In non-interactive environments like CI, verifyDepsBeforeRun: 'prompt' would
silently exit with code 0 even when node_modules were out of sync. This could
cause tests to pass when they should fail.

Now, pnpm throws an error in non-TTY environments, alerting users that they
need to run 'pnpm install' first.

Also handles Ctrl+C gracefully during the prompt - exits cleanly without
showing a stack trace.

Fixes #10889
Fixes #10888

* fix: improve Ctrl+C handling and fix prompt TTY guard

- Replace brittle ERR_USE_AFTER_CLOSE check with generic catch for prompt
  cancellation (enquirer rejects with empty string on Ctrl+C, not that error)
- Fix prompt test to mock isTTY=true since Jest runs in non-TTY environment
- Fix test description "noTTY" → "non-TTY"

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: narrow try/catch to only wrap enquirer.prompt

Avoid catching errors from install() which should propagate normally.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: zubeyralmaho <zubeyralmaho@users.noreply.github.com>
Co-authored-by: Zoltan Kochan <z@kochan.io>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 13:00:12 +01:00
Zoltan Kochan
5d5818e44f style: enforce node: protocol for builtin imports (#10951)
Add n/prefer-node-protocol rule and autofix all bare builtin imports
to use the node: prefix. Simplify the simple-import-sort builtins
pattern to just ^node: since all imports now use the prefix.
2026-03-13 07:59:51 +01:00
Zoltan Kochan
1c8c4e49f5 style: add eslint-plugin-simple-import-sort (#10947)
Add eslint-plugin-simple-import-sort to enforce consistent import ordering:
- Node.js builtins first
- External packages second
- Relative imports last
- Named imports sorted alphabetically within each statement
2026-03-13 02:02:38 +01:00
Zoltan Kochan
62f760ec3d fix(dlx): fix race conditions in parallel dlx calls sharing Global Virtual Store (#10939)
## Summary

Fixes intermittent failures in the `parallel dlx calls of the same package` test, especially on Windows CI. Multiple race conditions were discovered when concurrent `pnpm dlx` processes share the same Global Virtual Store (GVS):

- **Content-verified skip in GVS mode**: When `safeToSkip` is true and a rename fails because the target already exists (ENOTEMPTY/EEXIST/EPERM), verify all files match (inode or content comparison) before skipping. Falls through to `renameOverwriteSync` if content doesn't match.
- **Tolerate EPERM during bin creation on Windows**: `cmd-shim`'s `chmod` can fail with EPERM when another process holds the `.bin` file. Warn instead of crashing.
- **Handle EPERM in DLX cache symlink**: Added EPERM to the list of tolerated errors when creating the DLX cache symlink, as Windows can throw this when another process has the symlink open.

## Test plan

- [x] `parallel dlx calls of the same package` test passes on Windows CI
- [x] Full test suite passes on both Ubuntu and Windows
2026-03-12 21:06:32 +01:00
Zoltan Kochan
3a5bfaa94f chore: update zkochan packages to latest versions (#10930)
Update all packages from zkochan/packages to their latest major versions
and exclude them from minimumReleaseAge requirement. This includes
updating catalog entries, adapting to breaking API changes (default
exports replaced with named exports, sync functions renamed with Sync
suffix), and updating type declarations.
2026-03-11 13:47:46 +01:00
Brandon Cheng
01914345d5 build: enable @typescript-eslint/no-import-type-side-effects (#10630)
* build: enable `@typescript-eslint/no-import-type-side-effects`

* build: disable `@typescript-eslint/consistent-type-imports`

* chore: apply fixes for `no-import-type-side-effects`

pnpm exec eslint "**/src/**/*.ts" "**/test/**/*.ts" --fix
2026-03-08 00:02:48 +01:00
Zoltan Kochan
543c7e4bae feat: use global virtual store for global packages and dlx (#10694)
* feat: use global virtual store for global packages and dlx

* fix(config): remove unnecessary virtualStoreDir override for global installs

When the global virtual store is disabled, the default `node_modules/.pnpm`
path works fine — no need to explicitly override it to `.pnpm`.
2026-03-01 18:03:04 +01:00
Zoltan Kochan
fd511e4676 feat: isolated global packages (#10697)
**TLDR:** Global packages in pnpm v10 are annoying and slow because they all are installed to a single global package. Instead, we will now use a system that is similar to the one used by "pnpm dlx" (aka "pnpx").

Each globally installed package (or group of packages installed together) now gets its own isolated installation directory with its own `package.json`, `node_modules`, and lockfile. This prevents global packages from interfering with each other through peer dependency conflicts or version resolution shifts.

## Changes

- Add `@pnpm/global-packages` shared utilities package for scanning, hashing, and managing isolated global installs
- `pnpm add -g` creates isolated installs in `{pnpmHomeDir}/global/v11/{hash}/`
- `pnpm remove -g` removes the entire installation group containing the package
- `pnpm update -g` re-installs into new isolated directories and swaps symlinks
- `pnpm list -g` scans isolated directories to show installed global packages
- `pnpm outdated -g` checks each isolated installation for outdated dependencies
- `pnpm store prune` cleans up orphaned global installation directories

## Breaking changes

- `pnpm install -g` (no args) is no longer supported — use `pnpm add -g <pkg>`
- `pnpm link <pkg-name>` no longer resolves packages from the global store — only relative or absolute paths are accepted
- `pnpm link --global` is removed — use `pnpm add -g .` to register a local package's bins globally
2026-03-01 15:49:18 +01:00
Ishan Gupta
f8367e88d2 fix(dlx): print help message when no arguments are provided (#10690)
* fix(dlx): print help message on calling pnpm dlx without arguments

Running `pnpm dlx` with no arguments would crash Node.js with a
TypeError as it attempted to call `.indexOf()` on an undefined variable.
This commit adds a guard clause and displays the help message instead
and exits gracefully.

Fixes #10633

* refactor: dlx

---------

Co-authored-by: Zoltan Kochan <z@kochan.io>
2026-02-28 02:02:53 +01:00
Zoltan Kochan
6ea94ea5eb refactor: remove last mentions of use-node-version (#10674) 2026-02-23 08:24:16 +01:00
Ryo Matsukawa
fa5ff08473 fix(dlx): respect minimumReleaseAgeExclude (#10572)
close #10338
2026-02-11 02:32:54 +01:00
Maikel van Dort
f3cd9f7c05 feat: dlx timeout & retry (#10512) 2026-01-27 01:37:26 +01:00
Maikel van Dort
8eee41691c feat: add support for catalogs with dlx (#10434)
* feat: add support for catalogs with dlx

* fix: feedback

* Update .changeset/curly-dryers-jam.md

Co-authored-by: Brandon Cheng <gluxon@users.noreply.github.com>

* Update .changeset/curly-dryers-jam.md

Close #10249

Co-authored-by: Brandon Cheng <gluxon@users.noreply.github.com>

---------

Co-authored-by: Brandon Cheng <gluxon@users.noreply.github.com>
2026-01-26 07:06:36 +01:00
Zoltan Kochan
e3b35b6f37 style: update eslint to v9 (#10474) 2026-01-17 12:01:23 +01:00
Oleg Pustovit
46de860489 fix(run): fail when no packages have script in filtered recursive run (#10437)
* fix(run): fail when no packages have script in filtered recursive run

Previously, `pnpm run -r <script>` and `pnpm run --filter <filter> <script>`
would silently succeed with exit code 0 when no packages had the specified
script, as long as a filter was used. This was inconsistent with the
documentation which states "If none of the packages have the command, the
command fails."

This change makes the command fail with ERR_PNPM_RECURSIVE_RUN_NO_SCRIPT in
all cases where no packages have the script, regardless of whether a filter
is used. The `--if-present` flag can be used to suppress this error.

close #6844
2026-01-16 01:49:24 +01:00
Zoltan Kochan
e4d08f920e fix(exec): preserve user execution cwd (#10445)
close #5759
close #10403
2026-01-12 15:41:17 +01:00
Zoltan Kochan
095f659720 fix: setting requiredScripts in pnpm-workspace.yaml (#10404)
close #10261
2026-01-04 16:43:08 +01:00
Zoltan Kochan
8b4bdf9a83 refactor: replace onlyBuiltDependencies and ignoredBuiltDependencies with allowBuilds (#10401) 2026-01-02 23:21:17 +01:00
Zoltan Kochan
71de2b3f2b feat!: remove use-node-version CLI option and pnpm.executionEnv.nodeVersion manifest field (#10373) 2025-12-27 22:41:53 +01:00
Ryo Matsukawa
10bc39152e feat: add support for npm package trust evidence check via a new trustPolicy setting (#10103)
close #8889

---------

Co-authored-by: Zoltan Kochan <z@kochan.io>
2025-11-09 23:23:58 +01:00
Zoltan Kochan
a43166624e Merge remote-tracking branch 'origin/main' into v11 2025-10-10 10:01:19 +02:00
Zoltan Kochan
2b6100de12 fix: dlx command with minimumReleaseAge set (#10047)
close #9963
2025-10-08 10:56:07 +02:00
Zoltan Kochan
fddd85bf56 fix: dlx should work with minimumeReleaseAge set (#10038)
close #10037
2025-10-02 16:22:14 +02:00
Zoltan Kochan
46a65def8e Merge remote-tracking branch 'origin/main' into v11 2025-08-29 13:30:11 +02:00
Zoltan Kochan
3df6702bcb fix: update load-json-file, write-json-file, write-pkg 2025-08-28 11:37:38 +02:00
Zoltan Kochan
491a84fb26 feat: use ESM instead of commonjs (#9870) 2025-08-25 10:02:00 +02:00
btea
05dd45ea82 perf: replace startsWith with strict equality (#9881) 2025-08-21 14:14:26 +02:00
Zoltan Kochan
facd7656e8 refactor: always use extensions in relative imports (#9878) 2025-08-19 15:25:11 +02:00
btea
9df09dd38e feat: check the engine when excute the create command (#9775)
* feat: check the engine when excute the create command

* chore: test case

* test: update

* fix: update

* fix: update

* refactor: use readProjectManifestOnly to do engine checks on dependencies executed by dlx

---------

Co-authored-by: Zoltan Kochan <z@kochan.io>
2025-08-04 13:38:32 +02:00
Zoltan Kochan
b7d9301e4b fix(exec): wait for the child process to close 2025-07-18 23:24:49 +02:00
Khải
6f7ac0f48b feat: customize supportedArchitectures using CLI (#9745)
close #7510
2025-07-16 00:56:00 +02:00
Abhijeet Singh
61e7b0391a fix: support --help and -h flags for 'pnpm create' command (#9624)
close #8545
2025-06-15 22:17:11 +02:00
Anton Stoychev
b113520edc fix: respect silent reporter when deciding whether to output CI group stdout markers (#9565)
close #9563
2025-05-22 11:32:34 +02:00
modten
36d1448c48 feat: add workspace-concurrency cli option for pack and publish command (#9493)
* refactor: set the default `workspaceConcurrency` to `Math.min(os.availableParallelism(), 4)`

* feat(plugin-commands-publishing): add `workspace-concurrency` cli option for pack and publish

* feat(recursive): add support for `recursive pack`

* feat: get default workspaceConcurrency from config package

* test(config): mock cpus to support Node.js 18
2025-05-09 10:30:21 +02:00
Zoltan Kochan
9362b5fb15 fix: updateConfig in pnpm-workspace.yaml should not be ignored (#9501)
* fix: updateConfig in pnpm-workspace.yaml should not be ignored

close #9500

* fix: reading executionEnv from pnpm-workspace.yaml
2025-05-08 12:24:43 +02:00
Zoltan Kochan
8a9f3a4835 refactor: rename pref to bare specifier (#9445) 2025-04-20 22:58:08 +02:00
Khải
5d7ba81f77 refactor: replace & with interface extends where possible (#9437) 2025-04-18 23:02:25 +02:00
Khải
72cff38486 refactor: pass whole registries to the resolver (#9375) 2025-04-04 01:20:16 +02:00
Zoltan Kochan
c1f09d48fa fix: dlx with --allow-build flag (#9281)
close #9263
2025-03-14 02:27:58 +01:00
Khải
57f989ef45 fix(exec): add missing node-options to recursive run (#9264)
* fix(run): add missing `node-options` to `recursive`

Fixes https://github.com/pnpm/pnpm/issues/9180

* refactor: share code

* refactor: remove unused field
2025-03-11 02:52:59 +01:00
Zoltan Kochan
6a59366248 fix: self-update should not read pnpm settings from current package.json (#9196)
close #9188
close #9183
2025-03-01 13:49:56 +01:00
Zoltan Kochan
0b31bf00d8 fix: dlx should ignore settings from package.json (#9179)
close #9178
close #9174
2025-02-26 12:55:17 +01:00
Khải
e32b1a29e9 feat: update injected packages after run (#9100)
* feat: update injected packages after run (wip)

close #9081

* refactor: rename field

* feat: injectedPackages (wip)

* feat: findInjectedPackages (wip)

* feat: complete implementation

* test: findInjectedPackages

* docs: changeset

* refactor: be lazy

* chore: set `version` to `1000.0.0-0`

* feat: use hardlinks for injected packages

* refactor: just use `.modules.yaml`

* feat: debug logger

* refactor: `modulesDir` is unnecessary

* test: shouldUpdateInjectedFilesAfterRun

* fix(test): remove the test command

* test: updateInjectedPackagesAfterRun

* fix: eslint

* feat: rename config

* perf: diff to reduce fs operations

* perf: load source map only once

* chore(deps): remove unused dependencies

* fix: eslint

* refactor: use `symlink-dir`

* refactor: move type expr to an alias

* refactor: simplify types

* feat: reuse stats from the directory fetcher

* test: directories and symlinks

* feat: sort alphabetic

* test: diffDir

* test: rename a test

* test: remove nesting

* refactor: rename

* feat: remove buggy symlink support

* test: applyPatch

* docs: correct

* docs: fix

* test: extendFilesMap

* docs: remove outdated comment

* docs: remove unneeded comment

* test: fix

* test: more assertions

* test: DirPatcher

* test: more assertions

* test: more assertions

* test: just use `createDir`

* test: multiple patchers

* test: reuse stat results

* docs: consistent grammar

* test: workaround

* test: fix windows

* refactor: remove single-use `makeParent`

* refactor: remove nonsense test

How could I even misunderstand my own code?!

`Patcher.apply()` will never call stat on the files because they have all
been loaded to calculate `Patcher.patch`.

This test is therefore nonsense.

* feat: rename

* feat: rename again

* feat: remove `boolean`

* fix: broken lockfile

* test: use a fixture for testing sync injected deps

* test: refactor syne injected deps test

* test: refactor sync injected deps test

* test: refactor sync injected deps test

* refactor: rename injected deps to syncer

* refactor: change injected deps logger

* docs: update changeset

---------

Co-authored-by: Zoltan Kochan <z@kochan.io>
2025-02-24 02:09:45 +01:00
Zoltan Kochan
c52f55af30 refactor: create exec.pnpm-cli-runner (#9064) 2025-02-08 22:34:19 +01:00
Khải
265946bb6d fix: verify-deps-before-run after install --prod|--no-optional (#9055)
close #9019
2025-02-07 12:36:58 +01:00
Zoltan Kochan
b5ba5350bf feat(dlx): add an option to dlx for providing a list of deps that are allowed to run install scripts (#9026) 2025-02-03 14:46:28 +01:00
Khải
c96eb2b042 fix(lifecycle): skip verify for install hooks (#8957)
close #8954

---------

Co-authored-by: Zoltan Kochan <z@kochan.io>
2025-01-10 23:14:27 +01:00
Zoltan Kochan
7d7c51ecd6 feat!: dlx should use exact versions of packages in the cache key (#8811)
close #8722
2024-11-27 09:04:42 +01:00
Zoltan Kochan
7997ed4ae2 fix: running install automatically before run (#8805) 2024-11-25 14:02:17 +01:00
Zoltan Kochan
39c53852ea fix: some commands should not fail if a different package manager is set in package.json (#8802)
close #7959
2024-11-25 10:13:23 +01:00