]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/go: add go statement when initializing go.mod
authorIan Lance Taylor <iant@golang.org>
Fri, 2 Nov 2018 23:58:42 +0000 (16:58 -0700)
committerIan Lance Taylor <iant@golang.org>
Sat, 10 Nov 2018 01:22:06 +0000 (01:22 +0000)
When creating a go.mod file, add a go statement mentioning the current
Go version. We can be reasonably confident that the current version is
able to build the module. This is as described in the language
transition proposal at https://golang.org/issue/28221.

Updates #28221

Change-Id: I70a99b3a53f4b6c0288da07473c5a71bb28cd86f
Reviewed-on: https://go-review.googlesource.com/c/147281
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Bryan C. Mills <bcmills@google.com>
src/cmd/go/internal/modfile/rule.go
src/cmd/go/internal/modload/init.go
src/cmd/go/testdata/script/mod_edit.txt
src/cmd/go/testdata/script/mod_readonly.txt
src/cmd/go/testdata/script/mod_tidy.txt

index e11f0a6e31e152d1f887aff6dd5f82d556ab3b40..7f9a18c6c2a6c02c9aa90beb1bd32b8d95ccabc9 100644 (file)
@@ -154,7 +154,7 @@ func parseToFile(file string, data []byte, fix VersionFixer, strict bool) (*File
        return f, nil
 }
 
