Skip to content

Commit 5c6f427

Browse files
author
Bryan C. Mills
committed
cmd/go: relax validation for replacements for gopkg.in paths
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>
1 parent 0f834bb commit 5c6f427

File tree

2 files changed

+66
-4
lines changed

2 files changed

+66
-4
lines changed

src/cmd/go/internal/modfetch/coderepo.go

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -708,7 +708,7 @@ func (r *codeRepo) findDir(version string) (rev, dir string, gomod []byte, err e
708708
return "", "", nil, fmt.Errorf("reading %s/%s at revision %s: %v", r.pathPrefix, file1, rev, err1)
709709
}
710710
mpath1 := modfile.ModulePath(gomod1)
711-
found1 := err1 == nil && isMajor(mpath1, r.pathMajor)
711+
found1 := err1 == nil && (isMajor(mpath1, r.pathMajor) || r.canReplaceMismatchedVersionDueToBug(mpath1))
712712

713713
var file2 string
714714
if r.pathMajor != "" && r.codeRoot != r.modPath && !strings.HasPrefix(r.pathMajor, ".") {
@@ -817,6 +817,17 @@ func isMajor(mpath, pathMajor string) bool {
817817
return pathMajor[1:] == mpathMajor[1:]
818818
}
819819

820+
// canReplaceMismatchedVersionDueToBug reports whether versions of r
821+
// could replace versions of mpath with otherwise-mismatched major versions
822+
// due to a historical bug in the Go command (golang.org/issue/34254).
823+
func (r *codeRepo) canReplaceMismatchedVersionDueToBug(mpath string) bool {
824+
// The bug caused us to erroneously accept unversioned paths as replacements
825+
// for versioned gopkg.in paths.
826+
unversioned := r.pathMajor == ""
827+
replacingGopkgIn := strings.HasPrefix(mpath, "gopkg.in/")
828+
return unversioned && replacingGopkgIn
829+
}
830+
820831
func (r *codeRepo) GoMod(version string) (data []byte, err error) {
821832
if version != module.CanonicalVersion(version) {
822833
return nil, fmt.Errorf("version %s is not canonical", version)

src/cmd/go/testdata/script/mod_replace_gopkgin.txt

Lines changed: 54 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,65 @@ env GOSUMDB=off
1515
# Replacing gopkg.in/[…].vN with a repository with a root go.mod file
1616
# specifying […].vN and a compatible version should succeed, even if
1717
# the replacement path is not a gopkg.in path.
18-
cd dot-to-dot
19-
go list gopkg.in/src-d/go-git.v4
18+
cd 4-to-4
19+
go list -m gopkg.in/src-d/go-git.v4
2020

21-
-- dot-to-dot/go.mod --
21+
# Previous versions of the "go" command accepted v0 and v1 pseudo-versions
22+
# as replacements for gopkg.in/[…].v4.
23+
# As a special case, we continue to accept those.
24+
25+
cd ../4-to-0
26+
go list -m gopkg.in/src-d/go-git.v4
27+
28+
cd ../4-to-1
29+
go list -m gopkg.in/src-d/go-git.v4
30+
31+
cd ../4-to-incompatible
32+
go list -m gopkg.in/src-d/go-git.v4
33+
34+
# A mismatched gopkg.in path should not be able to replace a different major version.
35+
cd ../3-to-gomod-4
36+
! go list -m gopkg.in/src-d/go-git.v3
37+
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$'
38+
39+
-- 4-to-4/go.mod --
2240
module golang.org/issue/34254
2341

2442
go 1.13
2543

2644
require gopkg.in/src-d/go-git.v4 v4.13.1
2745

2846
replace gopkg.in/src-d/go-git.v4 v4.13.1 => github.com/src-d/go-git/v4 v4.13.1
47+
-- 4-to-1/go.mod --
48+
module golang.org/issue/34254
49+
50+
go 1.13
51+
52+
require gopkg.in/src-d/go-git.v4 v4.13.1
53+
54+
replace gopkg.in/src-d/go-git.v4 v4.13.1 => github.com/src-d/go-git v1.0.1-0.20190801152248-0d1a009cbb60
55+
-- 4-to-0/go.mod --
56+
module golang.org/issue/34254
57+
58+
go 1.13
59+
60+
require gopkg.in/src-d/go-git.v4 v4.13.1
61+
62+
replace gopkg.in/src-d/go-git.v4 v4.13.1 => github.com/src-d/go-git v0.0.0-20190801152248-0d1a009cbb60
63+
-- 4-to-incompatible/go.mod --
64+
module golang.org/issue/34254
65+
66+
go 1.13
67+
68+
require gopkg.in/src-d/go-git.v4 v4.13.1
69+
70+
replace gopkg.in/src-d/go-git.v4 v4.13.1 => github.com/src-d/go-git v4.6.0+incompatible
71+
-- 3-to-gomod-4/go.mod --
72+
module golang.org/issue/34254
73+
go 1.13
74+
75+
require gopkg.in/src-d/go-git.v3 v3.2.0
76+
77+
// This replacement has a go.mod file declaring its path to be
78+
// gopkg.in/src-d/go-git.v4, so it cannot be used as a replacement for v3.
79+
replace gopkg.in/src-d/go-git.v3 v3.2.0 => gopkg.in/src-d/go-git.v3 v3.0.0-20190801152248-0d1a009cbb60

0 commit comments

Comments
 (0)