]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/go: relax validation for replacements for gopkg.in paths
authorBryan C. Mills <bcmills@google.com>
Thu, 19 Dec 2019 20:46:06 +0000 (15:46 -0500)
committerBryan C. Mills <bcmills@google.com>
Thu, 19 Dec 2019 22:16:18 +0000 (22:16 +0000)
The 'go' command normally requires the 'go.mod' files for replacement
modules to have a major version compatible with the module they are
replacing.

However, prior to CL 206761, the 'go' command erroneously allowed
unversioned paths (which imply major version 0 or 1) to replace
'gopkg.in' paths with any major-version suffix.

An analysis of proxy.golang.org suggests that these replacements,
while uncommon, are not unheard-of. Rather than breaking the modules
that rely on them, we will continue to allow the erroneous replacement
paths for this particular pairing.

Updates #34254

Change-Id: Icb4e745981803edaa96060f17a8720a058219ab1
Reviewed-on: https://go-review.googlesource.com/c/go/+/212105
Run-TryBot: Bryan C. Mills <bcmills@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Jay Conrod <jayconrod@google.com>
src/cmd/go/internal/modfetch/coderepo.go
src/cmd/go/testdata/script/mod_replace_gopkgin.txt

index de757ecd27bc19c8a7c2cf38afa90dd6fc25a3e0..6f71d48b392dd964a795c38d967edd1818a3ca98 100644 (file)
@@ -708,7 +708,7 @@ func (r *codeRepo) findDir(version string) (rev, dir string, gomod []byte, err e
                return "", "", nil, fmt.Errorf("reading %s/%s at revision %s: %v", r.pathPrefix, file1, rev, err1)
        }
        mpath1 := modfile.ModulePath(gomod1)
-       found1 := err1 == nil && isMajor(mpath1, r.pathMajor)
+       found1 := err1 == nil && (isMajor(mpath1, r.pathMajor) || r.canReplaceMismatchedVersionDueToBug(mpath1))
 
        var file2 string
        if r.pathMajor != "" && r.codeRoot != r.modPath && !strings.HasPrefix(r.pathMajor, ".") {
@@ -817,6 +817,17 @@ func isMajor(mpath, pathMajor string) bool {
        return pathMajor[1:] == mpathMajor[1:]
 }
 
+// canReplaceMismatchedVersionDueToBug reports whether versions of r
+// could replace versions of mpath with otherwise-mismatched major versions
+// due to a historical bug in the Go command (golang.org/issue/34254).
+func (r *codeRepo) canReplaceMismatchedVersionDueToBug(mpath string) bool {
+       // The bug caused us to erroneously accept unversioned paths as replacements
+       // for versioned gopkg.in paths.
+       unversioned := r.pathMajor == ""
+       replacingGopkgIn := strings.HasPrefix(mpath, "gopkg.in/")
+       return unversioned && replacingGopkgIn
+}
+
 func (r *codeRepo) GoMod(version string) (data []byte, err error) {
        if version != module.CanonicalVersion(version) {
                return nil, fmt.Errorf("version %s is not canonical", version)
index 6608fb1b801129796fa7b188e7eef88719dfb556..28c1196284d9a5e2264a7125425d7248badcad9f 100644 (file)
@@ -15,10 +15,28 @@ env GOSUMDB=off
 # Replacing gopkg.in/[…].vN with a repository with a root go.mod file
 # specifying […].vN and a compatible version should succeed, even if
 # the replacement path is not a gopkg.in path.
-cd dot-to-dot
-go list gopkg.in/src-d/go-git.v4
+cd 4-to-4
+go list -m gopkg.in/src-d/go-git.v4
 
--- dot-to-dot/go.mod --
+# Previous versions of the "go" command accepted v0 and v1 pseudo-versions
+# as replacements for gopkg.in/[…].v4.
+# As a special case, we continue to accept those.
+
+cd ../4-to-0
+go list -m gopkg.in/src-d/go-git.v4
+
+cd ../4-to-1
+go list -m gopkg.in/src-d/go-git.v4
+
+cd ../4-to-incompatible
+go list -m gopkg.in/src-d/go-git.v4
+
+# A mismatched gopkg.in path should not be able to replace a different major version.
+cd ../3-to-gomod-4
+! go list -m gopkg.in/src-d/go-git.v3
+stderr '^go: gopkg\.in/src-d/go-git\.v3@v3.0.0-20190801152248-0d1a009cbb60: invalid version: go\.mod has non-\.\.\.\.v3 module path "gopkg\.in/src-d/go-git\.v4" at revision 0d1a009cbb60$'
+
+-- 4-to-4/go.mod --
 module golang.org/issue/34254
 
 go 1.13
@@ -26,3 +44,36 @@ go 1.13
 require gopkg.in/src-d/go-git.v4 v4.13.1
 
 replace gopkg.in/src-d/go-git.v4 v4.13.1 => github.com/src-d/go-git/v4 v4.13.1
+-- 4-to-1/go.mod --
+module golang.org/issue/34254
+
+go 1.13
+
+require gopkg.in/src-d/go-git.v4 v4.13.1
+
+replace gopkg.in/src-d/go-git.v4 v4.13.1 => github.com/src-d/go-git v1.0.1-0.20190801152248-0d1a009cbb60
+-- 4-to-0/go.mod --
+module golang.org/issue/34254
+
+go 1.13
+
+require gopkg.in/src-d/go-git.v4 v4.13.1
+
+replace gopkg.in/src-d/go-git.v4 v4.13.1 => github.com/src-d/go-git v0.0.0-20190801152248-0d1a009cbb60
+-- 4-to-incompatible/go.mod --
+module golang.org/issue/34254
+
+go 1.13
+
+require gopkg.in/src-d/go-git.v4 v4.13.1
+
+replace gopkg.in/src-d/go-git.v4 v4.13.1 => github.com/src-d/go-git v4.6.0+incompatible
+-- 3-to-gomod-4/go.mod --
+module golang.org/issue/34254
+go 1.13
+
+require gopkg.in/src-d/go-git.v3 v3.2.0
+
+// This replacement has a go.mod file declaring its path to be
+// gopkg.in/src-d/go-git.v4, so it cannot be used as a replacement for v3.
+replace gopkg.in/src-d/go-git.v3 v3.2.0 => gopkg.in/src-d/go-git.v3 v3.0.0-20190801152248-0d1a009cbb60