From f9258c1ca464b49179b28701aed66dbd6538759c Mon Sep 17 00:00:00 2001 From: Nabeel Saabna <48175656+nabeelsaabna@users.noreply.github.com> Date: Mon, 8 Aug 2022 21:46:07 +0300 Subject: [PATCH] fix(versioning/semver-coerced): fix bugs in semver-coerced (#16973) --- .../versioning/semver-coerced/index.spec.ts | 55 +++++++++++++------ .../versioning/semver-coerced/index.ts | 30 ++++++++-- 2 files changed, 64 insertions(+), 21 deletions(-) diff --git a/lib/modules/versioning/semver-coerced/index.spec.ts b/lib/modules/versioning/semver-coerced/index.spec.ts index 2e01daf209..49dfd6b731 100644 --- a/lib/modules/versioning/semver-coerced/index.spec.ts +++ b/lib/modules/versioning/semver-coerced/index.spec.ts @@ -49,16 +49,26 @@ describe('modules/versioning/semver-coerced/index', () => { }); describe('.getPatch(input)', () => { - it('should return patch version number for strict semver', () => { - expect(semverCoerced.getPatch('1.0.2')).toBe(2); - }); - - it('should return patch version number for non-strict semver', () => { - expect(semverCoerced.getPatch('v3.1.2-foo')).toBe(2); - }); - - it('invalid version', () => { - expect(semverCoerced.getMajor('xxx')).toBeNull(); + test.each` + version | expected + ${'1.0.2'} | ${2} + ${'v3.1.2-foo'} | ${2} + ${'v1.3.5'} | ${5} + ${'v2.1'} | ${0} + ${'3.4'} | ${0} + ${'v2'} | ${0} + ${'2'} | ${0} + ${'v1.0.4-alpha'} | ${4} + ${'1.0.3-Beta.1'} | ${3} + ${'1.0.0-rc2'} | ${0} + ${'v1.0.8-rc2'} | ${8} + ${'1.0-Beta.0'} | ${0} + ${'two1.0'} | ${0} + ${'ver1.2.3'} | ${3} + ${'r3.0'} | ${0} + ${'abc'} | ${null} + `('getPatch("$version") === $expected', ({ version, expected }) => { + expect(semverCoerced.getPatch(version)).toBe(expected); }); }); @@ -121,12 +131,25 @@ describe('modules/versioning/semver-coerced/index', () => { }); describe('.isStable(input)', () => { - it('should return true for a stable version', () => { - expect(semverCoerced.isStable('1.0.0')).toBeTrue(); - }); - - it('should return false for an prerelease version', () => { - expect(semverCoerced.isStable('v1.0-alpha')).toBeFalse(); + test.each` + version | expected + ${'1.0.0'} | ${true} + ${'v1.3.5'} | ${true} + ${'v2.1'} | ${true} + ${'3.4'} | ${true} + ${'v2'} | ${true} + ${'2'} | ${true} + ${'v1.0.0-alpha'} | ${false} + ${'1.0.0-Beta.1'} | ${false} + ${'1.0.0-rc2'} | ${false} + ${'v1.0.0-rc2'} | ${false} + ${'1.0-Beta.0'} | ${false} + ${'v1.0-alpha'} | ${false} + ${'two1.0'} | ${false} + ${'ver1.2.3'} | ${false} + ${'r3.0'} | ${false} + `('isStable("$version") === $expected', ({ version, expected }) => { + expect(semverCoerced.isStable(version)).toBe(expected); }); }); diff --git a/lib/modules/versioning/semver-coerced/index.ts b/lib/modules/versioning/semver-coerced/index.ts index 4500e1faf3..c17e9d248d 100644 --- a/lib/modules/versioning/semver-coerced/index.ts +++ b/lib/modules/versioning/semver-coerced/index.ts @@ -9,7 +9,25 @@ export const displayName = 'Coerced Semantic Versioning'; export const urls = ['https://semver.org/']; export const supportsRanges = false; -const { is: isStable } = stable; +function isStable(version: string): boolean { + // matching a version with the semver prefix + // v1.2.3, 1.2.3, v1.2, 1.2, v1, 1 + const regx = regEx( + /^v?(?<major>\d+)(?<minor>\.\d+)?(?<patch>\.\d+)?(?<others>.+)?/ + ); + const m = regx.exec(version); + + if (!m?.groups) { + return false; + } + + const major = m.groups['major']; + const newMinor = m.groups['minor'] ?? '.0'; + const newPatch = m.groups['patch'] ?? '.0'; + const others = m.groups['others'] ?? ''; + const fixed = major + newMinor + newPatch + others; + return stable.is(fixed); +} function sortVersions(a: string, b: string): number { const aCoerced = semver.coerce(a); @@ -29,7 +47,8 @@ function getMinor(a: string | SemVer): number | null { } function getPatch(a: string | SemVer): number | null { - return semver.patch(a); + const aCoerced = semver.coerce(a); + return aCoerced ? semver.patch(aCoerced) : null; } function matches(version: string, range: string): boolean { @@ -77,9 +96,10 @@ function isLessThanRange(version: string, range: string): boolean { function isGreaterThan(version: string, other: string): boolean { const coercedVersion = semver.coerce(version); const coercedOther = semver.coerce(other); - return coercedVersion && coercedOther - ? semver.gt(coercedVersion, coercedOther) - : false; + if (!coercedVersion || !coercedOther) { + return false; + } + return semver.gt(coercedVersion, coercedOther); } const startsWithNumberRegex = regEx(`^\\d`); -- GitLab