mirror of
https://github.com/pnpm/pnpm.git
synced 2026-04-27 18:46:18 -04:00
fix(lockfile): handle non-semver versions in lockfile merger without crashing (#11102)
* fix(lockfile): handle non-semver versions in lockfile merger without crashing * Apply suggestion from @Copilot Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: Zoltan Kochan <z@kochan.io> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
6
.changeset/fix-lockfile-merger-non-semver.md
Normal file
6
.changeset/fix-lockfile-merger-non-semver.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
"@pnpm/lockfile.merger": patch
|
||||
"pnpm": patch
|
||||
---
|
||||
|
||||
Fixed a crash in the lockfile merger when merging non-semver version strings (e.g. `link:`, `file:`, git URLs).
|
||||
@@ -99,8 +99,13 @@ function mergeVersions (ourValue: string, theirValue: string): string {
|
||||
if (!ourValue) return theirValue
|
||||
const [ourVersion] = ourValue.split('(')
|
||||
const [theirVersion] = theirValue.split('(')
|
||||
if (semver.gt(ourVersion, theirVersion)) {
|
||||
return ourValue
|
||||
const validOurVersion = semver.valid(ourVersion)
|
||||
const validTheirVersion = semver.valid(theirVersion)
|
||||
|
||||
if (validOurVersion && validTheirVersion) {
|
||||
return semver.gt(ourVersion, theirVersion) ? ourValue : theirValue
|
||||
}
|
||||
|
||||
// Non-semver versions (link:, file:, git URLs, etc.) — prefer theirs
|
||||
return theirValue
|
||||
}
|
||||
|
||||
@@ -353,3 +353,37 @@ test('prefers our lockfile resolutions when it has newer packages #2', () => {
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
test('does not crash when merging non-semver versions (link: protocol)', () => {
|
||||
const base: LockfileObject = {
|
||||
importers: {
|
||||
['.' as ProjectId]: {
|
||||
dependencies: { a: '1.0.0' },
|
||||
specifiers: {},
|
||||
},
|
||||
},
|
||||
lockfileVersion: '5.2',
|
||||
packages: {
|
||||
['/a@1.0.0' as DepPath]: {
|
||||
dependencies: { linked: 'link:../pkg1' },
|
||||
resolution: { integrity: '' },
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
const mergedLockfile = mergeLockfileChanges(
|
||||
base,
|
||||
{
|
||||
...base,
|
||||
packages: {
|
||||
['/a@1.0.0' as DepPath]: {
|
||||
dependencies: { linked: 'link:../pkg2' },
|
||||
resolution: { integrity: '' },
|
||||
},
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
// Should not crash and should pick theirs (the incoming change)
|
||||
expect(mergedLockfile.packages?.['/a@1.0.0' as DepPath].dependencies?.linked).toBe('link:../pkg2')
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user