mirror of
https://github.com/pnpm/pnpm.git
synced 2025-12-23 23:29:17 -05:00
fix: dependency graph hash calculation (#10236)
This commit is contained in:
6
.changeset/stale-bars-tan.md
Normal file
6
.changeset/stale-bars-tan.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
"@pnpm/dependency-path": patch
|
||||
"@pnpm/calc-dep-state": patch
|
||||
---
|
||||
|
||||
Fix dependency graph hash calculation for runtime dependencies (like Node.js, Deno).
|
||||
@@ -48,7 +48,15 @@ function calcDepGraphHash<T extends string> (
|
||||
if (cache[depPath]) return cache[depPath]
|
||||
const node = depsGraph[depPath]
|
||||
if (!node) return ''
|
||||
node.fullPkgId ??= createFullPkgId(node.pkgIdWithPatchHash!, node.resolution!)
|
||||
if (!node.fullPkgId) {
|
||||
if (!node.pkgIdWithPatchHash) {
|
||||
throw new Error(`pkgIdWithPatchHash is not defined for ${depPath} in depsGraph`)
|
||||
}
|
||||
if (!node.resolution) {
|
||||
throw new Error(`resolution is not defined for ${depPath} in depsGraph`)
|
||||
}
|
||||
node.fullPkgId = createFullPkgId(node.pkgIdWithPatchHash, node.resolution)
|
||||
}
|
||||
const deps: Record<string, string> = {}
|
||||
if (Object.keys(node.children).length && !parents.has(node.fullPkgId)) {
|
||||
const nextParents = new Set([...Array.from(parents), node.fullPkgId])
|
||||
@@ -135,6 +143,6 @@ function lockfileDepsToGraphChildren (deps: Record<string, string>): Record<stri
|
||||
}
|
||||
|
||||
function createFullPkgId (pkgIdWithPatchHash: PkgIdWithPatchHash, resolution: LockfileResolution): string {
|
||||
const res = 'integrity' in resolution ? resolution.integrity : JSON.stringify(resolution)
|
||||
const res = 'integrity' in resolution ? resolution.integrity : hashObject(resolution)
|
||||
return `${pkgIdWithPatchHash}:${res}`
|
||||
}
|
||||
|
||||
@@ -66,9 +66,6 @@ export function getPkgIdWithPatchHash (depPath: DepPath): PkgIdWithPatchHash {
|
||||
if (sepIndex !== -1) {
|
||||
pkgId = pkgId.substring(0, sepIndex)
|
||||
}
|
||||
if (pkgId.includes(':')) {
|
||||
pkgId = pkgId.substring(pkgId.indexOf('@', 1) + 1)
|
||||
}
|
||||
return pkgId as PkgIdWithPatchHash
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/// <reference path="../../../__typings__/index.d.ts"/>
|
||||
import {
|
||||
depPathToFilename,
|
||||
getPkgIdWithPatchHash,
|
||||
isAbsolute,
|
||||
parse,
|
||||
refToRelative,
|
||||
@@ -109,3 +110,32 @@ test('tryGetPackageId', () => {
|
||||
expect(tryGetPackageId('/@(-.-)/foo@1.0.0(@types/babel__core@7.1.14)' as DepPath)).toBe('/@(-.-)/foo@1.0.0')
|
||||
expect(tryGetPackageId('foo@1.0.0(patch_hash=xxxx)(@types/babel__core@7.1.14)' as DepPath)).toBe('foo@1.0.0')
|
||||
})
|
||||
|
||||
test('getPkgIdWithPatchHash', () => {
|
||||
// Runtime dependency
|
||||
expect(getPkgIdWithPatchHash('node@runtime:24.11.1' as DepPath)).toBe('node@runtime:24.11.1')
|
||||
|
||||
// Regular packages
|
||||
expect(getPkgIdWithPatchHash('foo@1.0.0' as DepPath)).toBe('foo@1.0.0')
|
||||
|
||||
// Packages with patch hash
|
||||
expect(getPkgIdWithPatchHash('foo@1.0.0(patch_hash=xxxx)' as DepPath)).toBe('foo@1.0.0(patch_hash=xxxx)')
|
||||
|
||||
// Packages with peer dependencies (should remove peer dependencies)
|
||||
expect(getPkgIdWithPatchHash('foo@1.0.0(@types/babel__core@7.1.14)' as DepPath)).toBe('foo@1.0.0')
|
||||
|
||||
// Packages with both patch hash and peer dependencies (should keep patch hash, remove peer dependencies)
|
||||
expect(getPkgIdWithPatchHash('foo@1.0.0(patch_hash=xxxx)(@types/babel__core@7.1.14)' as DepPath)).toBe('foo@1.0.0(patch_hash=xxxx)')
|
||||
|
||||
// Scoped packages
|
||||
expect(getPkgIdWithPatchHash('@foo/bar@1.0.0' as DepPath)).toBe('@foo/bar@1.0.0')
|
||||
|
||||
// Scoped packages with patch hash
|
||||
expect(getPkgIdWithPatchHash('@foo/bar@1.0.0(patch_hash=yyyy)' as DepPath)).toBe('@foo/bar@1.0.0(patch_hash=yyyy)')
|
||||
|
||||
// Scoped packages with peer dependencies
|
||||
expect(getPkgIdWithPatchHash('@foo/bar@1.0.0(@types/node@18.0.0)' as DepPath)).toBe('@foo/bar@1.0.0')
|
||||
|
||||
// Scoped packages with both patch hash and peer dependencies
|
||||
expect(getPkgIdWithPatchHash('@foo/bar@1.0.0(patch_hash=zzzz)(@types/node@18.0.0)' as DepPath)).toBe('@foo/bar@1.0.0(patch_hash=zzzz)')
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user