script/lint exits 0 on render-target collisions, so the signal is printed but not enforced #25
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
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.