@pnpm/building.after-install 1101.0.18 → 1101.0.19
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/lib/extendBuildOptions.d.ts +2 -0
- package/lib/index.js +46 -4
- package/package.json +26 -23
|
@@ -41,6 +41,8 @@ export type StrictBuildOptions = {
|
|
|
41
41
|
shamefullyHoist: boolean;
|
|
42
42
|
deployAllFiles: boolean;
|
|
43
43
|
allowBuilds?: Record<string, boolean | string>;
|
|
44
|
+
enableGlobalVirtualStore?: boolean;
|
|
45
|
+
globalVirtualStoreDir?: string;
|
|
44
46
|
virtualStoreDirMaxLength: number;
|
|
45
47
|
peersSuffixMaxLength: number;
|
|
46
48
|
strictStorePkgContentCheck: boolean;
|
package/lib/index.js
CHANGED
|
@@ -6,7 +6,7 @@ import { pkgRequiresBuild } from '@pnpm/building.pkg-requires-build';
|
|
|
6
6
|
import { createAllowBuildFunction } from '@pnpm/building.policy';
|
|
7
7
|
import { LAYOUT_VERSION, WANTED_LOCKFILE, } from '@pnpm/constants';
|
|
8
8
|
import { skippedOptionalDependencyLogger } from '@pnpm/core-loggers';
|
|
9
|
-
import { calcDepState, findRuntimeNodeVersion, lockfileToDepGraph } from '@pnpm/deps.graph-hasher';
|
|
9
|
+
import { calcDepState, findRuntimeNodeVersion, iterateHashedGraphNodes, iteratePkgMeta, lockfileToDepGraph } from '@pnpm/deps.graph-hasher';
|
|
10
10
|
import { graphSequencer } from '@pnpm/deps.graph-sequencer';
|
|
11
11
|
import * as dp from '@pnpm/deps.path';
|
|
12
12
|
import { PnpmError } from '@pnpm/error';
|
|
@@ -25,6 +25,10 @@ import pLimit from 'p-limit';
|
|
|
25
25
|
import { runGroups } from 'run-groups';
|
|
26
26
|
import semver from 'semver';
|
|
27
27
|
import { extendBuildOptions, } from './extendBuildOptions.js';
|
|
28
|
+
// Serializes builds of a shared GVS projection across concurrent per-project
|
|
29
|
+
// rebuilds: the first build proceeds, concurrent ones await it and reuse the
|
|
30
|
+
// result. Keyed by the absolute projection directory.
|
|
31
|
+
const gvsBuildLocks = new Map();
|
|
28
32
|
function findPackages(packages, searched, opts) {
|
|
29
33
|
return Object.keys(packages)
|
|
30
34
|
.filter((relativeDepPath) => {
|
|
@@ -229,12 +233,25 @@ async function _rebuild(ctx, opts) {
|
|
|
229
233
|
};
|
|
230
234
|
const builtDepPaths = new Set();
|
|
231
235
|
const storeIndex = opts.skipIfHasSideEffectsCache ? new StoreIndex(opts.storeDir) : undefined;
|
|
236
|
+
// Under GVS, packages live at `<globalVirtualStoreDir>/<hash>/node_modules/<name>`,
|
|
237
|
+
// not the classic virtualStoreDir layout. The hash is computed with the same inputs
|
|
238
|
+
// as the installer so rebuild resolves the exact directory the install created.
|
|
239
|
+
const gvsDirByDepPath = new Map();
|
|
240
|
+
if (opts.enableGlobalVirtualStore) {
|
|
241
|
+
const globalVirtualStoreDir = opts.globalVirtualStoreDir ?? path.join(opts.storeDir, 'links');
|
|
242
|
+
for (const { hash, pkgMeta } of iterateHashedGraphNodes(depGraph, iteratePkgMeta(ctx.currentLockfile, depGraph), _allowBuild, opts.supportedArchitectures, nodeVersion)) {
|
|
243
|
+
gvsDirByDepPath.set(pkgMeta.depPath, path.join(globalVirtualStoreDir, hash));
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
const pkgModulesDir = (depPath) => gvsDirByDepPath.has(depPath)
|
|
247
|
+
? path.join(gvsDirByDepPath.get(depPath), 'node_modules')
|
|
248
|
+
: path.join(ctx.virtualStoreDir, dp.depPathToFilename(depPath, opts.virtualStoreDirMaxLength), 'node_modules');
|
|
232
249
|
const groups = chunks.map((chunk) => chunk.filter((depPath) => ctx.pkgsToRebuild.has(depPath) && !ctx.skipped.has(depPath)).map((depPath) => async () => {
|
|
233
250
|
const pkgSnapshot = pkgSnapshots[depPath];
|
|
234
251
|
const pkgInfo = nameVerFromPkgSnapshot(depPath, pkgSnapshot);
|
|
235
252
|
const pkgRoots = opts.nodeLinker === 'hoisted'
|
|
236
253
|
? (ctx.modulesFile?.hoistedLocations?.[depPath] ?? []).map((hoistedLocation) => path.join(opts.lockfileDir, hoistedLocation))
|
|
237
|
-
: [path.join(
|
|
254
|
+
: [path.join(pkgModulesDir(depPath), pkgInfo.name)];
|
|
238
255
|
if (pkgRoots.length === 0) {
|
|
239
256
|
if (pkgSnapshot.optional)
|
|
240
257
|
return;
|
|
@@ -243,10 +260,32 @@ async function _rebuild(ctx, opts) {
|
|
|
243
260
|
});
|
|
244
261
|
}
|
|
245
262
|
const pkgRoot = pkgRoots[0];
|
|
263
|
+
// If another project is already building this shared projection, wait for it
|
|
264
|
+
// and reuse the result instead of racing on the same directory.
|
|
265
|
+
const gvsDir = gvsDirByDepPath.get(depPath);
|
|
266
|
+
if (gvsDir != null) {
|
|
267
|
+
const inFlight = gvsBuildLocks.get(gvsDir);
|
|
268
|
+
if (inFlight != null) {
|
|
269
|
+
await inFlight.catch(() => { });
|
|
270
|
+
pkgsThatWereRebuilt.add(depPath);
|
|
271
|
+
return;
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
let releaseGvsLock;
|
|
275
|
+
if (gvsDir != null) {
|
|
276
|
+
let resolveLock;
|
|
277
|
+
gvsBuildLocks.set(gvsDir, new Promise((resolve) => {
|
|
278
|
+
resolveLock = resolve;
|
|
279
|
+
}));
|
|
280
|
+
releaseGvsLock = () => {
|
|
281
|
+
gvsBuildLocks.delete(gvsDir);
|
|
282
|
+
resolveLock();
|
|
283
|
+
};
|
|
284
|
+
}
|
|
246
285
|
try {
|
|
247
286
|
const extraBinPaths = ctx.extraBinPaths;
|
|
248
287
|
if (opts.nodeLinker !== 'hoisted') {
|
|
249
|
-
const modules =
|
|
288
|
+
const modules = pkgModulesDir(depPath);
|
|
250
289
|
const binPath = path.join(pkgRoot, 'node_modules', '.bin');
|
|
251
290
|
await linkBins(modules, binPath, { extraNodePaths: ctx.extraNodePaths, warn });
|
|
252
291
|
}
|
|
@@ -337,6 +376,9 @@ async function _rebuild(ctx, opts) {
|
|
|
337
376
|
}
|
|
338
377
|
throw err;
|
|
339
378
|
}
|
|
379
|
+
finally {
|
|
380
|
+
releaseGvsLock?.();
|
|
381
|
+
}
|
|
340
382
|
if (pkgRoots.length > 1) {
|
|
341
383
|
await hardLinkDir(pkgRoot, pkgRoots.slice(1));
|
|
342
384
|
}
|
|
@@ -351,7 +393,7 @@ async function _rebuild(ctx, opts) {
|
|
|
351
393
|
.map(async (depPath) => limitLinking(async () => {
|
|
352
394
|
const pkgSnapshot = pkgSnapshots[depPath];
|
|
353
395
|
const pkgInfo = nameVerFromPkgSnapshot(depPath, pkgSnapshot);
|
|
354
|
-
const modules =
|
|
396
|
+
const modules = pkgModulesDir(depPath);
|
|
355
397
|
const binPath = path.join(modules, pkgInfo.name, 'node_modules', '.bin');
|
|
356
398
|
return linkBins(modules, binPath, { warn });
|
|
357
399
|
})));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pnpm/building.after-install",
|
|
3
|
-
"version": "1101.0.
|
|
3
|
+
"version": "1101.0.19",
|
|
4
4
|
"description": "Rebuild packages that are already installed by running their lifecycle scripts",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"pnpm",
|
|
@@ -9,7 +9,10 @@
|
|
|
9
9
|
],
|
|
10
10
|
"license": "MIT",
|
|
11
11
|
"funding": "https://opencollective.com/pnpm",
|
|
12
|
-
"repository":
|
|
12
|
+
"repository": {
|
|
13
|
+
"type": "git",
|
|
14
|
+
"url": "https://github.com/pnpm/pnpm/tree/main/building/after-install"
|
|
15
|
+
},
|
|
13
16
|
"homepage": "https://github.com/pnpm/pnpm/tree/main/building/after-install#readme",
|
|
14
17
|
"bugs": {
|
|
15
18
|
"url": "https://github.com/pnpm/pnpm/issues"
|
|
@@ -30,37 +33,37 @@
|
|
|
30
33
|
"p-limit": "^7.3.0",
|
|
31
34
|
"run-groups": "^5.0.0",
|
|
32
35
|
"semver": "^7.8.1",
|
|
33
|
-
"@pnpm/building.pkg-requires-build": "1100.0.
|
|
34
|
-
"@pnpm/
|
|
35
|
-
"@pnpm/
|
|
36
|
-
"@pnpm/config.normalize-registries": "1100.0.5",
|
|
37
|
-
"@pnpm/config.reader": "1101.5.0",
|
|
36
|
+
"@pnpm/building.pkg-requires-build": "1100.0.6",
|
|
37
|
+
"@pnpm/config.normalize-registries": "1100.0.6",
|
|
38
|
+
"@pnpm/config.reader": "1101.6.0",
|
|
38
39
|
"@pnpm/constants": "1100.0.0",
|
|
39
|
-
"@pnpm/
|
|
40
|
-
"@pnpm/
|
|
40
|
+
"@pnpm/building.policy": "1100.0.8",
|
|
41
|
+
"@pnpm/core-loggers": "1100.1.3",
|
|
41
42
|
"@pnpm/deps.graph-sequencer": "1100.0.0",
|
|
42
|
-
"@pnpm/deps.path": "1100.0.
|
|
43
|
+
"@pnpm/deps.path": "1100.0.6",
|
|
44
|
+
"@pnpm/deps.graph-hasher": "1100.2.3",
|
|
43
45
|
"@pnpm/error": "1100.0.0",
|
|
44
|
-
"@pnpm/
|
|
45
|
-
"@pnpm/
|
|
46
|
-
"@pnpm/installing.modules-yaml": "1100.0.
|
|
47
|
-
"@pnpm/lockfile.
|
|
48
|
-
"@pnpm/lockfile.walker": "1100.0.
|
|
49
|
-
"@pnpm/pkg-manifest.reader": "1100.0.
|
|
50
|
-
"@pnpm/
|
|
51
|
-
"@pnpm/store.connection-manager": "1100.2.
|
|
52
|
-
"@pnpm/store.controller-types": "1100.1.
|
|
53
|
-
"@pnpm/store.cafs": "1100.1.7",
|
|
46
|
+
"@pnpm/installing.context": "1100.0.15",
|
|
47
|
+
"@pnpm/exec.lifecycle": "1100.0.15",
|
|
48
|
+
"@pnpm/installing.modules-yaml": "1100.0.7",
|
|
49
|
+
"@pnpm/lockfile.utils": "1100.0.11",
|
|
50
|
+
"@pnpm/lockfile.walker": "1100.0.9",
|
|
51
|
+
"@pnpm/pkg-manifest.reader": "1100.0.6",
|
|
52
|
+
"@pnpm/store.cafs": "1100.1.8",
|
|
53
|
+
"@pnpm/store.connection-manager": "1100.2.6",
|
|
54
|
+
"@pnpm/store.controller-types": "1100.1.3",
|
|
54
55
|
"@pnpm/store.index": "1100.1.0",
|
|
55
|
-
"@pnpm/types": "
|
|
56
|
+
"@pnpm/lockfile.types": "1100.0.9",
|
|
57
|
+
"@pnpm/types": "1101.3.0",
|
|
58
|
+
"@pnpm/bins.linker": "1100.0.11"
|
|
56
59
|
},
|
|
57
60
|
"peerDependencies": {
|
|
58
61
|
"@pnpm/logger": "^1001.0.1",
|
|
59
|
-
"@pnpm/worker": "^1100.1.
|
|
62
|
+
"@pnpm/worker": "^1100.1.9"
|
|
60
63
|
},
|
|
61
64
|
"devDependencies": {
|
|
62
65
|
"@types/semver": "7.7.1",
|
|
63
|
-
"@pnpm/building.after-install": "1101.0.
|
|
66
|
+
"@pnpm/building.after-install": "1101.0.19"
|
|
64
67
|
},
|
|
65
68
|
"engines": {
|
|
66
69
|
"node": ">=22.13"
|