1
0
mirror of https://github.com/golang/go synced 2024-11-26 06:27:58 -07:00

cmd/go: make mod init disallow invalid major version suffixes

This CL reuses the SplitPathVersion function from the module package to
detect invalid major version suffixes and return a relevant error
message along with a suggested fix.

Fixes #44052
Fixes #46085

Change-Id: I6c06f31a134e864a1d9b6e00c048ca1c59b4365e
Reviewed-on: https://go-review.googlesource.com/c/go/+/288712
Reviewed-by: Jay Conrod <jayconrod@google.com>
Trust: Jay Conrod <jayconrod@google.com>
Trust: Bryan C. Mills <bcmills@google.com>
Run-TryBot: Jay Conrod <jayconrod@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
This commit is contained in:
Paschalis Tsilias 2021-02-02 15:25:21 +02:00 committed by Jay Conrod
parent 3848488f0f
commit a2a9a7b513
2 changed files with 142 additions and 0 deletions

View File

@ -523,6 +523,13 @@ func CreateModFile(ctx context.Context, modPath string) {
}
}
base.Fatalf("go: %v", err)
} else if _, _, ok := module.SplitPathVersion(modPath); !ok {
if strings.HasPrefix(modPath, "gopkg.in/") {
invalidMajorVersionMsg := fmt.Errorf("module paths beginning with gopkg.in/ must always have a major version suffix in the form of .vN:\n\tgo mod init %s", suggestGopkgIn(modPath))
base.Fatalf(`go: invalid module path "%v": %v`, modPath, invalidMajorVersionMsg)
}
invalidMajorVersionMsg := fmt.Errorf("major version suffixes must be in the form of /vN and are only allowed for v2 or later:\n\tgo mod init %s", suggestModulePath(modPath))
base.Fatalf(`go: invalid module path "%v": %v`, modPath, invalidMajorVersionMsg)
}
fmt.Fprintf(os.Stderr, "go: creating new go.mod: module %s\n", modPath)
@ -1197,3 +1204,56 @@ const (
func modkey(m module.Version) module.Version {
return module.Version{Path: m.Path, Version: m.Version + "/go.mod"}
}
func suggestModulePath(path string) string {
var m string
i := len(path)
for i > 0 && ('0' <= path[i-1] && path[i-1] <= '9' || path[i-1] == '.') {
i--
}
url := path[:i]
url = strings.TrimSuffix(url, "/v")
url = strings.TrimSuffix(url, "/")
f := func(c rune) bool {
return c > '9' || c < '0'
}
s := strings.FieldsFunc(path[i:], f)
if len(s) > 0 {
m = s[0]
}
m = strings.TrimLeft(m, "0")
if m == "" || m == "1" {
return url + "/v2"
}
return url + "/v" + m
}
func suggestGopkgIn(path string) string {
var m string
i := len(path)
for i > 0 && (('0' <= path[i-1] && path[i-1] <= '9') || (path[i-1] == '.')) {
i--
}
url := path[:i]
url = strings.TrimSuffix(url, ".v")
url = strings.TrimSuffix(url, "/v")
url = strings.TrimSuffix(url, "/")
f := func(c rune) bool {
return c > '9' || c < '0'
}
s := strings.FieldsFunc(path, f)
if len(s) > 0 {
m = s[0]
}
m = strings.TrimLeft(m, "0")
if m == "" {
return url + ".v1"
}
return url + ".v" + m
}

View File

@ -0,0 +1,82 @@
env GO111MODULE=on
env GOFLAGS=-mod=mod
! go mod init example.com/user/repo/v0
stderr '(?s)^go: invalid module path "example.com/user/repo/v0": major version suffixes must be in the form of /vN and are only allowed for v2 or later(.*)go mod init example.com/user/repo/v2$'
! go mod init example.com/user/repo/v02
stderr '(?s)^go: invalid module path "example.com/user/repo/v02": major version suffixes must be in the form of /vN and are only allowed for v2 or later(.*)go mod init example.com/user/repo/v2$'
! go mod init example.com/user/repo/v023
stderr '(?s)^go: invalid module path "example.com/user/repo/v023": major version suffixes must be in the form of /vN and are only allowed for v2 or later(.*)go mod init example.com/user/repo/v23$'
! go mod init example.com/user/repo/v1
stderr '(?s)^go: invalid module path "example.com/user/repo/v1": major version suffixes must be in the form of /vN and are only allowed for v2 or later(.*)go mod init example.com/user/repo/v2$'
! go mod init example.com/user/repo/v2.0
stderr '(?s)^go: invalid module path "example.com/user/repo/v2.0": major version suffixes must be in the form of /vN and are only allowed for v2 or later(.*)go mod init example.com/user/repo/v2$'
! go mod init example.com/user/repo/v2.1.4
stderr '(?s)^go: invalid module path "example.com/user/repo/v2.1.4": major version suffixes must be in the form of /vN and are only allowed for v2 or later(.*)go mod init example.com/user/repo/v2$'
! go mod init example.com/user/repo/v3.5
stderr '(?s)^go: invalid module path "example.com/user/repo/v3.5": major version suffixes must be in the form of /vN and are only allowed for v2 or later(.*)go mod init example.com/user/repo/v3$'
! go mod init example.com/user/repo/v4.1.4
stderr '(?s)^go: invalid module path "example.com/user/repo/v4.1.4": major version suffixes must be in the form of /vN and are only allowed for v2 or later(.*)go mod init example.com/user/repo/v4$'
! go mod init example.com/user/repo/v.2.3
stderr '(?s)^go: invalid module path "example.com/user/repo/v.2.3": major version suffixes must be in the form of /vN and are only allowed for v2 or later(.*)go mod init example.com/user/repo/v2$'
! go mod init example.com/user/repo/v.5.3
stderr '(?s)^go: invalid module path "example.com/user/repo/v.5.3": major version suffixes must be in the form of /vN and are only allowed for v2 or later(.*)go mod init example.com/user/repo/v5$'
! go mod init gopkg.in/pkg
stderr '(?s)^go: invalid module path "gopkg.in/pkg": module paths beginning with gopkg.in/ must always have a major version suffix in the form of .vN(.*)go mod init gopkg.in/pkg.v1$'
! go mod init gopkg.in/user/pkg
stderr '(?s)^go: invalid module path "gopkg.in/user/pkg": module paths beginning with gopkg.in/ must always have a major version suffix in the form of .vN(.*)go mod init gopkg.in/user/pkg.v1$'
! go mod init gopkg.in/user/pkg/v0
stderr '(?s)^go: invalid module path "gopkg.in/user/pkg/v0": module paths beginning with gopkg.in/ must always have a major version suffix in the form of .vN(.*)go mod init gopkg.in/user/pkg.v1$'
! go mod init gopkg.in/user/pkg/v1
stderr '(?s)^go: invalid module path "gopkg.in/user/pkg/v1": module paths beginning with gopkg.in/ must always have a major version suffix in the form of .vN(.*)go mod init gopkg.in/user/pkg.v1$'
! go mod init gopkg.in/user/pkg/v2
stderr '(?s)^go: invalid module path "gopkg.in/user/pkg/v2": module paths beginning with gopkg.in/ must always have a major version suffix in the form of .vN(.*)go mod init gopkg.in/user/pkg.v2$'
! go mod init gopkg.in/user/pkg.v
stderr '(?s)^go: invalid module path "gopkg.in/user/pkg.v": module paths beginning with gopkg.in/ must always have a major version suffix in the form of .vN(.*)go mod init gopkg.in/user/pkg.v1$'
! go mod init gopkg.in/user/pkg.v0.1
stderr '(?s)^go: invalid module path "gopkg.in/user/pkg.v0.1": module paths beginning with gopkg.in/ must always have a major version suffix in the form of .vN(.*)go mod init gopkg.in/user/pkg.v1$'
! go mod init gopkg.in/user/pkg.v.1
stderr '(?s)^go: invalid module path "gopkg.in/user/pkg.v.1": module paths beginning with gopkg.in/ must always have a major version suffix in the form of .vN(.*)go mod init gopkg.in/user/pkg.v1$'
! go mod init gopkg.in/user/pkg.v01
stderr '(?s)^go: invalid module path "gopkg.in/user/pkg.v01": module paths beginning with gopkg.in/ must always have a major version suffix in the form of .vN(.*)go mod init gopkg.in/user/pkg.v1$'
! go mod init gopkg.in/user/pkg.v.2.3
stderr '(?s)^go: invalid module path "gopkg.in/user/pkg.v.2.3": module paths beginning with gopkg.in/ must always have a major version suffix in the form of .vN(.*)go mod init gopkg.in/user/pkg.v2$'
# module paths with a trailing dot are rejected as invalid import paths
! go mod init example.com/user/repo/v2.
stderr '(?s)^go: malformed module path "example.com/user/repo/v2.": trailing dot in path element$'
! go mod init example.com/user/repo/v2..
stderr '(?s)^go: malformed module path "example.com/user/repo/v2..": trailing dot in path element$'
! go mod init gopkg.in/user/pkg.v.2.
stderr '(?s)^go: malformed module path "gopkg.in/user/pkg.v.2.": trailing dot in path element$'
! go mod init gopkg.in/user/pkg.v.2..
stderr '(?s)^go: malformed module path "gopkg.in/user/pkg.v.2..": trailing dot in path element$'
# module paths with spaces are also rejected
! go mod init 'foo bar'
stderr '(?s)^go: malformed module path "foo bar": invalid char '' ''$'
! go mod init 'foo bar baz'
stderr '(?s)^go: malformed module path "foo bar baz": invalid char '' ''$'