Skip to content

Commit a87b991

Browse files
authored
Merge pull request #16325 from github/mbg/go/use-parse-instead-of-parselax
2 parents 9c139b5 + b8cfff6 commit a87b991

File tree

2 files changed

+46
-3
lines changed

2 files changed

+46
-3
lines changed

go/extractor/project/project.go

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,13 @@ func findGoModFiles(root string) []string {
179179
// A regular expression for the Go toolchain version syntax.
180180
var toolchainVersionRe *regexp.Regexp = regexp.MustCompile(`(?m)^([0-9]+\.[0-9]+\.[0-9]+)$`)
181181

182+
// Returns true if the `go.mod` file specifies a Go language version, that version is `1.21` or greater, and
183+
// there is no `toolchain` directive, and the Go language version is not a valid toolchain version.
184+
func hasInvalidToolchainVersion(modFile *modfile.File) bool {
185+
return modFile.Toolchain == nil && modFile.Go != nil &&
186+
!toolchainVersionRe.Match([]byte(modFile.Go.Version)) && semver.Compare("v"+modFile.Go.Version, "v1.21.0") >= 0
187+
}
188+
182189
// Given a list of `go.mod` file paths, try to parse them all. The resulting array of `GoModule` objects
183190
// will be the same length as the input array and the objects will contain at least the `go.mod` path.
184191
// If parsing the corresponding file is successful, then the parsed contents will also be available.
@@ -196,7 +203,7 @@ func LoadGoModules(emitDiagnostics bool, goModFilePaths []string) []*GoModule {
196203
continue
197204
}
198205

199-
modFile, err := modfile.ParseLax(goModFilePath, modFileSrc, nil)
206+
modFile, err := modfile.Parse(goModFilePath, modFileSrc, nil)
200207

201208
if err != nil {
202209
log.Printf("Unable to parse %s: %s.\n", goModFilePath, err.Error())
@@ -209,8 +216,7 @@ func LoadGoModules(emitDiagnostics bool, goModFilePaths []string) []*GoModule {
209216
// there is no `toolchain` directive, check that it is a valid Go toolchain version. Otherwise,
210217
// `go` commands which try to download the right version of the Go toolchain will fail. We detect
211218
// this situation and emit a diagnostic.
212-
if modFile.Toolchain == nil && modFile.Go != nil &&
213-
!toolchainVersionRe.Match([]byte(modFile.Go.Version)) && semver.Compare("v"+modFile.Go.Version, "v1.21.0") >= 0 {
219+
if hasInvalidToolchainVersion(modFile) {
214220
diagnostics.EmitInvalidToolchainVersion(goModFilePath, modFile.Go.Version)
215221
}
216222
}

go/extractor/project/project_test.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ package project
33
import (
44
"path/filepath"
55
"testing"
6+
7+
"golang.org/x/mod/modfile"
68
)
79

810
func testStartsWithAnyOf(t *testing.T, path string, prefix string, expectation bool) {
@@ -25,3 +27,38 @@ func TestStartsWithAnyOf(t *testing.T) {
2527
testStartsWithAnyOf(t, filepath.Join("foo", "bar"), "bar", false)
2628
testStartsWithAnyOf(t, filepath.Join("foo", "bar"), filepath.Join("foo", "baz"), false)
2729
}
30+
31+
func testHasInvalidToolchainVersion(t *testing.T, contents string) bool {
32+
modFile, err := modfile.Parse("test.go", []byte(contents), nil)
33+
34+
if err != nil {
35+
t.Errorf("Unable to parse %s: %s.\n", contents, err.Error())
36+
}
37+
38+
return hasInvalidToolchainVersion(modFile)
39+
}
40+
41+
func TestHasInvalidToolchainVersion(t *testing.T) {
42+
invalid := []string{
43+
"go 1.21\n",
44+
"go 1.22\n",
45+
}
46+
47+
for _, v := range invalid {
48+
if !testHasInvalidToolchainVersion(t, v) {
49+
t.Errorf("Expected testHasInvalidToolchainVersion(\"%s\") to be true, but got false", v)
50+
}
51+
}
52+
53+
valid := []string{
54+
"go 1.20\n",
55+
"go 1.21.1\n",
56+
"go 1.22\n\ntoolchain go1.22.0\n",
57+
}
58+
59+
for _, v := range valid {
60+
if testHasInvalidToolchainVersion(t, v) {
61+
t.Errorf("Expected testHasInvalidToolchainVersion(\"%s\") to be false, but got true", v)
62+
}
63+
}
64+
}

0 commit comments

Comments
 (0)