-var goVersionRE = regexp.MustCompile(`([1-9][0-9]*)\.(0|[1-9][0-9]*)`)
+var GoVersionRE = regexp.MustCompile(`([1-9][0-9]*)\.(0|[1-9][0-9]*)`)
 
 func (f *File) add(errs *bytes.Buffer, line *Line, verb string, args []string, fix VersionFixer, strict bool) {
        // If strict is false, this module is a dependency.
@@ -181,7 +181,7 @@ func (f *File) add(errs *bytes.Buffer, line *Line, verb string, args []string, f
                        fmt.Fprintf(errs, "%s:%d: repeated go statement\n", f.Syntax.Name, line.Start.Line)
                        return
                }
-               if len(args) != 1 || !goVersionRE.MatchString(args[0]) {
+               if len(args) != 1 || !GoVersionRE.MatchString(args[0]) {
                        fmt.Fprintf(errs, "%s:%d: usage: go 1.23\n", f.Syntax.Name, line.Start.Line)
                        return
                }
@@ -477,6 +477,22 @@ func (f *File) Cleanup() {
        f.Syntax.Cleanup()
 }
 
+func (f *File) AddGoStmt(version string) error {
+       if !GoVersionRE.MatchString(version) {
+               return fmt.Errorf("invalid language version string %q", version)
+       }
+       if f.Go == nil {
+               f.Go = &Go{
+                       Version: version,
+                       Syntax:  f.Syntax.addLine(nil, "go", version),
+               }
+       } else {
+               f.Go.Version = version
+               f.Syntax.updateLine(f.Go.Syntax, "go", version)
+       }
+       return nil
+}
+
 func (f *File) AddRequire(path, vers string) error {
        need := true
        for _, r := range f.Require {
index 2bab3eede1387d24a2c8be6bb4a9f0520198bc91..da778b4fad413b5eef565b2132dc32a8295aceb1 100644 (file)
@@ -19,6 +19,7 @@ import (
        "cmd/go/internal/search"
        "encoding/json"
        "fmt"
+       "go/build"
        "io/ioutil"
        "os"
        "path"
@@ -335,6 +336,8 @@ func legacyModInit() {
                modFile.AddModuleStmt(path)
        }
 
+       addGoStmt()
+
        for _, name := range altConfigs {
                cfg := filepath.Join(ModRoot, name)
                data, err := ioutil.ReadFile(cfg)
@@ -357,6 +360,25 @@ func legacyModInit() {
        }
 }
 
+// InitGoStmt adds a go statement, unless there already is one.
+func InitGoStmt() {
+       if modFile.Go == nil {
+               addGoStmt()
+       }
+}
+
+// addGoStmt adds a go statement referring to the current version.
+func addGoStmt() {
+       tags := build.Default.ReleaseTags
+       version := tags[len(tags)-1]
+       if !strings.HasPrefix(version, "go") || !modfile.GoVersionRE.MatchString(version[2:]) {
+               base.Fatalf("go: unrecognized default version %q", version)
+       }
+       if err := modFile.AddGoStmt(version[2:]); err != nil {
+               base.Fatalf("go: internal error: %v", err)
+       }
+}
+
 var altConfigs = []string{
        "Gopkg.lock",
 
index 60a6f74536197f9a22b79433c7814ff6f83349fc..bf6f2a22c709948b5483240b885c20c3e27f2b4b 100644 (file)
@@ -10,16 +10,16 @@ stderr 'cannot determine module path'
 
 go mod init x.x/y/z
 stderr 'creating new go.mod: module x.x/y/z'
-cmp go.mod $WORK/go.mod.init
+cmpenv go.mod $WORK/go.mod.init
 
 ! go mod init
-cmp go.mod $WORK/go.mod.init
+cmpenv go.mod $WORK/go.mod.init
 
 # go mod edits
 go mod edit -droprequire=x.1 -require=x.1@v1.0.0 -require=x.2@v1.1.0 -droprequire=x.2 -exclude='x.1 @ v1.2.0' -exclude=x.1@v1.2.1 -replace=x.1@v1.3.0=y.1@v1.4.0 -replace='x.1@v1.4.0 = ../z'
-cmp go.mod $WORK/go.mod.edit1
+cmpenv go.mod $WORK/go.mod.edit1
 go mod edit -droprequire=x.1 -dropexclude=x.1@v1.2.1 -dropreplace=x.1@v1.3.0 -require=x.3@v1.99.0
-cmp go.mod $WORK/go.mod.edit2
+cmpenv go.mod $WORK/go.mod.edit2
 
 # go mod edit -json
 go mod edit -json
@@ -27,20 +27,20 @@ cmp stdout $WORK/go.mod.json
 
 # go mod edit -replace
 go mod edit -replace=x.1@v1.3.0=y.1/v2@v2.3.5 -replace=x.1@v1.4.0=y.1/v2@v2.3.5
-cmp go.mod $WORK/go.mod.edit3
+cmpenv go.mod $WORK/go.mod.edit3
 go mod edit -replace=x.1=y.1/v2@v2.3.6
-cmp go.mod $WORK/go.mod.edit4
+cmpenv go.mod $WORK/go.mod.edit4
 go mod edit -dropreplace=x.1
-cmp go.mod $WORK/go.mod.edit5
+cmpenv go.mod $WORK/go.mod.edit5
 
 # go mod edit -fmt
 cp $WORK/go.mod.badfmt go.mod
 go mod edit -fmt -print # -print should avoid writing file
-cmp stdout $WORK/go.mod.edit4
+cmpenv stdout $WORK/go.mod.edit6
 cmp go.mod $WORK/go.mod.badfmt
 go mod edit -fmt # without -print, should write file (and nothing to stdout)
 ! stdout .
-cmp go.mod $WORK/go.mod.edit4
+cmpenv go.mod $WORK/go.mod.edit6
 
 -- x.go --
 package x
@@ -50,9 +50,13 @@ package w
 
 -- $WORK/go.mod.init --
 module x.x/y/z
+
+go $goversion
 -- $WORK/go.mod.edit1 --
 module x.x/y/z
 
+go $goversion
+
 require x.1 v1.0.0
 
 exclude (
@@ -67,6 +71,8 @@ replace (
 -- $WORK/go.mod.edit2 --
 module x.x/y/z
 
+go $goversion
+
 exclude x.1 v1.2.0
 
 replace x.1 v1.4.0 => ../z
@@ -104,6 +110,8 @@ require x.3 v1.99.0
 -- $WORK/go.mod.edit3 --
 module x.x/y/z
 
+go $goversion
+
 exclude x.1 v1.2.0
 
 replace (
@@ -115,6 +123,8 @@ require x.3 v1.99.0
 -- $WORK/go.mod.edit4 --
 module x.x/y/z
 
+go $goversion
+
 exclude x.1 v1.2.0
 
 replace x.1 => y.1/v2 v2.3.6
@@ -123,12 +133,26 @@ require x.3 v1.99.0
 -- $WORK/go.mod.edit5 --
 module x.x/y/z
 
+go $goversion
+
 exclude x.1 v1.2.0
 
+require x.3 v1.99.0
+-- $WORK/go.mod.edit6 --
+module x.x/y/z
+
+go 1.10
+
+exclude x.1 v1.2.0
+
+replace x.1 => y.1/v2 v2.3.6
+
 require x.3 v1.99.0
 -- $WORK/go.mod.badfmt --
 module     x.x/y/z
 
+go 1.10
+
 exclude x.1     v1.2.0
 
 replace x.1    =>   y.1/v2 v2.3.6
index 1b5932e441e75df89187b7882a99aef4de3fe196..188a66d0e15fa8826c526744332771a72e846327 100644 (file)
@@ -37,6 +37,8 @@ cmp go.mod go.mod.inconsistent
 -- go.mod --
 module m
 
+go 1.20
+
 -- x.go --
 package x
 import _ "rsc.io/quote"
index 449aa073a784702e1bc0e3351594914ceb87809f..de3b52e2c023caa51a3ee4c73903b680cae46d08 100644 (file)
@@ -5,6 +5,9 @@ go mod tidy -v
 stderr '^unused y.1'
 ! stderr '^unused [^y]'
 
+# tidy should not touch existing go line
+grep 'go 1.10' go.mod
+
 go list -m all
 ! stdout '^y'
 stdout '^w.1 v1.2.0'
@@ -12,11 +15,17 @@ stdout '^z.1 v1.2.0'
 
 # empty tidy should not crash
 cd triv
+! grep 'go ' go.mod
 go mod tidy
 
+# tidy should add missing go line
+grep 'go ' go.mod
+
 -- go.mod --
 module m
 
+go 1.10
+
 require (
        x.1 v1.0.0
        y.1 v1.0.0