Add allod site preview, compiled into every build #181

Merged
vnprc merged 3 commits from agent/site-preview into master 2026-09-10 16:46:47 +01:00
Member

allod site preview now exists in every build of the allod CLI, so a dev machine can serve a site locally with the same zola version its deploy build pins, by running nix shell --inputs-from <root> nixpkgs#zola --command zola --root <root> serve from anywhere inside the site repository. deploy, check, and config are unchanged and still exist only in a build made with the site tag; on a dev machine allod site deploy is now "unknown site command" rather than an unknown namespace, and allod site lists preview alone. Preview never reads the rclone config, never runs the remote preflight, and takes no --config. Both test shapes and the flake check pass, and a real run against a scratch site with a minimal flake fetched zola and had it accept the argument order. If this is wrong, the dev-machine effect is limited to a local server on loopback; reverting restores the single tagged file. The command arrives on dev machines with their next pin advance; no deployment package change is needed.

Closes allod/tools#180. Refs allod/strategy#51.

What changed

  • cmd/allod/site_common.go (untagged): site root discovery, the site.toml parser, the command table type, the site dispatcher, and the usage generator, moved out of the tagged file unchanged.
  • cmd/allod/site_preview.go (untagged): registers the site namespace and the preview command; builds the argv in sitePreviewArgs, which tests never replace, and runs it through a seam at the exec boundary. --port, --interface, --base-url, --drafts, --open pass through only when given; -- ends option parsing; unknown options are errors. Usage says preview binds loopback and how to reach it from the host with an SSH tunnel.
  • cmd/allod/site.go (tagged): no longer registers a namespace; its init() appends deploy, check, config to the shared table. The command table is populated from init() functions rather than a var literal because a literal would be a Go initialization cycle through the usage generator; preview is prepended so it stays first whatever the file order.
  • Tests: site_absent_test.go now pins the untagged shape (preview present, the three tagged commands unknown, usage naming only preview); site_test.go pins all four in the tagged shape; site_preview_test.go pins the complete argv for the default case, each flag, and -- passthrough, plus rejection paths and exit-code propagation.
  • README "Optional namespaces" and the layout line describe the split.

One departure from the issue's literal design: the issue suggested a package-level var literal for the command table, which does not compile (initialization cycle); the code comments say why.

Risk

R1. The relocation of deploy, check, and config is mechanical and their pinned usage substrings still pass, but their code moved files. The new surface reaches nothing beyond a local loopback server. A full zola serve with live reload against a real site was not run; no site repository with content was reachable on this machine.

Validation

  • go vet ./... && go test ./... and go vet -tags site ./... && go test -tags site ./... pass; gofmt -l cmd/allod/ is empty.
  • nix flake check passes (seven checks, including the one that runs both test shapes).
  • Manual smoke of an untagged and a tagged binary in a directory with no site.toml: site, site --help, site deploy, site preview produce the expected usage or error text and exit codes in both shapes.
  • Real invocation: an untagged binary run in a scratch directory with site.toml and a minimal flake resolved --inputs-from, fetched zola 0.21.0, and zola accepted --root <root> serve, stopping only on the scratch site's missing config.toml.
  • A first review round found that zola serve --root is rejected by zola (verified with zola 0.22.1) and that the original test seam stubbed the whole argv builder; both fixed, and sabotaging the argument order back fails nine preview tests.
  • Reviewed by codex (gpt-5.6-sol) and pi (gpt-oss-120b) on the first and final diffs. The final round produced one wording nit in the usage text (the loopback default holds without --interface and --port), applied, after which nix flake check was re-run and passes; one pi claim (a leftover siteUsageText constant) was checked against source and is false.

Labels are unavailable to this token; none is warranted.

