]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/go: fix version validation in 'go mod edit -exclude'
authorBryan C. Mills <bcmills@google.com>
Mon, 22 Feb 2021 20:05:20 +0000 (15:05 -0500)
committerBryan C. Mills <bcmills@google.com>
Wed, 24 Feb 2021 15:54:12 +0000 (15:54 +0000)
The fix is to pull in CL 295089 from the x/mod repo.

Fixes #44497

Change-Id: I008b58d0f4bb48c09d4f1e6ed31d11a714f87dc0
Reviewed-on: https://go-review.googlesource.com/c/go/+/295150
Trust: Bryan C. Mills <bcmills@google.com>
Run-TryBot: Bryan C. Mills <bcmills@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Jay Conrod <jayconrod@google.com>
Reviewed-by: Michael Matloob <matloob@golang.org>
src/cmd/go.mod
src/cmd/go.sum
src/cmd/go/testdata/script/mod_edit.txt
src/cmd/vendor/golang.org/x/mod/modfile/rule.go
src/cmd/vendor/modules.txt

index 24ad6c24327da9e2bac942128a8d3df32e5347c0..3c90dca491a07a60bb45f07f7228ed50b509d953 100644 (file)
@@ -6,7 +6,7 @@ require (
        github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2
        golang.org/x/arch v0.0.0-20201008161808-52c3e6f60cff
        golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897
-       golang.org/x/mod v0.4.1
+       golang.org/x/mod v0.4.2-0.20210223202949-66f6d92cabd5
        golang.org/x/sys v0.0.0-20210218145245-beda7e5e158e // indirect
        golang.org/x/tools v0.1.1-0.20210220032852-2363391a5b2f
 )
index e9b62f46e16d9276109779a1eda0365cbc5883d5..498b92207f4888eccdacf41e40a18cead3bf60fd 100644 (file)
@@ -13,8 +13,9 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U
 golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
 golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897 h1:pLI5jrR7OSLijeIDcmRxNmw2api+jEfxLoykJVice/E=
 golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
-golang.org/x/mod v0.4.1 h1:Kvvh58BN8Y9/lBi7hTekvtMpm07eUZ0ck5pRHpsMWrY=
 golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/mod v0.4.2-0.20210223202949-66f6d92cabd5 h1:ETedWdSKv0zHgSxvhXszxH25fCWwA6olYCPu9ehlVKs=
+golang.org/x/mod v0.4.2-0.20210223202949-66f6d92cabd5/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
 golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
index 02d2d40bbb49b983bb366a87b7896028e0ad9b64..9da69306dacc4032e73c7610770c252732d7178b 100644 (file)
@@ -16,9 +16,9 @@ cmpenv 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' -retract=v1.6.0 -retract=[v1.1.0,v1.2.0] -retract=[v1.3.0,v1.4.0] -retract=v1.0.0
+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 -exclude=x.1@v2.0.0+incompatible -replace=x.1@v1.3.0=y.1@v1.4.0 -replace='x.1@v1.4.0 = ../z' -retract=v1.6.0 -retract=[v1.1.0,v1.2.0] -retract=[v1.3.0,v1.4.0] -retract=v1.0.0
 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 -dropretract=v1.0.0 -dropretract=[v1.1.0,v1.2.0]
+go mod edit -droprequire=x.1 -dropexclude=x.1@v1.2.1 -dropexclude=x.1@v2.0.0+incompatible -dropreplace=x.1@v1.3.0 -require=x.3@v1.99.0 -dropretract=v1.0.0 -dropretract=[v1.1.0,v1.2.0]
 cmpenv go.mod $WORK/go.mod.edit2
 
 # -exclude and -retract reject invalid versions.
@@ -26,25 +26,17 @@ cmpenv go.mod $WORK/go.mod.edit2
 stderr '^go mod: -exclude=example.com/m@bad: version "bad" invalid: must be of the form v1.2.3$'
 ! go mod edit -retract=bad
 stderr '^go mod: -retract=bad: version "bad" invalid: must be of the form v1.2.3$'
-cmpenv go.mod $WORK/go.mod.edit2
 
-cp go.mod go.mod.beforebugs
+! go mod edit -exclude=example.com/m@v2.0.0
+stderr '^go mod: -exclude=example.com/m@v2\.0\.0: version "v2\.0\.0" invalid: should be v2\.0\.0\+incompatible \(or module example\.com/m/v2\)$'
 
-# BUG(#44497): -exclude accepts a mismatched major version without +incompatible, but should not.
-go mod edit -exclude=example.com/m@v2.0.0
-! go mod edit -json
-stderr '^go: errors parsing go.mod:\n.*[/\\]go.mod:16: exclude example\.com/m: version "v2\.0\.0" invalid: should be v0 or v1, not v2$'
-cp go.mod.beforebugs go.mod
+! go mod edit -exclude=example.com/m/v2@v1.0.0
+stderr '^go mod: -exclude=example.com/m/v2@v1\.0\.0: version "v1\.0\.0" invalid: should be v2, not v1$'
 
