Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 18 additions & 19 deletions docs-site/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ Documentation site for GOWDK, written entirely in GOWDK source files. The pages
are `.gwdk`, styling is `app.css` (Tailwind v4), and client behavior lives in
GOWDK `js {}` blocks. No HTML, CSS, or JavaScript is generated from Go code.

It lives inside the GOWDK monorepo at `docs-site/` and is its own Go module. A
`replace github.com/cssbruno/gowdk => ../` directive in `go.mod` builds the site
against the **in-tree framework HEAD** rather than a published release, so the
site always reflects the sources it documents.
It lives inside the GOWDK monorepo at `docs-site/` and is its own Go module.
The site server depends on the released GOWDK runtime module, while docs-site
build and dev commands run the in-tree CLI via `go run ../cmd/gowdk ...` so the
published docs reflect the repository sources.

The documentation pages under `src/pages/docs/` and the sidebar
(`src/components/docs-sidebar.cmp.gwdk`) are **generated from the structured
Expand All @@ -21,10 +21,9 @@ every generated page is modular and consistent.
## Prerequisites

- Go 1.26.4+.
- The framework is resolved from the parent directory via the `replace` in
`go.mod`, so `go run github.com/cssbruno/gowdk/cmd/gowdk ...` runs the in-tree
CLI. (The `require ... v0.7.0` line is the minimum version selector; the
`replace` overrides it with the working-tree sources.)
- The site server imports the released GOWDK runtime module declared in
`go.mod`. Use `go run ../cmd/gowdk ...` for compiler/build commands that
should run against the in-tree repository checkout.
- The Tailwind CSS v4 standalone CLI at `tools/tailwindcss`. The GOWDK tailwind
addon (see `gowdk.config.go`) runs it during the build; it is not downloaded
automatically. The Render deploy pins `tailwindcss-linux-x64` to v4.3.1 and
Expand Down Expand Up @@ -62,7 +61,7 @@ parent repo.
## Develop

```sh
go run github.com/cssbruno/gowdk/cmd/gowdk dev --addr 127.0.0.1:8091
go run ../cmd/gowdk dev --addr 127.0.0.1:8091
```

Watches the `.gwdk` sources and `app.css` and rebuilds on change. Open
Expand All @@ -73,7 +72,7 @@ Watches the `.gwdk` sources and `app.css` and rebuilds on change. Open
```sh
go run ./cmd/syncdocs
rm -rf dist/site
go run github.com/cssbruno/gowdk/cmd/gowdk build
go run ../cmd/gowdk build
mkdir -p dist/site/assets
cp -R assets/. dist/site/assets/
cp assets/favicon.ico dist/site/favicon.ico
Expand All @@ -83,7 +82,7 @@ Always run `cmd/syncdocs` before the GOWDK build so the published docs match the
selected GOWDK source. `rm -rf dist/site` is required because the generated tree
mirrors the repo structure and stale routes must not linger.

`go run github.com/cssbruno/gowdk/cmd/gowdk build` compiles the `.gwdk` sources
`go run ../cmd/gowdk build` compiles the `.gwdk` sources
to static HTML, emits each page's `<head>` from its `title`, `description`, and
`canonical` metadata plus
`BuildConfig.Head`, and runs the tailwind addon, which builds `app.css`
Expand All @@ -97,17 +96,17 @@ mkdir -p bin
go build -o bin/gowdk-page .
```

Run "Build Site Output" first. `main.go` embeds `dist/site`, so a clean clone
cannot compile the binary until that generated output exists.
Run "Build Site Output" first. `main.go` serves `dist/site`, so the binary needs
that generated output at runtime.

## Run

```sh
GOWDK_ADDR=127.0.0.1:8091 ./bin/gowdk-page
```

The site binary serves the embedded site. If `GOWDK_ADDR` is omitted, it
defaults to `127.0.0.1:8080`.
The site binary serves the generated `dist/site` directory. If `GOWDK_ADDR` is
omitted, it defaults to `127.0.0.1:8080`.

## Preview & Deploy

Expand All @@ -120,11 +119,11 @@ language and generated output can change between releases.
To preview website changes locally before opening a PR:

```sh
go run github.com/cssbruno/gowdk/cmd/gowdk dev --addr 127.0.0.1:8091
go run ../cmd/gowdk dev --addr 127.0.0.1:8091
# or a production-faithful preview that serves the exact built output through
# the site's own Go binary (the same one that ships to production):
go run ./cmd/syncdocs
rm -rf dist/site && go run github.com/cssbruno/gowdk/cmd/gowdk build
rm -rf dist/site && go run ../cmd/gowdk build
GOWDK_ADDR=127.0.0.1:8091 go run .
```

Expand Down Expand Up @@ -167,7 +166,7 @@ project.
block remembers dismissal in a cookie. Works in dev and the production build.
- `tools/tailwindcss`: standalone Tailwind CLI used by the build.
- `assets/`: static assets copied into `dist/site/assets`.
- `main.go` / `bin/gowdk-page`: single-binary site server. `main.go` serves the
embedded files only; it constructs no markup.
- `main.go` / `bin/gowdk-page`: site server. `main.go` serves the generated
`dist/site` files only; it constructs no markup.
- `gowdk`: local CLI build for the VS Code extension (`.vscode/settings.json`
points `gowdk.cliPath` at it). Git-ignored.
5 changes: 0 additions & 5 deletions docs-site/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,3 @@ go 1.26.4
require github.com/cssbruno/gowdk v0.7.0

require github.com/yuin/goldmark v1.7.12

