mirror of
https://github.com/gradle/actions.git
synced 2025-08-24 10:51:27 +08:00
Improve comparison of Gradle versions
This commit is contained in:
parent
ec4681f7f5
commit
edf9e3c8c7
@ -35,18 +35,45 @@ async function executeGradleBuild(executable: string | undefined, root: string,
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function versionIsAtLeast(actualVersion: string, requiredVersion: string): boolean {
|
export function versionIsAtLeast(actualVersion: string, requiredVersion: string): boolean {
|
||||||
const splitVersion = actualVersion.split('-')
|
if (actualVersion === requiredVersion) {
|
||||||
const coreVersion = splitVersion[0]
|
return true
|
||||||
const prerelease = splitVersion.length > 1
|
|
||||||
|
|
||||||
const actualSemver = semver.coerce(coreVersion)!
|
|
||||||
const comparisonSemver = semver.coerce(requiredVersion)!
|
|
||||||
|
|
||||||
if (prerelease) {
|
|
||||||
return semver.gt(actualSemver, comparisonSemver)
|
|
||||||
} else {
|
|
||||||
return semver.gte(actualSemver, comparisonSemver)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const actual = new GradleVersion(actualVersion)
|
||||||
|
const required = new GradleVersion(requiredVersion)
|
||||||
|
|
||||||
|
const actualSemver = semver.coerce(actual.versionPart)!
|
||||||
|
const comparisonSemver = semver.coerce(required.versionPart)!
|
||||||
|
|
||||||
|
if (semver.gt(actualSemver, comparisonSemver)) {
|
||||||
|
return true // Actual version is greater than comparison. So it's at least as new.
|
||||||
|
}
|
||||||
|
if (semver.lt(actualSemver, comparisonSemver)) {
|
||||||
|
return false // Actual version is less than comparison. So it's not as new.
|
||||||
|
}
|
||||||
|
|
||||||
|
// Actual and required version numbers are equal, so compare the other parts
|
||||||
|
|
||||||
|
if (actual.snapshotPart || required.snapshotPart) {
|
||||||
|
if (actual.snapshotPart && !required.snapshotPart && !required.stagePart) {
|
||||||
|
return false // Actual has a snapshot, but required is a plain version. Required is newer.
|
||||||
|
}
|
||||||
|
if (required.snapshotPart && !actual.snapshotPart && !actual.stagePart) {
|
||||||
|
return true // Required has a snapshot, but actual is a plain version. Actual is newer.
|
||||||
|
}
|
||||||
|
|
||||||
|
return false // Cannot compare case where both versions have a snapshot or stage
|
||||||
|
}
|
||||||
|
|
||||||
|
if (actual.stagePart) {
|
||||||
|
if (required.stagePart) {
|
||||||
|
return actual.stagePart >= required.stagePart // Compare stages for newer
|
||||||
|
}
|
||||||
|
|
||||||
|
return false // Actual has a stage, but required does not. So required is always newer.
|
||||||
|
}
|
||||||
|
|
||||||
|
return true // Actual has no stage part or snapshot part, so it cannot be older than required.
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function findGradleVersionOnPath(): Promise<GradleExecutable | undefined> {
|
export async function findGradleVersionOnPath(): Promise<GradleExecutable | undefined> {
|
||||||
@ -72,3 +99,22 @@ class GradleExecutable {
|
|||||||
readonly executable: string
|
readonly executable: string
|
||||||
) {}
|
) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class GradleVersion {
|
||||||
|
static PATTERN = /((\d+)(\.\d+)+)(-([a-z]+)-(\w+))?(-(SNAPSHOT|\d{14}([-+]\d{4})?))?/
|
||||||
|
|
||||||
|
versionPart: string
|
||||||
|
stagePart: string
|
||||||
|
snapshotPart: string
|
||||||
|
|
||||||
|
constructor(readonly version: string) {
|
||||||
|
const matcher = GradleVersion.PATTERN.exec(version)
|
||||||
|
if (!matcher) {
|
||||||
|
throw new Error(`'${version}' is not a valid Gradle version string (examples: '1.0', '1.0-rc-1')`)
|
||||||
|
}
|
||||||
|
|
||||||
|
this.versionPart = matcher[1]
|
||||||
|
this.stagePart = matcher[4]
|
||||||
|
this.snapshotPart = matcher[7]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -3,43 +3,92 @@ import {describe, expect, it} from '@jest/globals'
|
|||||||
import {versionIsAtLeast, parseGradleVersionFromOutput} from '../../src/execution/gradle'
|
import {versionIsAtLeast, parseGradleVersionFromOutput} from '../../src/execution/gradle'
|
||||||
|
|
||||||
describe('gradle', () => {
|
describe('gradle', () => {
|
||||||
describe('can compare version with', () => {
|
describe('can compare versions that are', () => {
|
||||||
it('same version', async () => {
|
function versionsAreOrdered(versions: string[]): void {
|
||||||
expect(versionIsAtLeast('6.7.1', '6.7.1')).toBe(true)
|
for (let i = 0; i < versions.length; i++) {
|
||||||
expect(versionIsAtLeast('7.0', '7.0')).toBe(true)
|
// Compare with all other versions
|
||||||
expect(versionIsAtLeast('7.0', '7.0.0')).toBe(true)
|
for (let j = 0; j < versions.length; j++) {
|
||||||
})
|
if (i >= j) {
|
||||||
it('newer version', async () => {
|
it(`${versions[i]} is at least ${versions[j]}`, () => {
|
||||||
expect(versionIsAtLeast('6.7.1', '6.7.2')).toBe(false)
|
expect(versionIsAtLeast(versions[i], versions[j])).toBe(true)
|
||||||
expect(versionIsAtLeast('7.0', '8.0')).toBe(false)
|
})
|
||||||
expect(versionIsAtLeast('7.0', '7.0.1')).toBe(false)
|
} else {
|
||||||
})
|
it(`${versions[i]} is NOT at least ${versions[j]}`, () => {
|
||||||
it('older version', async () => {
|
expect(versionIsAtLeast(versions[i], versions[j])).toBe(false)
|
||||||
expect(versionIsAtLeast('6.7.2', '6.7.1')).toBe(true)
|
})
|
||||||
expect(versionIsAtLeast('8.0', '7.0')).toBe(true)
|
}
|
||||||
expect(versionIsAtLeast('7.0.1', '7.0')).toBe(true)
|
}
|
||||||
})
|
}
|
||||||
it('rc version', async () => {
|
}
|
||||||
expect(versionIsAtLeast('8.0.2-rc-1', '8.0.1')).toBe(true)
|
|
||||||
expect(versionIsAtLeast('8.0.2-rc-1', '8.0.2')).toBe(false)
|
|
||||||
expect(versionIsAtLeast('8.1-rc-1', '8.0')).toBe(true)
|
|
||||||
expect(versionIsAtLeast('8.0-rc-1', '8.0')).toBe(false)
|
|
||||||
})
|
|
||||||
it('snapshot version', async () => {
|
|
||||||
expect(versionIsAtLeast('8.11-20240829002031+0000', '8.10')).toBe(true)
|
|
||||||
expect(versionIsAtLeast('8.11-20240829002031+0000', '8.10.1')).toBe(true)
|
|
||||||
expect(versionIsAtLeast('8.11-20240829002031+0000', '8.11')).toBe(false)
|
|
||||||
|
|
||||||
expect(versionIsAtLeast('8.10.2-20240828012138+0000', '8.10')).toBe(true)
|
function versionsAreNotOrdered(versions: string[]): void {
|
||||||
expect(versionIsAtLeast('8.10.2-20240828012138+0000', '8.10.1')).toBe(true)
|
for (let i = 0; i < versions.length; i++) {
|
||||||
expect(versionIsAtLeast('8.10.2-20240828012138+0000', '8.10.2')).toBe(false)
|
// Compare with all other versions
|
||||||
expect(versionIsAtLeast('8.10.2-20240828012138+0000', '8.11')).toBe(false)
|
for (let j = 0; j < versions.length; j++) {
|
||||||
|
if (i !== j) {
|
||||||
|
it(`${versions[i]} is NOT at least ${versions[j]}`, () => {
|
||||||
|
expect(versionIsAtLeast(versions[i], versions[j])).toBe(false)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
expect(versionIsAtLeast('9.1-branch-provider_api_migration_public_api_changes-20240826121451+0000', '9.0')).toBe(true)
|
function versionsAreEqual(versions: string[]): void {
|
||||||
expect(versionIsAtLeast('9.1-branch-provider_api_migration_public_api_changes-20240826121451+0000', '9.0.1')).toBe(true)
|
for (let i = 0; i < versions.length; i++) {
|
||||||
expect(versionIsAtLeast('9.1-branch-provider_api_migration_public_api_changes-20240826121451+0000', '9.1')).toBe(false)
|
// Compare with all other versions
|
||||||
|
for (let j = 0; j < versions.length; j++) {
|
||||||
|
it(`${versions[i]} is at least ${versions[j]}`, () => {
|
||||||
|
expect(versionIsAtLeast(versions[i], versions[j])).toBe(true)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
describe('simple versions', () => {
|
||||||
|
versionsAreOrdered(['6.0', '6.7', '6.7.1', '6.7.2', '7.0', '7.0.1', '7.1', '8.0', '8.12.1'])
|
||||||
|
|
||||||
|
versionsAreEqual(['7.0', '7.0.0'])
|
||||||
|
versionsAreEqual(['7.1', '7.1.0'])
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('rc versions', () => {
|
||||||
|
versionsAreOrdered([
|
||||||
|
'8.10', '8.11-rc-1', '8.11-rc-2', '8.11', '8.11.1-rc-1', '8.11.1'
|
||||||
|
])
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('milestone versions', () => {
|
||||||
|
versionsAreOrdered([
|
||||||
|
'8.12.1', '8.12.2-milestone-1', '8.12.2', '8.13-milestone-1', '8.13-milestone-2', '8.13'
|
||||||
|
])
|
||||||
|
versionsAreOrdered([
|
||||||
|
'8.12.1', '8.12.2-milestone-1', '8.12.2-milestone-2', '8.12.2-rc-1', '8.12.2'
|
||||||
|
])
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('preview versions', () => {
|
||||||
|
versionsAreOrdered([
|
||||||
|
'8.12.1', '8.12.2-preview-1', '8.12.2', '8.13-preview-1', '8.13-preview-2', '8.13'
|
||||||
|
])
|
||||||
|
versionsAreOrdered([
|
||||||
|
'8.12.1', '8.12.2-milestone-1', '8.12.2-preview-1', '8.12.2-rc-1', '8.12.2'
|
||||||
|
])
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('snapshot versions', () => {
|
||||||
|
versionsAreOrdered([
|
||||||
|
'8.10.1', '8.10.2-20240828012138+0000', '8.10.2', '8.11-20240829002031+0000', '8.11'
|
||||||
|
])
|
||||||
|
versionsAreOrdered([
|
||||||
|
'9.0', '9.1-branch-provider_api_migration_public_api_changes-20240826121451+0000', '9.1'
|
||||||
|
])
|
||||||
|
versionsAreNotOrdered([
|
||||||
|
'8.10.2-20240828012138+0000', '8.10.2-20240828010000+1000', '8.10.2-milestone-1'
|
||||||
|
])
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('can parse version from output', () => {
|
describe('can parse version from output', () => {
|
||||||
it('major version', async () => {
|
it('major version', async () => {
|
||||||
const output = `
|
const output = `
|
||||||
|
Loading…
x
Reference in New Issue
Block a user