@@ -11,7 +11,6 @@ import (
1111 "strings"
1212
1313 "github.com/github/codeql-go/extractor/util"
14- "golang.org/x/mod/semver"
1514)
1615
1716// Check if Go is installed in the environment.
@@ -23,11 +22,11 @@ func IsInstalled() bool {
2322// The default Go version that is available on a system and a set of all versions
2423// that we know are installed on the system.
2524var goVersion = ""
26- var goVersions = map [string ]struct {}{}
25+ var goVersions = map [util. SemVer ]struct {}{}
2726
2827// Adds an entry to the set of installed Go versions for the normalised `version` number.
29- func addGoVersion (version string ) {
30- goVersions [semver . Canonical ( "v" + version ) ] = struct {}{}
28+ func addGoVersion (version util. SemVer ) {
29+ goVersions [version ] = struct {}{}
3130}
3231
3332// Returns the current Go version as returned by 'go version', e.g. go1.14.4
@@ -53,19 +52,19 @@ func GetEnvGoVersion() string {
5352 }
5453
5554 goVersion = parseGoVersion (string (out ))
56- addGoVersion (goVersion [ 2 :] )
55+ addGoVersion (util . NewSemVer ( goVersion ) )
5756 }
5857 return goVersion
5958}
6059
6160// Determines whether, to our knowledge, `version` is available on the current system.
62- func HasGoVersion (version string ) bool {
63- _ , found := goVersions [semver . Canonical ( "v" + version ) ]
61+ func HasGoVersion (version util. SemVer ) bool {
62+ _ , found := goVersions [version ]
6463 return found
6564}
6665
6766// Attempts to install the Go toolchain `version`.
68- func InstallVersion (workingDir string , version string ) bool {
67+ func InstallVersion (workingDir string , version util. SemVer ) bool {
6968 // No need to install it if we know that it is already installed.
7069 if HasGoVersion (version ) {
7170 return true
@@ -74,7 +73,7 @@ func InstallVersion(workingDir string, version string) bool {
7473 // Construct a command to invoke `go version` with `GOTOOLCHAIN=go1.N.0` to give
7574 // Go a valid toolchain version to download the toolchain we need; subsequent commands
7675 // should then work even with an invalid version that's still in `go.mod`
77- toolchainArg := "GOTOOLCHAIN=go" + semver . Canonical ( "v" + version )[1 :]
76+ toolchainArg := "GOTOOLCHAIN=go" + version . String ( )[1 :]
7877 versionCmd := Version ()
7978 versionCmd .Dir = workingDir
8079 versionCmd .Env = append (os .Environ (), toolchainArg )
@@ -107,20 +106,12 @@ func InstallVersion(workingDir string, version string) bool {
107106}
108107
109108// Returns the current Go version in semver format, e.g. v1.14.4
110- func GetEnvGoSemVer () string {
109+ func GetEnvGoSemVer () util. SemVer {
111110 goVersion := GetEnvGoVersion ()
112111 if ! strings .HasPrefix (goVersion , "go" ) {
113112 log .Fatalf ("Expected 'go version' output of the form 'go1.2.3'; got '%s'" , goVersion )
114113 }
115- // Go versions don't follow the SemVer format, but the only exception we normally care about
116- // is release candidates; so this is a horrible hack to convert e.g. `go1.22rc1` into `go1.22-rc1`
117- // which is compatible with the SemVer specification
118- rcIndex := strings .Index (goVersion , "rc" )
119- if rcIndex != - 1 {
120- return semver .Canonical ("v" + goVersion [2 :rcIndex ]) + "-" + goVersion [rcIndex :]
121- } else {
122- return semver .Canonical ("v" + goVersion [2 :])
123- }
114+ return util .NewSemVer (goVersion )
124115}
125116
126117// The 'go version' command may output warnings on separate lines before
@@ -137,7 +128,7 @@ func parseGoVersion(data string) string {
137128
138129// Returns a value indicating whether the system Go toolchain supports workspaces.
139130func SupportsWorkspaces () bool {
140- return semver . Compare ( GetEnvGoSemVer (), "v1.18.0" ) >= 0
131+ return GetEnvGoSemVer (). IsAtLeast ( util . NewSemVer ( "v1.18.0" ))
141132}
142133
143134// Run `go mod tidy -e` in the directory given by `path`.
0 commit comments