diff --git a/lib/versioning/semver-coerced/index.spec.ts b/lib/versioning/semver-coerced/index.spec.ts index 25fdee12ad445f539d1fd9e977c7e426125cb48b..27418066798bc1bfe1b151c23e69e9e43a27b66a 100644 --- a/lib/versioning/semver-coerced/index.spec.ts +++ b/lib/versioning/semver-coerced/index.spec.ts @@ -68,15 +68,19 @@ describe('versioning/semver-coerced/index', () => { it('should return false for lower version in strict semver', () => { expect(semverCoerced.isGreaterThan('3.1.2', '4.1.0')).toBeFalsy(); }); + + it('should return false if version cannot be coerced', () => { + expect(semverCoerced.isGreaterThan('e.e.e', '4.1.0')).toBeFalsy(); + }); }); describe('.isLessThanRange(version, range)', () => { it('should return true for a lower version in strict semver', () => { - expect(semverCoerced.isLessThanRange('1.0.2', '~2.0')).toBeTruthy(); + expect(semverCoerced.isLessThanRange?.('1.0.2', '~2.0')).toBeTruthy(); }); it('should return false for in-range version in strict semver', () => { - expect(semverCoerced.isLessThanRange('3.0.2', '~3.0')).toBeFalsy(); + expect(semverCoerced.isLessThanRange?.('3.0.2', '~3.0')).toBeFalsy(); }); }); diff --git a/lib/versioning/semver-coerced/index.ts b/lib/versioning/semver-coerced/index.ts index 980627059207320efee00979d312a08c365cf1a9..941f276e7a21d06c648a500da62509d50ed8c193 100644 --- a/lib/versioning/semver-coerced/index.ts +++ b/lib/versioning/semver-coerced/index.ts @@ -1,3 +1,4 @@ +import is from '@sindresorhus/is'; import semver, { SemVer } from 'semver'; import stable from 'semver-stable'; import { regEx } from '../../util/regex'; @@ -11,15 +12,20 @@ export const supportsRanges = false; const { is: isStable } = stable; function sortVersions(a: string, b: string): number { - return semver.compare(semver.coerce(a), semver.coerce(b)); + const aCoerced = semver.coerce(a); + const bCoerced = semver.coerce(b); + + return aCoerced && bCoerced ? semver.compare(aCoerced, bCoerced) : 0; } function getMajor(a: string | SemVer): number | null { - return semver.major(semver.coerce(a)); + const aCoerced = semver.coerce(a); + return aCoerced ? semver.major(aCoerced) : null; } function getMinor(a: string | SemVer): number | null { - return semver.minor(semver.coerce(a)); + const aCoerced = semver.coerce(a); + return aCoerced ? semver.minor(aCoerced) : null; } function getPatch(a: string | SemVer): number | null { @@ -27,11 +33,14 @@ function getPatch(a: string | SemVer): number | null { } function matches(version: string, range: string): boolean { - return semver.satisfies(semver.coerce(version), range); + const coercedVersion = semver.coerce(version); + return coercedVersion ? semver.satisfies(coercedVersion, range) : false; } function equals(a: string, b: string): boolean { - return semver.eq(semver.coerce(a), semver.coerce(b)); + const aCoerced = semver.coerce(a); + const bCoerced = semver.coerce(b); + return aCoerced && bCoerced ? semver.eq(aCoerced, bCoerced) : false; } function isValid(version: string): string | boolean | null { @@ -42,10 +51,10 @@ function getSatisfyingVersion( versions: string[], range: string ): string | null { - const coercedVersions = versions.map((version) => { - const coercedVersion = semver.coerce(version); - return coercedVersion ? coercedVersion.version : null; - }); + const coercedVersions = versions + .map((version) => semver.coerce(version)?.version) + .filter(is.string); + return semver.maxSatisfying(coercedVersions, range); } @@ -53,19 +62,24 @@ function minSatisfyingVersion( versions: string[], range: string ): string | null { - const coercedVersions = versions.map((version) => { - const coercedVersion = semver.coerce(version); - return coercedVersion ? coercedVersion.version : null; - }); + const coercedVersions = versions + .map((version) => semver.coerce(version)?.version) + .filter(is.string); + return semver.minSatisfying(coercedVersions, range); } function isLessThanRange(version: string, range: string): boolean { - return semver.ltr(semver.coerce(version), range); + const coercedVersion = semver.coerce(version); + return coercedVersion ? semver.ltr(coercedVersion, range) : false; } function isGreaterThan(version: string, other: string): boolean { - return semver.gt(semver.coerce(version), semver.coerce(other)); + const coercedVersion = semver.coerce(version); + const coercedOther = semver.coerce(other); + return coercedVersion && coercedOther + ? semver.gt(coercedVersion, coercedOther) + : false; } const startsWithNumberRegex = regEx(`^\\d`); @@ -81,7 +95,8 @@ function isSingleVersion(version: string): string | boolean | null { } // If this is left as an alias, inputs like "17.04.0" throw errors -export const isVersion = (input: string): string | boolean => isValid(input); +export const isVersion = (input: string): string | boolean | null => + isValid(input); export { isVersion as isValid, getSatisfyingVersion }; diff --git a/lib/versioning/semver/index.ts b/lib/versioning/semver/index.ts index 76ee0b6b537e2b17241a7348472a27306f32a61d..dc9f8485b3a6a8812fd2da4833c87aa153c84948 100644 --- a/lib/versioning/semver/index.ts +++ b/lib/versioning/semver/index.ts @@ -24,7 +24,8 @@ const { } = semver; // If this is left as an alias, inputs like "17.04.0" throw errors -export const isVersion = (input: string): string => valid(input); +export const isVersion = (input: string): string | boolean | null => + valid(input); export { isVersion as isValid, getSatisfyingVersion }; diff --git a/tsconfig.strict.json b/tsconfig.strict.json index 9076ab5e2e8f51528f39da6808a372ffc2b0916e..8fd3ec0ec6a3c550d0c7d3124ba2ccad02cd3864 100644 --- a/tsconfig.strict.json +++ b/tsconfig.strict.json @@ -46,6 +46,8 @@ "lib/util/url.ts", "lib/versioning/swift/*.ts", "lib/versioning/ubuntu/*.ts", + "lib/versioning/semver/*.ts", + "lib/versioning/semver-coerced/*.ts", "lib/workers/pr/changelog/hbs-template.ts", "lib/workers/pr/changelog/types.ts", "lib/workers/repository/init/types.ts",