From 207c53e038fb8e371d4778196fde9ecea6f6e20c Mon Sep 17 00:00:00 2001 From: =?utf8?q?Daniel=20Mart=C3=AD?= Date: Sun, 19 Nov 2017 17:28:46 +0000 Subject: [PATCH] cmd/doc: print a symbol error on "bytes Foo" MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit In golang.org/cl/59413, the two-argument behavior of cmd/doc was changed to use findPackage instead of build.Import, meaning that the tool was more consistent and useful. However, it introduced a regression: $ go doc bytes Foo doc: no such package: bytes This is because the directory list search would not find Foo in bytes, and reach the end of the directory list - thus resulting in a "no such package" error, since no directory matched our first argument. Move the "no such package" error out of parseArgs, so that the "loop until something is printed" loop can have control over it. In particular, it is useful to know when we have reached the end of the list without any exact match, yet we did find one package matching "bytes": $ go doc bytes Foo doc: no symbol Foo in package bytes While at it, make the "no such package" error not be fatal so that we may test for it. It is important to have the test, as parseArgs may now return a nil package instead of exiting the entire program, potentially meaning a nil pointer dereference panic. Fixes #22810. Change-Id: I90cc6fd755e2d1675bea6d49a1c13cc18ac9bfb9 Reviewed-on: https://go-review.googlesource.com/78677 Run-TryBot: Daniel Martí TryBot-Result: Gobot Gobot Reviewed-by: Rob Pike --- src/cmd/doc/doc_test.go | 18 ++++++++++++++++++ src/cmd/doc/main.go | 5 ++++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/cmd/doc/doc_test.go b/src/cmd/doc/doc_test.go index ce0d77a445..0df53a3630 100644 --- a/src/cmd/doc/doc_test.go +++ b/src/cmd/doc/doc_test.go @@ -569,6 +569,24 @@ func TestTwoArgLookup(t *testing.T) { t.Errorf("unexpected error %q from rand Float64", err) } } + { + var flagSet flag.FlagSet + err := do(&b, &flagSet, []string{"bytes", "Foo"}) + if err == nil { + t.Errorf("expected error from bytes Foo") + } else if !strings.Contains(err.Error(), "no symbol Foo") { + t.Errorf("unexpected error %q from bytes Foo", err) + } + } + { + var flagSet flag.FlagSet + err := do(&b, &flagSet, []string{"nosuchpackage", "Foo"}) + if err == nil { + // actually present in the user's filesystem + } else if !strings.Contains(err.Error(), "no such package") { + t.Errorf("unexpected error %q from nosuchpackage Foo", err) + } + } } type trimTest struct { diff --git a/src/cmd/doc/main.go b/src/cmd/doc/main.go index de275403a2..809a719a58 100644 --- a/src/cmd/doc/main.go +++ b/src/cmd/doc/main.go @@ -93,6 +93,9 @@ func do(writer io.Writer, flagSet *flag.FlagSet, args []string) (err error) { if i > 0 && !more { // Ignore the "more" bit on the first iteration. return failMessage(paths, symbol, method) } + if buildPackage == nil { + return fmt.Errorf("no such package: %s", userPath) + } symbol, method = parseSymbol(sym) pkg := parsePackage(writer, buildPackage, userPath) paths = append(paths, pkg.prettyPath()) @@ -179,7 +182,7 @@ func parseArgs(args []string) (pkg *build.Package, path, symbol string, more boo // Package must be findable and importable. packagePath, ok := findPackage(args[0]) if !ok { - log.Fatalf("no such package: %s", args[0]) + return nil, args[0], args[1], false } return importDir(packagePath), args[0], args[1], true } -- 2.48.1