Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix(lockfile): change sorting of keys in lockfile (#5151)
* fix(lockfile): change sorting of keys in lockfile Make it more deterministic and prevent unnecessary churn in the lockfile. It is useful when looking for affected projects after changes to the lockfile. When the changes happen among various developers using various locale, the locale specific sorting causes changes in the lockfile for extraneous projects. Therefore, it could cause running unnecessary CI jobs, builds, releases and other work that would not be needed otherwise. * chore: add comment Co-authored-by: Zoltan Kochan <z@kochan.io>
- Loading branch information
Showing
3 changed files
with
110 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
--- | ||
"@pnpm/lockfile-file": patch | ||
"pnpm": patch | ||
--- | ||
|
||
Fix sorting of keys in lockfile to make it more deterministic and prevent unnecessary churn in the lockfile [#5151](https://github.com/pnpm/pnpm/pull/5151). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
import { LOCKFILE_VERSION } from '@pnpm/constants' | ||
import { sortLockfileKeys } from '../lib/sortLockfileKeys' | ||
|
||
test('sorts keys alphabetically', () => { | ||
const normalizedLockfile = sortLockfileKeys({ | ||
lockfileVersion: LOCKFILE_VERSION, | ||
importers: { | ||
foo: { | ||
dependencies: { | ||
zzz: 'link:../zzz', | ||
bar: 'link:../bar', | ||
aaa: 'link:../aaa', | ||
}, | ||
specifiers: { | ||
zzz: 'link:../zzz', | ||
bar: 'link:../bar', | ||
aaa: 'link:../aaa', | ||
}, | ||
}, | ||
bar: { | ||
specifiers: { | ||
baz: 'link:../baz', | ||
}, | ||
dependencies: { | ||
baz: 'link:../baz', | ||
}, | ||
}, | ||
}, | ||
}) | ||
|
||
expect(normalizedLockfile).toStrictEqual({ | ||
lockfileVersion: LOCKFILE_VERSION, | ||
importers: { | ||
bar: { | ||
dependencies: { | ||
baz: 'link:../baz', | ||
}, | ||
specifiers: { | ||
baz: 'link:../baz', | ||
}, | ||
}, | ||
foo: { | ||
dependencies: { | ||
aaa: 'link:../aaa', | ||
bar: 'link:../bar', | ||
zzz: 'link:../zzz', | ||
}, | ||
specifiers: { | ||
aaa: 'link:../aaa', | ||
bar: 'link:../bar', | ||
zzz: 'link:../zzz', | ||
}, | ||
}, | ||
}, | ||
}) | ||
expect(Object.keys(normalizedLockfile.importers?.foo.dependencies ?? {})).toStrictEqual(['aaa', 'bar', 'zzz']) | ||
expect(Object.keys(normalizedLockfile.importers?.foo.specifiers ?? {})).toStrictEqual(['aaa', 'bar', 'zzz']) | ||
}) | ||
|
||
test('sorting does not care about locale (e.g. Czech has "ch" as a single character after "h")', () => { | ||
// The input is properly sorted according to Czech locale. | ||
const normalizedLockfile = sortLockfileKeys({ | ||
lockfileVersion: LOCKFILE_VERSION, | ||
importers: { | ||
foo: { | ||
dependencies: { | ||
bar: 'link:../bar', | ||
href: 'link:../href', | ||
chmod: 'link:../chmod', | ||
}, | ||
specifiers: { | ||
bar: 'link:../bar', | ||
href: 'link:../href', | ||
chmod: 'link:../chmod', | ||
}, | ||
}, | ||
}, | ||
}) | ||
|
||
// The result should be the same as on other machines using whatever locale, e.g. English. | ||
expect(normalizedLockfile).toStrictEqual({ | ||
lockfileVersion: LOCKFILE_VERSION, | ||
importers: { | ||
foo: { | ||
dependencies: { | ||
bar: 'link:../bar', | ||
chmod: 'link:../chmod', | ||
href: 'link:../href', | ||
}, | ||
specifiers: { | ||
bar: 'link:../bar', | ||
chmod: 'link:../chmod', | ||
href: 'link:../href', | ||
}, | ||
}, | ||
}, | ||
}) | ||
expect(Object.keys(normalizedLockfile.importers?.foo.dependencies ?? {})).toStrictEqual(['bar', 'chmod', 'href']) | ||
expect(Object.keys(normalizedLockfile.importers?.foo.specifiers ?? {})).toStrictEqual(['bar', 'chmod', 'href']) | ||
}) |