From ec50dc98ccc1aaddbe0fda7631eb24335163fe2b Mon Sep 17 00:00:00 2001 From: Andrew Leedham Date: Fri, 4 Aug 2023 15:39:43 +0100 Subject: [PATCH] fix(overrides): filter overrides by intersection instead of subset (#6904) close #6878 --- .changeset/sour-spiders-rest.md | 5 +++++ .../src/createVersionsOverrider.ts | 8 ++++---- hooks/read-package-hook/src/isIntersectingRange.ts | 9 +++++++++ .../test/createVersionOverrider.test.ts | 13 +++++++++++++ 4 files changed, 31 insertions(+), 4 deletions(-) create mode 100644 .changeset/sour-spiders-rest.md create mode 100644 hooks/read-package-hook/src/isIntersectingRange.ts diff --git a/.changeset/sour-spiders-rest.md b/.changeset/sour-spiders-rest.md new file mode 100644 index 0000000000..7a05f7461f --- /dev/null +++ b/.changeset/sour-spiders-rest.md @@ -0,0 +1,5 @@ +--- +"@pnpm/hooks.read-package-hook": patch +--- + +Compare overriding ranges with intersection instead of subset to fix override range bug [#6878](https://github.com/pnpm/pnpm/issues/6878). diff --git a/hooks/read-package-hook/src/createVersionsOverrider.ts b/hooks/read-package-hook/src/createVersionsOverrider.ts index ae16a9b8da..22f732a72a 100644 --- a/hooks/read-package-hook/src/createVersionsOverrider.ts +++ b/hooks/read-package-hook/src/createVersionsOverrider.ts @@ -5,7 +5,7 @@ import { type Dependencies, type PackageManifest, type ReadPackageHook } from '@ import { PnpmError } from '@pnpm/error' import { parseOverrides } from '@pnpm/parse-overrides' import normalizePath from 'normalize-path' -import { isSubRange } from './isSubRange' +import { isIntersectingRange } from './isIntersectingRange' export function createVersionsOverrider ( overrides: Record, @@ -94,13 +94,13 @@ function overrideDeps ( pickMostSpecificVersionOverride( versionOverrides.filter( ({ targetPkg }) => - targetPkg.name === name && isSubRange(targetPkg.pref, pref) + targetPkg.name === name && isIntersectingRange(targetPkg.pref, pref) ) ) ?? pickMostSpecificVersionOverride( genericVersionOverrides.filter( ({ targetPkg }) => - targetPkg.name === name && isSubRange(targetPkg.pref, pref) + targetPkg.name === name && isIntersectingRange(targetPkg.pref, pref) ) ) if (!versionOverride) continue @@ -122,5 +122,5 @@ function overrideDeps ( } function pickMostSpecificVersionOverride (versionOverrides: VersionOverride[]): VersionOverride | undefined { - return versionOverrides.sort((a, b) => isSubRange(b.targetPkg.pref ?? '', a.targetPkg.pref ?? '') ? -1 : 1)[0] + return versionOverrides.sort((a, b) => isIntersectingRange(b.targetPkg.pref ?? '', a.targetPkg.pref ?? '') ? -1 : 1)[0] } diff --git a/hooks/read-package-hook/src/isIntersectingRange.ts b/hooks/read-package-hook/src/isIntersectingRange.ts new file mode 100644 index 0000000000..828b233196 --- /dev/null +++ b/hooks/read-package-hook/src/isIntersectingRange.ts @@ -0,0 +1,9 @@ +import semver from 'semver' + +export function isIntersectingRange (range1: string | undefined, range2: string) { + return !range1 || + range2 === range1 || + semver.validRange(range2) != null && + semver.validRange(range1) != null && + semver.intersects(range2, range1) +} diff --git a/hooks/read-package-hook/test/createVersionOverrider.test.ts b/hooks/read-package-hook/test/createVersionOverrider.test.ts index 9b4859cc00..7e4aa3f588 100644 --- a/hooks/read-package-hook/test/createVersionOverrider.test.ts +++ b/hooks/read-package-hook/test/createVersionOverrider.test.ts @@ -370,3 +370,16 @@ test('createVersionOverrider() throws error when supplied an invalid selector', 'foo > bar': '2', }, process.cwd())).toThrowError('Cannot parse the "foo > bar" selector in pnpm.overrides') }) + +test('createVersionsOverrider() matches intersections', () => { + const overrider = createVersionsOverrider({ + 'foo@<1.2.4': '>=1.2.4', + }, process.cwd()) + expect( + overrider({ + dependencies: { foo: '^1.2.3' }, + }) + ).toStrictEqual({ + dependencies: { foo: '>=1.2.4' }, + }) +}) \ No newline at end of file