Merge pull request #341 from aminya/compiler-version [skip ci]

fix: more robust parsing of compiler name/versions
This commit is contained in:
Amin Ya 2025-02-15 22:43:22 -08:00 committed by GitHub
commit 68aea2b63e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 65 additions and 28 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -22,25 +22,47 @@ describe("getCompilerInfo", () => {
expect(compiler).toBe("llvm")
expect(version).toBe("12")
})
})
describe("getCompilerInfo", () => {
it("getCompilerInfo with semver", () => {
const { compiler, version } = getCompilerInfo("llvm-12.0.0")
expect(compiler).toBe("llvm")
expect(version).toBe("12.0.0")
it("extracts gcc version", () => {
const { compiler, version } = getCompilerInfo("gcc-11.2.0")
expect(compiler).toBe("gcc")
expect(version).toBe("11.2.0")
})
it("getCompilerInfo with major version", () => {
const { compiler, version } = getCompilerInfo("llvm-12")
expect(compiler).toBe("llvm")
expect(version).toBe("12")
it("extracts apple-clang version", () => {
const { compiler, version } = getCompilerInfo("apple-clang-14")
expect(compiler).toBe("apple-clang")
expect(version).toBe("14")
})
it("getCompilerInfo without version", () => {
const { compiler, version } = getCompilerInfo("llvm")
expect(compiler).toBe("llvm")
expect(version).toBeUndefined()
it("extracts msvc version", () => {
const { compiler, version } = getCompilerInfo("msvc-14.16.27023")
expect(compiler).toBe("msvc")
expect(version).toBe("14.16.27023")
})
it("extracts msvc version with year", () => {
const { compiler, version } = getCompilerInfo("msvc-2017")
expect(compiler).toBe("msvc")
expect(version).toBe("2017")
})
it("extracts msvc version with year and version", () => {
const { compiler, version } = getCompilerInfo("msvc-2017.1")
expect(compiler).toBe("msvc")
expect(version).toBe("2017.1")
})
it("extracts gcc version with pre-release and build metadata", () => {
const { compiler, version } = getCompilerInfo("gcc-11.2.0-beta.1+build.123")
expect(compiler).toBe("gcc")
expect(version).toBe("11.2.0-beta.1+build.123")
})
it("extracts clang version with pre-release", () => {
const { compiler, version } = getCompilerInfo("clang-15.0.0-rc1")
expect(compiler).toBe("clang")
expect(version).toBe("15.0.0-rc1")
})
})

View File

@ -19,7 +19,18 @@ export type CompilerInfo = {
}
/**
* Detecting the compiler version. Divide the given string by `-` and use the second element as the version
* Match version patterns like:
* - Standard versions: digit.digit.digit
* - Semver with pre-release: digit.digit.digit-alpha.1
* - Semver with build metadata: digit.digit.digit+build.123
* - MSVC style: digit.digit.digit.digit
* - Year versions: 2015, 2017, etc.
*/
const versionPattern = /[.-]((?:\d{4}|\d+(?:\.\d+)*(?:-[\w.-]+)?(?:\+[\w.-]+)?)$)/
/**
* Detecting the compiler version by looking for a version-like pattern.
* Supports compiler names that contain hyphens and various version formats.
*
* @param compilerAndVersion - The compiler and version string
* @returns The compiler and version
@ -28,16 +39,20 @@ export type CompilerInfo = {
*/
export function getCompilerInfo(compilerAndVersion: string): CompilerInfo {
try {
const compilerAndMaybeVersion = compilerAndVersion.split("-")
const compiler = compilerAndMaybeVersion[0]
if (1 in compilerAndMaybeVersion) {
const maybeVersion = compilerAndMaybeVersion[1]
if (semverValid(maybeVersion) === null) {
info(`Invalid semver version ${maybeVersion} used for the compiler.`)
}
return { compiler, version: maybeVersion }
const match = compilerAndVersion.match(versionPattern)
if (match === null) {
return { compiler: compilerAndVersion, version: undefined }
}
return { compiler, version: undefined }
const version = match[1]
const compiler = compilerAndVersion.slice(0, match.index).replace(/[.-]$/, "")
// Only check semver for non-year versions
if (!version.match(/^\d{4}$/) && semverValid(version) === null) {
info(`Non-semver version format: ${version}`)
}
return { compiler, version }
} catch (err) {
error(`Failed to parse the compiler info ${compilerAndVersion}: ${err}`)
return { compiler: compilerAndVersion, version: undefined }