Skip to content

Commit 8799207

Browse files
committed
docs: build source-aligned stable and next references
1 parent 31af743 commit 8799207

187 files changed

Lines changed: 4043 additions & 4630 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.gitignore‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,5 @@ vendor
1010
.cache/
1111
site/src/generated/
1212
site/dist/
13+
site/dist-next/
1314
site/node_modules/

‎README.md‎

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,14 @@ the runnable cookbook recipes the docs reference.
1515

1616
## Documentation site
1717

18-
Requires [Node.js](https://nodejs.org) (LTS), Go 1.27, and Git. The site build
19-
fetches the Echo commit recorded in `site/echo-source.json`, compiles the
20-
`reference/` examples against it, extracts exported middleware fields, and
21-
checks them against `site/reference-baseline.json` before building pages.
18+
Requires [Node.js](https://nodejs.org) (LTS), Go 1.27, and Git. The build
19+
publishes the stable docs at `/` and a next preview at `/next/`, each with its
20+
own search index and source revision. Those revisions are pinned in
21+
`site/echo-source.json` and `site/next-source.json`. The build compiles the
22+
`reference/` examples against both, extracts middleware fields and function
23+
signatures, and checks them against `site/reference-baseline.json`. JWT,
24+
Prometheus, and OpenTelemetry are extracted from their own pinned modules in
25+
`site/external-sources.json` and checked against `site/external-baseline.json`.
2226

2327
```bash
2428
cd site
@@ -28,18 +32,23 @@ npm run build # production build to site/dist
2832
npm run preview # preview the production build
2933
```
3034

31-
The first build fetches the pinned Echo source into `.cache/`. To test a proposed
32-
Echo checkout instead, set `ECHO_SOURCE_DIR` to its absolute path when running
33-
`npm run build`. The build reports changed fields and stops; review the affected
34-
pages, run `npm run source:prepare` and `npm run source:accept`, then review the
35-
baseline diff before committing it. The generated files in `site/src/generated/`
36-
are never edited or committed.
37-
38-
`npm run translations:status` reports whether the reviewed Spanish, Japanese,
39-
Portuguese, and Chinese Request Logger and Static pages still match the current
40-
English source. After reviewing those translations, run
41-
`npm run translations:accept` and review the hash changes. This report tracks
42-
freshness; it does not validate translation quality.
35+
The first build fetches pinned source into `.cache/`. To test a proposed next
36+
Echo checkout, set `ECHO_SOURCE_DIR` to its absolute path when running
37+
`npm run build`. The build reports changed API facts and stops. Review the
38+
affected pages and behavior, run `npm run source:prepare` and
39+
`npm run source:accept`, then review the baseline diff before committing it.
40+
The generated files in `site/src/generated/` are never edited or committed.
41+
`npm run site:check` checks routes, local links and fragments, image text,
42+
search assets, and locale coverage. `npm run performance:check` catches large
43+
HTML or first-load asset growth on representative stable and next pages.
44+
45+
`npm run translations:status` identifies changed sections in the Spanish,
46+
Japanese, Portuguese, and Chinese Request Logger, Static, and middleware task
47+
pages. Translate and review the affected section, then record that page with
48+
`npm run translations:accept -- es logger` (replace locale and page) and review
49+
the baseline diff. This tracks edits to both English and localized text; it
50+
does not judge translation quality. The API tables are generated from source,
51+
so translators focus on explanations, task guidance, examples, and safety notes.
4352

4453
Content is Markdown/MDX under `site/src/content/docs/` (`guide/`, `middleware/`,
4554
`cookbook/`). To add a page, drop a file in the right folder — the sidebar is

‎reference/cmd/config-fields/main.go‎

Lines changed: 38 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// SPDX-License-Identifier: MIT
22

3-
// config-fields emits source-backed middleware config fields for the website.
3+
// config-fields emits source-backed middleware API facts for the website.
44
// It does not claim to determine runtime defaults or behavior.
55
package main
66

@@ -33,22 +33,33 @@ type config struct {
3333
Fields []field `json:"fields"`
3434
}
3535

36+
type function struct {
37+
Name string `json:"name"`
38+
Signature string `json:"signature"`
39+
File string `json:"file"`
40+
Line int `json:"line"`
41+
}
42+
3643
type manifest struct {
37-
Module string `json:"module"`
38-
Revision string `json:"revision,omitempty"`
39-
Configs []config `json:"configs"`
44+
Module string `json:"module"`
45+
Revision string `json:"revision,omitempty"`
46+
Configs []config `json:"configs"`
47+
Functions []function `json:"functions"`
4048
}
4149

4250
func main() {
4351
root := flag.String("root", "", "Echo repository root")
4452
revision := flag.String("revision", "", "exact Echo commit or tag used for this build")
53+
module := flag.String("module", "github.com/labstack/echo/v5", "module path containing the source")
54+
directory := flag.String("directory", "middleware", "package directory relative to the module root")
55+
packageName := flag.String("package", "middleware", "Go package name")
4556
flag.Parse()
4657
if *root == "" {
4758
fmt.Fprintln(os.Stderr, "-root is required")
4859
os.Exit(2)
4960
}
5061

51-
result, err := extract(*root, *revision)
62+
result, err := extractPackage(*root, *revision, *module, *directory, *packageName)
5263
if err != nil {
5364
fmt.Fprintln(os.Stderr, err)
5465
os.Exit(1)
@@ -62,26 +73,43 @@ func main() {
6273
}
6374

6475
func extract(root, revision string) (manifest, error) {
76+
return extractPackage(root, revision, "github.com/labstack/echo/v5", "middleware", "middleware")
77+
}
78+
79+
func extractPackage(root, revision, module, directory, packageName string) (manifest, error) {
6580
root, err := filepath.Abs(root)
6681
if err != nil {
6782
return manifest{}, err
6883
}
6984
fs := token.NewFileSet()
70-
packageDir := filepath.Join(root, "middleware")
85+
packageDir := filepath.Join(root, directory)
7186
packages, err := parser.ParseDir(fs, packageDir, func(info os.FileInfo) bool {
7287
return strings.HasSuffix(info.Name(), ".go") && !strings.HasSuffix(info.Name(), "_test.go")
7388
}, parser.ParseComments)
7489
if err != nil {
7590
return manifest{}, err
7691
}
77-
pkg, ok := packages["middleware"]
92+
pkg, ok := packages[packageName]
7893
if !ok {
79-
return manifest{}, fmt.Errorf("middleware package not found in %s", packageDir)
94+
return manifest{}, fmt.Errorf("package %s not found in %s", packageName, packageDir)
8095
}
8196

82-
result := manifest{Module: "github.com/labstack/echo/v5", Revision: revision, Configs: []config{}}
97+
result := manifest{Module: module, Revision: revision, Configs: []config{}, Functions: []function{}}
8398
for filename, source := range pkg.Files {
8499
for _, declaration := range source.Decls {
100+
if fn, ok := declaration.(*ast.FuncDecl); ok && fn.Recv == nil && ast.IsExported(fn.Name.Name) {
101+
var rendered bytes.Buffer
102+
if err := format.Node(&rendered, fs, fn.Type); err != nil {
103+
return manifest{}, err
104+
}
105+
result.Functions = append(result.Functions, function{
106+
Name: fn.Name.Name,
107+
Signature: strings.Replace(rendered.String(), "func(", "func "+fn.Name.Name+"(", 1),
108+
File: filepath.ToSlash(strings.TrimPrefix(filename, root+string(filepath.Separator))),
109+
Line: fs.Position(fn.Pos()).Line,
110+
})
111+
continue
112+
}
85113
group, ok := declaration.(*ast.GenDecl)
86114
if !ok || group.Tok != token.TYPE {
87115
continue
@@ -121,6 +149,7 @@ func extract(root, revision string) (manifest, error) {
121149
}
122150
}
123151
sort.Slice(result.Configs, func(i, j int) bool { return result.Configs[i].Name < result.Configs[j].Name })
152+
sort.Slice(result.Functions, func(i, j int) bool { return result.Functions[i].Name < result.Functions[j].Name })
124153
return result, nil
125154
}
126155

‎reference/cmd/config-fields/main_test.go‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ type ExampleConfig struct {
2323
}
2424
type hiddenConfig struct { Visible bool }
2525
type OtherType struct { Visible bool }
26+
func ExampleWithConfig(c ExampleConfig) bool { return c.New != "" }
27+
func privateFunction() {}
2628
`
2729
if err := os.WriteFile(filepath.Join(dir, "example.go"), []byte(source), 0644); err != nil {
2830
t.Fatal(err)
@@ -42,4 +44,7 @@ type OtherType struct { Visible bool }
4244
if fields[0].Name != "Old" || fields[0].Type != "bool" || !fields[0].Deprecated || fields[1].Name != "New" {
4345
t.Fatalf("unexpected fields: %#v", fields)
4446
}
47+
if len(got.Functions) != 1 || got.Functions[0].Name != "ExampleWithConfig" || got.Functions[0].Signature != "func ExampleWithConfig(c ExampleConfig) bool" || got.Functions[0].File != "middleware/example.go" {
48+
t.Fatalf("unexpected functions: %#v", got.Functions)
49+
}
4550
}

‎site/astro.config.mjs‎

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,15 @@ import { defineConfig } from 'astro/config';
22
import starlight from '@astrojs/starlight';
33
import { redirects } from './src/redirects.mjs';
44

5+
const next = process.env.DOCS_CHANNEL === 'next';
6+
57
// https://astro.build/config
68
export default defineConfig({
79
site: 'https://echo.labstack.com',
10+
base: next ? '/next/' : '/',
11+
outDir: next ? './dist-next' : './dist',
812
// Preserve every live Docusaurus /docs/* URL at cutover (generated — see ./src/redirects.mjs).
9-
redirects,
13+
redirects: next ? {} : redirects,
1014
integrations: [
1115
starlight({
1216
title: 'Echo',
@@ -36,6 +40,7 @@ export default defineConfig({
3640
// Keep Starlight's built-in Pagefind ⌘K search; Search override adds the
3741
// empty-state launchpad. "Ask AI" is the kapa.ai widget (see head).
3842
components: {
43+
Banner: './src/components/VersionBanner.astro',
3944
Footer: './src/components/Footer.astro',
4045
Search: './src/components/Search.astro',
4146
},

‎site/echo-source.json‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
{
22
"repository": "https://github.com/labstack/echo.git",
3-
"revision": "68ac4cf7e0b862001a9de7cdbc50d9447287a07c"
3+
"revision": "caa018246b840091e71a1d61ea9ee1176ab81333",
4+
"release": "v5.3.0"
45
}

0 commit comments

Comments
 (0)