Skip to content

Commit d3e2b64

Browse files
committed
cmd/internal/doc: add doc command in its own module
This change adds a simpler version of cmd/pkgsite, called simply 'doc', that will be invoked by the go command to show package documentation in the browser. This version has a couple of small changes. The first is that it uses the AllowNoModules option added to the server to allow no modules to match. It also makes the logging more quiet so that it's more in line with expectations for a go tool. Finally, it takes the path of the page to open in the browser to open after we start listening on the given address. The unused functionality of cmd/pkgsite is stripped out of the doc command. The doc command is placed into its own module, in the cmd/internal directory so we can see the set of module dependencies in the go.mod file is limited to the smaller set of modules that cmd/pkgsite's dependencies were limited to. For golang/go#68106 Change-Id: Iab9db7c02044a5e08c1f6bc6894b24a400382aae Reviewed-on: https://go-review.googlesource.com/c/pkgsite/+/674437 Reviewed-by: Michael Matloob <[email protected]> kokoro-CI: kokoro <[email protected]> Reviewed-by: Jonathan Amsterdam <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]>
1 parent e960035 commit d3e2b64

File tree

3 files changed

+124
-0
lines changed

3 files changed

+124
-0
lines changed

cmd/internal/doc/go.mod

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
module golang.org/x/pkgsite/cmd/internal/doc
2+
3+
go 1.25
4+
5+
require golang.org/x/pkgsite v0.0.0-20250520185040-e960035a5a53
6+
7+
require (
8+
github.com/google/licensecheck v0.3.1 // indirect
9+
github.com/google/safehtml v0.0.3-0.20211026203422-d6f0e11a5516 // indirect
10+
golang.org/x/mod v0.24.0 // indirect
11+
golang.org/x/net v0.40.0 // indirect
12+
golang.org/x/sync v0.14.0 // indirect
13+
golang.org/x/text v0.25.0 // indirect
14+
golang.org/x/tools v0.33.0 // indirect
15+
rsc.io/markdown v0.0.0-20231214224604-88bb533a6020 // indirect
16+
)

cmd/internal/doc/go.sum

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
2+
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
3+
github.com/google/licensecheck v0.3.1 h1:QoxgoDkaeC4nFrtGN1jV7IPmDCHFNIVh54e5hSt6sPs=
4+
github.com/google/licensecheck v0.3.1/go.mod h1:ORkR35t/JjW+emNKtfJDII0zlciG9JgbT7SmsohlHmY=
5+
github.com/google/safehtml v0.0.3-0.20211026203422-d6f0e11a5516 h1:pSEdbeokt55L2hwtWo6A2k7u5SG08rmw0LhWEyrdWgk=
6+
github.com/google/safehtml v0.0.3-0.20211026203422-d6f0e11a5516/go.mod h1:L4KWwDsUJdECRAEpZoBn3O64bQaywRscowZjJAzjHnU=
7+
github.com/yuin/goldmark v1.6.0 h1:boZcn2GTjpsynOsC0iJHnBWa4Bi0qzfJjthwauItG68=
8+
github.com/yuin/goldmark v1.6.0/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
9+
golang.org/x/mod v0.24.0 h1:ZfthKaKaT4NrhGVZHO1/WDTwGES4De8KtWO0SIbNJMU=
10+
golang.org/x/mod v0.24.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww=
11+
golang.org/x/net v0.40.0 h1:79Xs7wF06Gbdcg4kdCCIQArK11Z1hr5POQ6+fIYHNuY=
12+
golang.org/x/net v0.40.0/go.mod h1:y0hY0exeL2Pku80/zKK7tpntoX23cqL3Oa6njdgRtds=
13+
golang.org/x/pkgsite v0.0.0-20250520185040-e960035a5a53 h1:AnyWwkkeXiEqLhlobTjVeVttvq/HraPwiovi+Lkb/AM=
14+
golang.org/x/pkgsite v0.0.0-20250520185040-e960035a5a53/go.mod h1:KqxqQMGbJ/D0bu4RSWD03NL8CxPXzBcuagsDqaQJkaI=
15+
golang.org/x/sync v0.14.0 h1:woo0S4Yywslg6hp4eUFjTVOyKt0RookbpAHG4c1HmhQ=
16+
golang.org/x/sync v0.14.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
17+
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
18+
golang.org/x/text v0.25.0 h1:qVyWApTSYLk/drJRO5mDlNYskwQznZmkpV2c8q9zls4=
19+
golang.org/x/text v0.25.0/go.mod h1:WEdwpYrmk1qmdHvhkSTNPm3app7v4rsT8F2UD6+VHIA=
20+
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
21+
golang.org/x/tools v0.33.0 h1:4qz2S3zmRxbGIhDIAgjxvFutSvH5EfnsYrRBj0UI0bc=
22+
golang.org/x/tools v0.33.0/go.mod h1:CIJMaWEY88juyUfo7UbgPqbC8rU2OqfAV1h2Qp0oMYI=
23+
rsc.io/markdown v0.0.0-20231214224604-88bb533a6020 h1:GqQcl3Kno/rOntek8/d8axYjau8r/c1zVFojXS6WJFI=
24+
rsc.io/markdown v0.0.0-20231214224604-88bb533a6020/go.mod h1:8xcPgWmwlZONN1D9bjxtHEjrUtSEa3fakVF8iaewYKQ=

