diff --git a/lib/versioning/nuget/index.spec.ts b/lib/versioning/nuget/index.spec.ts index d2d05f3846cf5f63ed8d925f8faad0a771139691..04d32164fdda825e33268496355976f7467374b9 100644 --- a/lib/versioning/nuget/index.spec.ts +++ b/lib/versioning/nuget/index.spec.ts @@ -56,13 +56,21 @@ describe('versioning/nuget/index', () => { }); test.each` - a | b | expected - ${'2.4.2'} | ${'2.4.1'} | ${true} - ${'2.4-beta'} | ${'2.4-alpha'} | ${true} - ${'1.9'} | ${'2'} | ${false} - ${'1.9'} | ${'1.9.1'} | ${false} - ${'2.4.0'} | ${'2.4.0-beta'} | ${true} - ${'2.4.0-alpha'} | ${'2.4.0'} | ${false} + a | b | expected + ${'2.4.2'} | ${'2.4.1'} | ${true} + ${'2.4-beta'} | ${'2.4-alpha'} | ${true} + ${'1.9'} | ${'2'} | ${false} + ${'1.9'} | ${'1.9.1'} | ${false} + ${'2.4.0'} | ${'2.4.0-beta'} | ${true} + ${'2.4.0-alpha'} | ${'2.4.0'} | ${false} + ${'1.2.0-beta.333'} | ${'1.2.0-beta.66'} | ${true} + ${'1.2.0-beta2'} | ${'1.2.0-beta10'} | ${true} + ${'1.2.0.1'} | ${'1.2.0'} | ${true} + ${'1.2.0.1'} | ${'1.2.0.1-beta'} | ${true} + ${'1.2.0.1-beta'} | ${'1.2.0.1'} | ${false} + ${undefined} | ${'1.2.0'} | ${true} + ${'1.2.0+1'} | ${'1.2.0'} | ${false} + ${'1.2.0'} | ${'1.2.0+1'} | ${false} `('isGreaterThan($a, $b) === $expected', ({ a, b, expected }) => { expect(nuget.isGreaterThan(a, b)).toBe(expected); }); diff --git a/lib/versioning/nuget/index.ts b/lib/versioning/nuget/index.ts index 0c94eccdb78c8327c65cbabd9cef91c20ad7cfc6..65f36b213b560eef33b6661d67e8947f61f15f0e 100644 --- a/lib/versioning/nuget/index.ts +++ b/lib/versioning/nuget/index.ts @@ -1,5 +1,7 @@ +import semver from 'semver'; import { regEx } from '../../util/regex'; import * as generic from '../loose/generic'; +import type { GenericVersion } from '../loose/generic'; import type { VersioningApi } from '../types'; export const id = 'nuget'; @@ -11,23 +13,34 @@ export const supportsRanges = false; const pattern = regEx(/^(\d+(?:\.\d+)*)(-[^+]+)?(\+.*)?$/); -function parse(version: string): any { +function parse(version: string): GenericVersion { const matches = pattern.exec(version); if (!matches) { return null; } - const [, prefix, prereleasesuffix] = matches; + const [, prefix, prerelease] = matches; const release = prefix.split('.').map(Number); - return { release, suffix: prereleasesuffix || '' }; + return { release, prerelease: prerelease || '' }; } -function compare(version1: string, version2: string): number { +function compareSemVer(version1: string, version2: string): number | null { + const parsed1 = semver.parse(version1); + const parsed2 = semver.parse(version2); + + if (!(parsed1 && parsed2)) { + return null; + } + + return parsed1.compare(parsed2); +} + +function compareLegacy(version1: string, version2: string): number { const parsed1 = parse(version1); const parsed2 = parse(version2); - // istanbul ignore if if (!(parsed1 && parsed2)) { return 1; } + const length = Math.max(parsed1.release.length, parsed2.release.length); for (let i = 0; i < length; i += 1) { // 2.1 and 2.1.0 are equivalent @@ -38,22 +51,26 @@ function compare(version1: string, version2: string): number { } } // numeric version equals - const suffixComparison = parsed1.suffix.localeCompare(parsed2.suffix); + const suffixComparison = parsed1.prerelease.localeCompare(parsed2.prerelease); if (suffixComparison !== 0) { // Empty suffix should compare greater than non-empty suffix - if (parsed1.suffix === '') { + if (parsed1.prerelease === '') { return 1; } - if (parsed2.suffix === '') { + if (parsed2.prerelease === '') { return -1; } } return suffixComparison; } -function isStable(version: string): boolean { - const parsed = parse(version); - return parsed && parsed.suffix === ''; +function compare(version1: string, version2: string): number { + const res = compareSemVer(version1, version2); + if (res !== null) { + return res; + } + + return compareLegacy(version1, version2); } export const api: VersioningApi = { @@ -61,7 +78,6 @@ export const api: VersioningApi = { parse, compare, }), - isStable, }; export default api;