Commit 3b921e6
committed
Rewrite summary-rendering check with AST-aware tokenizer
Addresses 15 issues from the multi-angle code review. The previous
regex scanner had real correctness gaps and ergonomic limitations.
Bugs the old scanner had:
1. Brace inside string literals (e.g. `{{ printf "{%s}" .Params.summary }}`)
silently skipped the action — the naive `{{[^{}]*}}` regex stopped
at the inner `{`.
2. Positional renderSummary regex matched when `.Params.summary` was
nested in a non-RenderString call: `{{ .RenderString (printf "%s"
.Params.summary) }}` falsely passed.
3. Piped renderSummary regex matched any later `.RenderString`
mention: `{{ .Params.summary | print "x" .Page.RenderString }}`
falsely passed because `.RenderString` appears after the pipe.
4. ifPredicate anchored to exact `if .Params.summary`, so compound
forms (`if and .Params.summary $cond`) and `else if` were flagged
as violations even though they only check presence.
5. Variable assignment `{{ $s := .Params.summary }}` was flagged
indiscriminately; subfield access `{{ if .Params.summary.X }}`
was flagged because the predicate regex required exact end.
6. Hugo comments mentioning the field (`{{/* .Params.summary */}}`)
were treated as live references.
The new scanner:
- Tokenizes actions with quote-aware lexing (handles double-quoted
and backtick strings; `{` and `}` inside strings no longer split
actions) — fixes #1.
- Strips `{{/* ... */}}` comments before scanning (preserves line
numbers via newline padding) — fixes #6.
- Classifies each action by leading keyword. `if` / `else if` /
`range` are presence predicates regardless of compound form or
subfield access — fixes #4 and the subfield case. `with` /
`else with` are flagged as rebinding the dot.
- Pipeline analysis: splits on `|` at paren-depth 0, walks each
stage. `.Params.summary` is safe only when it is a top-level
positional argument to `.RenderString` or the head of a pipeline
whose terminal stage is `.RenderString`. Nested references inside
parens are flagged — fixes #2 and #3.
Other fixes in this commit:
- `baseof.html` exemption is now by relative path
(`_default/baseof.html`), not basename. Hugo idiomatically
supports per-type baseof overrides; basename-only would silently
exempt all of them.
- The walker collects I/O errors into a side slice and continues,
so a transient ReadFile failure on one file no longer masks
every violation in the remaining files.
- `layoutsPath` deleted; the walk calls the existing `repoRoot(t)`
helper from messaging_test.go.
- Three duplicated regex blocks collapsed into package-level vars
and a single `scanSummaryViolations` helper. The multi-line test
no longer round-trips through a tempfile.
- baseof.html's meta description pipes the summary through
`$.RenderString (dict "display" "inline") . | plainify` so
backticks become `<code>` HTML and then plain text. SEO
snippets ship clean prose instead of literal Markdown
punctuation.
- The pipe-form alternation (YAGNI in the previous regex) is
generalized by the pipeline walker; no current template uses
the piped form but the scanner handles it correctly when one
does.
Verified by: 19-case `TestClassifyAction_TableDriven` covering
every safe and unsafe shape, plus three scenario tests
(`TestFindActions_BalancedStrings`,
`TestScanSummaryViolations_CommentsIgnored`,
`TestScanSummaryViolations_MultiLineWith`,
`TestScanSummaryViolations_BraceInString`). The real-layout walk
(`TestSummaryFrontMatterRenderedThroughRenderString`) passes
against the current `website/layouts/` tree, and the rendered
meta description on the progressive-disclosure page now shows
"Use <?catalog?> ..." rather than "Use \`<?catalog?>\` ...".
docs/development/website-config.md updated to enumerate the safe
and forbidden forms and explain the baseof.html meta-description
plainify path.
https://claude.ai/code/session_01Ly1xEwP5pfsLrtTCTKBQE31 parent 515559e commit 3b921e6
3 files changed
Lines changed: 610 additions & 200 deletions
File tree
- docs/development
- internal/release
- website/layouts/_default
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
103 | 103 | | |
104 | 104 | | |
105 | 105 | | |
106 | | - | |
| 106 | + | |
107 | 107 | | |
108 | 108 | | |
109 | 109 | | |
110 | 110 | | |
111 | | - | |
112 | | - | |
113 | | - | |
114 | | - | |
115 | | - | |
116 | | - | |
117 | | - | |
118 | | - | |
119 | | - | |
120 | | - | |
121 | | - | |
122 | | - | |
123 | | - | |
124 | | - | |
125 | | - | |
126 | | - | |
127 | | - | |
128 | | - | |
129 | | - | |
130 | | - | |
131 | | - | |
132 | | - | |
133 | | - | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
134 | 157 | | |
135 | 158 | | |
0 commit comments