cmd/internal/doc/main.go

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
// Copyright 2025 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
// doc is an internal command started by go doc -http
6+
// to serve documentation. It should not be invoked
7+
// directly.
8+
package main
9+
10+
import (
11+
"context"
12+
"flag"
13+
"log"
14+
"net"
15+
"net/http"
16+
"time"
17+
18+
"golang.org/x/pkgsite/cmd/internal/pkgsite"
19+
"golang.org/x/pkgsite/internal/browser"
20+
ilog "golang.org/x/pkgsite/internal/log"
21+
"golang.org/x/pkgsite/internal/middleware/timeout"
22+
"golang.org/x/pkgsite/internal/stdlib"
23+
)
24+
25+
var (
26+
goRepoPath = flag.String("gorepo", "", "")
27+
addr = flag.String("http", "", "")
28+
pathToOpen = flag.String("open", "", "")
29+
)
30+
31+
func main() {
32+
log.SetFlags(0)
33+
log.SetPrefix("doc: ")
34+
35+
// Print simple log entries without the severity, and
36+
// print error-level and above log messages to the user
37+
ilog.Use(docLogger{})
38+
ilog.SetLevel("error")
39+
40+
flag.Parse()
41+
if *goRepoPath == "" || *addr == "" || *pathToOpen == "" {
42+
log.Fatal("-gorepo, -http, or -open not provided to doc command")
43+
}
44+
45+
stdlib.SetGoRepoPath(*goRepoPath)
46+
47+
ctx := context.Background()
48+
server, err := pkgsite.BuildServer(ctx, pkgsite.ServerConfig{
49+
AllowNoModules: true,
50+
UseListedMods: true,
51+
UseLocalStdlib: true,
52+
GoRepoPath: *goRepoPath,
53+
})
54+
if err != nil {
55+
log.Fatal(err)
56+
}
57+
58+
ln, err := net.Listen("tcp", *addr)
59+
if err != nil {
60+
log.Fatal(err)
61+
}
62+
63+
url := "http://" + *addr
64+
log.Printf("Documentation server listening on addr %s", url)
65+
66+
go func() {
67+
if !browser.Open(*pathToOpen) {
68+
log.Printf("Failed to open browser window. Please visit %s in your browser.", *pathToOpen)
69+
}
70+
}()
71+
72+
router := http.NewServeMux()
73+
server.Install(router.Handle, nil, nil)
74+
mw := timeout.Timeout(54 * time.Second)
75+
srv := &http.Server{Addr: *addr, Handler: mw(router)}
76+
log.Fatal(srv.Serve(ln))
77+
}
78+
79+
// docLogger is a simple logger that prints the payload
80+
// using the standard library log package.
81+
type docLogger struct{}
82+
83+
func (docLogger) Log(ctx context.Context, s ilog.Severity, payload any) { log.Printf("%+v", payload) }
84+
func (docLogger) Flush() {}

0 commit comments

Comments
 (0)