diff options
| author | Jonathan Amsterdam <jba@google.com> | 2026-03-20 10:21:23 -0400 |
|---|---|---|
| committer | Jonathan Amsterdam <jba@google.com> | 2026-03-24 09:32:17 -0700 |
| commit | f2497254fdac6fde9ff38a604f6891753b583a20 (patch) | |
| tree | 3522fb17432e82bb336e83e643713e2955e637f2 /internal/api | |
| parent | 1b091e590bab0f0e98b815d7dd42b1e29041b473 (diff) | |
| download | go-x-pkgsite-f2497254fdac6fde9ff38a604f6891753b583a20.tar.xz | |
internal/api: initial logic for doc
Obtain the go/doc.Package from the retrieved unit and validate
the doc query param. Rendering is more complicated; it is deferred
to another CL.
Change-Id: I1d16fe98dbf06457182f5925ce0986448882d40e
Reviewed-on: https://go-review.googlesource.com/c/pkgsite/+/757360
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
kokoro-CI: kokoro <noreply+kokoro@google.com>
Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
Reviewed-by: Ethan Lee <ethanalee@google.com>
Diffstat (limited to 'internal/api')
| -rw-r--r-- | internal/api/api.go | 47 | ||||
| -rw-r--r-- | internal/api/api_test.go | 25 |
2 files changed, 64 insertions, 8 deletions
diff --git a/internal/api/api.go b/internal/api/api.go index 3b653fd8..679cf0ee 100644 --- a/internal/api/api.go +++ b/internal/api/api.go @@ -8,12 +8,14 @@ import ( "bytes" "encoding/json" "errors" + "go/doc" "net/http" "strconv" "strings" "golang.org/x/pkgsite/internal" "golang.org/x/pkgsite/internal/derrors" + "golang.org/x/pkgsite/internal/godoc" "golang.org/x/pkgsite/internal/stdlib" "golang.org/x/pkgsite/internal/version" ) @@ -120,6 +122,10 @@ func ServePackage(w http.ResponseWriter, r *http.Request, ds internal.DataSource } } + // Process documentation, including synopsis. + // Although unit.Documentation is a slice, it will + // have at most one item, the documentation matching + // the build context bc. synopsis := "" var docs string goos := params.GOOS @@ -127,13 +133,46 @@ func ServePackage(w http.ResponseWriter, r *http.Request, ds internal.DataSource if len(unit.Documentation) > 0 { d := unit.Documentation[0] synopsis = d.Synopsis + // Return the more precise GOOS/GOARCH. + // If the user didn't provide them, use the unit's. + // If the user did, assume what they provided is at + // least as specific as the unit's, and use it. if goos == "" { goos = d.GOOS } if goarch == "" { goarch = d.GOARCH } - // TODO(jba): Add support for docs. + if params.Doc != "" { + // d.Source is an encoded AST. Decode it, then use + // go/doc (not pkgsite's renderer) to generate the + // result. + gpkg, err := godoc.DecodePackage(d.Source) + if err != nil { + return serveErrorJSON(w, http.StatusInternalServerError, err.Error(), nil) + } + innerPath := internal.Suffix(unit.Path, unit.ModulePath) + modInfo := &godoc.ModuleInfo{ModulePath: unit.ModulePath, ResolvedVersion: unit.Version} + dpkg, err := gpkg.DocPackage(innerPath, modInfo) + if err != nil { + return err + } + var formatFunc func(string) []byte + switch params.Doc { + case "text": + formatFunc = dpkg.Text + case "md", "markdown": + formatFunc = dpkg.Markdown + case "html": + formatFunc = dpkg.HTML + default: + return serveErrorJSON(w, http.StatusBadRequest, "bad doc format: need one of 'text', 'md', 'markdown' or 'html'", nil) + } + docs, err = renderDoc(dpkg, formatFunc) + if err != nil { + return serveErrorJSON(w, http.StatusInternalServerError, err.Error(), nil) + } + } } imports := unit.Imports @@ -162,6 +201,12 @@ func ServePackage(w http.ResponseWriter, r *http.Request, ds internal.DataSource return serveJSON(w, http.StatusOK, resp) } +// renderDoc renders the documentation for dpkg according to format. +// TODO(jba): implement +func renderDoc(dpkg *doc.Package, formatFunc func(string) []byte) (string, error) { + return string(formatFunc("TODO")), nil +} + // ServeModule handles requests for the v1 module metadata endpoint. func ServeModule(w http.ResponseWriter, r *http.Request, ds internal.DataSource) (err error) { defer derrors.Wrap(&err, "ServeModule") diff --git a/internal/api/api_test.go b/internal/api/api_test.go index 9112c576..87d6b8d0 100644 --- a/internal/api/api_test.go +++ b/internal/api/api_test.go @@ -14,6 +14,7 @@ import ( "github.com/google/go-cmp/cmp" "golang.org/x/pkgsite/internal" "golang.org/x/pkgsite/internal/testing/fakedatasource" + "golang.org/x/pkgsite/internal/testing/sample" ) func TestServePackage(t *testing.T) { @@ -35,11 +36,7 @@ func TestServePackage(t *testing.T) { ModuleInfo: internal.ModuleInfo{ModulePath: "example.com", Version: version}, Name: "pkg", }, - Documentation: []*internal.Documentation{{ - GOOS: "linux", - GOARCH: "amd64", - Synopsis: "Basic synopsis", - }}, + Documentation: []*internal.Documentation{sample.Documentation("linux", "amd64", sample.DocContents)}, }}, }) @@ -84,7 +81,7 @@ func TestServePackage(t *testing.T) { Path: "example.com/pkg", ModulePath: "example.com", ModuleVersion: version, - Synopsis: "Basic synopsis", + Synopsis: "This is a package synopsis for GOOS=linux, GOARCH=amd64", GOOS: "linux", GOARCH: "amd64", }, @@ -123,11 +120,25 @@ func TestServePackage(t *testing.T) { Path: "example.com/pkg", ModulePath: "example.com", ModuleVersion: version, - Synopsis: "Basic synopsis", + Synopsis: "This is a package synopsis for GOOS=linux, GOARCH=amd64", GOOS: "linux", GOARCH: "amd64", }, }, + { + name: "doc", + url: "/v1/package/example.com/pkg?version=v1.2.3&doc=text", + wantStatus: http.StatusOK, + want: &Package{ + Path: "example.com/pkg", + ModulePath: "example.com", + ModuleVersion: version, + Synopsis: "This is a package synopsis for GOOS=linux, GOARCH=amd64", + GOOS: "linux", + GOARCH: "amd64", + Docs: "TODO\n", + }, + }, } { t.Run(test.name, func(t *testing.T) { r := httptest.NewRequest("GET", test.url, nil) |
