@@ -61,11 +61,19 @@ var goVersion = ""
6161// Returns the current Go version as returned by 'go version', e.g. go1.14.4
6262func getEnvGoVersion () string {
6363 if goVersion == "" {
64- gover , err := exec .Command ("go" , "version" ).CombinedOutput ()
64+ // Since Go 1.21, running 'go version' in a directory with a 'go.mod' file will attempt to
65+ // download the version of Go specified in there. That may either fail or result in us just
66+ // being told what's already in 'go.mod'. Setting 'GOTOOLCHAIN' to 'local' will force it
67+ // to use the local Go toolchain instead.
68+ cmd := exec .Command ("go" , "version" )
69+ cmd .Env = append (os .Environ (), "GOTOOLCHAIN=local" )
70+ out , err := cmd .CombinedOutput ()
71+
6572 if err != nil {
6673 log .Fatalf ("Unable to run the go command, is it installed?\n Error: %s" , err .Error ())
6774 }
68- goVersion = parseGoVersion (string (gover ))
75+
76+ goVersion = parseGoVersion (string (out ))
6977 }
7078 return goVersion
7179}
@@ -367,8 +375,15 @@ func getDepMode(emitDiagnostics bool) (DependencyInstallerMode, string) {
367375 return GoGetNoModules , "."
368376}
369377
378+ type GoVersionInfo struct {
379+ // The version string, if any
380+ Version string
381+ // A value indicating whether a version string was found
382+ Found bool
383+ }
384+
370385// Tries to open `go.mod` and read a go directive, returning the version and whether it was found.
371- func tryReadGoDirective (buildInfo BuildInfo ) ( string , bool ) {
386+ func tryReadGoDirective (buildInfo BuildInfo ) GoVersionInfo {
372387 if buildInfo .DepMode == GoGetWithModules {
373388 versionRe := regexp .MustCompile (`(?m)^go[ \t\r]+([0-9]+\.[0-9]+(\.[0-9]+)?)$` )
374389 goMod , err := os .ReadFile (filepath .Join (buildInfo .BaseDir , "go.mod" ))
@@ -378,12 +393,12 @@ func tryReadGoDirective(buildInfo BuildInfo) (string, bool) {
378393 matches := versionRe .FindSubmatch (goMod )
379394 if matches != nil {
380395 if len (matches ) > 1 {
381- return string (matches [1 ]), true
396+ return GoVersionInfo { string (matches [1 ]), true }
382397 }
383398 }
384399 }
385400 }
386- return "" , false
401+ return GoVersionInfo { "" , false }
387402}
388403
389404// Returns the appropriate ModMode for the current project
@@ -771,13 +786,15 @@ func installDependenciesAndBuild() {
771786 os .Setenv ("GO111MODULE" , "auto" )
772787 }
773788
774- goModVersion , goModVersionFound := tryReadGoDirective (buildInfo )
789+ goVersionInfo := tryReadGoDirective (buildInfo )
775790
776- if goModVersionFound && semver .Compare ("v" + goModVersion , getEnvGoSemVer ()) > 0 {
791+ // This diagnostic is not required if the system Go version is 1.21 or greater, since the
792+ // Go tooling should install required Go versions as needed.
793+ if semver .Compare (getEnvGoSemVer (), "v1.21.0" ) < 0 && goVersionInfo .Found && semver .Compare ("v" + goVersionInfo .Version , getEnvGoSemVer ()) > 0 {
777794 diagnostics .EmitNewerGoVersionNeeded ()
778795 }
779796
780- fixGoVendorIssues (& buildInfo , goModVersionFound )
797+ fixGoVendorIssues (& buildInfo , goVersionInfo . Found )
781798
782799 tryUpdateGoModAndGoSum (buildInfo )
783800
@@ -1092,7 +1109,8 @@ func isGoInstalled() bool {
10921109func identifyEnvironment () {
10931110 var v versionInfo
10941111 buildInfo := getBuildInfo (false )
1095- v .goModVersion , v .goModVersionFound = tryReadGoDirective (buildInfo )
1112+ goVersionInfo := tryReadGoDirective (buildInfo )
1113+ v .goModVersion , v .goModVersionFound = goVersionInfo .Version , goVersionInfo .Found
10961114
10971115 v .goEnvVersionFound = isGoInstalled ()
10981116 if v .goEnvVersionFound {
0 commit comments