-# BUG(#44497): -exclude accepts a v1 version for a v2 module, but should not.
-go mod edit -exclude=example.com/m/v2@v1.0.0
-! go mod edit -json
-stderr '^go: errors parsing go.mod:\n.*[/\\]go.mod:16: exclude example\.com/m/v2: version "v1\.0\.0" invalid: should be v2, not v1$'
-cp go.mod.beforebugs go.mod
+! go mod edit -exclude=gopkg.in/example.v1@v2.0.0
+stderr '^go mod: -exclude=gopkg\.in/example\.v1@v2\.0\.0: version "v2\.0\.0" invalid: should be v1, not v2$'
 
-# BUG(#44497): -exclude rejects a +incompatible version for an unversioned
-# module path, but should not.
-! go mod edit -exclude=example.com/m@v2.0.0+incompatible
+cmpenv go.mod $WORK/go.mod.edit2
 
 # go mod edit -json
 go mod edit -json
@@ -107,6 +99,7 @@ require x.1 v1.0.0
 exclude (
        x.1 v1.2.0
        x.1 v1.2.1
+       x.1 v2.0.0+incompatible
 )
 
 replace (
index c6a189dbe049d843811236ec7b7265038c0afc8d..8fcf96b713842761e45bdc3010b7ae12f265d794 100644 (file)
@@ -835,11 +835,8 @@ func (f *File) DropRequire(path string) error {
 // AddExclude adds a exclude statement to the mod file. Errors if the provided
 // version is not a canonical version string
 func (f *File) AddExclude(path, vers string) error {
-       if !isCanonicalVersion(vers) {
-               return &module.InvalidVersionError{
-                       Version: vers,
-                       Err:     errors.New("must be of the form v1.2.3"),
-               }
+       if err := checkCanonicalVersion(path, vers); err != nil {
+               return err
        }
 
        var hint *Line
@@ -916,17 +913,15 @@ func (f *File) DropReplace(oldPath, oldVers string) error {
 // AddRetract adds a retract statement to the mod file. Errors if the provided
 // version interval does not consist of canonical version strings
 func (f *File) AddRetract(vi VersionInterval, rationale string) error {
-       if !isCanonicalVersion(vi.High) {
-               return &module.InvalidVersionError{
-                       Version: vi.High,
-                       Err:     errors.New("must be of the form v1.2.3"),
-               }
+       var path string
+       if f.Module != nil {
+               path = f.Module.Mod.Path
        }
-       if !isCanonicalVersion(vi.Low) {
-               return &module.InvalidVersionError{
-                       Version: vi.Low,
-                       Err:     errors.New("must be of the form v1.2.3"),
-               }
+       if err := checkCanonicalVersion(path, vi.High); err != nil {
+               return err
+       }
+       if err := checkCanonicalVersion(path, vi.Low); err != nil {
+               return err
        }
 
        r := &Retract{
@@ -1086,8 +1081,40 @@ func lineRetractLess(li, lj *Line) bool {
        return semver.Compare(vii.High, vij.High) > 0
 }
 
-// isCanonicalVersion tests if the provided version string represents a valid
-// canonical version.
-func isCanonicalVersion(vers string) bool {
-       return vers != "" && semver.Canonical(vers) == vers
+// checkCanonicalVersion returns a non-nil error if vers is not a canonical
+// version string or does not match the major version of path.
+//
+// If path is non-empty, the error text suggests a format with a major version
+// corresponding to the path.
+func checkCanonicalVersion(path, vers string) error {
+       _, pathMajor, pathMajorOk := module.SplitPathVersion(path)
+
+       if vers == "" || vers != module.CanonicalVersion(vers) {
+               if pathMajor == "" {
+                       return &module.InvalidVersionError{
+                               Version: vers,
+                               Err:     fmt.Errorf("must be of the form v1.2.3"),
+                       }
+               }
+               return &module.InvalidVersionError{
+                       Version: vers,
+                       Err:     fmt.Errorf("must be of the form %s.2.3", module.PathMajorPrefix(pathMajor)),
+               }
+       }
+
+       if pathMajorOk {
+               if err := module.CheckPathMajor(vers, pathMajor); err != nil {
+                       if pathMajor == "" {
+                               // In this context, the user probably wrote "v2.3.4" when they meant
+                               // "v2.3.4+incompatible". Suggest that instead of "v0 or v1".
+                               return &module.InvalidVersionError{
+                                       Version: vers,
+                                       Err:     fmt.Errorf("should be %s+incompatible (or module %s/%v)", vers, path, semver.Major(vers)),
+                               }
+                       }
+                       return err
+               }
+       }
+
+       return nil
 }
index abe70ae87e9536141f9d62c1629f65000d9c41db..254cff70dd674d2ece05b9bcf3f5361a9a98a8cd 100644 (file)
@@ -28,7 +28,7 @@ golang.org/x/arch/x86/x86asm
 golang.org/x/crypto/ed25519
 golang.org/x/crypto/ed25519/internal/edwards25519
 golang.org/x/crypto/ssh/terminal
-# golang.org/x/mod v0.4.1
+# golang.org/x/mod v0.4.2-0.20210223202949-66f6d92cabd5
 ## explicit
 golang.org/x/mod/internal/lazyregexp
 golang.org/x/mod/modfile