We have added a new toolchain directive in go.mod and go.work.
This CL adds support in mod edit and work edit for changing the toolchain line.
For #57001.
Change-Id: I36a960796630a359b8a587877cb9548c299d5c87
Reviewed-on: https://go-review.googlesource.com/c/go/+/497296
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Bryan Mills <bcmills@google.com>
Run-TryBot: Russ Cox <rsc@golang.org>
//
// The -go=version flag sets the expected Go language version.
//
+// The -toolchain=name flag sets the Go toolchain to use.
+//
// The -print flag prints the final go.mod in its text format instead of
// writing it back to go.mod.
//
// }
//
// type GoMod struct {
-// Module ModPath
-// Go string
-// Require []Require
-// Exclude []Module
-// Replace []Replace
-// Retract []Retract
+// Module ModPath
+// Go string
+// Toolchain string
+// Require []Require
+// Exclude []Module
+// Replace []Replace
+// Retract []Retract
// }
//
// type ModPath struct {
//
// The -go=version flag sets the expected Go language version.
//
+// The -toolchain=name flag sets the Go toolchain to use.
+//
// The -print flag prints the final go.work in its text format instead of
// writing it back to go.mod.
//
// writing it back to go.mod. The JSON output corresponds to these Go types:
//
// type GoWork struct {
-// Go string
-// Use []Use
-// Replace []Replace
+// Go string
+// Toolchain string
+// Use []Use
+// Replace []Replace
// }
//
// type Use struct {
The -go=version flag sets the expected Go language version.
+The -toolchain=name flag sets the Go toolchain to use.
+
The -print flag prints the final go.mod in its text format instead of
writing it back to go.mod.
}
type GoMod struct {
- Module ModPath
- Go string
- Require []Require
- Exclude []Module
- Replace []Replace
- Retract []Retract
+ Module ModPath
+ Go string
+ Toolchain string
+ Require []Require
+ Exclude []Module
+ Replace []Replace
+ Retract []Retract
}
type ModPath struct {
}
var (
- editFmt = cmdEdit.Flag.Bool("fmt", false, "")
- editGo = cmdEdit.Flag.String("go", "", "")
- editJSON = cmdEdit.Flag.Bool("json", false, "")
- editPrint = cmdEdit.Flag.Bool("print", false, "")
- editModule = cmdEdit.Flag.String("module", "", "")
- edits []func(*modfile.File) // edits specified in flags
+ editFmt = cmdEdit.Flag.Bool("fmt", false, "")
+ editGo = cmdEdit.Flag.String("go", "", "")
+ editToolchain = cmdEdit.Flag.String("toolchain", "", "")
+ editJSON = cmdEdit.Flag.Bool("json", false, "")
+ editPrint = cmdEdit.Flag.Bool("print", false, "")
+ editModule = cmdEdit.Flag.String("module", "", "")
+ edits []func(*modfile.File) // edits specified in flags
)
type flagFunc func(string)
}
func runEdit(ctx context.Context, cmd *base.Command, args []string) {
- anyFlags :=
- *editModule != "" ||
- *editGo != "" ||
- *editJSON ||
- *editPrint ||
- *editFmt ||
- len(edits) > 0
+ anyFlags := *editModule != "" ||
+ *editGo != "" ||
+ *editToolchain != "" ||
+ *editJSON ||
+ *editPrint ||
+ *editFmt ||
+ len(edits) > 0
if !anyFlags {
base.Fatalf("go: no flags specified (see 'go help mod edit').")
}
}
- if *editGo != "" {
+ if *editGo != "" && *editGo != "none" {
if !modfile.GoVersionRE.MatchString(*editGo) {
base.Fatalf(`go mod: invalid -go option; expecting something like "-go %s"`, gover.Local())
}
}
+ if *editToolchain != "" && *editToolchain != "none" {
+ if !modfile.ToolchainRE.MatchString(*editToolchain) {
+ base.Fatalf(`go mod: invalid -toolchain option; expecting something like "-toolchain go%s"`, gover.Local())
+ }
+ }
data, err := lockedfile.Read(gomod)
if err != nil {
modFile.AddModuleStmt(*editModule)
}
- if *editGo != "" {
+ if *editGo == "none" {
+ modFile.DropGoStmt()
+ } else if *editGo != "" {
if err := modFile.AddGoStmt(*editGo); err != nil {
base.Fatalf("go: internal error: %v", err)
}
}
+ if *editToolchain == "none" {
+ modFile.DropToolchainStmt()
+ } else if *editToolchain != "" {
+ if err := modFile.AddToolchainStmt(*editToolchain); err != nil {
+ base.Fatalf("go: internal error: %v", err)
+ }
+ }
if len(edits) > 0 {
for _, edit := range edits {
// fileJSON is the -json output data structure.
type fileJSON struct {
- Module editModuleJSON
- Go string `json:",omitempty"`
- Require []requireJSON
- Exclude []module.Version
- Replace []replaceJSON
- Retract []retractJSON
+ Module editModuleJSON
+ Go string `json:",omitempty"`
+ Toolchain string `json:",omitempty"`
+ Require []requireJSON
+ Exclude []module.Version
+ Replace []replaceJSON
+ Retract []retractJSON
}
type editModuleJSON struct {
if modFile.Go != nil {
f.Go = modFile.Go.Version
}
+ if modFile.Toolchain != nil {
+ f.Toolchain = modFile.Toolchain.Name
+ }
for _, r := range modFile.Require {
f.Require = append(f.Require, requireJSON{Path: r.Mod.Path, Version: r.Mod.Version, Indirect: r.Indirect})
}
The -go=version flag sets the expected Go language version.
+The -toolchain=name flag sets the Go toolchain to use.
+
The -print flag prints the final go.work in its text format instead of
writing it back to go.mod.
writing it back to go.mod. The JSON output corresponds to these Go types:
type GoWork struct {
- Go string
- Use []Use
- Replace []Replace
+ Go string
+ Toolchain string
+ Use []Use
+ Replace []Replace
}
type Use struct {
}
var (
- editFmt = cmdEdit.Flag.Bool("fmt", false, "")
- editGo = cmdEdit.Flag.String("go", "", "")
- editJSON = cmdEdit.Flag.Bool("json", false, "")
- editPrint = cmdEdit.Flag.Bool("print", false, "")
- workedits []func(file *modfile.WorkFile) // edits specified in flags
+ editFmt = cmdEdit.Flag.Bool("fmt", false, "")
+ editGo = cmdEdit.Flag.String("go", "", "")
+ editToolchain = cmdEdit.Flag.String("toolchain", "", "")
+ editJSON = cmdEdit.Flag.Bool("json", false, "")
+ editPrint = cmdEdit.Flag.Bool("print", false, "")
+ workedits []func(file *modfile.WorkFile) // edits specified in flags
)
type flagFunc func(string)
modload.InitWorkfile()
gowork = modload.WorkFilePath()
}
+ if gowork == "" {
+ base.Fatalf("go: no go.work file found\n\t(run 'go work init' first or specify path using GOWORK environment variable)")
+ }
- if *editGo != "" {
+ if *editGo != "" && *editGo != "none" {
if !modfile.GoVersionRE.MatchString(*editGo) {
- base.Fatalf(`go mod: invalid -go option; expecting something like "-go %s"`, gover.Local())
+ base.Fatalf(`go work: invalid -go option; expecting something like "-go %s"`, gover.Local())
}
}
-
- if gowork == "" {
- base.Fatalf("go: no go.work file found\n\t(run 'go work init' first or specify path using GOWORK environment variable)")
+ if *editToolchain != "" && *editToolchain != "none" {
+ if !modfile.ToolchainRE.MatchString(*editToolchain) {
+ base.Fatalf(`go work: invalid -toolchain option; expecting something like "-toolchain go%s"`, gover.Local())
+ }
}
- anyFlags :=
- *editGo != "" ||
- *editJSON ||
- *editPrint ||
- *editFmt ||
- len(workedits) > 0
+ anyFlags := *editGo != "" ||
+ *editToolchain != "" ||
+ *editJSON ||
+ *editPrint ||
+ *editFmt ||
+ len(workedits) > 0
if !anyFlags {
base.Fatalf("go: no flags specified (see 'go help work edit').")
base.Fatalf("go: errors parsing %s:\n%s", base.ShortPath(gowork), err)
}
- if *editGo != "" {
+ if *editGo == "none" {
+ workFile.DropGoStmt()
+ } else if *editGo != "" {
if err := workFile.AddGoStmt(*editGo); err != nil {
base.Fatalf("go: internal error: %v", err)
}
}
+ if *editToolchain == "none" {
+ workFile.DropToolchainStmt()
+ } else if *editToolchain != "" {
+ if err := workFile.AddToolchainStmt(*editToolchain); err != nil {
+ base.Fatalf("go: internal error: %v", err)
+ }
+ }
if len(workedits) > 0 {
for _, edit := range workedits {
-# Test support for go mod -edit to set language version.
+# Test support for go mod edit -go to set language version.
env GO111MODULE=on
! go build
! go build
stderr 'type aliases requires'
+# go=none should drop the line
+go mod edit -go=none
+! grep go go.mod
-- go.mod --
module m
--- /dev/null
+# Test support for go mod edit -toolchain to set toolchain to use
+
+env GOTOOLCHAIN=local
+env GO111MODULE=on
+
+! grep toolchain go.mod
+go mod edit -toolchain=go1.9
+grep 'toolchain go1.9' go.mod
+
+go mod edit -toolchain=local
+grep 'toolchain local' go.mod
+
+go mod edit -toolchain=none
+! grep toolchain go.mod
+
+-- go.mod --
+module m
+go 1.8
go work edit -use n
cmpenv go.work go.work.want_use_n
+grep go go.work
+go work edit -go none
+! grep go go.work
+
go work edit -go 1.18
cmp go.work go.work.want_go_118
--- /dev/null
+# Test support for go work edit -toolchain to set toolchain to use
+
+env GOTOOLCHAIN=local
+env GO111MODULE=on
+
+! grep toolchain go.work
+go work edit -toolchain=go1.9
+grep 'toolchain go1.9' go.work
+
+go work edit -toolchain=local
+grep 'toolchain local' go.work
+
+go work edit -toolchain=none
+! grep toolchain go.work
+
+-- go.work --
+go 1.8
+use .
+-- go.mod --
+module m