From 2d725cf0443c8c611cabc55896cf121ce7e69e2a Mon Sep 17 00:00:00 2001 From: Brian Chen Date: Thu, 6 Jan 2022 07:37:14 +1100 Subject: [PATCH 1/3] add working change --- cli/src/lib/npm/npmLibDefs.js | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/cli/src/lib/npm/npmLibDefs.js b/cli/src/lib/npm/npmLibDefs.js index 3c8922233e..a4333442ba 100644 --- a/cli/src/lib/npm/npmLibDefs.js +++ b/cli/src/lib/npm/npmLibDefs.js @@ -313,7 +313,23 @@ function pkgVersionMatch(pkgSemverRaw: string, libDefSemverRaw: string) { const libDefUpper = getRangeUpperBound(libDefRange); const pkgBelowLower = semver.gtr(libDefLower, pkgSemver); - const pkgAboveUpper = semver.ltr(libDefUpper, pkgSemver); + // semver.coerce explanation: + // We compare a libdef version against a package version + // to check if it matches the range, if pkgAboveUpper would be true + // that means it doesn't match. + // + // Mismatches occur when for example libdef is defined as is 8.5.x + // which makes it's upper <8.6.0 + // pkgSemver is ^8.5.1 who's range will reach a max of <9.0.0 + // therefore libDefUpper is less than maximum pkgSemver range. + // + // coerce will transform any semver passed in to an explicit + // version, in this case, ^8.5.1 becomes 8.5.1 which allows + // 8.6.0 (libdef) to be above 8.5.1 (pkg). + const pkgAboveUpper = semver.ltr( + libDefUpper, + semver.coerce(pkgSemver)?.version ?? pkgSemver, + ); if (pkgBelowLower || pkgAboveUpper) { return false; } From 38ca09de1928b1feb7846592fe2cdb0ce4e1e598 Mon Sep 17 00:00:00 2001 From: Brian Chen Date: Thu, 6 Jan 2022 07:41:35 +1100 Subject: [PATCH 2/3] expose pkgVersionMatch func for testing --- cli/src/lib/npm/npmLibDefs.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/cli/src/lib/npm/npmLibDefs.js b/cli/src/lib/npm/npmLibDefs.js index a4333442ba..c1f1e36054 100644 --- a/cli/src/lib/npm/npmLibDefs.js +++ b/cli/src/lib/npm/npmLibDefs.js @@ -254,7 +254,10 @@ function validateVersionNumPart(part: string, partName: string): number { return num; } -function pkgVersionMatch(pkgSemverRaw: string, libDefSemverRaw: string) { +export function pkgVersionMatch( + pkgSemverRaw: string, + libDefSemverRaw: string, +): boolean { // The package version should be treated as a semver implicitly prefixed by // `^` or `~`. Depending on whether or not the minor value is defined. // i.e.: "foo_v2.2.x" is the same range as "~2.2.x" From d2589ceae3fa7a689a9a03aa98e9eb6374749c09 Mon Sep 17 00:00:00 2001 From: Brian Chen Date: Thu, 6 Jan 2022 07:50:00 +1100 Subject: [PATCH 3/3] add test cases --- cli/src/lib/npm/__tests__/npmLibDefs-test.js | 50 ++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/cli/src/lib/npm/__tests__/npmLibDefs-test.js b/cli/src/lib/npm/__tests__/npmLibDefs-test.js index 4ca5e83fbf..1f838b21ee 100644 --- a/cli/src/lib/npm/__tests__/npmLibDefs-test.js +++ b/cli/src/lib/npm/__tests__/npmLibDefs-test.js @@ -10,6 +10,7 @@ import { findNpmLibDef, getScopedPackageName, parseSignedCodeVersion, + pkgVersionMatch, } from '../npmLibDefs'; import * as cacheRepoUtils from '../../cacheRepoUtils'; @@ -299,6 +300,55 @@ describe('npmLibDefs', () => { }); }); + describe('pkgVersionMatch', () => { + it('matches minor libdef', () => { + expect(pkgVersionMatch('^8.5.1', '8.5.x')).toBe(true); + expect(pkgVersionMatch('~8.5.1', '8.5.x')).toBe(true); + }); + + it('matches major libdef', () => { + expect(pkgVersionMatch('^8.5.1', '8.x.x')).toBe(true); + expect(pkgVersionMatch('~8.5.1', '8.x.x')).toBe(true); + }); + + it('will not match a lower libdef', () => { + expect(pkgVersionMatch('^8.5.1', '8.4.x')).toBe(false); + expect(pkgVersionMatch('~8.5.1', '8.4.x')).toBe(false); + }); + + it('will not match a lower libdef by major value', () => { + expect(pkgVersionMatch('^8.5.1', '7.x.x')).toBe(false); + expect(pkgVersionMatch('~8.5.1', '7.x.x')).toBe(false); + }); + + it('will not match a greater libdef by minor value', () => { + expect(pkgVersionMatch('^8.5.1', '8.6.x')).toBe(false); + expect(pkgVersionMatch('~8.5.1', '8.6.x')).toBe(false); + }); + + it('will not match a greater libdef by major value', () => { + expect(pkgVersionMatch('^8.5.1', '9.x.x')).toBe(false); + expect(pkgVersionMatch('~8.5.1', '9.x.x')).toBe(false); + }); + + it('matches lowest range when version has >=', () => { + expect(pkgVersionMatch('>=8.5.1', '8.x.x')).toBe(true); + expect(pkgVersionMatch('>=8.5.1', '8.5.x')).toBe(true); + }); + + it('will not match any greater libdef when version has >=', () => { + expect(pkgVersionMatch('>=8.5.1', '9.x.x')).toBe(false); + }); + + it('matches explicit libdef with major range libdef', () => { + expect(pkgVersionMatch('8.5.1', '8.x.x')).toBe(true); + }); + + it('matches explicit libdef with minor range libdef', () => { + expect(pkgVersionMatch('8.5.1', '8.5.x')).toBe(true); + }); + }); + describe('getInstalledNpmLibDefs', () => { const FIXTURE_ROOT = path.join(BASE_FIXTURE_ROOT, 'getInstalledNpmLibDefs');