Commit 207c53e0 authored by Daniel Martí's avatar Daniel Martí

cmd/doc: print a symbol error on "bytes Foo"

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í <mvdan@mvdan.cc>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: 's avatarRob Pike <r@golang.org>
parent f91ab6c0
...@@ -569,6 +569,24 @@ func TestTwoArgLookup(t *testing.T) { ...@@ -569,6 +569,24 @@ func TestTwoArgLookup(t *testing.T) {
t.Errorf("unexpected error %q from rand Float64", err) 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 { type trimTest struct {
......
...@@ -93,6 +93,9 @@ func do(writer io.Writer, flagSet *flag.FlagSet, args []string) (err error) { ...@@ -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. if i > 0 && !more { // Ignore the "more" bit on the first iteration.
return failMessage(paths, symbol, method) return failMessage(paths, symbol, method)
} }
if buildPackage == nil {
return fmt.Errorf("no such package: %s", userPath)
}
symbol, method = parseSymbol(sym) symbol, method = parseSymbol(sym)
pkg := parsePackage(writer, buildPackage, userPath) pkg := parsePackage(writer, buildPackage, userPath)
paths = append(paths, pkg.prettyPath()) paths = append(paths, pkg.prettyPath())
...@@ -179,7 +182,7 @@ func parseArgs(args []string) (pkg *build.Package, path, symbol string, more boo ...@@ -179,7 +182,7 @@ func parseArgs(args []string) (pkg *build.Package, path, symbol string, more boo
// Package must be findable and importable. // Package must be findable and importable.
packagePath, ok := findPackage(args[0]) packagePath, ok := findPackage(args[0])
if !ok { 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 return importDir(packagePath), args[0], args[1], true
} }
......
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