make:*, plugin:add and new inserted toolchain go1.27.0 into go.mod and go.work whenever that exact line was missing. A file that already named another toolchain (go mod tidy and go work use write the running one) ended up with two toolchain lines, and Go refused to load it with "repeated toolchain statement". ensureToolchain now keeps an existing line, replaces it only when it names an older toolchain, and inserts one only when there is none.
59 lines
1.3 KiB
Go
59 lines
1.3 KiB
Go
package build
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestEnsureToolchain(t *testing.T) {
|
|
cases := []struct {
|
|
name string
|
|
in string
|
|
want string
|
|
}{
|
|
{
|
|
name: "missing line is added after go",
|
|
in: "go 1.27\n\nuse .\n",
|
|
want: "go 1.27\n\n" + toolchainLine + "\n\nuse .\n",
|
|
},
|
|
{
|
|
name: "our line is kept",
|
|
in: "go 1.27\n\n" + toolchainLine + "\n",
|
|
want: "go 1.27\n\n" + toolchainLine + "\n",
|
|
},
|
|
{
|
|
name: "newer toolchain is kept, not repeated",
|
|
in: "go 1.27\n\ntoolchain go1.99.2\n\nuse .\n",
|
|
want: "go 1.27\n\ntoolchain go1.99.2\n\nuse .\n",
|
|
},
|
|
{
|
|
name: "older toolchain is replaced",
|
|
in: "module x\n\ngo 1.25\n\ntoolchain go1.25.1\n",
|
|
want: "module x\n\ngo 1.25\n\n" + toolchainLine + "\n",
|
|
},
|
|
}
|
|
for _, tc := range cases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
path := filepath.Join(t.TempDir(), "go.work")
|
|
if err := os.WriteFile(path, []byte(tc.in), 0o644); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := ensureToolchain(path); err != nil {
|
|
t.Fatalf("ensureToolchain: %v", err)
|
|
}
|
|
got, err := os.ReadFile(path)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if string(got) != tc.want {
|
|
t.Fatalf("got:\n%s\nwant:\n%s", got, tc.want)
|
|
}
|
|
if n := strings.Count(string(got), "\ntoolchain "); n != 1 {
|
|
t.Fatalf("got %d toolchain lines, want 1", n)
|
|
}
|
|
})
|
|
}
|
|
}
|