feat: sort keys before calculating checksum (#6839)

close #6824
This commit is contained in:
Khải
2023-07-19 19:19:27 +07:00
committed by GitHub
parent 22bbe92554
commit 388a13b56a
6 changed files with 127 additions and 4 deletions

View File

@@ -0,0 +1,6 @@
---
"@pnpm/core": patch
"pnpm": patch
---
Sort keys in `packageExtensions` before calculating `packageExtensionsChecksum`. Fix [#6824](https://github.com/pnpm/pnpm/issues/6824).

View File

@@ -67,6 +67,7 @@
"ramda": "npm:@pnpm/ramda@0.28.1",
"run-groups": "^3.0.1",
"semver": "^7.5.4",
"sort-keys": "^4.2.0",
"version-selector-type": "^3.0.0"
},
"devDependencies": {

View File

@@ -0,0 +1,60 @@
import { createObjectChecksum } from './index'
function assets () {
const sorted = {
abc: {
a: 0,
b: [0, 1, 2],
c: null,
},
def: {
foo: 'bar',
hello: 'world',
},
} as const
const unsorted1 = {
abc: {
b: [0, 1, 2],
a: 0,
c: null,
},
def: {
hello: 'world',
foo: 'bar',
},
} as const
const unsorted2 = {
def: {
foo: 'bar',
hello: 'world',
},
abc: {
a: 0,
b: [0, 1, 2],
c: null,
},
} as const
const unsorted3 = {
def: {
hello: 'world',
foo: 'bar',
},
abc: {
b: [0, 1, 2],
a: 0,
c: null,
},
} as const
return { sorted, unsorted1, unsorted2, unsorted3 } as const
}
test('createObjectChecksum', () => {
const { sorted, unsorted1, unsorted2, unsorted3 } = assets()
expect(createObjectChecksum(unsorted1)).toBe(createObjectChecksum(sorted))
expect(createObjectChecksum(unsorted2)).toBe(createObjectChecksum(sorted))
expect(createObjectChecksum(unsorted3)).toBe(createObjectChecksum(sorted))
})

View File

@@ -72,6 +72,7 @@ import pickBy from 'ramda/src/pickBy'
import pipeWith from 'ramda/src/pipeWith'
import props from 'ramda/src/props'
import unnest from 'ramda/src/unnest'
import sortKeys from 'sort-keys'
import { parseWantedDependencies } from '../parseWantedDependencies'
import { removeDeps } from '../uninstall/removeDeps'
import { allProjectsAreUpToDate } from './allProjectsAreUpToDate'
@@ -749,8 +750,8 @@ function getOutdatedLockfileSetting (
return null
}
export function createObjectChecksum (obj: unknown) {
const s = JSON.stringify(obj)
export function createObjectChecksum (obj: Record<string, unknown>) {
const s = JSON.stringify(sortKeys(obj, { deep: true }))
return crypto.createHash('md5').update(s).digest('hex')
}

View File

@@ -1,7 +1,7 @@
import { PnpmError } from '@pnpm/error'
import { prepareEmpty } from '@pnpm/prepare'
import { addDependenciesToPackage, mutateModulesInSingleProject } from '@pnpm/core'
import { type PackageExtension } from '@pnpm/types'
import { addDependenciesToPackage, mutateModulesInSingleProject, install } from '@pnpm/core'
import { type PackageExtension, type ProjectManifest } from '@pnpm/types'
import { createObjectChecksum } from '../../lib/install/index'
import {
testDefaults,
@@ -94,6 +94,58 @@ test('manifests are extended with fields specified by packageExtensions', async
)
})
test('packageExtensionsChecksum does not change regardless of keys order', async () => {
const project = prepareEmpty()
const packageExtensions1: Record<string, PackageExtension> = {
'is-odd': {
peerDependencies: {
'is-number': '*',
},
},
'is-even': {
peerDependencies: {
'is-number': '*',
},
},
}
const packageExtensions2: Record<string, PackageExtension> = {
'is-even': {
peerDependencies: {
'is-number': '*',
},
},
'is-odd': {
peerDependencies: {
'is-number': '*',
},
},
}
const manifest = (): ProjectManifest => ({
dependencies: {
'is-even': '*',
'is-odd': '*',
},
})
await install(manifest(), await testDefaults({
packageExtensions: packageExtensions1,
}))
const lockfile1 = await project.readLockfile()
const checksum1 = lockfile1.packageExtensionsChecksum
await install(manifest(), await testDefaults({
packageExtensions: packageExtensions2,
}))
const lockfile2 = await project.readLockfile()
const checksum2 = lockfile2.packageExtensionsChecksum
expect(checksum1).toBe(checksum2)
expect(checksum1).not.toBeFalsy()
})
test('manifests are patched by extensions from the compatibility database', async () => {
const project = prepareEmpty()

3
pnpm-lock.yaml generated
View File

@@ -3000,6 +3000,9 @@ importers:
semver:
specifier: ^7.5.4
version: 7.5.4
sort-keys:
specifier: ^4.2.0
version: 4.2.0
version-selector-type:
specifier: ^3.0.0
version: 3.0.0