cmd/go: diagnose misuse of path@version syntax
We should only see path@version arguments
in module mode, and then only for 'go get'.
Change-Id: I223a924b42bbd1710713c2202e5b4403fef7e18d
Reviewed-on: https://go-review.googlesource.com/122405
Reviewed-by: Bryan C. Mills <bcmills@google.com>
diff --git a/vendor/cmd/go/go_test.go b/vendor/cmd/go/go_test.go
index 555b457..d549b94 100644
--- a/vendor/cmd/go/go_test.go
+++ b/vendor/cmd/go/go_test.go
@@ -6232,12 +6232,12 @@
tg.tempFile("src/@x/x.go", "package x\n")
tg.setenv("GOPATH", tg.path("."))
tg.runFail("build", "@x")
- tg.grepStderr("invalid input directory name \"@x\"", "did not reject @x directory")
+ tg.grepStderr("invalid input directory name \"@x\"|cannot use path@version syntax", "did not reject @x directory")
tg.tempFile("src/@x/y/y.go", "package y\n")
tg.setenv("GOPATH", tg.path("."))
tg.runFail("build", "@x/y")
- tg.grepStderr("invalid import path \"@x/y\"", "did not reject @x/y import path")
+ tg.grepStderr("invalid import path \"@x/y\"|cannot use path@version syntax", "did not reject @x/y import path")
tg.tempFile("src/-x/x.go", "package x\n")
tg.setenv("GOPATH", tg.path("."))
diff --git a/vendor/cmd/go/internal/get/get.go b/vendor/cmd/go/internal/get/get.go
index 76ba238..36aa171 100644
--- a/vendor/cmd/go/internal/get/get.go
+++ b/vendor/cmd/go/internal/get/get.go
@@ -199,6 +199,12 @@
// in the hope that we can figure out the repository from the
// initial ...-free prefix.
func downloadPaths(args []string) []string {
+ for _, arg := range args {
+ if strings.Contains(arg, "@") {
+ base.Fatalf("go: cannot use path@version syntax in GOPATH mode")
+ }
+ }
+
args = load.ImportPathsForGoGet(args)
var out []string
for _, a := range args {
diff --git a/vendor/cmd/go/internal/load/pkg.go b/vendor/cmd/go/internal/load/pkg.go
index 0e5e758..edc29ad 100644
--- a/vendor/cmd/go/internal/load/pkg.go
+++ b/vendor/cmd/go/internal/load/pkg.go
@@ -442,6 +442,24 @@
}
}
+ if strings.Contains(path, "@") {
+ var text string
+ if cfg.ModulesEnabled {
+ text = "can only use path@version syntax with 'go get'"
+ } else {
+ text = "cannot use path@version syntax in GOPATH mode"
+ }
+ return &Package{
+ PackagePublic: PackagePublic{
+ ImportPath: path,
+ Error: &PackageError{
+ ImportStack: stk.Copy(),
+ Err: text,
+ },
+ },
+ }
+ }
+
// Determine canonical identifier for this package.
// For a local import the identifier is the pseudo-import path
// we create from the full directory to the package.
diff --git a/vendor/cmd/go/internal/modload/load.go b/vendor/cmd/go/internal/modload/load.go
index fe3f64d..703d576 100644
--- a/vendor/cmd/go/internal/modload/load.go
+++ b/vendor/cmd/go/internal/modload/load.go
@@ -533,6 +533,11 @@
// It is also possible to return successfully with a zero module.Version,
// for packages in the standard library or when using vendored code.
func (ld *loader) findDir(path string) (dir string, mod module.Version, err error) {
+ if strings.Contains(path, "@") {
+ // Leave for error during load.
+ return
+ }
+
// Is the package in the standard library?
if search.IsStandardImportPath(path) {
if path == "C" || path == "unsafe" {
diff --git a/vendor/cmd/go/mod_test.go b/vendor/cmd/go/mod_test.go
index e723d4e..258066f 100644
--- a/vendor/cmd/go/mod_test.go
+++ b/vendor/cmd/go/mod_test.go
@@ -92,6 +92,25 @@
tg.grepStdout(`"GOMOD": ""`, "expected module mode disabled")
}
+func TestModVersionsInGOPATHMode(t *testing.T) {
+ tg := testgo(t)
+ tg.setenv("GO111MODULE", "off") // GOPATH mode
+ defer tg.cleanup()
+ tg.makeTempdir()
+
+ tg.runFail("get", "rsc.io/quote@v1.5.1")
+ tg.grepStderr(`go: cannot use path@version syntax in GOPATH mode`, "expected path@version error")
+
+ tg.runFail("build", "rsc.io/quote@v1.5.1")
+ tg.grepStderr(`can't load package:.* cannot use path@version syntax in GOPATH mode`, "expected path@version error")
+
+ tg.setenv("GO111MODULE", "on") // GOPATH mode
+ tg.tempFile("x/go.mod", "module x")
+ tg.cd(tg.path("x"))
+ tg.runFail("build", "rsc.io/quote@v1.5.1")
+ tg.grepStderr(`can't load package:.* can only use path@version syntax with 'go get'`, "expected path@version error")
+}
+
func TestModFindModuleRoot(t *testing.T) {
tg := testgo(t)
tg.setenv("GO111MODULE", "on")