Skip to content

Commit e161b1e

Browse files
committed
cmd/go/internal/module: allow v0.0.0 pseudoversion for gopkg.in/check.v1
It worked once. It needs to keep working. Change-Id: Iaa43726e1c78f0c4a20b5805c7c2bfa76fab2489 Reviewed-on: https://go-review.googlesource.com/124383 Run-TryBot: Russ Cox <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Bryan C. Mills <[email protected]>
1 parent 56deebb commit e161b1e

File tree

4 files changed

+26
-26
lines changed

4 files changed

+26
-26
lines changed

src/cmd/go/internal/module/module.go

Lines changed: 16 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ package module
1212
// There are many subtle considerations, including Unicode ambiguity,
1313
// security, network, and file system representations.
1414
//
15+
// This file also defines the set of valid module path and version combinations,
16+
// another topic with many subtle considerations.
17+
//
1518
// Changes to the semantics in this file require approval from rsc.
1619

1720
import (
@@ -50,31 +53,17 @@ func Check(path, version string) error {
5053
if !semver.IsValid(version) {
5154
return fmt.Errorf("malformed semantic version %v", version)
5255
}
53-
vm := semver.Major(version)
54-
_, pathVersion, _ := SplitPathVersion(path)
55-
56-
if strings.HasPrefix(pathVersion, ".") {
57-
// Special-case gopkg.in path requirements.
58-
pathVersion = pathVersion[1:] // cut .
59-
if vm == pathVersion {
60-
return nil
61-
}
62-
} else {
63-
// Standard path requirements.
64-
if pathVersion != "" {
65-
pathVersion = pathVersion[1:] // cut /
66-
}
67-
if vm == "v0" || vm == "v1" {
68-
vm = ""
56+
_, pathMajor, _ := SplitPathVersion(path)
57+
if !MatchPathMajor(version, pathMajor) {
58+
if pathMajor == "" {
59+
pathMajor = "v0 or v1"
6960
}
70-
if vm == pathVersion {
71-
return nil
72-
}
73-
if pathVersion == "" {
74-
pathVersion = "v0 or v1"
61+
if pathMajor[0] == '.' { // .v1
62+
pathMajor = pathMajor[1:]
7563
}
64+
return fmt.Errorf("mismatched module path %v and version %v (want %v)", path, version, pathMajor)
7665
}
77-
return fmt.Errorf("mismatched module path %v and version %v (want %v)", path, version, pathVersion)
66+
return nil
7867
}
7968

8069
// firstPathOK reports whether r can appear in the first element of a module path.
@@ -328,6 +317,11 @@ func splitGopkgIn(path string) (prefix, pathMajor string, ok bool) {
328317
// MatchPathMajor reports whether the semantic version v
329318
// matches the path major version pathMajor.
330319
func MatchPathMajor(v, pathMajor string) bool {
320+
if strings.HasPrefix(v, "v0.0.0-") && pathMajor == ".v1" {
321+
// Allow old bug in pseudo-versions that generated v0.0.0- pseudoversion for gopkg .v1.
322+
// For example, gopkg.in/[email protected]'s go.mod requires gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405.
323+
return true
324+
}
331325
m := semver.Major(v)
332326
if pathMajor == "" {
333327
return m == "v0" || m == "v1"

src/cmd/go/internal/module/module_test.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,14 @@ var checkTests = []struct {
3737
{"gopkg.in/yaml.v1", "v2.1.5", false},
3838
{"gopkg.in/yaml.v1", "v3.0.0", false},
3939

40+
// For gopkg.in, .v1 means v1 only (not v0).
41+
// But early versions of vgo still generated v0 pseudo-versions for it.
42+
// Even though now we'd generate those as v1 pseudo-versions,
43+
// we accept the old pseudo-versions to avoid breaking existing go.mod files.
44+
// For example gopkg.in/[email protected]'s go.mod requires check.v1 at a v0 pseudo-version.
45+
{"gopkg.in/check.v1", "v0.0.0", false},
46+
{"gopkg.in/check.v1", "v0.0.0-20160102150405-abcdef123456", true},
47+
4048
{"gopkg.in/yaml.v2", "v1.0.0", false},
4149
{"gopkg.in/yaml.v2", "v2.0.0", true},
4250
{"gopkg.in/yaml.v2", "v2.1.5", true},

src/cmd/go/mod_test.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -834,14 +834,12 @@ func TestModFileNames(t *testing.T) {
834834
"rsc.io/badfile3",
835835
"rsc.io/badfile4",
836836
"rsc.io/badfile5",
837-
"rsc.io/badfile6",
838837
)
839838
tg.grepStderrNot(`unzip .*badfile1.*:`, "badfile1 should be OK")
840839
tg.grepStderr(`rsc.io/badfile2.*malformed file path "☺.go": invalid char '☺'`, "want diagnosed invalid character")
841-
tg.grepStderr(`rsc.io/badfile3.*malformed file path "x@y.go": invalid char '@'`, "want diagnosed invalid character")
840+
tg.grepStderr(`rsc.io/badfile3.*malformed file path "x\?y.go": invalid char '\?'`, "want diagnosed invalid character")
842841
tg.grepStderr(`rsc.io/badfile4.*case-insensitive file name collision: "x/Y.go" and "x/y.go"`, "want case collision")
843842
tg.grepStderr(`rsc.io/badfile5.*case-insensitive file name collision: "x/y" and "x/Y"`, "want case collision")
844-
tg.grepStderr(`rsc.io/badfile6.*malformed file path "x/.gitignore/y": leading dot in path element`, "want leading dot in path element")
845843
}
846844

847845
func TestModBadDomain(t *testing.T) {

src/cmd/go/testdata/mod/rsc.io_badfile3_v1.0.0.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,6 @@ module rsc.io/badfile3
77
{"Version":"v1.0.0"}
88
-- go.mod --
99
module rsc.io/badfile3
10-
-- x@y.go --
10+
-- x?y.go --
1111
package x
1212

0 commit comments

Comments
 (0)