From f595fb5c9663ecbe1b08ae76e9c0a1b69cd0fa33 Mon Sep 17 00:00:00 2001 From: Dmitri Shuralyov Date: Sat, 4 Mar 2017 19:06:07 -0500 Subject: [PATCH] cmd/godoc, godoc: implement build.Context.IsDir, update expected error string Prior to this change, handlerServer.GetPageInfo created a build.Context starting with build.Default, and provided custom implementations for its IsAbsPath, ReadDir, and OpenFile funcs. Those funcs would operate on h.c.fs virtual filesystem. https://godoc.org/go/build#Context.IsDir is documented as: // IsDir reports whether the path names a directory. // If IsDir is nil, Import calls os.Stat and uses the result's IsDir method. IsDir func(path string) bool IsDir was left as nil, and so the default implementation was used. The default implementation uses os.Stat and isn't aware of the h.c.fs virtual filesystem. This appears to have been harmless in the past, but after the change to go/build in https://golang.org/cl/33158, it started to interfere with the operation of godoc. The command godoc began to fail to resolve relative import path "." in directories that exist, because the incorrect IsDir implementation was looking in real filesystem, rather than the virtual one: $ ./godoc fmt 2017/03/04 18:59:50 cannot find package "." in: /target $ ./godoc -http=localhost:6060 2017/03/04 19:00:07 cannot find package "." in: /src/fmt Providing a custom implementation of IsDir that is aware of the h.c.fs virtual filesystem, and performs a stat operation on the correct path there resolves that problem. It also fixes the failing tests. Additionally, because the exact error string returned from Context.Import has changed after https://golang.org/cl/33158, and now contains the text "package not found" rather than the underlying error text from filesystem caused by a failed ReadDir operation, the expected error message from "./godoc nonexistingpkg" in a test needed to be updated to "cannot find package". It's no longer dependent on the operating system. It might be desirable to provide more relevant detail in the error message from cmd/godoc when a package is not found, but that should be determined and done in a followup CL. The scope of this one is to fix normal functionality. This change follows update to go/build in https://golang.org/cl/33158. Helps golang/go#19401. Change-Id: I00e2f746ec4a2fe7e640218adce75f15bdf29aaf Reviewed-on: https://go-review.googlesource.com/37768 Run-TryBot: Brad Fitzpatrick TryBot-Result: Gobot Gobot Reviewed-by: Brad Fitzpatrick --- cmd/godoc/godoc_test.go | 4 +--- godoc/server.go | 4 ++++ 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/cmd/godoc/godoc_test.go b/cmd/godoc/godoc_test.go index 483b8643..97b00d0c 100644 --- a/cmd/godoc/godoc_test.go +++ b/cmd/godoc/godoc_test.go @@ -44,9 +44,7 @@ var godocTests = []struct { { args: []string{"nonexistingpkg"}, matches: []string{ - // The last pattern (does not e) is for plan9: - // http://build.golang.org/log/2d8e5e14ed365bfa434b37ec0338cd9e6f8dd9bf - `no such file or directory|does not exist|cannot find the file|(?:' does not e)`, + `cannot find package`, }, }, { diff --git a/godoc/server.go b/godoc/server.go index 104e75b6..162e5a6a 100644 --- a/godoc/server.go +++ b/godoc/server.go @@ -65,6 +65,10 @@ func (h *handlerServer) GetPageInfo(abspath, relpath string, mode PageInfoMode, // are used. ctxt := build.Default ctxt.IsAbsPath = pathpkg.IsAbs + ctxt.IsDir = func(path string) bool { + fi, err := h.c.fs.Stat(filepath.ToSlash(path)) + return err == nil && fi.IsDir() + } ctxt.ReadDir = func(dir string) ([]os.FileInfo, error) { f, err := h.c.fs.ReadDir(filepath.ToSlash(dir)) filtered := make([]os.FileInfo, 0, len(f))