// The docs site lives inside the GOWDK monorepo and is built against the
// in-tree framework HEAD, not the published release, so the site always
// reflects the current sources it documents.
replace github.com/cssbruno/gowdk => ../
2 changes: 2 additions & 0 deletions docs-site/go.sum
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
github.com/cssbruno/gowdk v0.7.0 h1:1/f+VY/CaxYzEFjX3gG43rYv9kJ7R0fW+r+qsNwTeKI=
github.com/cssbruno/gowdk v0.7.0/go.mod h1:sMgrgsBcCjHh0i01XkSDvXe0YRwhCXBA9AOg5eL2J+A=
github.com/evanw/esbuild v0.28.0 h1:V96ghtc5p5JnNUQIUsc5H3kr+AcFcMqOJll2ZmJW6Lo=
github.com/evanw/esbuild v0.28.0/go.mod h1:D2vIQZqV/vIf/VRHtViaUtViZmG7o+kKmlBfVQuRi48=
github.com/yuin/goldmark v1.7.12 h1:YwGP/rrea2/CnCtUHgjuolG/PnMxdQtPMO5PvaE2/nY=
Expand Down
23 changes: 15 additions & 8 deletions docs-site/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package main

import (
"bytes"
"embed"
"fmt"
"io/fs"
"log"
"mime"
Expand All @@ -16,11 +16,10 @@ import (
"github.com/cssbruno/gowdk/addons/ratelimit"
)

//go:embed dist/site
var embeddedSite embed.FS
const siteOutputDir = "dist/site"

func main() {
root, err := fs.Sub(embeddedSite, "dist/site")
root, err := siteRoot(siteOutputDir)
if err != nil {
log.Fatal(err)
}
Expand All @@ -39,12 +38,20 @@ func main() {
IdleTimeout: 60 * time.Second,
MaxHeaderBytes: 1 << 20,
}
log.Printf("serving embedded GOWDK page at http://%s", addr)
log.Printf("serving GOWDK page at http://%s", addr)
if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
log.Fatal(err)
}
}

func siteRoot(outputDir string) (fs.FS, error) {
root := os.DirFS(outputDir)
if _, err := fs.Stat(root, "index.html"); err != nil {
return nil, fmt.Errorf("generated site output missing at %q: run the docs-site build before starting the server: %w", outputDir, err)
}
return root, nil
}

func listenAddress() string {
if addr := strings.TrimSpace(os.Getenv("GOWDK_ADDR")); addr != "" {
return addr
Expand Down Expand Up @@ -109,10 +116,10 @@ func (server *siteServer) ServeHTTP(writer http.ResponseWriter, request *http.Re
http.Error(writer, "method not allowed", http.StatusMethodNotAllowed)
return
}
serveEmbeddedFile(writer, request, server.root)
serveStaticFile(writer, request, server.root)
}

func serveEmbeddedFile(writer http.ResponseWriter, request *http.Request, root fs.FS) {
func serveStaticFile(writer http.ResponseWriter, request *http.Request, root fs.FS) {
filePath, redirectPath, ok := resolveStaticPath(root, request.URL.Path)
if !ok {
http.NotFound(writer, request)
Expand Down Expand Up @@ -146,7 +153,7 @@ func serveEmbeddedFile(writer http.ResponseWriter, request *http.Request, root f
http.ServeContent(writer, request, info.Name(), info.ModTime(), bytes.NewReader(payload))
}

// resolveStaticPath maps a request path to an embedded file. The site root
// resolveStaticPath maps a request path to a generated site file. The site root
// serves the documentation home, and extensionless paths resolve to their
// directory index.
func resolveStaticPath(root fs.FS, requestPath string) (filePath, redirectPath string, ok bool) {
Expand Down
23 changes: 23 additions & 0 deletions docs-site/main_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package main

import (
"os"
"path/filepath"
"testing"
)

func TestSiteRootRequiresGeneratedIndex(t *testing.T) {
if _, err := siteRoot(t.TempDir()); err == nil {
t.Fatal("expected missing generated site output error")
}
}

func TestSiteRootUsesGeneratedOutputDirectory(t *testing.T) {
dir := t.TempDir()
if err := os.WriteFile(filepath.Join(dir, "index.html"), []byte("<!doctype html>"), 0o644); err != nil {
t.Fatal(err)
}
if _, err := siteRoot(dir); err != nil {
t.Fatalf("expected generated site output to be accepted: %v", err)
}
}
6 changes: 3 additions & 3 deletions docs-site/render.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ services:
name: gowdk-page
runtime: go
rootDir: docs-site
# main.go embeds dist/site, so the build must generate the GOWDK site
# output before compiling the Go server binary.
# main.go serves dist/site, so the build must generate the GOWDK site output
# before compiling the Go server binary.
buildCommand: |
set -euo pipefail
mkdir -p tools
Expand All @@ -16,7 +16,7 @@ services:
chmod +x tools/tailwindcss
go run ./cmd/syncdocs
rm -rf dist/site
go run github.com/cssbruno/gowdk/cmd/gowdk build
go run ../cmd/gowdk build

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Use a module-aware GOWDK invocation in Render build

go help run says module-aware go run runs in the context of the main module; with this service's rootDir: docs-site and no go.work, the main module is docs-site, so go run ../cmd/gowdk build fails before generating dist/site with directory ../cmd/gowdk outside main module or its selected dependencies. This breaks the documented Render/manual deployment path; run the CLI from the repo module/workspace or restore an import-path invocation that resolves to the in-tree command.

Useful? React with 👍 / 👎.

mkdir -p dist/site/assets
cp -R assets/. dist/site/assets/
cp assets/favicon.ico dist/site/favicon.ico
Expand Down