From dc5e368d2be9b1cefeb875daeb323792c9a9f572 Mon Sep 17 00:00:00 2001 From: clawbot <35+clawbot@noreply.example.org> Date: Wed, 21 Oct 2026 15:06:16 +0200 Subject: [PATCH] Make script/lint fail on any Hugo warning (closes #25) The lint step in Dockerfile.lint now passes --panicOnWarning alongside --printPathWarnings. Until now Hugo printed "Duplicate target paths" when two pages wrote the same output file and still exited 0, so the lint passed while one page was silently lost. The flag turns that warning, and every other Hugo warning, into a failed lint. script/test and the deploy build are unchanged. The comments in Dockerfile.lint, script/lint and script/check, the README entry for script/lint, and TODO.md now describe the stricter lint. Model: opus-5-5 --- Dockerfile.lint | 11 +++++++---- README.md | 7 ++++--- TODO.md | 11 +++++++---- script/check | 2 +- script/lint | 15 ++++++++------- 5 files changed, 27 insertions(+), 19 deletions(-) diff --git a/Dockerfile.lint b/Dockerfile.lint index 898ee34..67021a9 100644 --- a/Dockerfile.lint +++ b/Dockerfile.lint @@ -21,9 +21,11 @@ # so calling it from inside would recurse into a docker build with no # daemon. # -# This repo's lint is a clean Hugo build that surfaces broken internal -# links and template path problems: `hugo` fails on build errors and -# --printPathWarnings reports render-target collisions. +# This repo's lint is a Hugo build that fails on any build error and on +# any Hugo warning. --printPathWarnings makes Hugo warn when two pages +# write the same output path, and --panicOnWarning turns that warning, +# and every other one, into a failed build. Only the lint is this strict: +# script/test and the deploy build stay plain `hugo --minify`. # alpine 3.21, 2026-02-28 FROM alpine@sha256:c3f8e73fdb79deaebaa2037150150191b9dcbfba68b4a46d70103204c53f4709 @@ -58,4 +60,5 @@ COPY . . # references. ARG CHECK_EPOCH RUN [ -n "$CHECK_EPOCH" ] || exit 1 -RUN echo "lint epoch: ${CHECK_EPOCH}" && hugo --minify --printPathWarnings +RUN echo "lint epoch: ${CHECK_EPOCH}" && \ + hugo --minify --printPathWarnings --panicOnWarning diff --git a/README.md b/README.md index c147478..968c3a1 100644 --- a/README.md +++ b/README.md @@ -66,9 +66,10 @@ provide: git pre-commit hook - `script/test` — the correctness check: a clean `hugo --minify` production build -- `script/lint` — a clean build that surfaces broken links and path collisions, - run inside Docker: it builds `Dockerfile.lint`, where the lint is a build - step, so a successful build is a clean lint +- `script/lint` — a Hugo build that fails on any Hugo warning, including two + pages that write the same output path, run inside Docker: it builds + `Dockerfile.lint`, where the lint is a build step, so a successful build is a + clean lint - `script/fmt` — format every markdown and CSS file in the repo with prettier; the exclusions live in `.prettierignore` with the reason for each - `script/fmt-check` — check that formatting (read-only) diff --git a/TODO.md b/TODO.md index c57fd1c..3b9cf6c 100644 --- a/TODO.md +++ b/TODO.md @@ -34,6 +34,13 @@ leaning on `.gitignore` (https://git.eeqj.de/sneak/lora.vegas/issues/33). # Completed Steps +- 2026-10-21: made `script/lint` fail when two pages write the same output path + (https://git.eeqj.de/sneak/lora.vegas/issues/25). `Dockerfile.lint` now runs + `hugo --minify --printPathWarnings --panicOnWarning`. `--printPathWarnings` + makes Hugo warn about the collision, and `--panicOnWarning` turns that warning + and every other Hugo warning into a failed lint; until now the warning was + printed and the lint still exited 0. `script/test` and the deploy build stay + plain `hugo --minify` - 2026-08-10: added the `cibuild` and `precommit` targets to the `Makefile` (https://git.eeqj.de/sneak/lora.vegas/issues/34). Both scripts already existed, were already documented, and are the two entrypoints a contributor is @@ -328,10 +335,6 @@ outside this repo, so nothing there may be picked up as the Next Step. ## Blocked -- Decide whether `script/lint` should fail on render-target collisions rather - than only print them; `--printPathWarnings` exits 0 today, so the signal is - reported and not enforced. Owner call, since it changes what the gate rejects - (https://git.eeqj.de/sneak/lora.vegas/issues/25) - Move the artifact actions in `.gitea/workflows/deploy.yml` to v4 once this Gitea Actions instance serves the v4 artifact protocol; they are pinned on the deprecated v3 line because v4 fails here diff --git a/script/check b/script/check index 51cb839..e6c3270 100755 --- a/script/check +++ b/script/check @@ -2,7 +2,7 @@ # script/check: run all checks. Our own extension to # scripts-to-rule-them-all. Must not modify any tracked files. Runs the # canonical order: the clean production build, then the lint build that -# reports path warnings, then the read-only formatting check. +# fails on any Hugo warning, then the read-only formatting check. # # The lint - and only the lint - runs inside Docker: it is a build of # Dockerfile.lint, so this script needs a working docker daemon and has diff --git a/script/lint b/script/lint index 605d67f..1f3ce71 100755 --- a/script/lint +++ b/script/lint @@ -1,12 +1,13 @@ #!/bin/sh # script/lint: run the lint. This Hugo site has no dedicated linter, so -# the lint gate is a clean build that surfaces broken internal links and -# template path problems -- but where it runs is not negotiable: every -# lint run happens inside a Docker container, so this script does -# nothing except build Dockerfile.lint. The lint is a build step there, -# so a successful build is a clean lint. There is deliberately no host -# fallback and no "already inside a container?" branch: either would be -# a host lint path wearing a disguise. +# the lint is a Hugo build that fails on any build error and on any Hugo +# warning, including two pages that write the same output path. Where +# it runs is not negotiable. Every lint run happens inside a Docker +# container, so this script does nothing except build Dockerfile.lint. +# The lint is a build step there, so a successful build is a clean lint. +# There is deliberately no host fallback and no "already inside a +# container?" branch: either would be a host lint path wearing a +# disguise. # # No --target: Dockerfile.lint has exactly one stage, so the whole-file # build IS the lint. See that file for why a second, sibling stage would