mirror of
https://github.com/golang/go.git
synced 2025-10-19 11:03:18 +00:00
cmd/doc: use golang.org/x/pkgsite/cmd/internal/doc to start server
This change switches the pkgsite command invoked to start a pkgsite server from golang.org/x/pkgsite/cmd/pkgsite to golang.org/x/pkgsite/cmd/internal/doc. The doc command is a simplified version of cmd/pkgsite that changes some options to improve the user experience. For example, it limits logging informational log messages, doesn't always expect to find modules (for example if we're outside of a module getting documentation for the standard library), and it takes the address of the page to open in the browser (which simplifies waiting for the server to start listening). Fixes #68106 Change-Id: I667a49d03823242fa1aff333ecb1c0f198e92412 Reviewed-on: https://go-review.googlesource.com/c/go/+/674158 LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Jonathan Amsterdam <jba@google.com> Reviewed-by: David Chase <drchase@google.com>
This commit is contained in:
parent
546761aff4
commit
609197b406
1 changed files with 27 additions and 55 deletions
|
@ -44,7 +44,6 @@ package main
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"errors"
|
||||
"flag"
|
||||
"fmt"
|
||||
|
@ -53,17 +52,13 @@ import (
|
|||
"io"
|
||||
"log"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/exec"
|
||||
"os/signal"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"cmd/internal/browser"
|
||||
"cmd/internal/quoted"
|
||||
"cmd/internal/telemetry/counter"
|
||||
)
|
||||
|
||||
|
@ -203,36 +198,14 @@ func listUserPath(userPath string) (string, error) {
|
|||
}
|
||||
|
||||
func doPkgsite(userPath string, pkg *Package, symbol, method string) error {
|
||||
ctx := context.Background()
|
||||
|
||||
cmdline := "go run golang.org/x/pkgsite/cmd/pkgsite@latest -gorepo=" + buildCtx.GOROOT
|
||||
words, err := quoted.Split(cmdline)
|
||||
port, err := pickUnusedPort()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to find port for documentation server: %v", err)
|
||||
}
|
||||
addr := fmt.Sprintf("localhost:%d", port)
|
||||
words = append(words, fmt.Sprintf("-http=%s", addr))
|
||||
cmd := exec.CommandContext(context.Background(), words[0], words[1:]...)
|
||||
cmd.Stdout = os.Stderr
|
||||
cmd.Stderr = os.Stderr
|
||||
// Turn off the default signal handler for SIGINT (and SIGQUIT on Unix)
|
||||
// and instead wait for the child process to handle the signal and
|
||||
// exit before exiting ourselves.
|
||||
signal.Ignore(signalsToIgnore...)
|
||||
|
||||
if err := cmd.Start(); err != nil {
|
||||
return fmt.Errorf("starting pkgsite: %v", err)
|
||||
}
|
||||
|
||||
// Wait for pkgsite to became available.
|
||||
if !waitAvailable(ctx, addr) {
|
||||
cmd.Cancel()
|
||||
cmd.Wait()
|
||||
return errors.New("could not connect to local documentation server")
|
||||
}
|
||||
|
||||
// Open web browser.
|
||||
// Assemble url to open on the browser, to point to documentation of
|
||||
// the requested object.
|
||||
importPath := pkg.build.ImportPath
|
||||
if importPath == "." {
|
||||
// go/build couldn't determine the import path, probably
|
||||
|
@ -251,16 +224,33 @@ func doPkgsite(userPath string, pkg *Package, symbol, method string) error {
|
|||
if object != "" {
|
||||
path = path + "#" + object
|
||||
}
|
||||
if ok := browser.Open(path); !ok {
|
||||
cmd.Cancel()
|
||||
cmd.Wait()
|
||||
return errors.New("failed to open browser")
|
||||
|
||||
// Turn off the default signal handler for SIGINT (and SIGQUIT on Unix)
|
||||
// and instead wait for the child process to handle the signal and
|
||||
// exit before exiting ourselves.
|
||||
signal.Ignore(signalsToIgnore...)
|
||||
|
||||
const version = "v0.0.0-20250520201116-40659211760d"
|
||||
cmd := exec.Command("go", "run", "golang.org/x/pkgsite/cmd/internal/doc@"+version,
|
||||
"-gorepo", buildCtx.GOROOT,
|
||||
"-http", addr,
|
||||
"-open", path)
|
||||
cmd.Stdout = os.Stderr
|
||||
cmd.Stderr = os.Stderr
|
||||
|
||||
if err := cmd.Run(); err != nil {
|
||||
var ee *exec.ExitError
|
||||
if errors.As(err, &ee) {
|
||||
// Exit with the same exit status as pkgsite to avoid
|
||||
// printing of "exit status" error messages.
|
||||
// Any relevant messages have already been printed
|
||||
// to stdout or stderr.
|
||||
os.Exit(ee.ExitCode())
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// Wait for child to terminate. We expect the child process to receive signals from
|
||||
// this terminal and terminate in a timely manner, so this process will terminate
|
||||
// soon after.
|
||||
return cmd.Wait()
|
||||
return nil
|
||||
}
|
||||
|
||||
// pickUnusedPort finds an unused port by trying to listen on port 0
|
||||
|
@ -279,24 +269,6 @@ func pickUnusedPort() (int, error) {
|
|||
return port, nil
|
||||
}
|
||||
|
||||
func waitAvailable(ctx context.Context, addr string) bool {
|
||||
ctx, cancel := context.WithTimeout(ctx, 15*time.Second)
|
||||
defer cancel()
|
||||
for ctx.Err() == nil {
|
||||
req, err := http.NewRequestWithContext(ctx, "HEAD", "http://"+addr, nil)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return false
|
||||
}
|
||||
resp, err := http.DefaultClient.Do(req)
|
||||
if err == nil {
|
||||
resp.Body.Close()
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// failMessage creates a nicely formatted error message when there is no result to show.
|
||||
func failMessage(paths []string, symbol, method string) error {
|
||||
var b bytes.Buffer
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue