#9 fixed script/check so that script/lint actually runs. But the signal it
recovers is printed and then ignored, because Hugo exits 0 on a duplicate
render-target warning.
Demonstrated during the review of PR #24, on a scratch copy of the site with
two pages rendering to the same permalink:
script/test (hugo --minify) — prints nothing, exit 0.
script/lint (hugo --minify --printPathWarnings) — prints WARN Duplicate target paths: /collide/index.html (2), and exits 0.
script/check with the collision present — exit 0.
So a real render-target collision does not fail make check, does not fail the
pre-commit hook, and does not fail CI. It scrolls past in the build log.
This is worth stating plainly: #9's rationale was mildly overstated, and I
wrote it. I described script/lint as "a real check" whose signal was "being
discarded". The accurate version is that the signal moves from discarded to printed-and-ignored. That is a genuine improvement — you cannot act on output
that never runs — but it is not yet a gate, and #9's issue text implied it was.
Correcting the record here rather than leaving the overstatement standing.
Why this matters for a Hugo site
A duplicate render target means two pieces of content silently overwrite each
other in public/. One of them does not get published, and nothing fails. On a
site whose entire purpose is publishing a small number of pages, losing one
silently is exactly the failure you want a gate to catch. It has not bitten
this repo yet only because the site is currently a single page.
There is also a build-noise interaction: the site already emits an unrelated
taxonomy WARN (#13). Two classes of ignorable warning train everyone to
ignore the third.
Options
Option A — --panicOnWarning on script/lint (recommended, but see the
caveat). Hugo's documented mechanism for making warnings fatal. One flag,
correct semantics, no bespoke parsing. Caveat: it makes ALL warnings fatal,
not just collisions. That means #13 (the taxonomy layout warning) and #18
(the languageCode deprecation) must be fixed first, or the gate goes red
immediately. It also means a future Hugo release that adds a new warning
category can break the build — arguably correct behaviour, but it should be a
conscious choice.
Option B — grep the lint output for the specific warning and fail on it.
Narrower: fails only on duplicate target paths, leaves other warnings advisory.
Costs a bespoke shell pipeline in script/lint that has to keep matching
Hugo's message text — brittle across Hugo upgrades in a way Option A is not.
Option C — leave it advisory and rely on humans reading build output. Not
recommended; that is the status quo and the reason this issue exists.
My recommendation: Option A, sequenced after #13 and #18. It is the
supported mechanism and it makes the whole warning class meaningful rather than
carving out one message. The dependency on #13 and #18 is a feature — it forces
the existing warning backlog to zero before warnings become enforcing, which is
the only order in which "warnings are fatal" is a livable policy.
Definition of done
A render-target collision causes make check to exit non-zero.
Demonstrated the way it was found: construct a collision on a scratch copy
(do not commit colliding content), show make check failing, remove it,
show make check passing. Paste both.
If Option A: #13 and #18 are closed first, and make check is confirmed
green on the real site with the flag active before the flag is merged.
script/lint's header comment describes the new behaviour accurately —
it currently claims it "is a real check", which this issue shows is only
half true today.
script/cibuild succeeds, with the check layer confirmed genuinely executed
and not CACHED (see #23).
TODO.md updated in the same commit.
Depends on
#13 (taxonomy warning) and #18 (languageCode deprecation) if Option A is
chosen. Both must be closed first or the gate fails on day one.
Interacts with #23: verifying this needs a genuinely-executed check layer.
Making script/test strict. script/test is the plain production build and
should stay the fast path; enforcement belongs in script/lint.
## Problem
#9 fixed `script/check` so that `script/lint` actually runs. But the signal it
recovers is **printed and then ignored**, because Hugo exits 0 on a duplicate
render-target warning.
Demonstrated during the review of PR #24, on a scratch copy of the site with
two pages rendering to the same permalink:
- `script/test` (`hugo --minify`) — prints nothing, exit 0.
- `script/lint` (`hugo --minify --printPathWarnings`) — prints
`WARN Duplicate target paths: /collide/index.html (2)`, and **exits 0**.
- `script/check` with the collision present — **exit 0**.
So a real render-target collision does not fail `make check`, does not fail the
pre-commit hook, and does not fail CI. It scrolls past in the build log.
This is worth stating plainly: **#9's rationale was mildly overstated, and I
wrote it.** I described `script/lint` as "a real check" whose signal was "being
discarded". The accurate version is that the signal moves from *discarded* to
*printed-and-ignored*. That is a genuine improvement — you cannot act on output
that never runs — but it is not yet a gate, and #9's issue text implied it was.
Correcting the record here rather than leaving the overstatement standing.
## Why this matters for a Hugo site
A duplicate render target means two pieces of content silently overwrite each
other in `public/`. One of them does not get published, and nothing fails. On a
site whose entire purpose is publishing a small number of pages, losing one
silently is exactly the failure you want a gate to catch. It has not bitten
this repo yet only because the site is currently a single page.
There is also a build-noise interaction: the site already emits an unrelated
taxonomy `WARN` (#13). Two classes of ignorable warning train everyone to
ignore the third.
## Options
**Option A — `--panicOnWarning` on `script/lint` (recommended, but see the
caveat).** Hugo's documented mechanism for making warnings fatal. One flag,
correct semantics, no bespoke parsing. **Caveat: it makes ALL warnings fatal,
not just collisions.** That means #13 (the taxonomy layout warning) and #18
(the `languageCode` deprecation) must be fixed first, or the gate goes red
immediately. It also means a future Hugo release that adds a new warning
category can break the build — arguably correct behaviour, but it should be a
conscious choice.
**Option B — grep the lint output for the specific warning and fail on it.**
Narrower: fails only on duplicate target paths, leaves other warnings advisory.
Costs a bespoke shell pipeline in `script/lint` that has to keep matching
Hugo's message text — brittle across Hugo upgrades in a way Option A is not.
**Option C — leave it advisory and rely on humans reading build output.** Not
recommended; that is the status quo and the reason this issue exists.
**My recommendation: Option A, sequenced after #13 and #18.** It is the
supported mechanism and it makes the whole warning class meaningful rather than
carving out one message. The dependency on #13 and #18 is a feature — it forces
the existing warning backlog to zero before warnings become enforcing, which is
the only order in which "warnings are fatal" is a livable policy.
## Definition of done
1. A render-target collision causes `make check` to exit non-zero.
2. Demonstrated the way it was found: construct a collision on a scratch copy
(do **not** commit colliding content), show `make check` failing, remove it,
show `make check` passing. Paste both.
3. If Option A: `#13` and `#18` are closed first, and `make check` is confirmed
green on the real site with the flag active before the flag is merged.
4. `script/lint`'s header comment describes the new behaviour accurately —
it currently claims it "is a real check", which this issue shows is only
half true today.
5. `script/cibuild` succeeds, with the check layer confirmed genuinely executed
and not `CACHED` (see #23).
6. `TODO.md` updated in the same commit.
## Depends on
- #13 (taxonomy warning) and #18 (`languageCode` deprecation) if Option A is
chosen. Both must be closed first or the gate fails on day one.
- Interacts with #23: verifying this needs a genuinely-executed check layer.
## Out of scope
- Fixing #13 or #18 themselves.
- Making `script/test` strict. `script/test` is the plain production build and
should stay the fast path; enforcement belongs in `script/lint`.
Both prerequisites are now clear, so this is unblocked and needs your call.
#18 (languageCode deprecation) — closed, merged in PR #27.
#13 (taxonomy warning) — fixed in PR #29, under review. Build output is
warning-free.
So the noise floor is genuinely zero and Option A would no longer fail the
build on day one. My recommendation is unchanged: Option A, --panicOnWarning on script/lint.
Assigning to you because the caveat in the issue body is the whole decision and
it is not mine to make: --panicOnWarning makes every Hugo warning fatal,
not just render-target collisions. The upside is that a silent
page-overwriting collision can never ship. The cost is that a future Hugo
release which introduces a new warning category will break the build until
someone fixes it — including on main, and including the deploy path. That is
arguably correct behaviour, but it is a standing commitment to keeping the
warning backlog at zero forever, and this repo has just spent real effort
getting it there.
Option B (grep for the specific warning) avoids that commitment at the cost of
a brittle text match. Option C is the status quo.
Not blocking on this — moving to #23 next. Answer whenever; the work is a small
change to script/lint once you pick.
Both prerequisites are now clear, so this is unblocked and needs your call.
- #18 (`languageCode` deprecation) — closed, merged in PR #27.
- #13 (taxonomy warning) — fixed in PR #29, under review. Build output is
warning-free.
So the noise floor is genuinely zero and Option A would no longer fail the
build on day one. My recommendation is unchanged: **Option A**,
`--panicOnWarning` on `script/lint`.
Assigning to you because the caveat in the issue body is the whole decision and
it is not mine to make: **`--panicOnWarning` makes every Hugo warning fatal,
not just render-target collisions.** The upside is that a silent
page-overwriting collision can never ship. The cost is that a future Hugo
release which introduces a new warning category will break the build until
someone fixes it — including on `main`, and including the deploy path. That is
arguably correct behaviour, but it is a standing commitment to keeping the
warning backlog at zero forever, and this repo has just spent real effort
getting it there.
Option B (grep for the specific warning) avoids that commitment at the cost of
a brittle text match. Option C is the status quo.
Not blocking on this — moving to #23 next. Answer whenever; the work is a small
change to `script/lint` once you pick.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Problem
#9 fixed
script/checkso thatscript/lintactually runs. But the signal itrecovers is printed and then ignored, because Hugo exits 0 on a duplicate
render-target warning.
Demonstrated during the review of PR #24, on a scratch copy of the site with
two pages rendering to the same permalink:
script/test(hugo --minify) — prints nothing, exit 0.script/lint(hugo --minify --printPathWarnings) — printsWARN Duplicate target paths: /collide/index.html (2), and exits 0.script/checkwith the collision present — exit 0.So a real render-target collision does not fail
make check, does not fail thepre-commit hook, and does not fail CI. It scrolls past in the build log.
This is worth stating plainly: #9's rationale was mildly overstated, and I
wrote it. I described
script/lintas "a real check" whose signal was "beingdiscarded". The accurate version is that the signal moves from discarded to
printed-and-ignored. That is a genuine improvement — you cannot act on output
that never runs — but it is not yet a gate, and #9's issue text implied it was.
Correcting the record here rather than leaving the overstatement standing.
Why this matters for a Hugo site
A duplicate render target means two pieces of content silently overwrite each
other in
public/. One of them does not get published, and nothing fails. On asite whose entire purpose is publishing a small number of pages, losing one
silently is exactly the failure you want a gate to catch. It has not bitten
this repo yet only because the site is currently a single page.
There is also a build-noise interaction: the site already emits an unrelated
taxonomy
WARN(#13). Two classes of ignorable warning train everyone toignore the third.
Options
Option A —
--panicOnWarningonscript/lint(recommended, but see thecaveat). Hugo's documented mechanism for making warnings fatal. One flag,
correct semantics, no bespoke parsing. Caveat: it makes ALL warnings fatal,
not just collisions. That means #13 (the taxonomy layout warning) and #18
(the
languageCodedeprecation) must be fixed first, or the gate goes redimmediately. It also means a future Hugo release that adds a new warning
category can break the build — arguably correct behaviour, but it should be a
conscious choice.
Option B — grep the lint output for the specific warning and fail on it.
Narrower: fails only on duplicate target paths, leaves other warnings advisory.
Costs a bespoke shell pipeline in
script/lintthat has to keep matchingHugo's message text — brittle across Hugo upgrades in a way Option A is not.
Option C — leave it advisory and rely on humans reading build output. Not
recommended; that is the status quo and the reason this issue exists.
My recommendation: Option A, sequenced after #13 and #18. It is the
supported mechanism and it makes the whole warning class meaningful rather than
carving out one message. The dependency on #13 and #18 is a feature — it forces
the existing warning backlog to zero before warnings become enforcing, which is
the only order in which "warnings are fatal" is a livable policy.
Definition of done
make checkto exit non-zero.(do not commit colliding content), show
make checkfailing, remove it,show
make checkpassing. Paste both.#13and#18are closed first, andmake checkis confirmedgreen on the real site with the flag active before the flag is merged.
script/lint's header comment describes the new behaviour accurately —it currently claims it "is a real check", which this issue shows is only
half true today.
script/cibuildsucceeds, with the check layer confirmed genuinely executedand not
CACHED(see #23).TODO.mdupdated in the same commit.Depends on
languageCodedeprecation) if Option A ischosen. Both must be closed first or the gate fails on day one.
Out of scope
script/teststrict.script/testis the plain production build andshould stay the fast path; enforcement belongs in
script/lint.Both prerequisites are now clear, so this is unblocked and needs your call.
languageCodedeprecation) — closed, merged in PR #27.warning-free.
So the noise floor is genuinely zero and Option A would no longer fail the
build on day one. My recommendation is unchanged: Option A,
--panicOnWarningonscript/lint.Assigning to you because the caveat in the issue body is the whole decision and
it is not mine to make:
--panicOnWarningmakes every Hugo warning fatal,not just render-target collisions. The upside is that a silent
page-overwriting collision can never ship. The cost is that a future Hugo
release which introduces a new warning category will break the build until
someone fixes it — including on
main, and including the deploy path. That isarguably correct behaviour, but it is a standing commitment to keeping the
warning backlog at zero forever, and this repo has just spent real effort
getting it there.
Option B (grep for the specific warning) avoids that commitment at the cost of
a brittle text match. Option C is the status quo.
Not blocking on this — moving to #23 next. Answer whenever; the work is a small
change to
script/lintonce you pick.