Skip to content

Commit

Permalink
refactor(versioning/generic): Strict null checks (#14006)
Browse files Browse the repository at this point in the history
Co-authored-by: Michael Kriese <michael.kriese@visualon.de>
Co-authored-by: Rhys Arkins <rhys@arkins.net>
  • Loading branch information
3 people committed Feb 5, 2022
1 parent 6752419 commit 1525d38
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 32 deletions.
2 changes: 1 addition & 1 deletion lib/versioning/nuget/index.ts
Expand Up @@ -13,7 +13,7 @@ export const supportsRanges = false;
const pattern = regEx(/^(\d+(?:\.\d+)*)(-[^+]+)?(\+.*)?$/);

class NugetVersioningApi extends GenericVersioningApi {
protected _parse(version: string): GenericVersion {
protected _parse(version: string): GenericVersion | null {
const matches = pattern.exec(version);
if (!matches) {
return null;
Expand Down
2 changes: 2 additions & 0 deletions lib/versioning/regex/index.spec.ts
Expand Up @@ -247,6 +247,7 @@ describe('versioning/regex/index', () => {
${['2.1.5', '2.1.6a1', '2.1.6', '2.1.6-foo']} | ${'2.1.6-foo'} | ${'2.1.6'}
${['2.1.5-foo', '2.1.6']} | ${'2.1.6-foo'} | ${'2.1.6'}
${['1.2.3', '1.2.4']} | ${'3.5.0'} | ${null}
${['1.2.3', '1.2.4']} | ${'!@#'} | ${null}
`(
'getSatisfyingVersion($versions, "$range") === $expected',
({ versions, range, expected }) => {
Expand All @@ -260,6 +261,7 @@ describe('versioning/regex/index', () => {
${['2.1.5', '2.1.6a1', '2.1.6', '2.1.6-foo']} | ${'2.1.6-foo'} | ${'2.1.6'}
${['2.1.5', '2.1.6-foo']} | ${'2.1.5-foo'} | ${'2.1.5'}
${['1.2.3', '1.2.4']} | ${'3.5.0'} | ${null}
${['1.2.3', '1.2.4']} | ${'!@#'} | ${null}
`(
'minSatisfyingVersion($versions, "$range") === "$expected"',
({ versions, range, expected }) => {
Expand Down
85 changes: 56 additions & 29 deletions lib/versioning/regex/index.ts
Expand Up @@ -39,11 +39,11 @@ export class RegExpVersioningApi extends GenericVersioningApi<RegExpVersion> {
// RegExp('^(?<major>\\d+)\\.(?<minor>\\d+)\\.(?<patch>\\d+)(?<prerelease>[^.-]+)?(-(?<compatibility>.*))?$');
// * matches the versioning approach used by the Bitnami images on DockerHub:
// RegExp('^(?<major>\\d+)\\.(?<minor>\\d+)\\.(?<patch>\\d+)(:?-(?<compatibility>.*-r)(?<build>\\d+))?$');
private _config: RegExp = null;
private _config: RegExp | null = null;

constructor(_new_config: string) {
constructor(_new_config: string | undefined) {
super();
const new_config = _new_config || '^(?<major>\\d+)?$';
const new_config = _new_config ?? '^(?<major>\\d+)?$';

// without at least one of {major, minor, patch} specified in the regex,
// this versioner will not work properly
Expand All @@ -66,66 +66,93 @@ export class RegExpVersioningApi extends GenericVersioningApi<RegExpVersion> {

// convenience method for passing a string into a Version given current config.
protected _parse(version: string): RegExpVersion | null {
const match = this._config.exec(version);
if (match === null) {
const groups = this._config?.exec(version)?.groups;
if (!groups) {
return null;
}

const groups = match.groups;
const { major, minor, patch, build, prerelease, compatibility } = groups;
const release = [
typeof groups.major === 'undefined' ? 0 : Number(groups.major),
typeof groups.minor === 'undefined' ? 0 : Number(groups.minor),
typeof groups.patch === 'undefined' ? 0 : Number(groups.patch),
typeof major === 'undefined' ? 0 : Number.parseInt(major, 10),
typeof minor === 'undefined' ? 0 : Number.parseInt(minor, 10),
typeof patch === 'undefined' ? 0 : Number.parseInt(patch, 10),
];

if (groups.build) {
release.push(Number(groups.build));
if (build) {
release.push(Number.parseInt(build, 10));
}

return {
release,
prerelease: groups.prerelease,
compatibility: groups.compatibility,
prerelease: prerelease,
compatibility: compatibility,
};
}

override isCompatible(version: string, current: string): boolean {
return (
this._parse(version).compatibility === this._parse(current).compatibility
const parsedVersion = this._parse(version);
const parsedCurrent = this._parse(current);
return !!(
parsedVersion &&
parsedCurrent &&
parsedVersion.compatibility === parsedCurrent.compatibility
);
}

override isLessThanRange(version: string, range: string): boolean {
return semver.ltr(
asSemver(this._parse(version)),
asSemver(this._parse(range))
const parsedVersion = this._parse(version);
const parsedRange = this._parse(range);
return !!(
parsedVersion &&
parsedRange &&
semver.ltr(asSemver(parsedVersion), asSemver(parsedRange))
);
}

private _getSemverVersions(versions: string[]): string[] {
const parsedVersions: string[] = [];
versions.forEach((v) => {
const parsedVersion = this._parse(v);
if (parsedVersion) {
parsedVersions.push(asSemver(parsedVersion));
}
});
return parsedVersions;
}

override getSatisfyingVersion(
versions: string[],
range: string
): string | null {
return semver.maxSatisfying(
versions.map((v) => asSemver(this._parse(v))),
asSemver(this._parse(range))
);
const parsedRange = this._parse(range);
return parsedRange
? semver.maxSatisfying(
this._getSemverVersions(versions),
asSemver(parsedRange)
)
: null;
}

override minSatisfyingVersion(
versions: string[],
range: string
): string | null {
return semver.minSatisfying(
versions.map((v) => asSemver(this._parse(v))),
asSemver(this._parse(range))
);
const parsedRange = this._parse(range);
return parsedRange
? semver.minSatisfying(
this._getSemverVersions(versions),
asSemver(parsedRange)
)
: null;
}

override matches(version: string, range: string): boolean {
return semver.satisfies(
asSemver(this._parse(version)),
asSemver(this._parse(range))
const parsedVersion = this._parse(version);
const parsedRange = this._parse(range);
return !!(
parsedVersion &&
parsedRange &&
semver.satisfies(asSemver(parsedVersion), asSemver(parsedRange))
);
}
}
Expand Down
2 changes: 0 additions & 2 deletions tsconfig.strict.json
Expand Up @@ -395,11 +395,9 @@
"lib/versioning/hashicorp/index.ts",
"lib/versioning/helm/index.ts",
"lib/versioning/index.ts",
"lib/versioning/nuget/index.ts",
"lib/versioning/poetry/index.ts",
"lib/versioning/poetry/patterns.ts",
"lib/versioning/poetry/transform.ts",
"lib/versioning/regex/index.ts",
"lib/versioning/types.ts",
"lib/workers/branch/artifacts.ts",
"lib/workers/branch/auto-replace.ts",
Expand Down

0 comments on commit 1525d38

Please sign in to comment.