Skip to content

Commit

Permalink
modfile: add parsing support for toolchain
Browse files Browse the repository at this point in the history
Add new toolchain directive to go.mod and go.work parser.
Also fix error checking in parsing tests.

For golang/go#57001.

Change-Id: Ib7603f82cbd667f2152ed6b0c5989f08c28ceb1c
Reviewed-on: https://go-review.googlesource.com/c/mod/+/497399
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Bryan Mills <bcmills@google.com>
  • Loading branch information
rsc committed May 23, 2023
1 parent a73672d commit 1846133
Show file tree
Hide file tree
Showing 7 changed files with 63 additions and 10 deletions.
27 changes: 21 additions & 6 deletions modfile/read_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,13 @@ func TestPrintParse(t *testing.T) {
pf1, err := Parse(base, data, nil)
if err != nil {
switch base {
case "testdata/replace2.in", "testdata/gopkg.in.golden":
case "testdata/block.golden",
"testdata/block.in",
"testdata/comment.golden",
"testdata/comment.in",
"testdata/rule1.golden":
// ignore
default:
t.Errorf("should parse %v: %v", base, err)
}
}
Expand Down Expand Up @@ -425,28 +431,37 @@ func TestModulePath(t *testing.T) {
}
}

func TestGoVersion(t *testing.T) {
func TestParseVersions(t *testing.T) {
tests := []struct {
desc, input string
ok bool
laxOK bool // ok=true implies laxOK=true; only set if ok=false
}{
// go lines
{desc: "empty", input: "module m\ngo \n", ok: false},
{desc: "one", input: "module m\ngo 1\n", ok: false},
{desc: "two", input: "module m\ngo 1.22\n", ok: true},
{desc: "three", input: "module m\ngo 1.22.333", ok: true},
{desc: "before", input: "module m\ngo v1.2\n", ok: false},
{desc: "after", input: "module m\ngo 1.2rc1\n", ok: true},
{desc: "space", input: "module m\ngo 1.2 3.4\n", ok: false},
{desc: "alt1", input: "module m\ngo 1.2.3\n", ok: true, laxOK: true},
{desc: "alt2", input: "module m\ngo 1.2rc1\n", ok: true, laxOK: true},
{desc: "alt3", input: "module m\ngo 1.2beta1\n", ok: true, laxOK: true},
{desc: "alt1", input: "module m\ngo 1.2.3\n", ok: true},
{desc: "alt2", input: "module m\ngo 1.2rc1\n", ok: true},
{desc: "alt3", input: "module m\ngo 1.2beta1\n", ok: true},
{desc: "alt4", input: "module m\ngo 1.2.beta1\n", ok: false, laxOK: true},
{desc: "alt1", input: "module m\ngo v1.2.3\n", ok: false, laxOK: true},
{desc: "alt2", input: "module m\ngo v1.2rc1\n", ok: false, laxOK: true},
{desc: "alt3", input: "module m\ngo v1.2beta1\n", ok: false, laxOK: true},
{desc: "alt4", input: "module m\ngo v1.2.beta1\n", ok: false, laxOK: true},
{desc: "alt1", input: "module m\ngo v1.2\n", ok: false, laxOK: true},

// toolchain lines
{desc: "tool", input: "module m\ntoolchain go1.2\n", ok: true},
{desc: "tool1", input: "module m\ntoolchain go1.2.3\n", ok: true},
{desc: "tool2", input: "module m\ntoolchain go1.2rc1\n", ok: true},
{desc: "tool3", input: "module m\ntoolchain gccgo-go1.2rc1\n", ok: true},
{desc: "tool4", input: "module m\ntoolchain local\n", ok: true},
{desc: "tool5", input: "module m\ntoolchain inconceivable!\n", ok: false, laxOK: true},
}
t.Run("Strict", func(t *testing.T) {
for _, test := range tests {
Expand All @@ -462,7 +477,7 @@ func TestGoVersion(t *testing.T) {
t.Run("Lax", func(t *testing.T) {
for _, test := range tests {
t.Run(test.desc, func(t *testing.T) {
if _, err := Parse("go.mod", []byte(test.input), nil); err == nil && !(test.ok || test.laxOK) {
if _, err := ParseLax("go.mod", []byte(test.input), nil); err == nil && !(test.ok || test.laxOK) {
t.Error("unexpected success")
} else if err != nil && test.ok {
t.Errorf("unexpected error: %v", err)
Expand Down
31 changes: 31 additions & 0 deletions modfile/rule.go
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,21 @@ func (f *File) add(errs *ErrorList, block *LineBlock, line *Line, verb string, a
f.Go = &Go{Syntax: line}
f.Go.Version = args[0]

case "toolchain":
if f.Toolchain != nil {
errorf("repeated toolchain statement")
return
}
if len(args) != 1 {
errorf("toolchain directive expects exactly one argument")
return
} else if strict && !ToolchainRE.MatchString(args[0]) {
errorf("invalid toolchain version '%s': must match format go1.23 or local", args[0])
return
}
f.Toolchain = &Toolchain{Syntax: line}
f.Toolchain.Name = args[0]

case "module":
if f.Module != nil {
errorf("repeated module statement")
Expand Down Expand Up @@ -623,6 +638,22 @@ func (f *WorkFile) add(errs *ErrorList, line *Line, verb string, args []string,
f.Go = &Go{Syntax: line}
f.Go.Version = args[0]

case "toolchain":
if f.Toolchain != nil {
errorf("repeated toolchain statement")
return
}
if len(args) != 1 {
errorf("toolchain directive expects exactly one argument")
return
} else if !ToolchainRE.MatchString(args[0]) {
errorf("invalid toolchain version '%s': must match format go1.23 or local", args[0])
return
}

f.Toolchain = &Toolchain{Syntax: line}
f.Toolchain.Name = args[0]

case "use":
if len(args) != 1 {
errorf("usage: %s local/dir", verb)
Expand Down
3 changes: 3 additions & 0 deletions modfile/testdata/goline.golden
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
go 1.2.3

toolchain local
2 changes: 2 additions & 0 deletions modfile/testdata/goline.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
go 1.2.3
toolchain local
3 changes: 3 additions & 0 deletions modfile/testdata/work/goline.golden
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
go 1.2.3

toolchain local
2 changes: 2 additions & 0 deletions modfile/testdata/work/goline.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
go 1.2.3
toolchain local
5 changes: 1 addition & 4 deletions modfile/work_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -332,10 +332,7 @@ func TestWorkPrintParse(t *testing.T) {

pf1, err := ParseWork(base, data, nil)
if err != nil {
switch base {
case "testdata/replace2.in", "testdata/gopkg.in.golden":
t.Errorf("should parse %v: %v", base, err)
}
t.Errorf("should parse %v: %v", base, err)
}
if err == nil {
pf2, err := ParseWork(base, ndata, nil)
Expand Down

0 comments on commit 1846133

Please sign in to comment.