aboutsummaryrefslogtreecommitdiff
path: root/src/cmd
diff options
context:
space:
mode:
authorMichael Matloob <matloob@golang.org>2026-04-07 17:15:10 -0400
committerGopher Robot <gobot@golang.org>2026-04-09 09:24:43 -0700
commit28c56bb5fb438d46d921a37f2e172ecf198f75c2 (patch)
treeb9e1f71e10f66af1ea310d1d7abe8f4aed9b9172 /src/cmd
parentf6d825cd3a7f98fbb48880b791b4c2be8cecddf3 (diff)
downloadgo-28c56bb5fb438d46d921a37f2e172ecf198f75c2.tar.xz
cmd/go: build pkgsite doc command in same go command invocation
Instead of running go run. This is enabled by Ian Alexander's work to remove global state in the loader package. This also fixes an issue where we can't build and run the pkgsite binary because, with our GOPROXY setting, if pkgsite module is available in the module cache at the requested version, but the pkgsite/cmd/internal/doc module isn't we'll give up trying to fetch the doc module. Now that the build and execution are separated, we can make sure the GOPROXY setting is only supplied to the running pkgsite binary, but not to the operations that build it. Fixes #78457 Change-Id: Id2a754fee12b68240243773f81e7d00b6a6a6964 Reviewed-on: https://go-review.googlesource.com/c/go/+/763760 Reviewed-by: Michael Matloob <matloob@google.com> Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Auto-Submit: Michael Matloob <matloob@golang.org> Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Diffstat (limited to 'src/cmd')
-rw-r--r--src/cmd/go/internal/doc/doc.go8
-rw-r--r--src/cmd/go/internal/doc/pkgsite.go59
-rw-r--r--src/cmd/go/internal/doc/pkgsite_bootstrap.go4
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 }