diff options
| -rw-r--r-- | _content/doc/next.md | 6 | ||||
| -rw-r--r-- | cmd/golangorg/server.go | 37 | ||||
| -rw-r--r-- | cmd/golangorg/testdata/web.txt | 6 | ||||
| -rw-r--r-- | go.mod | 1 | ||||
| -rw-r--r-- | go.sum | 2 |
5 files changed, 50 insertions, 2 deletions
diff --git a/_content/doc/next.md b/_content/doc/next.md new file mode 100644 index 00000000..2eb58d95 --- /dev/null +++ b/_content/doc/next.md @@ -0,0 +1,6 @@ +--- +title: Next Release Notes Draft +template: true +--- + +{{with docNext}}{{.}}{{else}}No next release note fragments available.{{end}} diff --git a/cmd/golangorg/server.go b/cmd/golangorg/server.go index 4f873307..6c42ade3 100644 --- a/cmd/golangorg/server.go +++ b/cmd/golangorg/server.go @@ -33,6 +33,7 @@ import ( "time" "cloud.google.com/go/datastore" + "golang.org/x/build/relnote" "golang.org/x/build/repos" "golang.org/x/website" "golang.org/x/website/internal/blog" @@ -49,6 +50,7 @@ import ( "golang.org/x/website/internal/tour" "golang.org/x/website/internal/web" "golang.org/x/website/internal/webtest" + "rsc.io/markdown" ) var ( @@ -277,6 +279,7 @@ func newSite(mux *http.ServeMux, host string, content, goroot fs.FS) (*web.Site, "rfc3339": parseRFC3339, "section": section, "version": func() string { return runtime.Version() }, + "docNext": releaseNotePreview{goroot}.MergedFragments, }) docs, err := pkgdoc.NewServer(fsys, site, googleCN) if err != nil { @@ -290,6 +293,34 @@ func newSite(mux *http.ServeMux, host string, content, goroot fs.FS) (*web.Site, return site, nil } +// releaseNotePreview implements a preview of upcoming release notes. +type releaseNotePreview struct { + goroot fs.FS // goroot provides the doc/next content to use, if any. +} + +// MergedFragments returns Markdown obtained by merging release note fragments +// found in the doc/next directory in goroot, to preview relnote generate output. +// An empty string and no error is returned if the doc/next directory doesn't exist. +func (p releaseNotePreview) MergedFragments() (markdownWithEmbeddedHTML template.HTML, _ error) { + next, err := fs.Sub(p.goroot, "doc/next") + if err != nil { + return "", err + } + if _, err := fs.Stat(next, "."); os.IsNotExist(err) || errors.Is(err, errNoFileSystem) { + // No next release note fragments. + return "", nil + } + doc, err := relnote.Merge(next) + if err != nil { + return "", fmt.Errorf("relnote.Merge: %v", err) + } + // Note: It's possible to render doc, a parsed Markdown document with embedded HTML, + // into Markdown or HTML. We choose to render to Markdown and let x/website/internal/web + // handle the remaining conversion to HTML. This means the rendering is more consistent + // with what'll happen when relnote generate output is added as _content/doc/go1.N.md. + return template.HTML(markdown.ToMarkdown(doc)), nil +} + func parseRFC3339(s string) (time.Time, error) { return time.Parse(time.RFC3339, s) } @@ -831,12 +862,14 @@ func (m *mountFS) Open(name string) (fs.File, error) { return m.old.Open(name) } +var errNoFileSystem = errors.New("no file system") + // Open returns fsys.Open(name) where fsys is the file system passed to the most recent call to Set. -// If there has been no call to Set, Open returns an error with text “no file system”. +// If there has been no call to Set, Open returns errNoFileSystem, an error with text “no file system”. func (a *atomicFS) Open(name string) (fs.File, error) { fsys, _ := a.v.Load().(*fs.FS) if fsys == nil { - return nil, &fs.PathError{Path: name, Op: "open", Err: fmt.Errorf("no file system")} + return nil, &fs.PathError{Path: name, Op: "open", Err: errNoFileSystem} } return (*fsys).Open(name) } diff --git a/cmd/golangorg/testdata/web.txt b/cmd/golangorg/testdata/web.txt index 834a9284..da95c428 100644 --- a/cmd/golangorg/testdata/web.txt +++ b/cmd/golangorg/testdata/web.txt @@ -458,3 +458,9 @@ body contains is:merged author: GET https://go.dev/CONTRIBUTORS redirect == /AUTHORS + +GET https://go.dev/doc/next +body contains <h1>Next Release Notes Draft</h1> + +GET https://tip.golang.org/doc/next +body contains <h1>Next Release Notes Draft</h1> @@ -19,6 +19,7 @@ require ( golang.org/x/tools v0.21.0 google.golang.org/api v0.136.0 gopkg.in/yaml.v3 v3.0.1 + rsc.io/markdown v0.0.0-20240306144322-0bf8f97ee8ef ) require ( @@ -255,3 +255,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +rsc.io/markdown v0.0.0-20240306144322-0bf8f97ee8ef h1:mqLYrXCXYEZOop9/Dbo6RPX11539nwiCNBb1icVPmw8= +rsc.io/markdown v0.0.0-20240306144322-0bf8f97ee8ef/go.mod h1:8xcPgWmwlZONN1D9bjxtHEjrUtSEa3fakVF8iaewYKQ= |
