cmd/go/internal/vgo: allow dotless module paths if replaced
In general a module path's first element should be a domain name,
or else we can't resolve it to find out how to download it.
But if a module is named and has a replace directive giving
a local directory where it can be found, we need not enforce
the leading-dot rule.
This test also serves to test that the go.mod version fixer does
not try to resolve the module path when it's well formed.
Fixes golang/go#24100.
Change-Id: I5cf3b82289db1f29b583f41fcf9f2509c7fc442a
Reviewed-on: https://go-review.googlesource.com/107661
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Bryan C. Mills <bcmills@google.com>
diff --git a/vendor/cmd/go/internal/search/search.go b/vendor/cmd/go/internal/search/search.go
index 8b2f7c6..42a6be0 100644
--- a/vendor/cmd/go/internal/search/search.go
+++ b/vendor/cmd/go/internal/search/search.go
@@ -407,6 +407,12 @@
// part of the standard distribution. For historical reasons we allow people to add
// their own code to $GOROOT instead of using $GOPATH, but we assume that
// code will start with a domain name (dot in the first element).
+//
+// Note that this function is meant to evaluate whether a directory found in GOROOT
+// should be treated as part of the standard library. It should not be used to decide
+// that a directory found in GOPATH should be rejected: directories in GOPATH
+// need not have dots in the first element, and they just take their chances
+// with future collisions in the standard library.
func IsStandardImportPath(path string) bool {
i := strings.Index(path, "/")
if i < 0 {
diff --git a/vendor/cmd/go/internal/vgo/build.go b/vendor/cmd/go/internal/vgo/build.go
index d548f22..f2c8d72 100644
--- a/vendor/cmd/go/internal/vgo/build.go
+++ b/vendor/cmd/go/internal/vgo/build.go
@@ -7,11 +7,14 @@
import (
"bytes"
"cmd/go/internal/base"
+ "cmd/go/internal/cfg"
"cmd/go/internal/modinfo"
"cmd/go/internal/module"
"cmd/go/internal/search"
"encoding/hex"
"fmt"
+ "os"
+ "path/filepath"
)
var (
@@ -19,9 +22,19 @@
infoEnd, _ = hex.DecodeString("f932433186182072008242104116d8f2")
)
+func isStandardImportPath(path string) bool {
+ if search.IsStandardImportPath(path) {
+ dir := filepath.Join(cfg.GOROOT, "src", path)
+ if _, err := os.Stat(dir); err == nil {
+ return true
+ }
+ }
+ return false
+}
+
func PackageModuleInfo(path string) modinfo.ModulePublic {
var info modinfo.ModulePublic
- if search.IsStandardImportPath(path) || !Enabled() {
+ if isStandardImportPath(path) || !Enabled() {
return info
}
target := findModule(path, path)
@@ -32,13 +45,13 @@
}
func PackageBuildInfo(path string, deps []string) string {
- if search.IsStandardImportPath(path) || !Enabled() {
+ if isStandardImportPath(path) || !Enabled() {
return ""
}
target := findModule(path, path)
mdeps := make(map[module.Version]bool)
for _, dep := range deps {
- if !search.IsStandardImportPath(dep) {
+ if !isStandardImportPath(dep) {
mdeps[findModule(path, dep)] = true
}
}
diff --git a/vendor/cmd/go/internal/vgo/load.go b/vendor/cmd/go/internal/vgo/load.go
index 282a1d3..ea4095b 100644
--- a/vendor/cmd/go/internal/vgo/load.go
+++ b/vendor/cmd/go/internal/vgo/load.go
@@ -103,7 +103,7 @@
func Lookup(parentPath, path string) (dir, realPath string, err error) {
realPath = importmap[path]
if realPath == "" {
- if search.IsStandardImportPath(path) {
+ if isStandardImportPath(path) {
dir := filepath.Join(cfg.GOROOT, "src", path)
if _, err := os.Stat(dir); err == nil {
return dir, path, nil
@@ -246,7 +246,10 @@
if strings.HasPrefix(path, "golang_org/") {
return filepath.Join(cfg.GOROOT, "src/vendor", path)
}
- return filepath.Join(cfg.GOROOT, "src", path)
+ dir := filepath.Join(cfg.GOROOT, "src", path)
+ if _, err := os.Stat(dir); err == nil {
+ return dir
+ }
}
var mod1 module.Version
diff --git a/vendor/cmd/go/internal/vgo/search.go b/vendor/cmd/go/internal/vgo/search.go
index b32dce2..301c3e5 100644
--- a/vendor/cmd/go/internal/vgo/search.go
+++ b/vendor/cmd/go/internal/vgo/search.go
@@ -165,7 +165,7 @@
ld.importList(local, levelTestRecursive)
var all []string
for _, pkg := range ld.importmap {
- if !search.IsStandardImportPath(pkg) {
+ if !isStandardImportPath(pkg) {
all = append(all, pkg)
}
}
diff --git a/vendor/cmd/go/vgo_test.go b/vendor/cmd/go/vgo_test.go
index 6cc8297..082c1d7 100644
--- a/vendor/cmd/go/vgo_test.go
+++ b/vendor/cmd/go/vgo_test.go
@@ -51,3 +51,28 @@
tg.must(os.Remove(tg.path("x/" + file)))
}
}
+
+func TestLocalModule(t *testing.T) {
+ // Test that local replacements work
+ // and that they can use a dummy name
+ // that isn't resolvable and need not even
+ // include a dot. See golang.org/issue/24100.
+ tg := testgo(t)
+ defer tg.cleanup()
+ tg.makeTempdir()
+
+ tg.must(os.MkdirAll(tg.path("x/y"), 0777))
+ tg.must(os.MkdirAll(tg.path("x/z"), 0777))
+ tg.must(ioutil.WriteFile(tg.path("x/y/go.mod"), []byte(`
+ module x/y
+ require zz v1.0.0
+ replace zz v1.0.0 => ../z
+ `), 0666))
+ tg.must(ioutil.WriteFile(tg.path("x/y/y.go"), []byte(`package y; import _ "zz"`), 0666))
+ tg.must(ioutil.WriteFile(tg.path("x/z/go.mod"), []byte(`
+ module x/z
+ `), 0666))
+ tg.must(ioutil.WriteFile(tg.path("x/z/z.go"), []byte(`package z`), 0666))
+ tg.cd(tg.path("x/y"))
+ tg.run("-vgo", "build")
+}