`allod site preview` now exists in every build of the `allod` CLI, so a dev machine can serve a site locally with the same zola version its deploy build pins, by running `nix shell --inputs-from <root> nixpkgs#zola --command zola --root <root> serve` from anywhere inside the site repository. `deploy`, `check`, and `config` are unchanged and still exist only in a build made with the `site` tag; on a dev machine `allod site deploy` is now "unknown site command" rather than an unknown namespace, and `allod site` lists `preview` alone. Preview never reads the rclone config, never runs the remote preflight, and takes no `--config`. Both test shapes and the flake check pass, and a real run against a scratch site with a minimal flake fetched zola and had it accept the argument order. If this is wrong, the dev-machine effect is limited to a local server on loopback; reverting restores the single tagged file. The command arrives on dev machines with their next pin advance; no deployment package change is needed. Closes allod/tools#180. Refs allod/strategy#51. ## What changed - `cmd/allod/site_common.go` (untagged): site root discovery, the `site.toml` parser, the command table type, the `site` dispatcher, and the usage generator, moved out of the tagged file unchanged. - `cmd/allod/site_preview.go` (untagged): registers the `site` namespace and the `preview` command; builds the argv in `sitePreviewArgs`, which tests never replace, and runs it through a seam at the exec boundary. `--port`, `--interface`, `--base-url`, `--drafts`, `--open` pass through only when given; `--` ends option parsing; unknown options are errors. Usage says preview binds loopback and how to reach it from the host with an SSH tunnel. - `cmd/allod/site.go` (tagged): no longer registers a namespace; its `init()` appends `deploy`, `check`, `config` to the shared table. The command table is populated from `init()` functions rather than a var literal because a literal would be a Go initialization cycle through the usage generator; `preview` is prepended so it stays first whatever the file order. - Tests: `site_absent_test.go` now pins the untagged shape (preview present, the three tagged commands unknown, usage naming only preview); `site_test.go` pins all four in the tagged shape; `site_preview_test.go` pins the complete argv for the default case, each flag, and `--` passthrough, plus rejection paths and exit-code propagation. - README "Optional namespaces" and the layout line describe the split. One departure from the issue's literal design: the issue suggested a package-level var literal for the command table, which does not compile (initialization cycle); the code comments say why. ## Risk R1. The relocation of `deploy`, `check`, and `config` is mechanical and their pinned usage substrings still pass, but their code moved files. The new surface reaches nothing beyond a local loopback server. A full `zola serve` with live reload against a real site was not run; no site repository with content was reachable on this machine. ## Validation - `go vet ./... && go test ./...` and `go vet -tags site ./... && go test -tags site ./...` pass; `gofmt -l cmd/allod/` is empty. - `nix flake check` passes (seven checks, including the one that runs both test shapes). - Manual smoke of an untagged and a tagged binary in a directory with no `site.toml`: `site`, `site --help`, `site deploy`, `site preview` produce the expected usage or error text and exit codes in both shapes. - Real invocation: an untagged binary run in a scratch directory with `site.toml` and a minimal flake resolved `--inputs-from`, fetched zola 0.21.0, and zola accepted `--root <root> serve`, stopping only on the scratch site's missing `config.toml`. - A first review round found that `zola serve --root` is rejected by zola (verified with zola 0.22.1) and that the original test seam stubbed the whole argv builder; both fixed, and sabotaging the argument order back fails nine preview tests. - Reviewed by codex (gpt-5.6-sol) and pi (gpt-oss-120b) on the first and final diffs. The final round produced one wording nit in the usage text (the loopback default holds without `--interface` and `--port`), applied, after which `nix flake check` was re-run and passes; one pi claim (a leftover `siteUsageText` constant) was checked against source and is false. Labels are unavailable to this token; none is warranted.
build, resolving the site root and running the site's own locked zola
through 'nix shell --inputs-from'. 'deploy', 'check', and 'config' stay
behind the 'site' build tag, extending the same namespace rather than
registering a second one. Usage text is generated from a per-build
command table so each shape advertises exactly what it carries.

Refs allod/tools#180
option and must precede 'serve', not follow it, in the argv preview
builds; move the test seam to the exec boundary so the argv construction
itself stays live in tests rather than being replaced by a stub; correct
two stale comments in site.go that still named site_common.go as the
file that registers the namespace; and reword the namespace summary so
it reads correctly on both the tagged and untagged build.

Refs allod/tools#180
Refs allod/tools#180
vnprc approved these changes 2026-09-10 16:46:41 +01:00
vnprc merged commit 8efdda4ff1 into master 2026-09-10 16:46:47 +01:00
vnprc deleted branch agent/site-preview 2026-09-10 16:46:47 +01:00
Sign in to join this conversation.
No description provided.