From db211c594c61df5670ff8a2fad422a58c5dd4f4a Mon Sep 17 00:00:00 2001
From: Rhys Arkins <rhys@arkins.net>
Date: Fri, 14 Jan 2022 11:50:41 +0100
Subject: [PATCH] refactor: versioning.is functions return boolean (#13557)

Co-authored-by: Michael Kriese <michael.kriese@visualon.de>
---
 lib/versioning/cargo/index.ts          |  6 +++---
 lib/versioning/composer/index.spec.ts  |  7 +++++++
 lib/versioning/composer/index.ts       | 18 +++++++++++-------
 lib/versioning/docker/index.ts         |  4 ++--
 lib/versioning/gradle/index.spec.ts    |  2 +-
 lib/versioning/gradle/index.ts         |  4 ++--
 lib/versioning/hashicorp/index.ts      |  4 ++--
 lib/versioning/ivy/index.spec.ts       | 15 +++++++++++++++
 lib/versioning/ivy/index.ts            | 16 ++++++++++++----
 lib/versioning/loose/generic.ts        |  6 +++---
 lib/versioning/loose/index.spec.ts     | 15 +++++++++++++++
 lib/versioning/poetry/index.ts         |  4 ++--
 lib/versioning/regex/index.ts          |  4 ++--
 lib/versioning/rez/index.spec.ts       |  7 +++++++
 lib/versioning/rez/index.ts            | 12 ++++++++----
 lib/versioning/ruby/range.ts           |  6 +++---
 lib/versioning/semver-coerced/index.ts | 19 +++++++++++--------
 lib/versioning/semver/index.spec.ts    |  7 +++++++
 lib/versioning/semver/index.ts         | 21 ++++++++++++++++-----
 lib/versioning/types.ts                |  8 ++++----
 lib/versioning/ubuntu/index.ts         | 15 ++++++---------
 21 files changed, 139 insertions(+), 61 deletions(-)

diff --git a/lib/versioning/cargo/index.ts b/lib/versioning/cargo/index.ts
index ee33955a09..2a699e8de5 100644
--- a/lib/versioning/cargo/index.ts
+++ b/lib/versioning/cargo/index.ts
@@ -11,7 +11,7 @@ export const urls = [
 export const supportsRanges = true;
 export const supportedRangeStrategies = ['bump', 'extend', 'pin', 'replace'];
 
-const isVersion = (input: string): string | boolean => npm.isVersion(input);
+const isVersion = (input: string): boolean => npm.isVersion(input);
 
 function convertToCaret(item: string): string {
   // In Cargo, "1.2.3" doesn't mean exactly 1.2.3, it means >= 1.2.3 < 2.0.0
@@ -57,7 +57,7 @@ function npm2cargo(input: string): string {
 const isLessThanRange = (version: string, range: string): boolean =>
   npm.isLessThanRange(version, cargo2npm(range));
 
-export const isValid = (input: string): string | boolean =>
+export const isValid = (input: string): boolean =>
   npm.isValid(cargo2npm(input));
 
 const matches = (version: string, range: string): boolean =>
@@ -69,7 +69,7 @@ const getSatisfyingVersion = (versions: string[], range: string): string =>
 const minSatisfyingVersion = (versions: string[], range: string): string =>
   npm.minSatisfyingVersion(versions, cargo2npm(range));
 
-const isSingleVersion = (constraint: string): string | boolean =>
+const isSingleVersion = (constraint: string): boolean =>
   constraint.trim().startsWith('=') &&
   isVersion(constraint.trim().substring(1).trim());
 
diff --git a/lib/versioning/composer/index.spec.ts b/lib/versioning/composer/index.spec.ts
index b14bb08e01..f83d443870 100644
--- a/lib/versioning/composer/index.spec.ts
+++ b/lib/versioning/composer/index.spec.ts
@@ -169,4 +169,11 @@ describe('versioning/composer/index', () => {
   `('$versions -> sortVersions -> $expected ', ({ versions, expected }) => {
     expect(versions.sort(semver.sortVersions)).toEqual(expected);
   });
+
+  test.each`
+    version    | expected
+    ${'1.2.0'} | ${true}
+  `('isCompatible("$version") === $expected', ({ version, expected }) => {
+    expect(semver.isCompatible(version)).toBe(expected);
+  });
 });
diff --git a/lib/versioning/composer/index.ts b/lib/versioning/composer/index.ts
index 6d45845cd1..0b64fb5670 100644
--- a/lib/versioning/composer/index.ts
+++ b/lib/versioning/composer/index.ts
@@ -102,17 +102,17 @@ const isGreaterThan = (a: string, b: string): boolean =>
 const isLessThanRange = (version: string, range: string): boolean =>
   npm.isLessThanRange(composer2npm(version), composer2npm(range));
 
-const isSingleVersion = (input: string): string | boolean =>
-  input && npm.isSingleVersion(composer2npm(input));
+const isSingleVersion = (input: string): boolean =>
+  !!input && npm.isSingleVersion(composer2npm(input));
 
 const isStable = (version: string): boolean =>
   version && npm.isStable(composer2npm(version));
 
-export const isValid = (input: string): string | boolean =>
-  input && npm.isValid(composer2npm(input));
+export const isValid = (input: string): boolean =>
+  !!input && npm.isValid(composer2npm(input));
 
-export const isVersion = (input: string): string | boolean =>
-  input && npm.isVersion(composer2npm(input));
+export const isVersion = (input: string): boolean =>
+  !!input && npm.isVersion(composer2npm(input));
 
 const matches = (version: string, range: string): boolean =>
   npm.matches(composer2npm(version), composer2npm(range));
@@ -234,12 +234,16 @@ function sortVersions(a: string, b: string): number {
   return npm.sortVersions(composer2npm(a), composer2npm(b));
 }
 
+function isCompatible(version: string): boolean {
+  return isVersion(version);
+}
+
 export const api: VersioningApi = {
   equals,
   getMajor,
   getMinor,
   getPatch,
-  isCompatible: isVersion,
+  isCompatible,
   isGreaterThan,
   isLessThanRange,
   isSingleVersion,
diff --git a/lib/versioning/docker/index.ts b/lib/versioning/docker/index.ts
index 909ede9a8e..3e9ce2ad5e 100644
--- a/lib/versioning/docker/index.ts
+++ b/lib/versioning/docker/index.ts
@@ -71,9 +71,9 @@ class DockerVersioningApi extends GenericVersioningApi {
     return parsed2.suffix.localeCompare(parsed1.suffix);
   }
 
-  override isCompatible(version: string, range: string): boolean {
+  override isCompatible(version: string, current: string): boolean {
     const parsed1 = this._parse(version);
-    const parsed2 = this._parse(range);
+    const parsed2 = this._parse(current);
     return (
       parsed1.suffix === parsed2.suffix &&
       parsed1.release.length === parsed2.release.length
diff --git a/lib/versioning/gradle/index.spec.ts b/lib/versioning/gradle/index.spec.ts
index 903db8b72c..3a8502120f 100644
--- a/lib/versioning/gradle/index.spec.ts
+++ b/lib/versioning/gradle/index.spec.ts
@@ -154,7 +154,7 @@ describe('versioning/gradle/index', () => {
 
   test.each`
     input                                   | expected
-    ${''}                                   | ${null}
+    ${''}                                   | ${false}
     ${'foobar'}                             | ${true}
     ${'final'}                              | ${true}
     ${'1'}                                  | ${true}
diff --git a/lib/versioning/gradle/index.ts b/lib/versioning/gradle/index.ts
index fa60dc22c5..380e7722aa 100644
--- a/lib/versioning/gradle/index.ts
+++ b/lib/versioning/gradle/index.ts
@@ -87,7 +87,7 @@ const unstable = new Set([
   'snapshot',
 ]);
 
-const isStable = (version: string): boolean | null => {
+const isStable = (version: string): boolean => {
   if (isVersion(version)) {
     const tokens = tokenize(version);
     for (const token of tokens) {
@@ -100,7 +100,7 @@ const isStable = (version: string): boolean | null => {
     }
     return true;
   }
-  return null;
+  return false;
 };
 
 const matches = (a: string, b: string): boolean => {
diff --git a/lib/versioning/hashicorp/index.ts b/lib/versioning/hashicorp/index.ts
index d716458531..eca16e90c1 100644
--- a/lib/versioning/hashicorp/index.ts
+++ b/lib/versioning/hashicorp/index.ts
@@ -18,8 +18,8 @@ function hashicorp2npm(input: string): string {
 const isLessThanRange = (version: string, range: string): boolean =>
   npm.isLessThanRange(hashicorp2npm(version), hashicorp2npm(range));
 
-export const isValid = (input: string): string | boolean =>
-  input && npm.isValid(hashicorp2npm(input));
+export const isValid = (input: string): boolean =>
+  !!input && npm.isValid(hashicorp2npm(input));
 
 const matches = (version: string, range: string): boolean =>
   npm.matches(hashicorp2npm(version), hashicorp2npm(range));
diff --git a/lib/versioning/ivy/index.spec.ts b/lib/versioning/ivy/index.spec.ts
index 9f19cdd817..76b873b044 100644
--- a/lib/versioning/ivy/index.spec.ts
+++ b/lib/versioning/ivy/index.spec.ts
@@ -179,4 +179,19 @@ describe('versioning/ivy/index', () => {
       expect(ivy.getSatisfyingVersion(versions, range)).toBe(expected);
     }
   );
+
+  test.each`
+    version    | expected
+    ${'1.2.0'} | ${true}
+  `('isCompatible("$version") === $expected', ({ version, expected }) => {
+    expect(ivy.isCompatible(version)).toBe(expected);
+  });
+
+  test.each`
+    version     | expected
+    ${'1.2.0'}  | ${true}
+    ${'^1.2.0'} | ${false}
+  `('isSingleVersion("$version") === $expected', ({ version, expected }) => {
+    expect(ivy.isSingleVersion(version)).toBe(expected);
+  });
 });
diff --git a/lib/versioning/ivy/index.ts b/lib/versioning/ivy/index.ts
index ed5c3000eb..ca6062f138 100644
--- a/lib/versioning/ivy/index.ts
+++ b/lib/versioning/ivy/index.ts
@@ -31,14 +31,14 @@ const {
   sortVersions,
 } = maven;
 
-function isValid(str: string): string | boolean {
+function isValid(str: string): boolean {
   if (!str) {
     return false;
   }
   return maven.isVersion(str) || !!parseDynamicRevision(str);
 }
 
-function isVersion(str: string): string | boolean {
+function isVersion(str: string): boolean {
   if (!str || LATEST_REGEX.test(str)) {
     return false;
   }
@@ -101,14 +101,22 @@ function getNewValue({
   return autoExtendMavenRange(currentValue, newVersion);
 }
 
+function isCompatible(version: string): boolean {
+  return isVersion(version);
+}
+
+function isSingleVersion(version: string): boolean {
+  return isVersion(version);
+}
+
 export const api: VersioningApi = {
   equals,
   getMajor,
   getMinor,
   getPatch,
-  isCompatible: isVersion,
+  isCompatible,
   isGreaterThan,
-  isSingleVersion: isVersion,
+  isSingleVersion,
   isStable,
   isValid,
   isVersion,
diff --git a/lib/versioning/loose/generic.ts b/lib/versioning/loose/generic.ts
index cf8d49bbed..0691111d2d 100644
--- a/lib/versioning/loose/generic.ts
+++ b/lib/versioning/loose/generic.ts
@@ -78,7 +78,7 @@ export abstract class GenericVersioningApi<
     return this._parse(version) !== null;
   }
 
-  isCompatible(version: string, _range: string): boolean {
+  isCompatible(version: string, _current: string): boolean {
     return this.isValid(version);
   }
 
@@ -87,11 +87,11 @@ export abstract class GenericVersioningApi<
     return parsed && !parsed.prerelease;
   }
 
-  isSingleVersion(version: string): string | boolean {
+  isSingleVersion(version: string): boolean {
     return this.isValid(version);
   }
 
-  isVersion(version: string): string | boolean {
+  isVersion(version: string): boolean {
     return this.isValid(version);
   }
 
diff --git a/lib/versioning/loose/index.spec.ts b/lib/versioning/loose/index.spec.ts
index 1d27d33dee..56687e4af9 100644
--- a/lib/versioning/loose/index.spec.ts
+++ b/lib/versioning/loose/index.spec.ts
@@ -47,4 +47,19 @@ describe('versioning/loose/index', () => {
   `('isGreaterThan("$a", "$b") === $expected', ({ a, b, expected }) => {
     expect(loose.isGreaterThan(a, b)).toBe(expected);
   });
+
+  test.each`
+    version    | expected
+    ${'1.2.0'} | ${true}
+  `('isCompatible("$version") === $expected', ({ version, expected }) => {
+    expect(loose.isCompatible(version)).toBe(expected);
+  });
+
+  test.each`
+    version     | expected
+    ${'1.2.0'}  | ${true}
+    ${'^1.2.0'} | ${false}
+  `('isSingleVersion("$version") === $expected', ({ version, expected }) => {
+    expect(loose.isSingleVersion(version)).toBe(expected);
+  });
 });
diff --git a/lib/versioning/poetry/index.ts b/lib/versioning/poetry/index.ts
index e2914024d6..dbeb05779d 100644
--- a/lib/versioning/poetry/index.ts
+++ b/lib/versioning/poetry/index.ts
@@ -47,7 +47,7 @@ function isLessThanRange(version: string, range: string): boolean {
   );
 }
 
-export function isValid(input: string): string | boolean {
+export function isValid(input: string): boolean {
   return npm.isValid(poetry2npm(input));
 }
 
@@ -79,7 +79,7 @@ function minSatisfyingVersion(versions: string[], range: string): string {
   );
 }
 
-function isSingleVersion(constraint: string): string | boolean {
+function isSingleVersion(constraint: string): boolean {
   return (
     (constraint.trim().startsWith('=') &&
       isVersion(constraint.trim().substring(1).trim())) ||
diff --git a/lib/versioning/regex/index.ts b/lib/versioning/regex/index.ts
index 7429dd220e..417dd48633 100644
--- a/lib/versioning/regex/index.ts
+++ b/lib/versioning/regex/index.ts
@@ -89,9 +89,9 @@ export class RegExpVersioningApi extends GenericVersioningApi<RegExpVersion> {
     };
   }
 
-  override isCompatible(version: string, range: string): boolean {
+  override isCompatible(version: string, current: string): boolean {
     return (
-      this._parse(version).compatibility === this._parse(range).compatibility
+      this._parse(version).compatibility === this._parse(current).compatibility
     );
   }
 
diff --git a/lib/versioning/rez/index.spec.ts b/lib/versioning/rez/index.spec.ts
index f7860ddc31..69a6fd3bf0 100644
--- a/lib/versioning/rez/index.spec.ts
+++ b/lib/versioning/rez/index.spec.ts
@@ -439,4 +439,11 @@ describe('versioning/rez/index', () => {
       expect(res).toBe(expected);
     }
   );
+
+  test.each`
+    version    | expected
+    ${'1.2.0'} | ${true}
+  `('isCompatible("$version") === $expected', ({ version, expected }) => {
+    expect(versioning.isCompatible(version)).toBe(expected);
+  });
 });
diff --git a/lib/versioning/rez/index.ts b/lib/versioning/rez/index.ts
index f027ed5254..33712bb0b5 100644
--- a/lib/versioning/rez/index.ts
+++ b/lib/versioning/rez/index.ts
@@ -72,7 +72,7 @@ function isLessThanRange(version: string, range: string): boolean {
   );
 }
 
-export function isValid(input: string): string | boolean {
+export function isValid(input: string): boolean {
   return npm.isValid(rez2npm(input));
 }
 
@@ -80,7 +80,7 @@ function isStable(version: string): boolean {
   return npm.isStable(padZeroes(version));
 }
 
-function isVersion(input: string): string | boolean {
+function isVersion(input: string): boolean {
   return npm.isVersion(padZeroes(rez2npm(input)));
 }
 
@@ -99,7 +99,7 @@ function minSatisfyingVersion(versions: string[], range: string): string {
   return npm.minSatisfyingVersion(versions, rez2npm(range));
 }
 
-function isSingleVersion(constraint: string): string | boolean {
+function isSingleVersion(constraint: string): boolean {
   return (
     (constraint.trim().startsWith('==') &&
       isVersion(constraint.trim().substring(2).trim())) ||
@@ -192,6 +192,10 @@ function getNewValue({
   return null;
 }
 
+function isCompatible(version: string): boolean {
+  return isVersion(version);
+}
+
 export const api: VersioningApi = {
   equals,
   getMajor,
@@ -199,7 +203,7 @@ export const api: VersioningApi = {
   getPatch,
   getNewValue,
   getSatisfyingVersion,
-  isCompatible: isVersion,
+  isCompatible,
   isGreaterThan,
   isLessThanRange,
   isSingleVersion,
diff --git a/lib/versioning/ruby/range.ts b/lib/versioning/ruby/range.ts
index 8230d1d7fe..555e34a0ee 100644
--- a/lib/versioning/ruby/range.ts
+++ b/lib/versioning/ruby/range.ts
@@ -32,11 +32,11 @@ const parse = (range: string): Range => {
 
 type GemRequirement = [string, Version];
 
-const ltr = (version: string, range: string): boolean | null => {
+const ltr = (version: string, range: string): boolean => {
   const gemVersion = create(version);
   if (!gemVersion) {
     logger.warn(`Invalid ruby version '${version}'`);
-    return null;
+    return false;
   }
   const requirements: GemRequirement[] = range.split(',').map(_parse);
 
@@ -58,7 +58,7 @@ const ltr = (version: string, range: string): boolean | null => {
       // istanbul ignore next
       default:
         logger.warn(`Unsupported operator '${operator}'`);
-        return null;
+        return false;
     }
   });
 
diff --git a/lib/versioning/semver-coerced/index.ts b/lib/versioning/semver-coerced/index.ts
index 941f276e7a..b3a9ba35e4 100644
--- a/lib/versioning/semver-coerced/index.ts
+++ b/lib/versioning/semver-coerced/index.ts
@@ -43,8 +43,8 @@ function equals(a: string, b: string): boolean {
   return aCoerced && bCoerced ? semver.eq(aCoerced, bCoerced) : false;
 }
 
-function isValid(version: string): string | boolean | null {
-  return semver.valid(semver.coerce(version));
+function isValid(version: string): boolean {
+  return !!semver.valid(semver.coerce(version));
 }
 
 function getSatisfyingVersion(
@@ -84,19 +84,18 @@ function isGreaterThan(version: string, other: string): boolean {
 
 const startsWithNumberRegex = regEx(`^\\d`);
 
-function isSingleVersion(version: string): string | boolean | null {
+function isSingleVersion(version: string): boolean {
   // Since coercion accepts ranges as well as versions, we have to manually
   // check that the version string starts with either 'v' or a digit.
   if (!version.startsWith('v') && !startsWithNumberRegex.exec(version)) {
-    return null;
+    return false;
   }
 
-  return semver.valid(semver.coerce(version));
+  return !!semver.valid(semver.coerce(version));
 }
 
 // If this is left as an alias, inputs like "17.04.0" throw errors
-export const isVersion = (input: string): string | boolean | null =>
-  isValid(input);
+export const isVersion = (input: string): boolean => isValid(input);
 
 export { isVersion as isValid, getSatisfyingVersion };
 
@@ -104,12 +103,16 @@ function getNewValue({ newVersion }: NewValueConfig): string {
   return newVersion;
 }
 
+function isCompatible(version: string): boolean {
+  return isVersion(version);
+}
+
 export const api: VersioningApi = {
   equals,
   getMajor,
   getMinor,
   getPatch,
-  isCompatible: isVersion,
+  isCompatible,
   isGreaterThan,
   isLessThanRange,
   isSingleVersion,
diff --git a/lib/versioning/semver/index.spec.ts b/lib/versioning/semver/index.spec.ts
index 5a3c3ff65f..164c3480ef 100644
--- a/lib/versioning/semver/index.spec.ts
+++ b/lib/versioning/semver/index.spec.ts
@@ -43,4 +43,11 @@ describe('versioning/semver/index', () => {
       expect(res).toEqual(expected);
     }
   );
+
+  test.each`
+    version    | expected
+    ${'1.2.0'} | ${true}
+  `('isCompatible("$version") === $expected', ({ version, expected }) => {
+    expect(semver.isCompatible(version)).toBe(expected);
+  });
 });
diff --git a/lib/versioning/semver/index.ts b/lib/versioning/semver/index.ts
index dc9f8485b3..5bb38c9954 100644
--- a/lib/versioning/semver/index.ts
+++ b/lib/versioning/semver/index.ts
@@ -24,8 +24,7 @@ const {
 } = semver;
 
 // If this is left as an alias, inputs like "17.04.0" throw errors
-export const isVersion = (input: string): string | boolean | null =>
-  valid(input);
+export const isVersion = (input: string): boolean => !!valid(input);
 
 export { isVersion as isValid, getSatisfyingVersion };
 
@@ -33,17 +32,29 @@ function getNewValue({ newVersion }: NewValueConfig): string {
   return newVersion;
 }
 
+function isCompatible(version: string): boolean {
+  return isVersion(version);
+}
+
+function isSingleVersion(version: string): boolean {
+  return isVersion(version);
+}
+
+function isValid(input: string): boolean {
+  return isVersion(input);
+}
+
 export const api: VersioningApi = {
   equals,
   getMajor,
   getMinor,
   getPatch,
-  isCompatible: isVersion,
+  isCompatible,
   isGreaterThan,
   isLessThanRange,
-  isSingleVersion: isVersion,
+  isSingleVersion,
   isStable,
-  isValid: isVersion,
+  isValid,
   isVersion,
   matches,
   getSatisfyingVersion,
diff --git a/lib/versioning/types.ts b/lib/versioning/types.ts
index cb2091c9f7..928676c6d4 100644
--- a/lib/versioning/types.ts
+++ b/lib/versioning/types.ts
@@ -9,11 +9,11 @@ export interface NewValueConfig {
 }
 export interface VersioningApi {
   // validation
-  isCompatible(version: string, range?: string): string | boolean | null;
-  isSingleVersion(version: string): string | boolean | null;
+  isCompatible(version: string, current?: string): boolean;
+  isSingleVersion(version: string): boolean;
   isStable(version: string): boolean;
-  isValid(version: string): string | boolean | null;
-  isVersion(version: string): string | boolean | null;
+  isValid(input: string): boolean;
+  isVersion(input: string): boolean;
 
   // digestion of version
   getMajor(version: string | SemVer): null | number;
diff --git a/lib/versioning/ubuntu/index.ts b/lib/versioning/ubuntu/index.ts
index 07e470eedf..0bce4216a5 100644
--- a/lib/versioning/ubuntu/index.ts
+++ b/lib/versioning/ubuntu/index.ts
@@ -11,26 +11,23 @@ const temporarilyUnstable = ['22.04'];
 
 // validation
 
-function isValid(input: string): string | boolean | null {
+function isValid(input: string): boolean {
   return (
     typeof input === 'string' &&
     regEx(/^(0[4-5]|[6-9]|[1-9][0-9])\.[0-9][0-9](\.[0-9]{1,2})?$/).test(input)
   );
 }
 
-function isVersion(input: string): string | boolean | null {
+function isVersion(input: string): boolean {
   return isValid(input);
 }
 
-function isCompatible(
-  version: string,
-  _range?: string
-): string | boolean | null {
+function isCompatible(version: string, _current?: string): boolean {
   return isValid(version);
 }
 
-function isSingleVersion(version: string): string | boolean | null {
-  return isValid(version) ? true : null;
+function isSingleVersion(version: string): boolean {
+  return isValid(version);
 }
 
 function isStable(version: string): boolean {
@@ -72,7 +69,7 @@ function getPatch(version: string): null | number {
 // comparison
 
 function equals(version: string, other: string): boolean {
-  return !!isVersion(version) && !!isVersion(other) && version === other;
+  return isVersion(version) && isVersion(other) && version === other;
 }
 
 function isGreaterThan(version: string, other: string): boolean {
-- 
GitLab