From a8d87ea4ea5f7eb27f56c65d9360faa4ae0205f1 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Wed, 8 May 2024 14:58:54 +0100 Subject: [PATCH] Go: Make `getVersionToInstall` resilient to different version strings --- go/extractor/autobuilder/BUILD.bazel | 1 + go/extractor/autobuilder/build-environment.go | 29 ++++++++++--------- .../autobuilder/build-environment_test.go | 18 +++++++++++- 3 files changed, 33 insertions(+), 15 deletions(-) diff --git a/go/extractor/autobuilder/BUILD.bazel b/go/extractor/autobuilder/BUILD.bazel index e40dc3a03215..702d34e63ecd 100644 --- a/go/extractor/autobuilder/BUILD.bazel +++ b/go/extractor/autobuilder/BUILD.bazel @@ -23,4 +23,5 @@ go_test( name = "autobuilder_test", srcs = ["build-environment_test.go"], embed = [":autobuilder"], + deps = ["//go/extractor/util"], ) diff --git a/go/extractor/autobuilder/build-environment.go b/go/extractor/autobuilder/build-environment.go index 3f03ff922af7..b0041d895be2 100644 --- a/go/extractor/autobuilder/build-environment.go +++ b/go/extractor/autobuilder/build-environment.go @@ -8,6 +8,7 @@ import ( "github.com/github/codeql-go/extractor/diagnostics" "github.com/github/codeql-go/extractor/project" "github.com/github/codeql-go/extractor/toolchain" + "github.com/github/codeql-go/extractor/util" "golang.org/x/mod/semver" ) @@ -30,13 +31,13 @@ func (v versionInfo) String() string { // Check if `version` is lower than `minGoVersion`. Note that for this comparison we ignore the // patch part of the version, so 1.20.1 and 1.20 are considered equal. func belowSupportedRange(version string) bool { - return semver.Compare(semver.MajorMinor("v"+version), "v"+minGoVersion) < 0 + return semver.Compare(semver.MajorMinor(util.FormatSemVer(version)), util.FormatSemVer(minGoVersion)) < 0 } // Check if `version` is higher than `maxGoVersion`. Note that for this comparison we ignore the // patch part of the version, so 1.20.1 and 1.20 are considered equal. func aboveSupportedRange(version string) bool { - return semver.Compare(semver.MajorMinor("v"+version), "v"+maxGoVersion) > 0 + return semver.Compare(semver.MajorMinor(util.FormatSemVer(version)), util.FormatSemVer(maxGoVersion)) > 0 } // Check if `version` is lower than `minGoVersion` or higher than `maxGoVersion`. Note that for @@ -113,7 +114,7 @@ func getVersionWhenGoModVersionTooHigh(v versionInfo) (msg, version string) { "). Requesting the maximum supported version of Go (" + maxGoVersion + ")." version = maxGoVersion diagnostics.EmitGoModVersionTooHighAndEnvVersionTooLow(msg) - } else if semver.Compare("v"+maxGoVersion, "v"+v.goEnvVersion) > 0 { + } else if semver.Compare(util.FormatSemVer(maxGoVersion), util.FormatSemVer(v.goEnvVersion)) > 0 { // The version in the `go.mod` file is above the supported range. The version of Go that // is installed is supported and below the maximum supported version. We install the // maximum supported version as a best effort. @@ -195,7 +196,7 @@ func getVersionWhenGoModVersionSupported(v versionInfo) (msg, version string) { v.goModVersion + ")." version = v.goModVersion diagnostics.EmitGoModVersionSupportedAndGoEnvUnsupported(msg) - } else if semver.Compare("v"+v.goModVersion, "v"+v.goEnvVersion) > 0 { + } else if semver.Compare(util.FormatSemVer(v.goModVersion), util.FormatSemVer(v.goEnvVersion)) > 0 { // The version of Go that is installed is supported. The version in the `go.mod` file is // supported and is higher than the version that is installed. We install the version from // the `go.mod` file. @@ -233,18 +234,18 @@ func getVersionWhenGoModVersionSupported(v versionInfo) (msg, version string) { // +-----------------------+-----------------------+-----------------------+-----------------------------------------------------+------------------------------------------------+ func getVersionToInstall(v versionInfo) (msg, version string) { if !v.goModVersionFound { - return getVersionWhenGoModVersionNotFound(v) - } - - if aboveSupportedRange(v.goModVersion) { - return getVersionWhenGoModVersionTooHigh(v) - } - - if belowSupportedRange(v.goModVersion) { - return getVersionWhenGoModVersionTooLow(v) + msg, version = getVersionWhenGoModVersionNotFound(v) + } else if aboveSupportedRange(v.goModVersion) { + msg, version = getVersionWhenGoModVersionTooHigh(v) + } else if belowSupportedRange(v.goModVersion) { + msg, version = getVersionWhenGoModVersionTooLow(v) + } else { + msg, version = getVersionWhenGoModVersionSupported(v) } - return getVersionWhenGoModVersionSupported(v) + // Make sure that we return a normal version string, not one starting with "v" + version = util.UnformatSemVer(version) + return } // Output some JSON to stdout specifying the version of Go to install, unless `version` is the diff --git a/go/extractor/autobuilder/build-environment_test.go b/go/extractor/autobuilder/build-environment_test.go index 994381b0b4c7..c045b131a167 100644 --- a/go/extractor/autobuilder/build-environment_test.go +++ b/go/extractor/autobuilder/build-environment_test.go @@ -1,6 +1,10 @@ package autobuilder -import "testing" +import ( + "testing" + + "github.com/github/codeql-go/extractor/util" +) func TestGetVersionToInstall(t *testing.T) { tests := map[versionInfo]string{ @@ -44,5 +48,17 @@ func TestGetVersionToInstall(t *testing.T) { if actual != expected { t.Errorf("Expected getVersionToInstall(\"%s\") to be \"%s\", but got \"%s\".", input, expected, actual) } + + if input.goEnvVersionFound { + input.goEnvVersion = util.FormatSemVer(input.goEnvVersion) + } + if input.goEnvVersionFound { + input.goModVersion = util.FormatSemVer(input.goModVersion) + } + + _, actual = getVersionToInstall(input) + if actual != expected { + t.Errorf("Expected getVersionToInstall(\"%s\") to be \"%s\", but got \"%s\".", input, expected, actual) + } } }