@pnpm/deps.graph-hasher 1100.3.0 → 1100.3.1
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 +10 -0
- package/lib/index.d.ts +18 -3
- package/lib/index.js +46 -31
- package/package.json +4 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# @pnpm/calc-dep-state
|
|
2
2
|
|
|
3
|
+
## 1100.3.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Fixed global virtual store hashes for dependency cycles. Every package that transitively depends on an allowed build now includes the engine in its store path, independent of traversal order [pnpm/pnpm#14341](https://github.com/pnpm/pnpm/issues/14341).
|
|
8
|
+
|
|
9
|
+
- Updated dependencies:
|
|
10
|
+
- @pnpm/lockfile.types@1100.1.1
|
|
11
|
+
- @pnpm/lockfile.utils@1102.1.1
|
|
12
|
+
|
|
3
13
|
## 1100.3.0
|
|
4
14
|
|
|
5
15
|
### Minor Changes
|
package/lib/index.d.ts
CHANGED
|
@@ -126,11 +126,11 @@ export interface GraphNodeHashOptions {
|
|
|
126
126
|
lockfileDir?: string;
|
|
127
127
|
}
|
|
128
128
|
export declare function iterateHashedGraphNodes<T extends PkgMeta>(graph: DepsGraph<DepPath>, pkgMetaIterator: PkgMetaIterator<T>, opts?: GraphNodeHashOptions): IterableIterator<HashedDepPath<T>>;
|
|
129
|
-
export declare function calcGraphNodeHash<T extends PkgMeta>({ graph, cache,
|
|
129
|
+
export declare function calcGraphNodeHash<T extends PkgMeta>({ graph, cache, buildRequiredDepPaths, supportedArchitectures, nodeVersion, lockfileDir }: {
|
|
130
130
|
graph: DepsGraph<DepPath>;
|
|
131
131
|
cache: DepsStateCache;
|
|
132
|
-
|
|
133
|
-
|
|
132
|
+
/** See {@link computeBuildRequiredDepPaths}. */
|
|
133
|
+
buildRequiredDepPaths?: Set<DepPath>;
|
|
134
134
|
supportedArchitectures?: SupportedArchitectures;
|
|
135
135
|
/** See {@link GraphNodeHashOptions.nodeVersion}. */
|
|
136
136
|
nodeVersion?: string;
|
|
@@ -152,3 +152,18 @@ export interface PkgMetaAndSnapshot extends PkgMeta {
|
|
|
152
152
|
}
|
|
153
153
|
export declare function iteratePkgMeta(lockfile: LockfileObject, graph: DepsGraph<DepPath>): PkgMetaIterator<PkgMetaAndSnapshot>;
|
|
154
154
|
export declare function lockfileToDepGraph(lockfile: LockfileObject, supportedArchitectures?: SupportedArchitectures, lockfileDir?: string): DepsGraph<DepPath>;
|
|
155
|
+
/**
|
|
156
|
+
* Expand `builtDepPaths` to every node that is, or transitively depends
|
|
157
|
+
* on, one of them.
|
|
158
|
+
*
|
|
159
|
+
* The result gates the engine string in {@link calcGraphNodeHash}: only a
|
|
160
|
+
* package that may run a build script — or that depends on one — keeps the
|
|
161
|
+
* engine in its GVS hash. It is computed as one graph-wide reverse closure,
|
|
162
|
+
* so a package inside a dependency cycle gets the same answer no matter
|
|
163
|
+
* which node the hasher reaches it from.
|
|
164
|
+
*
|
|
165
|
+
* A path with no node in `graph` is kept and still marks whatever depends on
|
|
166
|
+
* it: the built set comes from the allowBuild policy rather than the graph,
|
|
167
|
+
* so the two can disagree.
|
|
168
|
+
*/
|
|
169
|
+
export declare function computeBuildRequiredDepPaths(graph: DepsGraph<DepPath>, builtDepPaths: Set<DepPath>): Set<DepPath>;
|
package/lib/index.js
CHANGED
|
@@ -167,11 +167,11 @@ function createDepGraphHashContext(supportedArchitectures) {
|
|
|
167
167
|
};
|
|
168
168
|
}
|
|
169
169
|
export function* iterateHashedGraphNodes(graph, pkgMetaIterator, opts = {}) {
|
|
170
|
-
let
|
|
170
|
+
let buildRequiredDepPaths;
|
|
171
171
|
let entries;
|
|
172
172
|
if (opts.allowBuild != null) {
|
|
173
173
|
const pkgMetaList = Array.from(pkgMetaIterator);
|
|
174
|
-
|
|
174
|
+
buildRequiredDepPaths = computeBuildRequiredDepPaths(graph, computeBuiltDepPaths(pkgMetaList, opts.allowBuild));
|
|
175
175
|
entries = pkgMetaList;
|
|
176
176
|
}
|
|
177
177
|
else {
|
|
@@ -180,8 +180,7 @@ export function* iterateHashedGraphNodes(graph, pkgMetaIterator, opts = {}) {
|
|
|
180
180
|
const ctx = {
|
|
181
181
|
graph,
|
|
182
182
|
cache: {},
|
|
183
|
-
|
|
184
|
-
buildRequiredCache: builtDepPaths !== undefined ? {} : undefined,
|
|
183
|
+
buildRequiredDepPaths,
|
|
185
184
|
supportedArchitectures: opts.supportedArchitectures,
|
|
186
185
|
nodeVersion: opts.nodeVersion,
|
|
187
186
|
lockfileDir: opts.lockfileDir,
|
|
@@ -193,15 +192,14 @@ export function* iterateHashedGraphNodes(graph, pkgMetaIterator, opts = {}) {
|
|
|
193
192
|
};
|
|
194
193
|
}
|
|
195
194
|
}
|
|
196
|
-
export function calcGraphNodeHash({ graph, cache,
|
|
195
|
+
export function calcGraphNodeHash({ graph, cache, buildRequiredDepPaths, supportedArchitectures, nodeVersion, lockfileDir }, pkgMeta) {
|
|
197
196
|
const { name, version, depPath } = pkgMeta;
|
|
198
|
-
// When
|
|
199
|
-
// we only include the engine name for packages that are allowed
|
|
200
|
-
// or transitively depend on a package that is allowed to build.
|
|
197
|
+
// When buildRequiredDepPaths is provided (derived from the allowBuilds
|
|
198
|
+
// config), we only include the engine name for packages that are allowed
|
|
199
|
+
// to build or transitively depend on a package that is allowed to build.
|
|
201
200
|
// This makes GVS hashes engine-agnostic for pure-JS packages,
|
|
202
201
|
// so they survive Node.js upgrades and architecture changes.
|
|
203
|
-
const includeEngine =
|
|
204
|
-
transitivelyRequiresBuild(graph, builtDepPaths, buildRequiredCache ??= {}, depPath, new Set());
|
|
202
|
+
const includeEngine = buildRequiredDepPaths === undefined || buildRequiredDepPaths.has(depPath);
|
|
205
203
|
// A snapshot that declares `engines.runtime` carries the desugared
|
|
206
204
|
// `node@runtime:<version>` pin as a child; that's the Node the bin
|
|
207
205
|
// linker spawns for its lifecycle scripts, so it has to drive the
|
|
@@ -347,30 +345,47 @@ function computeBuiltDepPaths(entries, allowBuild) {
|
|
|
347
345
|
}
|
|
348
346
|
return builtDepPaths;
|
|
349
347
|
}
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
348
|
+
/**
|
|
349
|
+
* Expand `builtDepPaths` to every node that is, or transitively depends
|
|
350
|
+
* on, one of them.
|
|
351
|
+
*
|
|
352
|
+
* The result gates the engine string in {@link calcGraphNodeHash}: only a
|
|
353
|
+
* package that may run a build script — or that depends on one — keeps the
|
|
354
|
+
* engine in its GVS hash. It is computed as one graph-wide reverse closure,
|
|
355
|
+
* so a package inside a dependency cycle gets the same answer no matter
|
|
356
|
+
* which node the hasher reaches it from.
|
|
357
|
+
*
|
|
358
|
+
* A path with no node in `graph` is kept and still marks whatever depends on
|
|
359
|
+
* it: the built set comes from the allowBuild policy rather than the graph,
|
|
360
|
+
* so the two can disagree.
|
|
361
|
+
*/
|
|
362
|
+
export function computeBuildRequiredDepPaths(graph, builtDepPaths) {
|
|
363
|
+
const buildRequiredDepPaths = new Set(builtDepPaths);
|
|
364
|
+
if (builtDepPaths.size === 0)
|
|
365
|
+
return buildRequiredDepPaths;
|
|
366
|
+
const parentsByChild = new Map();
|
|
367
|
+
for (const parent of Object.keys(graph)) {
|
|
368
|
+
for (const child of Object.values(graph[parent].children)) {
|
|
369
|
+
const parents = parentsByChild.get(child);
|
|
370
|
+
if (parents == null) {
|
|
371
|
+
parentsByChild.set(child, [parent]);
|
|
372
|
+
}
|
|
373
|
+
else {
|
|
374
|
+
parents.push(parent);
|
|
375
|
+
}
|
|
376
|
+
}
|
|
364
377
|
}
|
|
365
|
-
const
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
378
|
+
const pending = Array.from(builtDepPaths);
|
|
379
|
+
while (pending.length > 0) {
|
|
380
|
+
const child = pending.pop();
|
|
381
|
+
for (const parent of parentsByChild.get(child) ?? []) {
|
|
382
|
+
if (!buildRequiredDepPaths.has(parent)) {
|
|
383
|
+
buildRequiredDepPaths.add(parent);
|
|
384
|
+
pending.push(parent);
|
|
385
|
+
}
|
|
370
386
|
}
|
|
371
387
|
}
|
|
372
|
-
|
|
373
|
-
return false;
|
|
388
|
+
return buildRequiredDepPaths;
|
|
374
389
|
}
|
|
375
390
|
function lockfileDepsToGraphChildren(deps, lockfileDir, linkTargetNodes) {
|
|
376
391
|
const children = {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pnpm/deps.graph-hasher",
|
|
3
|
-
"version": "1100.3.
|
|
3
|
+
"version": "1100.3.1",
|
|
4
4
|
"description": "Calculates the state of a dependency",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"pnpm",
|
|
@@ -30,15 +30,15 @@
|
|
|
30
30
|
"@pnpm/crypto.object-hasher": "1100.0.1",
|
|
31
31
|
"@pnpm/deps.path": "1101.0.1",
|
|
32
32
|
"@pnpm/engine.runtime.system-version": "1100.0.11",
|
|
33
|
-
"@pnpm/lockfile.types": "1100.1.
|
|
34
|
-
"@pnpm/lockfile.utils": "1102.1.
|
|
33
|
+
"@pnpm/lockfile.types": "1100.1.1",
|
|
34
|
+
"@pnpm/lockfile.utils": "1102.1.1",
|
|
35
35
|
"@pnpm/resolving.resolver-base": "1101.2.0",
|
|
36
36
|
"@pnpm/types": "1102.1.0",
|
|
37
37
|
"detect-libc": "^2.1.2"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
40
|
"@jest/globals": "30.4.1",
|
|
41
|
-
"@pnpm/deps.graph-hasher": "1100.3.
|
|
41
|
+
"@pnpm/deps.graph-hasher": "1100.3.1"
|
|
42
42
|
},
|
|
43
43
|
"engines": {
|
|
44
44
|
"node": ">=22.13"
|