pnpm 12.4.1 → 12.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +88 -0
- package/dist/node_modules/.pnpm-workspace-state-v1.json +5 -7
- package/dist/node_modules/get-pnpm/lib/platformPackageName.js +21 -6
- package/dist/node_modules/get-pnpm/package.json +1 -1
- package/package.json +15 -15
- package/pn +35 -1
- package/pnpm +13 -3
- package/pnpx +35 -1
- package/pnx +35 -1
- package/dist/node_modules/.package-map.json +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,93 @@
|
|
|
1
1
|
# pnpm
|
|
2
2
|
|
|
3
|
+
## 12.4.2
|
|
4
|
+
|
|
5
|
+
pnpm 12.4.2 includes security fixes for executable shims and GitHub Actions links, more reliable installs, faster peer dependency checks in workspaces, and Python lockfiles that work across compatible targets.
|
|
6
|
+
|
|
7
|
+
### Patch Changes
|
|
8
|
+
|
|
9
|
+
#### Security
|
|
10
|
+
|
|
11
|
+
- Dependency executables can no longer take over another package's POSIX bin shim through its shell helpers. Reinstall dependencies to replace existing shims [#14837](https://github.com/pnpm/pnpm/issues/14837).
|
|
12
|
+
|
|
13
|
+
On Cygwin, MSYS2, and WSL, shims still use `PATH` for Windows path conversion, so dependency executables can still redirect them there.
|
|
14
|
+
|
|
15
|
+
- GitHub Actions homepage links no longer expose server credentials. GitHub server URLs now require HTTPS, with HTTP allowed only for loopback hosts.
|
|
16
|
+
|
|
17
|
+
#### Installing packages
|
|
18
|
+
|
|
19
|
+
- pnpm no longer crashes at startup on FreeBSD and other Unix-like platforms. Platforms other than Windows and macOS use `~/.local/share/pnpm/store` by default [#14859](https://github.com/pnpm/pnpm/issues/14859).
|
|
20
|
+
|
|
21
|
+
- `pnpm install` on Windows no longer fails with `ERR_PNPM_PACKAGE_MANAGER_REMOVE_MODULES_DIR` when clearing `node_modules` containing linked dependencies, such as when changing `nodeLinker` [#14790](https://github.com/pnpm/pnpm/issues/14790).
|
|
22
|
+
|
|
23
|
+
- `pnpm install <pkg>` now accepts `--prod` and `--dev`, including `--prod=false` [#14868](https://github.com/pnpm/pnpm/issues/14868).
|
|
24
|
+
|
|
25
|
+
- `pnpm install` and `pnpm update` now honor `--ignore-workspace` in nested projects excluded from the surrounding workspace. The flag also skips that workspace's settings during the `packageManager` check [#14809](https://github.com/pnpm/pnpm/issues/14809).
|
|
26
|
+
|
|
27
|
+
- `pnpm install` on macOS no longer reuses stale files for `file:` tarball or git-hosted tarball dependencies.
|
|
28
|
+
|
|
29
|
+
- `pnpm install` in a single-project directory now detects `package.json` edits made while the previous install was finishing [#14890](https://github.com/pnpm/pnpm/issues/14890).
|
|
30
|
+
|
|
31
|
+
- `pnpm install --frozen-lockfile` now removes packages no longer reachable from any project in `pnpm-lock.yaml`. This also prevents repeated lifecycle script execution and unnecessary installs before `pnpm run` and `pnpm exec` with `verifyDepsBeforeRun` [#14891](https://github.com/pnpm/pnpm/issues/14891).
|
|
32
|
+
|
|
33
|
+
#### Resolving and updating dependencies
|
|
34
|
+
|
|
35
|
+
- Node.js runtime resolution now reports network failures from unofficial-builds.nodejs.org. These failures previously omitted musl builds from `pnpm-lock.yaml`, making its contents depend on network access [#14813](https://github.com/pnpm/pnpm/issues/14813).
|
|
36
|
+
|
|
37
|
+
- `pnpm install` now rejects invalid `peerDependencies` specifiers with `ERR_PNPM_INVALID_PEER_DEPENDENCY_SPECIFICATION`. A value such as `"foo": "foo@1.0.0"` previously created a broken directory link [#14791](https://github.com/pnpm/pnpm/issues/14791).
|
|
38
|
+
|
|
39
|
+
- `pnpm deploy` now writes plain registry versions in the deployed `package.json`, without peer dependency suffixes. The lockfile retains peer bindings, and npm aliases retain their target package names [#14873](https://github.com/pnpm/pnpm/issues/14873).
|
|
40
|
+
|
|
41
|
+
- `pnpm add <git repository>` now names repositories without a `package.json` as `@owner/repo`, allowing dependencies on equally named repositories from different owners [#14870](https://github.com/pnpm/pnpm/issues/14870).
|
|
42
|
+
|
|
43
|
+
- Peer dependency resolution now deduplicates packages whose child dependency resolves an optional peer in only some workspace projects, such as `next` with `styled-jsx`'s optional `babel-plugin-macros` peer [#14800](https://github.com/pnpm/pnpm/issues/14800).
|
|
44
|
+
|
|
45
|
+
- `pnpm update` now settles the lockfile in one run when an upgrade removes the package providing an optional peer dependency [#14895](https://github.com/pnpm/pnpm/issues/14895).
|
|
46
|
+
|
|
47
|
+
- `pnpm update --no-save` now preserves override-applied specifiers for dependencies it is not updating, preventing subsequent frozen installs from failing with `ERR_PNPM_OUTDATED_LOCKFILE` [#14836](https://github.com/pnpm/pnpm/issues/14836).
|
|
48
|
+
|
|
49
|
+
- `pnpm update --no-save` now succeeds under `minimumReleaseAgeStrict` when every resolved version is old enough [#14835](https://github.com/pnpm/pnpm/issues/14835).
|
|
50
|
+
|
|
51
|
+
#### Performance
|
|
52
|
+
|
|
53
|
+
- Workspace installs and `pnpm peers check` are faster when projects depend on each other, fixing a slowdown introduced in 12.3.0. Unmet peer dependencies of workspace packages are now reported only under projects that link them directly [#14906](https://github.com/pnpm/pnpm/issues/14906).
|
|
54
|
+
|
|
55
|
+
- Hoisted installs use less memory when packages are cached. Frozen-lockfile hoisted installs on macOS are also faster when reusable package directories are cached.
|
|
56
|
+
|
|
57
|
+
#### Python projects
|
|
58
|
+
|
|
59
|
+
- `pnpm install --frozen-lockfile` now reuses `pylock.toml` across compatible Python targets, including after kernel updates. Reuse requires unchanged requirements, index, and `requires-python`, compatible wheels, and a locked dependency graph matching the target's markers [#14843](https://github.com/pnpm/pnpm/issues/14843).
|
|
60
|
+
|
|
61
|
+
The lockfile's `environments` marker now includes only the interpreter version and marker variables used by the dependency graph. Without `--frozen-lockfile`, pnpm warns and resolves again when the locked graph no longer matches the target.
|
|
62
|
+
|
|
63
|
+
- Python resolution no longer fails on malformed `Requires-Python` values, such as the trailing comma in `openpyxl` 3.0.x. pnpm treats these releases as declaring no interpreter range [#14910](https://github.com/pnpm/pnpm/issues/14910).
|
|
64
|
+
|
|
65
|
+
- `pnpm add pypi:...` now rejects unsupported `--save-prefix` values before editing the manifest or resolving dependencies.
|
|
66
|
+
|
|
67
|
+
#### Workspaces and scripts
|
|
68
|
+
|
|
69
|
+
- Scripts listed in `syncInjectedDepsAfterScripts` no longer fail with `ERR_PNPM_INJECTED_DEPS_SYNC_READ_DIR` when the lockfile contains an injected package copy that no project depends on.
|
|
70
|
+
|
|
71
|
+
- `shellEmulator` now expands `${VAR}`, `${VAR:-default}`, and `${VAR:+alternative}` in scripts [#14814](https://github.com/pnpm/pnpm/issues/14814).
|
|
72
|
+
|
|
73
|
+
- Cargo and Python project discovery now honors `!` exclusions in `pnpm-workspace.yaml` `packages`, skipping both parsing and generated source configuration for excluded projects [#14844](https://github.com/pnpm/pnpm/issues/14844).
|
|
74
|
+
|
|
75
|
+
- `pnpm --filter "./packages/{app,lib}"` now selects either alternative. Brace alternatives can nest, span path separators, and combine with other wildcards.
|
|
76
|
+
|
|
77
|
+
- GitHub Actions updates now stop if an action reference changes during version resolution, and preserve unrelated workflow edits.
|
|
78
|
+
|
|
79
|
+
#### CLI and output
|
|
80
|
+
|
|
81
|
+
- `pn`, `pnpx`, and `pnx` now run the pnpm installed alongside them, even when that directory is absent from `PATH` or another pnpm comes first [#14803](https://github.com/pnpm/pnpm/issues/14803).
|
|
82
|
+
|
|
83
|
+
- `pnpm --version` now reports failures to install or record a project's pinned pnpm, then prints the running CLI's version. It also honors `--store-dir` and `--store` [#14831](https://github.com/pnpm/pnpm/issues/14831).
|
|
84
|
+
|
|
85
|
+
- `pnpm self-update` no longer reinstalls the active version when it was installed by the standalone installation script [#14823](https://github.com/pnpm/pnpm/issues/14823).
|
|
86
|
+
|
|
87
|
+
- `pnpm t` and `pnpm tst` work again as aliases for `pnpm test`.
|
|
88
|
+
|
|
89
|
+
- `pnpm sbom` now emits valid repository URLs in CycloneDX `externalReferences[].url` and SPDX `homepage`. Shorthands such as `vercel/ms` become `git+https` URLs, embedded credentials are removed, and invalid repository values are omitted [#14773](https://github.com/pnpm/pnpm/issues/14773).
|
|
90
|
+
|
|
3
91
|
## 12.4.1
|
|
4
92
|
|
|
5
93
|
pnpm 12.4.1 fixes installs that failed on filesystems refusing hard links or clones, on Android, and under `nodeLinker: hoisted`. Repeat installs are faster.
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
|
-
"lastValidatedTimestamp":
|
|
2
|
+
"lastValidatedTimestamp": 1789466800429,
|
|
3
3
|
"projects": {
|
|
4
4
|
"/home/runner/_work/pnpm/pnpm/pnpm/npm/pnpm/temp-deploy": {
|
|
5
5
|
"name": "pacquet",
|
|
6
|
-
"version": "12.4.
|
|
6
|
+
"version": "12.4.2"
|
|
7
7
|
}
|
|
8
8
|
},
|
|
9
9
|
"pnpmfiles": [],
|
|
@@ -94,7 +94,6 @@
|
|
|
94
94
|
"@yarnpkg/lockfile": "^1.1.0",
|
|
95
95
|
"@yarnpkg/nm": "4.1.1",
|
|
96
96
|
"@yarnpkg/pnp": "^4.1.7",
|
|
97
|
-
"@zkochan/cmd-shim": "^9.0.7",
|
|
98
97
|
"@zkochan/retry": "^0.2.0",
|
|
99
98
|
"@zkochan/rimraf": "^4.0.0",
|
|
100
99
|
"@zkochan/table": "^2.0.1",
|
|
@@ -142,7 +141,7 @@
|
|
|
142
141
|
"fast-glob": "^3.3.3",
|
|
143
142
|
"fs-extra": "^11.4.0",
|
|
144
143
|
"fuse-native": "^2.2.6",
|
|
145
|
-
"get-pnpm": "^0.0.
|
|
144
|
+
"get-pnpm": "^0.0.4",
|
|
146
145
|
"get-port": "^7.2.0",
|
|
147
146
|
"ghooks": "2.0.4",
|
|
148
147
|
"graceful-fs": "^4.2.11",
|
|
@@ -172,6 +171,7 @@
|
|
|
172
171
|
"lru-cache": "^11.5.2",
|
|
173
172
|
"make-empty-dir": "^4.0.0",
|
|
174
173
|
"mdast-util-to-string": "^4.0.0",
|
|
174
|
+
"memfs": "^3.5.3",
|
|
175
175
|
"memoize": "^11.0.0",
|
|
176
176
|
"micromatch": "^4.0.8",
|
|
177
177
|
"msgpackr": "2.1.0",
|
|
@@ -311,15 +311,13 @@
|
|
|
311
311
|
"write-ini-file",
|
|
312
312
|
"write-json5-file",
|
|
313
313
|
"write-yaml-file",
|
|
314
|
-
"http-proxy-middleware@3.0.7"
|
|
315
|
-
"get-pnpm@0.0.3"
|
|
314
|
+
"http-proxy-middleware@3.0.7"
|
|
316
315
|
],
|
|
317
316
|
"minimumReleaseAgeIgnoreMissingTime": true,
|
|
318
317
|
"minimumReleaseAgeStrict": true,
|
|
319
318
|
"nodeLinker": "hoisted",
|
|
320
319
|
"optional": true,
|
|
321
320
|
"patchedDependencies": {
|
|
322
|
-
"adm-zip@0.6.0": "../../../../__patches__/adm-zip@0.6.0.patch",
|
|
323
321
|
"graceful-fs@4.2.11": "../../../../__patches__/graceful-fs@4.2.11.patch",
|
|
324
322
|
"normalize-registry-url@2.0.1": "../../../../__patches__/normalize-registry-url@2.0.1.patch"
|
|
325
323
|
},
|
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
const V12_ONLY_TARGETS = new Set([
|
|
2
|
+
'android-arm64',
|
|
3
|
+
'android-x64',
|
|
4
|
+
'freebsd-x64',
|
|
5
|
+
'linux-ppc64',
|
|
6
|
+
'linux-riscv64',
|
|
7
|
+
'linux-s390x',
|
|
8
|
+
]);
|
|
1
9
|
/**
|
|
2
10
|
* Name of the npm package that carries the pnpm executable for `target`.
|
|
3
11
|
*
|
|
@@ -6,15 +14,22 @@
|
|
|
6
14
|
* publishes `@pnpm/exe.<process.platform>-<arch>[-musl]`, while v11 and older
|
|
7
15
|
* publish `@pnpm/<macos|win|linux|linuxstatic>-<arch>`.
|
|
8
16
|
*
|
|
9
|
-
* @throws if pnpm publishes no binary for the host —
|
|
10
|
-
*
|
|
17
|
+
* @throws if pnpm publishes no binary for the host — because the host is not
|
|
18
|
+
* built for at all, because the binary arrived in v12 and an older major was
|
|
19
|
+
* asked for, or because of the v11-only Intel macOS gap.
|
|
11
20
|
*/
|
|
12
21
|
export function platformPackageName({ major, platform, arch, musl }) {
|
|
13
|
-
|
|
14
|
-
|
|
22
|
+
const target = `${platform}-${arch}`;
|
|
23
|
+
if (V12_ONLY_TARGETS.has(target)) {
|
|
24
|
+
if (major >= 12)
|
|
25
|
+
return `@pnpm/exe.${target}`;
|
|
26
|
+
throw new Error(`pnpm v${major} does not provide a pre-built binary for ${target}. pnpm 12 does:
|
|
27
|
+
|
|
28
|
+
npx get-pnpm 12`);
|
|
15
29
|
}
|
|
16
|
-
if (
|
|
17
|
-
|
|
30
|
+
if ((arch !== 'x64' && arch !== 'arm64') ||
|
|
31
|
+
(platform !== 'darwin' && platform !== 'linux' && platform !== 'win32')) {
|
|
32
|
+
throw new Error(`Sorry! pnpm does not provide a pre-built binary for ${target}.`);
|
|
18
33
|
}
|
|
19
34
|
if (platform === 'darwin' && arch === 'x64' && major === 11) {
|
|
20
35
|
throw new Error(`pnpm v11 does not provide a working binary for Intel macOS (darwin-x64) due to an upstream Node.js SEA bug.
|
package/package.json
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"./dist/node_modules/node-gyp/gyp/gyp"
|
|
10
10
|
]
|
|
11
11
|
},
|
|
12
|
-
"version": "12.4.
|
|
12
|
+
"version": "12.4.2",
|
|
13
13
|
"description": "Fast, disk space efficient package manager",
|
|
14
14
|
"keywords": [
|
|
15
15
|
"pnpm",
|
|
@@ -46,20 +46,20 @@
|
|
|
46
46
|
"THIRD-PARTY-NOTICES.md"
|
|
47
47
|
],
|
|
48
48
|
"optionalDependencies": {
|
|
49
|
-
"@pnpm/exe.win32-x64": "12.4.
|
|
50
|
-
"@pnpm/exe.win32-arm64": "12.4.
|
|
51
|
-
"@pnpm/exe.darwin-x64": "12.4.
|
|
52
|
-
"@pnpm/exe.darwin-arm64": "12.4.
|
|
53
|
-
"@pnpm/exe.linux-x64": "12.4.
|
|
54
|
-
"@pnpm/exe.linux-arm64": "12.4.
|
|
55
|
-
"@pnpm/exe.linux-riscv64": "12.4.
|
|
56
|
-
"@pnpm/exe.linux-ppc64": "12.4.
|
|
57
|
-
"@pnpm/exe.linux-s390x": "12.4.
|
|
58
|
-
"@pnpm/exe.linux-x64-musl": "12.4.
|
|
59
|
-
"@pnpm/exe.linux-arm64-musl": "12.4.
|
|
60
|
-
"@pnpm/exe.freebsd-x64": "12.4.
|
|
61
|
-
"@pnpm/exe.android-arm64": "12.4.
|
|
62
|
-
"@pnpm/exe.android-x64": "12.4.
|
|
49
|
+
"@pnpm/exe.win32-x64": "12.4.2",
|
|
50
|
+
"@pnpm/exe.win32-arm64": "12.4.2",
|
|
51
|
+
"@pnpm/exe.darwin-x64": "12.4.2",
|
|
52
|
+
"@pnpm/exe.darwin-arm64": "12.4.2",
|
|
53
|
+
"@pnpm/exe.linux-x64": "12.4.2",
|
|
54
|
+
"@pnpm/exe.linux-arm64": "12.4.2",
|
|
55
|
+
"@pnpm/exe.linux-riscv64": "12.4.2",
|
|
56
|
+
"@pnpm/exe.linux-ppc64": "12.4.2",
|
|
57
|
+
"@pnpm/exe.linux-s390x": "12.4.2",
|
|
58
|
+
"@pnpm/exe.linux-x64-musl": "12.4.2",
|
|
59
|
+
"@pnpm/exe.linux-arm64-musl": "12.4.2",
|
|
60
|
+
"@pnpm/exe.freebsd-x64": "12.4.2",
|
|
61
|
+
"@pnpm/exe.android-arm64": "12.4.2",
|
|
62
|
+
"@pnpm/exe.android-x64": "12.4.2"
|
|
63
63
|
},
|
|
64
64
|
"scripts": {
|
|
65
65
|
"preinstall": "node install.js",
|
package/pn
CHANGED
|
@@ -1,2 +1,36 @@
|
|
|
1
1
|
#!/bin/sh
|
|
2
|
-
|
|
2
|
+
# `pn` is `pnpm`. The pnpm it hands over to is the one installed alongside it,
|
|
3
|
+
# found relative to this file: a `PATH` lookup would run whatever other pnpm
|
|
4
|
+
# comes first there, and would find nothing at all when the directory holding
|
|
5
|
+
# these bins is not on `PATH`.
|
|
6
|
+
#
|
|
7
|
+
# $0 is whatever shim or symlink `pn` was launched through, so walk to the file
|
|
8
|
+
# itself first. The hop cap matches the kernel's ELOOP limit, so a cycle cannot
|
|
9
|
+
# hang the script. Directories come from `${self%/*}` and `readlink` runs through
|
|
10
|
+
# `command -p`, so the caller's `PATH` decides nothing here.
|
|
11
|
+
self=$0
|
|
12
|
+
# `${self%/*}` needs a slash to strip. A bare name came from a `PATH` lookup and
|
|
13
|
+
# stands for a file in the current directory.
|
|
14
|
+
case $self in
|
|
15
|
+
*/*) ;;
|
|
16
|
+
*) self=./$self ;;
|
|
17
|
+
esac
|
|
18
|
+
hops=0
|
|
19
|
+
while [ -L "$self" ] && [ "$hops" -lt 40 ]; do
|
|
20
|
+
hops=$((hops + 1))
|
|
21
|
+
link=$(command -p readlink "$self")
|
|
22
|
+
case $link in
|
|
23
|
+
/*) self=$link ;;
|
|
24
|
+
*) self=${self%/*}/$link ;;
|
|
25
|
+
esac
|
|
26
|
+
done
|
|
27
|
+
# The walk has to end at a regular file. Running out of hops leaves $self a
|
|
28
|
+
# symlink; a chain that changed under us can leave it dangling or a directory, and
|
|
29
|
+
# a failed readlink leaves a trailing slash. Each case would take `pnpm` from the
|
|
30
|
+
# wrong directory — the substitution this script exists to prevent.
|
|
31
|
+
if [ -L "$self" ] || [ ! -f "$self" ]; then
|
|
32
|
+
echo "pn: could not resolve $0 to a regular file within 40 symlink hops." >&2
|
|
33
|
+
exit 1
|
|
34
|
+
fi
|
|
35
|
+
|
|
36
|
+
exec "${self%/*}/pnpm" "$@"
|
package/pnpm
CHANGED
|
@@ -24,15 +24,25 @@ fi
|
|
|
24
24
|
# $0 is whatever shim or symlink pnpm was launched through; ./bin/pnpm.mjs is
|
|
25
25
|
# found relative to this file. The hop cap matches the kernel's ELOOP limit, so
|
|
26
26
|
# a cycle cannot hang the script.
|
|
27
|
+
#
|
|
28
|
+
# `readlink` runs through `command -p`, which searches the system default path,
|
|
29
|
+
# and directories come from `${self%/*}`, which runs nothing at all. The caller's
|
|
30
|
+
# PATH therefore decides only which `node` runs, which is what it is for.
|
|
27
31
|
self=$0
|
|
32
|
+
# `${self%/*}` needs a slash to strip. A bare name came from a PATH lookup and
|
|
33
|
+
# stands for a file in the current directory.
|
|
34
|
+
case $self in
|
|
35
|
+
*/*) ;;
|
|
36
|
+
*) self=./$self ;;
|
|
37
|
+
esac
|
|
28
38
|
hops=0
|
|
29
39
|
while [ -L "$self" ] && [ "$hops" -lt 40 ]; do
|
|
30
40
|
hops=$((hops + 1))
|
|
31
|
-
link=$(readlink "$self")
|
|
41
|
+
link=$(command -p readlink "$self")
|
|
32
42
|
case $link in
|
|
33
43
|
/*) self=$link ;;
|
|
34
|
-
*) self=$
|
|
44
|
+
*) self=${self%/*}/$link ;;
|
|
35
45
|
esac
|
|
36
46
|
done
|
|
37
47
|
|
|
38
|
-
exec node "$
|
|
48
|
+
exec node "${self%/*}/bin/pnpm.mjs" "$@"
|
package/pnpx
CHANGED
|
@@ -1,2 +1,36 @@
|
|
|
1
1
|
#!/bin/sh
|
|
2
|
-
|
|
2
|
+
# `pnpx` is `pnpm dlx`. The pnpm it hands over to is the one installed alongside
|
|
3
|
+
# it, found relative to this file: a `PATH` lookup would run whatever other pnpm
|
|
4
|
+
# comes first there, and would find nothing at all when the directory holding
|
|
5
|
+
# these bins is not on `PATH`.
|
|
6
|
+
#
|
|
7
|
+
# $0 is whatever shim or symlink `pnpx` was launched through, so walk to the file
|
|
8
|
+
# itself first. The hop cap matches the kernel's ELOOP limit, so a cycle cannot
|
|
9
|
+
# hang the script. Directories come from `${self%/*}` and `readlink` runs through
|
|
10
|
+
# `command -p`, so the caller's `PATH` decides nothing here.
|
|
11
|
+
self=$0
|
|
12
|
+
# `${self%/*}` needs a slash to strip. A bare name came from a `PATH` lookup and
|
|
13
|
+
# stands for a file in the current directory.
|
|
14
|
+
case $self in
|
|
15
|
+
*/*) ;;
|
|
16
|
+
*) self=./$self ;;
|
|
17
|
+
esac
|
|
18
|
+
hops=0
|
|
19
|
+
while [ -L "$self" ] && [ "$hops" -lt 40 ]; do
|
|
20
|
+
hops=$((hops + 1))
|
|
21
|
+
link=$(command -p readlink "$self")
|
|
22
|
+
case $link in
|
|
23
|
+
/*) self=$link ;;
|
|
24
|
+
*) self=${self%/*}/$link ;;
|
|
25
|
+
esac
|
|
26
|
+
done
|
|
27
|
+
# The walk has to end at a regular file. Running out of hops leaves $self a
|
|
28
|
+
# symlink; a chain that changed under us can leave it dangling or a directory, and
|
|
29
|
+
# a failed readlink leaves a trailing slash. Each case would take `pnpm` from the
|
|
30
|
+
# wrong directory — the substitution this script exists to prevent.
|
|
31
|
+
if [ -L "$self" ] || [ ! -f "$self" ]; then
|
|
32
|
+
echo "pnpx: could not resolve $0 to a regular file within 40 symlink hops." >&2
|
|
33
|
+
exit 1
|
|
34
|
+
fi
|
|
35
|
+
|
|
36
|
+
exec "${self%/*}/pnpm" dlx "$@"
|
package/pnx
CHANGED
|
@@ -1,2 +1,36 @@
|
|
|
1
1
|
#!/bin/sh
|
|
2
|
-
|
|
2
|
+
# `pnx` is `pnpm dlx`. The pnpm it hands over to is the one installed alongside
|
|
3
|
+
# it, found relative to this file: a `PATH` lookup would run whatever other pnpm
|
|
4
|
+
# comes first there, and would find nothing at all when the directory holding
|
|
5
|
+
# these bins is not on `PATH`.
|
|
6
|
+
#
|
|
7
|
+
# $0 is whatever shim or symlink `pnx` was launched through, so walk to the file
|
|
8
|
+
# itself first. The hop cap matches the kernel's ELOOP limit, so a cycle cannot
|
|
9
|
+
# hang the script. Directories come from `${self%/*}` and `readlink` runs through
|
|
10
|
+
# `command -p`, so the caller's `PATH` decides nothing here.
|
|
11
|
+
self=$0
|
|
12
|
+
# `${self%/*}` needs a slash to strip. A bare name came from a `PATH` lookup and
|
|
13
|
+
# stands for a file in the current directory.
|
|
14
|
+
case $self in
|
|
15
|
+
*/*) ;;
|
|
16
|
+
*) self=./$self ;;
|
|
17
|
+
esac
|
|
18
|
+
hops=0
|
|
19
|
+
while [ -L "$self" ] && [ "$hops" -lt 40 ]; do
|
|
20
|
+
hops=$((hops + 1))
|
|
21
|
+
link=$(command -p readlink "$self")
|
|
22
|
+
case $link in
|
|
23
|
+
/*) self=$link ;;
|
|
24
|
+
*) self=${self%/*}/$link ;;
|
|
25
|
+
esac
|
|
26
|
+
done
|
|
27
|
+
# The walk has to end at a regular file. Running out of hops leaves $self a
|
|
28
|
+
# symlink; a chain that changed under us can leave it dangling or a directory, and
|
|
29
|
+
# a failed readlink leaves a trailing slash. Each case would take `pnpm` from the
|
|
30
|
+
# wrong directory — the substitution this script exists to prevent.
|
|
31
|
+
if [ -L "$self" ] || [ ! -f "$self" ]; then
|
|
32
|
+
echo "pnx: could not resolve $0 to a regular file within 40 symlink hops." >&2
|
|
33
|
+
exit 1
|
|
34
|
+
fi
|
|
35
|
+
|
|
36
|
+
exec "${self%/*}/pnpm" dlx "$@"
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"packages":{".":{"url":"..","dependencies":{"get-pnpm":"get-pnpm","node-gyp":"node-gyp","pacquet":"."}},"@isaacs/fs-minipass":{"url":"./@isaacs/fs-minipass","dependencies":{"@isaacs/fs-minipass":"@isaacs/fs-minipass","minipass":"minipass"}},"abbrev":{"url":"./abbrev","dependencies":{"abbrev":"abbrev"}},"chownr":{"url":"./chownr","dependencies":{"chownr":"chownr"}},"env-paths":{"url":"./env-paths","dependencies":{"env-paths":"env-paths"}},"exponential-backoff":{"url":"./exponential-backoff","dependencies":{"exponential-backoff":"exponential-backoff"}},"fdir":{"url":"./fdir","dependencies":{"fdir":"fdir","picomatch":"picomatch"}},"get-pnpm":{"url":"./get-pnpm","dependencies":{"get-pnpm":"get-pnpm"}},"graceful-fs":{"url":"./graceful-fs","dependencies":{"graceful-fs":"graceful-fs"}},"isexe":{"url":"./isexe","dependencies":{"isexe":"isexe"}},"minipass":{"url":"./minipass","dependencies":{"minipass":"minipass"}},"minizlib":{"url":"./minizlib","dependencies":{"minipass":"minipass","minizlib":"minizlib"}},"node-gyp":{"url":"./node-gyp","dependencies":{"env-paths":"env-paths","exponential-backoff":"exponential-backoff","graceful-fs":"graceful-fs","node-gyp":"node-gyp","nopt":"nopt","proc-log":"proc-log","semver":"semver","tar":"tar","tinyglobby":"tinyglobby","undici":"undici","which":"which"}},"nopt":{"url":"./nopt","dependencies":{"abbrev":"abbrev","nopt":"nopt"}},"picomatch":{"url":"./picomatch","dependencies":{"picomatch":"picomatch"}},"proc-log":{"url":"./proc-log","dependencies":{"proc-log":"proc-log"}},"semver":{"url":"./semver","dependencies":{"semver":"semver"}},"tar":{"url":"./tar","dependencies":{"@isaacs/fs-minipass":"@isaacs/fs-minipass","chownr":"chownr","minipass":"minipass","minizlib":"minizlib","tar":"tar","yallist":"yallist"}},"tinyglobby":{"url":"./tinyglobby","dependencies":{"fdir":"fdir","picomatch":"picomatch","tinyglobby":"tinyglobby"}},"undici":{"url":"./undici","dependencies":{"undici":"undici"}},"which":{"url":"./which","dependencies":{"isexe":"isexe","which":"which"}},"yallist":{"url":"./yallist","dependencies":{"yallist":"yallist"}}}}
|