Commit Graph

106 Commits

Author SHA1 Message Date
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
Zoltan Kochan
4dd27a894f feat: add an option to install dependencies before running scripts (#8781) 2024-11-25 09:02:12 +01:00
Zoltan Kochan
e200728e0b fix: parameters should be passed down to the executed script when running pnpm t (#8776) 2024-11-17 22:55:04 +01:00
btea
ef7c10221c fix: pnpm exec should specify command (#8774) 2024-11-17 17:07:32 +01:00
Khải
19d5b51558 feat(exec): check dependencies before running scripts (#8645)
* refactor: break a long line into multiple lines

* feat: cache that tracks workspace structures

* feat: handle hash collisions

* docs(changeset): packages-list-cache

* feat(packages-list-cache): store mtime

* fix(packages-list-cache): JSON5 and YAML manifests

* feat(packages-list-cache): add catalogs

* style: sort fields alphabetically

* fix: actually fix it

* lint: fix

* lint: fix

* test(packages-list-cache): test

* feat(exec): check deps before run scripts

Resolves https://github.com/pnpm/pnpm/issues/8585

* style: fix eslint

* feat: use a single lastValidatedTimestamp

* refactor: rearrange

* perf: don't do pointless comparisons

* perf: optimize non-workspace

* perf: optimize sharedWorkspaceLockfile=false

* perf: remove unnecessary fs reads

* refactor: statManifestFile

* perf: skip comparing manifest to lockfile by stats

* feat: add wantedLockfileDir to error message

* refactor: shorten a function name

* refactor: rename a function

* docs: improve wordings

* feat: export `linkedPackagesAreUpToDate`

* feat: make sure lockfile specs satisfy manifest (wip)

* docs: todo

* fix: projectId

* feat: skip install-related scripts

* fix: type errors

* refactor: use tagged union

* refactor: remove unnecessary type expression

* docs: todo

* feat: add linkedPackagesAreUpToDate (wip)

* refactor: rearrange fields

* refactor: remove a temporary variable

* feat: export `getWorkspacePackagesByDirectory`

* feat: make workspacePackages optional

* feat: complete `linkedPackagesAreUpToDate`

* docs: remove unapplicable todo

* docs: explain why check is skipped

* feat: load allProjects and try again

* refactor: remove unused dependencies

* refactor: remove commented-out code

* refactor: replace `else if` with `return`

* feat: use-case without workspace manifest

* perf: skip unnecessary work

* feat: add a guard

* fix: eslint

* refactor: move code to new package

* refactor: sort dependencies

* test: outline

* refactor: extract assertLockfilesEqual for testing

* test: skip failing tests for now

* fix: eslint

* test: assertLockfilesEqual

* refactor: extract statManifestFile for testing

* test: todo

* test: statManifestFile

* test: shouldRunCheck

* refactor: rename a test file

* test: add

* test: todo

* docs: remove a commented-out code

* test: create groups

* test: todo

* test: add

* test: platform agnostic

* test: remove unnecessary scripts

* test: use `assert.strictEqual` instead

* test: export bin locations

* test: nested `pnpm run`

* test: todo

* test: add `cwd` option to `execPnpmSync`

* test: add

* fix: recursive

* test: add

* test: fix package names

* fix: catalogs comparison

* test: add

* refactor: just use ramda filter

* test: add

* test: mutations

* fix: package.json

* fix: jest

* feat(packages-list): debug logs

* feat: add debug messages

* fix: eslint

* test: check debug messages in other case

* docs: add next step

* test: mtime updates without modification

* docs: correct test description

* test: mtime changes

* test: check should be skipped

* docs: remove fulfilled todos

* fix: remove `.only`

* docs: todo

* docs: correct test names

* test: workspace structure changes

* test: packages list cache

* test: add

* refactor: divide a test file into 2

* docs: consistent wordings

* refactor: clearer error messages

* fix: ignore check in recursive nested scripts

* test: no dependencies

* test: print error messages on failures

* test: improve stdout/stderr in error messages

* docs: consistent wordings

* docs: clarify what did what

* test: nested script

* docs: consistent test descriptions

* docs(changeset): correction

* fix: save catalogs to packages list

* test: catalogs

* test: fix

* test: fix windows

* refactor: remove unused option field

* refactor: prefer `!= null`

* feat: use `node_modules` instead

* refactor: rename a package

* refactor: apply suggestion

* refactor: remove workspaceDir

* refactor: move `shouldRunCheck` to `exec`

* feat: rename config key

* refactor: rename a test dir

* refactor: correct grammar

* refactor: make loadPackagesList sync

* test: multiple lockfiles

* feat: prevent deletion of `node_modules`

* feat: skip checking on filtered install

* fix: accidentally dropping catalogs

* refactor: remove unnecessary `Promise.all`

* refactor: use `virtualStoreDir` from config

* refactor: split `opts` into `ctx` and `opts`

* test: fix

* style: fix eslint

* test: fix windows

* feat(exec): add `verifyDepsBeforeRun` to `exec`

* refactor: sync stat

* feat: stop ignoring filtered install

* test: filtered install

* refactor: rearrange imports

* feat: rename "packages list" to "workspace state"

* test: fix

* fix: workspace state on failed install
2024-11-15 01:01:09 +01:00
Jonathan Hefner
8c3de19fc1 fix(dlx): ENOENT when symlink=false (#8732) (#8733)
Prior to this commit, if `symlink` was set to `false` (such as in an RC
file), `dlx` would throw `ENOENT` because it expected the
`node_modules/the-package` symlink to exist:

  ```console
  $ pnpm config get symlink
  false

  $ rm -rf ~/.cache/pnpm/

  $ pnpm dlx the-package
  Packages: +1
  +
  Progress: resolved 1, reused 1, downloaded 0, added 1, done
   ENOENT  ENOENT: no such file or directory, open '/home/${USER}/.cache/pnpm/dlx/.../
                                                    node_modules/the-package/package.json'
  ```

This commit filters the `symlink` option before installing the package,
allowing the symlink to be created, preventing the error.

Fixes #8732.
2024-11-06 10:43:35 +01:00