Commit e646d073 authored by Dmitri Shuralyov's avatar Dmitri Shuralyov Committed by Ian Lance Taylor

go/build: fix lack of error for Import of nonexistent local import path

When calling build.Import, normally, an error is returned if the
directory doesn't exist. However, that didn't happen for local
import paths when build.FindOnly ImportMode was used.

This change fixes that, and adds tests. It also makes the error
value more consistent in all scenarios where it occurs.

When calling build.Import with a local import path, the package
can only exist in a single deterministic directory. That makes
it possible verify that directory exists earlier in the path,
and return a "cannot find package" error if it doesn't.
Previously, this occurred only when build.FindOnly ImportMode
was not set. It occurred quite late, after getting past Found
label, to line that calls ctxt.readDir. Doing so would return
an error like "no such file or directory" when the directory
does not exist.

Fixes #17863.
Updates #17888 (relevant issue I ran into while working on this CL).

Change-Id: If6a6996ac6176ac203a88bd31419748f88d89d7c
Reviewed-on: https://go-review.googlesource.com/33158Reviewed-by: 's avatarIan Lance Taylor <iant@golang.org>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent 2dc714e1
......@@ -155,6 +155,7 @@ func (ctxt *Context) hasSubdir(root, dir string) (rel string, ok bool) {
return hasSubdir(rootSym, dirSym)
}
// hasSubdir reports if dir is within root by performing lexical analysis only.
func hasSubdir(root, dir string) (rel string, ok bool) {
const sep = string(filepath.Separator)
root = filepath.Clean(root)
......@@ -528,6 +529,10 @@ func (ctxt *Context) Import(path string, srcDir string, mode ImportMode) (*Packa
if !ctxt.isAbsPath(path) {
p.Dir = ctxt.joinPath(srcDir, path)
}
if !ctxt.isDir(p.Dir) {
// package was not found
return p, fmt.Errorf("cannot find package %q in:\n\t%s", path, p.Dir)
}
// Determine canonical import path, if any.
// Exclude results where the import path would include /testdata/.
inTestdata := func(sub string) bool {
......
......@@ -300,6 +300,30 @@ func TestShellSafety(t *testing.T) {
}
}
// Want to get a "cannot find package" error when directory for package does not exist.
func TestImportDirNotExist(t *testing.T) {
testenv.MustHaveGoBuild(t) // really must just have source
ctxt := Default
ctxt.GOPATH = ""
tests := []struct {
label string
path, srcDir string
mode ImportMode
}{
{"Import(full, 0)", "go/build/doesnotexist", "", 0},
{"Import(local, 0)", "./doesnotexist", filepath.Join(ctxt.GOROOT, "src/go/build"), 0},
{"Import(full, FindOnly)", "go/build/doesnotexist", "", FindOnly},
{"Import(local, FindOnly)", "./doesnotexist", filepath.Join(ctxt.GOROOT, "src/go/build"), FindOnly},
}
for _, test := range tests {
_, err := ctxt.Import(test.path, test.srcDir, test.mode)
if err == nil || !strings.HasPrefix(err.Error(), "cannot find package") {
t.Errorf(`%s got error: %q, want "cannot find package" error`, test.label, err)
}
}
}
func TestImportVendor(t *testing.T) {
testenv.MustHaveGoBuild(t) // really must just have source
ctxt := Default
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment