@pnpm/engine.pm.commands 1000.0.0 → 1100.0.0
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.
|
@@ -2,12 +2,16 @@ import fs from 'node:fs';
|
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import util from 'node:util';
|
|
4
4
|
import { linkBins } from '@pnpm/bins.linker';
|
|
5
|
+
import { createAllowBuildFunction } from '@pnpm/building.policy';
|
|
5
6
|
import { getCurrentPackageName } from '@pnpm/cli.meta';
|
|
6
7
|
import { iterateHashedGraphNodes, iteratePkgMeta, lockfileToDepGraph, } from '@pnpm/deps.graph-hasher';
|
|
7
8
|
import { installGlobalPackages } from '@pnpm/global.commands';
|
|
8
9
|
import { cleanOrphanedInstallDirs, createGlobalCacheKey, createInstallDir, findGlobalPackage, getHashLink, } from '@pnpm/global.packages';
|
|
9
10
|
import { headlessInstall } from '@pnpm/installing.deps-restorer';
|
|
10
|
-
import symlinkDir from 'symlink-dir';
|
|
11
|
+
import { symlinkDir } from 'symlink-dir';
|
|
12
|
+
// @pnpm/exe has platform-specific binaries, so its GVS hash must
|
|
13
|
+
// include ENGINE_NAME for correct per-platform resolution.
|
|
14
|
+
const PNPM_ALLOW_BUILDS = { '@pnpm/exe': true };
|
|
11
15
|
/**
|
|
12
16
|
* Installs pnpm to the global packages directory (for self-update).
|
|
13
17
|
* Creates an entry in globalPkgDir that is visible to `pnpm ls -g`.
|
|
@@ -34,7 +38,7 @@ export async function installPnpmToStore(pnpmVersion, opts) {
|
|
|
34
38
|
const wantedLockfile = buildLockfileFromEnvLockfile(opts.envLockfile, currentPkgName, pnpmVersion);
|
|
35
39
|
const globalVirtualStoreDir = path.join(opts.storeDir, 'links');
|
|
36
40
|
// Compute the GVS hash for the pnpm package to find its path
|
|
37
|
-
const pnpmGvsPath = findPnpmGvsPath(wantedLockfile, currentPkgName, globalVirtualStoreDir);
|
|
41
|
+
const pnpmGvsPath = findPnpmGvsPath(wantedLockfile, currentPkgName, globalVirtualStoreDir, PNPM_ALLOW_BUILDS);
|
|
38
42
|
const pnpmPkgDir = path.join(pnpmGvsPath, 'node_modules', currentPkgName);
|
|
39
43
|
const binDir = path.join(pnpmGvsPath, 'bin');
|
|
40
44
|
// Check if already installed in the GVS
|
|
@@ -51,6 +55,7 @@ export async function installPnpmToStore(pnpmVersion, opts) {
|
|
|
51
55
|
try {
|
|
52
56
|
await installFromLockfile(tmpInstallDir, binDir, {
|
|
53
57
|
wantedLockfile,
|
|
58
|
+
allowBuilds: PNPM_ALLOW_BUILDS,
|
|
54
59
|
storeController: opts.storeController,
|
|
55
60
|
storeDir: opts.storeDir,
|
|
56
61
|
registries: opts.registries,
|
|
@@ -70,10 +75,11 @@ export async function installPnpmToStore(pnpmVersion, opts) {
|
|
|
70
75
|
}
|
|
71
76
|
}
|
|
72
77
|
function noop(_message) { }
|
|
73
|
-
function findPnpmGvsPath(lockfile, pkgName, globalVirtualStoreDir) {
|
|
78
|
+
function findPnpmGvsPath(lockfile, pkgName, globalVirtualStoreDir, allowBuilds) {
|
|
74
79
|
const graph = lockfileToDepGraph(lockfile);
|
|
75
80
|
const pkgMetaIterator = iteratePkgMeta(lockfile, graph);
|
|
76
|
-
|
|
81
|
+
const allowBuild = createAllowBuildFunction({ allowBuilds });
|
|
82
|
+
for (const { hash, pkgMeta } of iterateHashedGraphNodes(graph, pkgMetaIterator, allowBuild)) {
|
|
77
83
|
if (pkgMeta.name === pkgName) {
|
|
78
84
|
return path.join(globalVirtualStoreDir, hash);
|
|
79
85
|
}
|
|
@@ -110,6 +116,7 @@ async function installPnpmToGlobalDir(opts, pkgName, version, wantedLockfile) {
|
|
|
110
116
|
if (wantedLockfile != null && opts.storeController != null && opts.storeDir != null) {
|
|
111
117
|
await installFromLockfile(installDir, binDir, {
|
|
112
118
|
wantedLockfile,
|
|
119
|
+
allowBuilds: PNPM_ALLOW_BUILDS,
|
|
113
120
|
storeController: opts.storeController,
|
|
114
121
|
storeDir: opts.storeDir,
|
|
115
122
|
registries: opts.registries,
|
|
@@ -150,8 +157,8 @@ async function installFromLockfile(installDir, binDir, opts) {
|
|
|
150
157
|
registries: opts.registries,
|
|
151
158
|
enableGlobalVirtualStore: true,
|
|
152
159
|
globalVirtualStoreDir: path.join(opts.storeDir, 'links'),
|
|
160
|
+
allowBuilds: opts.allowBuilds,
|
|
153
161
|
ignoreScripts: true,
|
|
154
|
-
ignoreDepScripts: true,
|
|
155
162
|
force: false,
|
|
156
163
|
engineStrict: false,
|
|
157
164
|
currentEngine: {
|
|
@@ -177,7 +184,7 @@ async function installFromLockfile(installDir, binDir, opts) {
|
|
|
177
184
|
virtualStoreDirMaxLength: opts.virtualStoreDirMaxLength,
|
|
178
185
|
sideEffectsCacheRead: false,
|
|
179
186
|
sideEffectsCacheWrite: false,
|
|
180
|
-
|
|
187
|
+
configByUri: {},
|
|
181
188
|
unsafePerm: false,
|
|
182
189
|
userAgent: '',
|
|
183
190
|
packageManager: opts.packageManager ?? { name: 'pnpm', version: '' },
|
|
@@ -238,6 +245,18 @@ export function linkExePlatformBinary(installDir) {
|
|
|
238
245
|
if (!fs.existsSync(src))
|
|
239
246
|
return;
|
|
240
247
|
const dest = path.join(exePkgDir, executable);
|
|
248
|
+
forceLink(src, dest);
|
|
249
|
+
if (platform === 'win') {
|
|
250
|
+
const exePkgJsonPath = path.join(exePkgDir, 'package.json');
|
|
251
|
+
const exePkg = JSON.parse(fs.readFileSync(exePkgJsonPath, 'utf8'));
|
|
252
|
+
exePkg.bin.pnpm = 'pnpm.exe';
|
|
253
|
+
exePkg.bin.pn = 'pn.cmd';
|
|
254
|
+
exePkg.bin.pnpx = 'pnpx.cmd';
|
|
255
|
+
exePkg.bin.pnx = 'pnx.cmd';
|
|
256
|
+
fs.writeFileSync(exePkgJsonPath, JSON.stringify(exePkg, null, 2));
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
function forceLink(src, dest) {
|
|
241
260
|
try {
|
|
242
261
|
fs.unlinkSync(dest);
|
|
243
262
|
}
|
|
@@ -248,13 +267,6 @@ export function linkExePlatformBinary(installDir) {
|
|
|
248
267
|
}
|
|
249
268
|
fs.linkSync(src, dest);
|
|
250
269
|
fs.chmodSync(dest, 0o755);
|
|
251
|
-
if (platform === 'win') {
|
|
252
|
-
const exePkgJsonPath = path.join(exePkgDir, 'package.json');
|
|
253
|
-
const exePkg = JSON.parse(fs.readFileSync(exePkgJsonPath, 'utf8'));
|
|
254
|
-
fs.writeFileSync(path.join(exePkgDir, 'pnpm'), 'This file intentionally left blank');
|
|
255
|
-
exePkg.bin.pnpm = 'pnpm.exe';
|
|
256
|
-
fs.writeFileSync(exePkgJsonPath, JSON.stringify(exePkg, null, 2));
|
|
257
|
-
}
|
|
258
270
|
}
|
|
259
271
|
function buildLockfileFromEnvLockfile(envLockfile, pkgName, version) {
|
|
260
272
|
const dependencies = {};
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { type Config } from '@pnpm/config.reader';
|
|
1
|
+
import { type Config, type ConfigContext } from '@pnpm/config.reader';
|
|
2
2
|
import { type CreateStoreControllerOptions } from '@pnpm/store.connection-manager';
|
|
3
3
|
export declare function rcOptionsTypes(): Record<string, unknown>;
|
|
4
4
|
export declare function cliOptionsTypes(): Record<string, unknown>;
|
|
5
5
|
export declare const commandNames: string[];
|
|
6
6
|
export declare const skipPackageManagerCheck = true;
|
|
7
7
|
export declare function help(): string;
|
|
8
|
-
export type SelfUpdateCommandOptions = CreateStoreControllerOptions & Pick<Config, 'globalPkgDir' | 'lockfileDir' | 'managePackageManagerVersions' | 'modulesDir' | 'pnpmHomeDir'
|
|
8
|
+
export type SelfUpdateCommandOptions = CreateStoreControllerOptions & Pick<Config, 'globalPkgDir' | 'lockfileDir' | 'managePackageManagerVersions' | 'modulesDir' | 'pnpmHomeDir'> & Pick<ConfigContext, 'rootProjectManifestDir' | 'wantedPackageManager'>;
|
|
9
9
|
export declare function handler(opts: SelfUpdateCommandOptions, params: string[]): Promise<undefined | string>;
|
|
@@ -41,7 +41,7 @@ export async function handler(opts, params) {
|
|
|
41
41
|
if (isExecutedByCorepack()) {
|
|
42
42
|
throw new PnpmError('CANT_SELF_UPDATE_IN_COREPACK', 'You should update pnpm with corepack');
|
|
43
43
|
}
|
|
44
|
-
const { resolve } = createResolver({ ...opts,
|
|
44
|
+
const { resolve } = createResolver({ ...opts, configByUri: opts.configByUri });
|
|
45
45
|
const pkgName = 'pnpm';
|
|
46
46
|
const bareSpecifier = params[0] ?? 'latest';
|
|
47
47
|
const resolution = await resolve({ alias: pkgName, bareSpecifier }, {
|
|
@@ -108,8 +108,8 @@ export async function handler(opts, params) {
|
|
|
108
108
|
storeController: store.ctrl,
|
|
109
109
|
storeDir: store.dir,
|
|
110
110
|
});
|
|
111
|
-
// Link bins to pnpmHomeDir so the updated pnpm is the active global binary
|
|
112
|
-
await linkBins(path.join(baseDir, 'node_modules'), opts.pnpmHomeDir, { warn: globalWarn });
|
|
111
|
+
// Link bins to pnpmHomeDir/bin so the updated pnpm is the active global binary
|
|
112
|
+
await linkBins(path.join(baseDir, 'node_modules'), path.join(opts.pnpmHomeDir, 'bin'), { warn: globalWarn });
|
|
113
113
|
if (alreadyExisted) {
|
|
114
114
|
return `The ${bareSpecifier} version, v${resolution.manifest.version}, is already present on the system. It was activated by linking it from ${baseDir}.`;
|
|
115
115
|
}
|
package/lib/setup/setup.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ export declare const rcOptionsTypes: () => Record<string, unknown>;
|
|
|
2
2
|
export declare const cliOptionsTypes: () => Record<string, unknown>;
|
|
3
3
|
export declare const shorthands: {};
|
|
4
4
|
export declare const commandNames: string[];
|
|
5
|
+
export declare const overridableByScript = true;
|
|
5
6
|
export declare function help(): string;
|
|
6
7
|
export declare function handler(opts: {
|
|
7
8
|
force?: boolean;
|
package/lib/setup/setup.js
CHANGED
|
@@ -5,6 +5,7 @@ import { detectIfCurrentPkgIsExecutable, packageManager } from '@pnpm/cli.meta';
|
|
|
5
5
|
import { docsUrl } from '@pnpm/cli.utils';
|
|
6
6
|
import { logger } from '@pnpm/logger';
|
|
7
7
|
import { addDirToEnvPath, } from '@pnpm/os.env.path-extender';
|
|
8
|
+
import PATH from 'path-name';
|
|
8
9
|
import { renderHelp } from 'render-help';
|
|
9
10
|
export const rcOptionsTypes = () => ({});
|
|
10
11
|
export const cliOptionsTypes = () => ({
|
|
@@ -12,6 +13,7 @@ export const cliOptionsTypes = () => ({
|
|
|
12
13
|
});
|
|
13
14
|
export const shorthands = {};
|
|
14
15
|
export const commandNames = ['setup'];
|
|
16
|
+
export const overridableByScript = true;
|
|
15
17
|
export function help() {
|
|
16
18
|
return renderHelp({
|
|
17
19
|
description: 'Sets up pnpm',
|
|
@@ -55,7 +57,7 @@ function installCliGlobally(execPath, pnpmHomeDir) {
|
|
|
55
57
|
fs.writeFileSync(pkgJsonPath, JSON.stringify({
|
|
56
58
|
name: '@pnpm/exe',
|
|
57
59
|
version: packageManager.version,
|
|
58
|
-
bin: { pnpm: execName },
|
|
60
|
+
bin: { pnpm: execName, pn: execName },
|
|
59
61
|
}));
|
|
60
62
|
createdPkgJson = true;
|
|
61
63
|
}
|
|
@@ -64,11 +66,13 @@ function installCliGlobally(execPath, pnpmHomeDir) {
|
|
|
64
66
|
prefix: process.cwd(),
|
|
65
67
|
});
|
|
66
68
|
try {
|
|
69
|
+
const binDir = path.join(pnpmHomeDir, 'bin');
|
|
67
70
|
const { status, error } = spawnSync(execPath, ['add', '-g', `file:${execDir}`], {
|
|
68
71
|
stdio: 'inherit',
|
|
69
72
|
env: {
|
|
70
73
|
...process.env,
|
|
71
74
|
PNPM_HOME: pnpmHomeDir,
|
|
75
|
+
[PATH]: `${binDir}${path.delimiter}${process.env[PATH] ?? ''}`,
|
|
72
76
|
},
|
|
73
77
|
});
|
|
74
78
|
if (error)
|
|
@@ -83,7 +87,7 @@ function installCliGlobally(execPath, pnpmHomeDir) {
|
|
|
83
87
|
}
|
|
84
88
|
}
|
|
85
89
|
}
|
|
86
|
-
function
|
|
90
|
+
function createAliasScripts(targetDir) {
|
|
87
91
|
// Why script files instead of aliases?
|
|
88
92
|
// 1. Aliases wouldn't work on all platform, such as Windows Command Prompt or POSIX `sh`.
|
|
89
93
|
// 2. Aliases wouldn't work on all environments, such as non-interactive shells and CI environments.
|
|
@@ -91,32 +95,31 @@ function createPnpxScripts(targetDir) {
|
|
|
91
95
|
// 4. Aliases cannot be located with the `which` or `where` command.
|
|
92
96
|
// 5. Editing rc files is more error-prone than just write new files to the filesystem.
|
|
93
97
|
fs.mkdirSync(targetDir, { recursive: true });
|
|
98
|
+
createShellScript(targetDir, 'pn', 'pnpm');
|
|
99
|
+
createShellScript(targetDir, 'pnpx', 'pnpm dlx');
|
|
100
|
+
createShellScript(targetDir, 'pnx', 'pnpm dlx');
|
|
101
|
+
}
|
|
102
|
+
function createShellScript(targetDir, name, command) {
|
|
94
103
|
// windows can also use shell script via mingw or cygwin so no filter
|
|
95
|
-
const shellScript =
|
|
96
|
-
|
|
97
|
-
'exec pnpm dlx "$@"',
|
|
98
|
-
].join('\n');
|
|
99
|
-
fs.writeFileSync(path.join(targetDir, 'pnpx'), shellScript, { mode: 0o755 });
|
|
104
|
+
const shellScript = `#!/bin/sh\nexec ${command} "$@"\n`;
|
|
105
|
+
fs.writeFileSync(path.join(targetDir, name), shellScript, { mode: 0o755 });
|
|
100
106
|
if (process.platform === 'win32') {
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
'pnpm dlx %*',
|
|
104
|
-
].join('\n');
|
|
105
|
-
fs.writeFileSync(path.join(targetDir, 'pnpx.cmd'), batchScript);
|
|
106
|
-
const powershellScript = 'pnpm dlx @args';
|
|
107
|
-
fs.writeFileSync(path.join(targetDir, 'pnpx.ps1'), powershellScript);
|
|
107
|
+
fs.writeFileSync(path.join(targetDir, `${name}.cmd`), `@echo off\n${command} %*\n`);
|
|
108
|
+
fs.writeFileSync(path.join(targetDir, `${name}.ps1`), `${command} @args\n`);
|
|
108
109
|
}
|
|
109
110
|
}
|
|
110
111
|
export async function handler(opts) {
|
|
111
112
|
const execPath = getExecPath();
|
|
113
|
+
const binDir = path.join(opts.pnpmHomeDir, 'bin');
|
|
112
114
|
if (execPath.match(/\.[cm]?js$/) == null) {
|
|
113
115
|
installCliGlobally(execPath, opts.pnpmHomeDir);
|
|
114
|
-
|
|
116
|
+
createAliasScripts(binDir);
|
|
115
117
|
}
|
|
116
118
|
try {
|
|
117
119
|
const report = await addDirToEnvPath(opts.pnpmHomeDir, {
|
|
118
120
|
configSectionName: 'pnpm',
|
|
119
121
|
proxyVarName: 'PNPM_HOME',
|
|
122
|
+
proxyVarSubDir: 'bin',
|
|
120
123
|
overwrite: opts.force,
|
|
121
124
|
position: 'start',
|
|
122
125
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pnpm/engine.pm.commands",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "1100.0.0",
|
|
4
4
|
"description": "pnpm commands for self-updating and setting up pnpm",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"pnpm",
|
|
@@ -24,44 +24,46 @@
|
|
|
24
24
|
"!*.map"
|
|
25
25
|
],
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"@pnpm/os.env.path-extender": "^
|
|
27
|
+
"@pnpm/os.env.path-extender": "^3.0.0",
|
|
28
|
+
"path-name": "^1.0.0",
|
|
28
29
|
"ramda": "npm:@pnpm/ramda@0.28.1",
|
|
29
30
|
"render-help": "^2.0.0",
|
|
30
31
|
"semver": "^7.7.2",
|
|
31
|
-
"symlink-dir": "^
|
|
32
|
-
"@pnpm/bins.linker": "
|
|
33
|
-
"@pnpm/
|
|
34
|
-
"@pnpm/
|
|
35
|
-
"@pnpm/cli.utils": "
|
|
36
|
-
"@pnpm/config.reader": "
|
|
37
|
-
"@pnpm/
|
|
38
|
-
"@pnpm/global.
|
|
39
|
-
"@pnpm/
|
|
40
|
-
"@pnpm/
|
|
41
|
-
"@pnpm/installing.deps-restorer": "
|
|
42
|
-
"@pnpm/
|
|
43
|
-
"@pnpm/
|
|
44
|
-
"@pnpm/
|
|
45
|
-
"@pnpm/store.connection-manager": "
|
|
46
|
-
"@pnpm/
|
|
47
|
-
"@pnpm/
|
|
48
|
-
"@pnpm/workspace.project-manifest-reader": "
|
|
32
|
+
"symlink-dir": "^10.0.1",
|
|
33
|
+
"@pnpm/bins.linker": "1100.0.0",
|
|
34
|
+
"@pnpm/building.policy": "1100.0.0",
|
|
35
|
+
"@pnpm/cli.meta": "1100.0.0",
|
|
36
|
+
"@pnpm/cli.utils": "1100.0.0",
|
|
37
|
+
"@pnpm/config.reader": "1100.0.0",
|
|
38
|
+
"@pnpm/deps.graph-hasher": "1100.0.0",
|
|
39
|
+
"@pnpm/global.commands": "1100.0.0",
|
|
40
|
+
"@pnpm/error": "1100.0.0",
|
|
41
|
+
"@pnpm/installing.client": "1100.0.0",
|
|
42
|
+
"@pnpm/installing.deps-restorer": "1100.0.0",
|
|
43
|
+
"@pnpm/installing.env-installer": "1100.0.0",
|
|
44
|
+
"@pnpm/global.packages": "1100.0.0",
|
|
45
|
+
"@pnpm/lockfile.types": "1100.0.0",
|
|
46
|
+
"@pnpm/store.connection-manager": "1100.0.0",
|
|
47
|
+
"@pnpm/types": "1100.0.0",
|
|
48
|
+
"@pnpm/store.controller": "1100.0.0",
|
|
49
|
+
"@pnpm/workspace.project-manifest-reader": "1100.0.0",
|
|
50
|
+
"@pnpm/resolving.npm-resolver": "1100.0.0"
|
|
49
51
|
},
|
|
50
52
|
"peerDependencies": {
|
|
51
53
|
"@pnpm/logger": ">=1001.0.0 <1002.0.0"
|
|
52
54
|
},
|
|
53
55
|
"devDependencies": {
|
|
54
|
-
"@jest/globals": "30.0
|
|
56
|
+
"@jest/globals": "30.3.0",
|
|
55
57
|
"@types/cross-spawn": "^6.0.6",
|
|
56
|
-
"@types/ramda": "0.
|
|
58
|
+
"@types/ramda": "0.31.1",
|
|
57
59
|
"@types/semver": "7.7.1",
|
|
58
60
|
"cross-spawn": "^7.0.6",
|
|
59
|
-
"
|
|
60
|
-
"@pnpm/engine.pm.commands": "
|
|
61
|
-
"@pnpm/
|
|
62
|
-
"@pnpm/
|
|
63
|
-
"@pnpm/
|
|
64
|
-
"@pnpm/
|
|
61
|
+
"@pnpm/logger": "1100.0.0",
|
|
62
|
+
"@pnpm/engine.pm.commands": "1100.0.0",
|
|
63
|
+
"@pnpm/prepare": "1100.0.0",
|
|
64
|
+
"@pnpm/error": "1100.0.0",
|
|
65
|
+
"@pnpm/shell.path": "1100.0.0",
|
|
66
|
+
"@pnpm/testing.mock-agent": "1100.0.0"
|
|
65
67
|
},
|
|
66
68
|
"engines": {
|
|
67
69
|
"node": ">=22.13"
|
|
@@ -71,8 +73,8 @@
|
|
|
71
73
|
},
|
|
72
74
|
"scripts": {
|
|
73
75
|
"lint": "eslint \"src/**/*.ts\" \"test/**/*.ts\"",
|
|
74
|
-
"test": "
|
|
75
|
-
"compile": "tsgo --build &&
|
|
76
|
-
"
|
|
76
|
+
"test": "pn compile && pn .test",
|
|
77
|
+
"compile": "tsgo --build && pn lint --fix",
|
|
78
|
+
".test": "cross-env NODE_OPTIONS=\"$NODE_OPTIONS --experimental-vm-modules --disable-warning=ExperimentalWarning --disable-warning=DEP0169\" jest"
|
|
77
79
|
}
|
|
78
80
|
}
|