diff options
| -rw-r--r-- | src/cmd/go/internal/doc/doc.go | 8 | ||||
| -rw-r--r-- | src/cmd/go/internal/doc/pkgsite.go | 59 | ||||
| -rw-r--r-- | src/cmd/go/internal/doc/pkgsite_bootstrap.go | 4 |
3 files changed, 58 insertions, 13 deletions
diff --git a/src/cmd/go/internal/doc/doc.go b/src/cmd/go/internal/doc/doc.go index 4376e3344e..d961c2a215 100644 --- a/src/cmd/go/internal/doc/doc.go +++ b/src/cmd/go/internal/doc/doc.go @@ -222,16 +222,16 @@ func do(ctx context.Context, writer io.Writer, flagSet *flag.FlagSet, args []str mod, err := runCmd(append(os.Environ(), "GOWORK=off"), "go", "list", "-m") if err == nil && mod != "" && mod != "command-line-arguments" { // If there's a module, go to the module's doc page. - return doPkgsite(mod, "") + return doPkgsite(ctx, mod, "") } gowork, err := runCmd(nil, "go", "env", "GOWORK") if err == nil && gowork != "" { // Outside a module, but in a workspace, go to the home page // with links to each of the modules' pages. - return doPkgsite("", "") + return doPkgsite(ctx, "", "") } // Outside a module or workspace, go to the documentation for the standard library. - return doPkgsite("std", "") + return doPkgsite(ctx, "std", "") } // If args are provided, we need to figure out which page to open on the pkgsite @@ -296,7 +296,7 @@ func do(ctx context.Context, writer io.Writer, flagSet *flag.FlagSet, args []str if err != nil { return err } - return doPkgsite(path, fragment) + return doPkgsite(ctx, path, fragment) } return nil } diff --git a/src/cmd/go/internal/doc/pkgsite.go b/src/cmd/go/internal/doc/pkgsite.go index 2c135cdc34..a2398ef397 100644 --- a/src/cmd/go/internal/doc/pkgsite.go +++ b/src/cmd/go/internal/doc/pkgsite.go @@ -7,17 +7,21 @@ package doc import ( + "context" "errors" "fmt" "net" "net/url" "os" "os/exec" - "os/signal" "path/filepath" "strings" + "cmd/go/internal/base" "cmd/go/internal/cfg" + "cmd/go/internal/load" + "cmd/go/internal/modload" + "cmd/go/internal/work" ) // pickUnusedPort finds an unused port by trying to listen on port 0 @@ -36,7 +40,49 @@ func pickUnusedPort() (int, error) { return port, nil } -func doPkgsite(urlPath, fragment string) error { +// buildPkgsite builds a pkgsite binary whose build may be cached. +func buildPkgsite(ctx context.Context) string { + loader := modload.NewLoader() + + // Set the builder to have no module root so we can build a pkg@version pattern. + loader.ForceUseModules = true + loader.RootMode = modload.NoRoot + loader.AllowMissingModuleImports() + modload.Init(loader) + + work.BuildInit(loader) + b := work.NewBuilder("", loader.VendorDirOrEmpty) + defer func() { + if err := b.Close(); err != nil { + base.Fatal(err) + } + }() + + const version = "v0.0.0-20251223195805-1a3bd3c788fe" + pkgVers := "golang.org/x/pkgsite/cmd/internal/doc@" + version + pkgOpts := load.PackageOpts{MainOnly: true} + pkgs, err := load.PackagesAndErrorsOutsideModule(loader, ctx, pkgOpts, []string{pkgVers}) + if err != nil { + base.Fatal(err) + } + if len(pkgs) == 0 { + base.Fatalf("go: internal error: no packages loaded for %s", pkgVers) + } + if len(pkgs) > 1 { + base.Fatalf("go: internal error: pattern %s matches multiple packages", pkgVers) + } + p := pkgs[0] + p.Internal.OmitDebug = true + p.Internal.ExeName = p.DefaultExecName() + load.CheckPackageErrors([]*load.Package{p}) + + a := b.LinkAction(loader, work.ModeBuild, work.ModeBuild, p) + a.CacheExecutable = true + b.Do(ctx, a) + return a.BuiltTarget() +} + +func doPkgsite(ctx context.Context, urlPath, fragment string) error { port, err := pickUnusedPort() if err != nil { return fmt.Errorf("failed to find port for documentation server: %v", err) @@ -57,7 +103,7 @@ func doPkgsite(urlPath, fragment string) error { // 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...) + base.StartSigHandlers() // Prepend the local download cache to GOPROXY to get around deprecation checks. env := os.Environ() @@ -77,11 +123,8 @@ func doPkgsite(urlPath, fragment string) error { env = append(env, "GOPROXY="+gomodcache+","+goproxy) } - const version = "v0.0.0-20251223195805-1a3bd3c788fe" - cmd := exec.Command(goCmd(), "run", "golang.org/x/pkgsite/cmd/internal/doc@"+version, - "-gorepo", cfg.GOROOT, - "-http", addr, - "-open", path) + pkgsite := buildPkgsite(ctx) + cmd := exec.Command(pkgsite, "-gorepo", cfg.GOROOT, "-http", addr, "-open", path) cmd.Env = env cmd.Stdout = os.Stderr cmd.Stderr = os.Stderr diff --git a/src/cmd/go/internal/doc/pkgsite_bootstrap.go b/src/cmd/go/internal/doc/pkgsite_bootstrap.go index 3c9f546957..cb72492cb5 100644 --- a/src/cmd/go/internal/doc/pkgsite_bootstrap.go +++ b/src/cmd/go/internal/doc/pkgsite_bootstrap.go @@ -8,4 +8,6 @@ package doc -func doPkgsite(string, string) error { return nil } +import "context" + +func doPkgsite(context.Context, string, string) error { return nil } |
