]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/go: add mod edit -toolchain and work edit -toolchain
authorRuss Cox <rsc@golang.org>
Mon, 22 May 2023 16:26:15 +0000 (12:26 -0400)
committerRuss Cox <rsc@golang.org>
Wed, 24 May 2023 00:49:56 +0000 (00:49 +0000)
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>

src/cmd/go/alldocs.go
src/cmd/go/internal/modcmd/edit.go
src/cmd/go/internal/workcmd/edit.go
src/cmd/go/testdata/script/mod_edit_go.txt
src/cmd/go/testdata/script/mod_edit_toolchain.txt [new file with mode: 0644]
src/cmd/go/testdata/script/work_edit.txt
src/cmd/go/testdata/script/work_edit_toolchain.txt [new file with mode: 0644]

index 455a0f753631ab087d9329796f3df80de8180aa0..6a1cb8b81036954999baab527238151357e41d6e 100644 (file)
 //
 // 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 {
index 2b63af58553673d84587fec86efe3586b3d6bc37..bd22649172a53ec8c29c87868348391c3fec9087 100644 (file)
@@ -79,6 +79,8 @@ and the changes are applied in the order given.
 
 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.
 
@@ -91,12 +93,13 @@ writing it back to go.mod. The JSON output corresponds to these Go types:
        }
 
        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 {
@@ -135,12 +138,13 @@ See https://golang.org/ref/mod#go-mod-edit for more about 'go mod edit'.
 }
 
 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)
@@ -166,13 +170,13 @@ func init() {
 }
 
 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').")
@@ -198,11 +202,16 @@ func runEdit(ctx context.Context, cmd *base.Command, args []string) {
                }
        }
 
-       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 {
@@ -218,11 +227,20 @@ func runEdit(ctx context.Context, cmd *base.Command, args []string) {
                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 {
@@ -460,12 +478,13 @@ func flagDropRetract(arg string) {
 
 // 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 {
@@ -502,6 +521,9 @@ func editPrintJSON(modFile *modfile.File) {
        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})
        }
index e4254782a8169c3512b8535d8266024394f29983..4157e521d79fc8dcf18e28a6cb515da8422055cf 100644 (file)
@@ -58,6 +58,8 @@ editing flags may be repeated, and the changes are applied in the order given.
 
 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.
 
@@ -65,9 +67,10 @@ The -json flag prints the final go.work file in JSON format instead of
 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 {
@@ -91,11 +94,12 @@ for more information.
 }
 
 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)
@@ -128,23 +132,27 @@ func runEditwork(ctx context.Context, cmd *base.Command, args []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').")
@@ -155,11 +163,20 @@ func runEditwork(ctx context.Context, cmd *base.Command, args []string) {
                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 {
index 7e9740fec43763a0727719f623c7ee708e98de97..ec04f40f52efabd2df0c8bb0150fc19f77103525 100644 (file)
@@ -1,4 +1,4 @@
-# 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
@@ -13,6 +13,9 @@ go mod edit -go=1.8
 ! 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
diff --git a/src/cmd/go/testdata/script/mod_edit_toolchain.txt b/src/cmd/go/testdata/script/mod_edit_toolchain.txt
new file mode 100644 (file)
index 0000000..525e4dd
--- /dev/null
@@ -0,0 +1,18 @@
+# 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
index ad5de6286d288a811cbdd25883b967eded54a190..c67696dd6e008d1de55435437a58163f4ac6a2c1 100644 (file)
@@ -6,6 +6,10 @@ cmpenv go.work go.work.want_initial
 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
 
diff --git a/src/cmd/go/testdata/script/work_edit_toolchain.txt b/src/cmd/go/testdata/script/work_edit_toolchain.txt
new file mode 100644 (file)
index 0000000..a171296
--- /dev/null
@@ -0,0 +1,20 @@
+# 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