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") +}