diff options
| author | Michael Matloob <matloob@golang.org> | 2025-05-21 12:18:03 -0400 |
|---|---|---|
| committer | Michael Matloob <matloob@golang.org> | 2025-05-21 09:58:00 -0700 |
| commit | 2a5ac1a993efc463efdce7996efd356dabf03a25 (patch) | |
| tree | 6e962316264f4526308edc29fc124f009f9468cb /src/cmd | |
| parent | 8b45a3f78b178ce66f419038a664cbd6a82ada54 (diff) | |
| download | go-2a5ac1a993efc463efdce7996efd356dabf03a25.tar.xz | |
cmd/doc: allow go doc -http without package in current directory
go doc tries to find a package to display documentation for. In the case
that no package is provided, it uses "." just like go list does. So if
go doc -http is run without any arguments, it tries to show the
documentation for the package in the current directory. As a special
case, if no arguments are provided, allow no package to match the
current directory and just open the root pkgsite page.
For #68106
Change-Id: I6d65b160a838591db953fac630eced6b09106877
Reviewed-on: https://go-review.googlesource.com/c/go/+/675075
Reviewed-by: Alan Donovan <adonovan@google.com>
Reviewed-by: Michael Matloob <matloob@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Diffstat (limited to 'src/cmd')
| -rw-r--r-- | src/cmd/doc/main.go | 60 |
1 files changed, 40 insertions, 20 deletions
diff --git a/src/cmd/doc/main.go b/src/cmd/doc/main.go index 4c47b4bcfc..03654e5824 100644 --- a/src/cmd/doc/main.go +++ b/src/cmd/doc/main.go @@ -122,8 +122,21 @@ func do(writer io.Writer, flagSet *flag.FlagSet, args []string) (err error) { } } if serveHTTP { - // We want to run the logic below to determine a match for a symbol, method, - // or field, but not actually print the documentation to the output. + // Special case: if there are no arguments to go doc -http, allow + // there to be no package in the current directory. We'll still try + // to open the page for the documentation of the package in the current + // directory, but if one doesn't exist, fall back to opening the home page. + if len(flagSet.Args()) == 0 { + var path string + if importPath, err := runCmd("go", "list"); err == nil { + path = importPath + } + return doPkgsite(path) + } + + // If args are provided, we need to figure out which page to open on the pkgsite + // instance. Run the logic below to determine a match for a symbol, method, + // or field, but don't actually print the documentation to the output. writer = io.Discard } var paths []string @@ -179,44 +192,41 @@ func do(writer io.Writer, flagSet *flag.FlagSet, args []string) (err error) { } if found { if serveHTTP { - return doPkgsite(userPath, pkg, symbol, method) + path, err := objectPath(userPath, pkg, symbol, method) + if err != nil { + return err + } + return doPkgsite(path) } return nil } } } -func listUserPath(userPath string) (string, error) { +func runCmd(cmdline ...string) (string, error) { var stdout, stderr strings.Builder - cmd := exec.Command("go", "list", userPath) + cmd := exec.Command(cmdline[0], cmdline[1:]...) cmd.Stdout = &stdout cmd.Stderr = &stderr if err := cmd.Run(); err != nil { - return "", fmt.Errorf("go doc: go list %s: %v\n%s\n", userPath, err, stderr.String()) + return "", fmt.Errorf("go doc: %s: %v\n%s\n", strings.Join(cmdline, " "), err, stderr.String()) } return strings.TrimSpace(stdout.String()), nil } -func doPkgsite(userPath string, pkg *Package, symbol, method string) error { - port, err := pickUnusedPort() - if err != nil { - return fmt.Errorf("failed to find port for documentation server: %v", err) - } - addr := fmt.Sprintf("localhost:%d", port) - - // Assemble url to open on the browser, to point to documentation of - // the requested object. - importPath := pkg.build.ImportPath - if importPath == "." { +func objectPath(userPath string, pkg *Package, symbol, method string) (string, error) { + var err error + path := pkg.build.ImportPath + if path == "." { // go/build couldn't determine the import path, probably // because this was a relative path into a module. Use // go list to get the import path. - importPath, err = listUserPath(userPath) + path, err = runCmd("go", "list", userPath) if err != nil { - return err + return "", err } } - path := path.Join("http://"+addr, importPath) + object := symbol if symbol != "" && method != "" { object = symbol + "." + method @@ -224,6 +234,16 @@ func doPkgsite(userPath string, pkg *Package, symbol, method string) error { if object != "" { path = path + "#" + object } + return path, nil +} + +func doPkgsite(urlPath string) error { + port, err := pickUnusedPort() + if err != nil { + return fmt.Errorf("failed to find port for documentation server: %v", err) + } + addr := fmt.Sprintf("localhost:%d", port) + path := path.Join("http://"+addr, urlPath) // Turn off the default signal handler for SIGINT (and SIGQUIT on Unix) // and instead wait for the child process to handle the signal and |
