Refactor/tpl text template migration#109
Merged
Merged
Conversation
Add the design spec for migrating the multi-line block templates in internal/assets/tpl/tpl_*.go off fmt.Sprintf format-string constants to Go text/template + embedded files, and wire its reference into the line-252 task. Three tiers: (1) multi-line documents/scripts/config -> one embedded file each, parsed at init into *template.Template handles (no magic name literals at call sites); (2) the recall <details>/<table> HTML assembly -> two data-driven block templates (metaTable, details) that delete the scattered paired-tag constants; (3) single-line format strings, pure positional joins, and the RecallListRow meta-format stay fmt.Sprintf. No-panic init parse, gated by TestTemplatesParse. Behavior-preserving, asserted by byte-for-byte golden tests. Spec: specs/tpl-text-template-migration.md Signed-off-by: Jose Alekhinne <jose@ctx.ist>
First slice of the tpl migration (task 252): stand up the rendering
pipeline and convert ObsidianReadme as the proof-of-pattern.
- internal/assets/tpl: tpl-local //go:embed templates/*, a Render
helper generalizing message/render.go, and an init parse table.
parseTemplate returns a non-nil template even on failure (recording
the cause in parseErrs) so Render never panics on a nil handle;
TestTemplatesParse turns a malformed template into a CI failure
instead -- no template.Must, per the no-panic invariant.
- ObsidianReadme is now a *template.Template handle; obsidian/vault.go
renders via tpl.Render(tpl.ObsidianReadme, tpl.ObsidianData{...}),
passing a typed struct (no map-key literal) so the non-exempt caller
stays magic-string clean.
- File split honors the audit: exported funcs in render.go, unexported
loader in load.go, the data type in types.go.
- TestObsidianReadmeMatchesLegacy keeps the pre-migration format string
verbatim and asserts byte-for-byte identical render output.
- Spec refined: embed is tpl-local (leaf package, cycle avoidance),
not assets.FS.
Spec: specs/tpl-text-template-migration.md
Signed-off-by: Jose Alekhinne <jose@ctx.ist>
…cision
Chunk 1 of the tpl migration (task 252): the four straightforward
interpolated block templates move to embedded files behind handles.
- New templates/{journal-site-readme.md,trigger-script.sh,learning.md,
decision.md}.tmpl; the consts are deleted (tpl_trigger.go, which held
only TriggerScript, is removed entirely).
- TriggerScript drops fmt's positional %[1]s/%[2]s for {{.Name}}/
{{.Type}}; Decision drops the repeated-%s title for {{.Title}} twice
-- both eliminate positional-argument fragility.
- Render returns (string, error), so the bare-string helpers it now
feeds gain an error return: generate.SiteReadme, format.Learning,
format.Decision, with callers (journal/cmd/site, entry/write)
propagating. trigger/cmd/add renders inline; its fmt import is gone.
- Golden tests keep each legacy format string verbatim and assert
byte-for-byte identical output.
Spec: specs/tpl-text-template-migration.md
Signed-off-by: Jose Alekhinne <jose@ctx.ist>
Chunk 2 (task 252): ZensicalProject and ZensicalTheme were static multi-line consts (zero interpolation), so they move to embedded .toml files loaded verbatim as string vars at init via loadStatic (no text/template parse). Call sites are unchanged -- a string var swaps in for a string const transparently, so generate.ZensicalToml output stays identical. - Bodies extracted from the consts byte-for-byte (written by Go, not retyped); consts removed from tpl_journal.go (ZensicalExtraCSS, a one-liner, stays Tier-3). - embed glob extended to templates/*.toml; loadStatic added (no parse). - TestZensicalStaticLoaded pins the loaded blocks structurally; the generate package's ZensicalToml tests cover full output end-to-end. Spec: specs/tpl-text-template-migration.md Signed-off-by: Jose Alekhinne <jose@ctx.ist>
Chunk 3 (task 252): the Ralph-loop bash script -- the composed
template -- moves to an embedded file.
- templates/loop-script.sh.tmpl absorbs LoopMaxIter as a {{if .MaxIter}}
block (replacing the Go-side maxIterCheck pre-format) and inlines
LoopNotify literally at both completion points; the LoopScript,
LoopMaxIter, and LoopNotify consts are removed. LoopCmd*/Load* stay
Tier-3 (script.go still selects the tool command and passes it as
{{.AICommand}}).
- script.Generate returns (string, error); its sole caller
(loop/cmd/root) propagates. filepath.Abs's error -- previously
discarded -- is now handled, since the signature already carries one.
- Verified by golden fixtures captured from the legacy code path
(testdata/*.golden): byte-for-byte across the iteration-cap on/off
branch and each tool.
Spec: specs/tpl-text-template-migration.md
Signed-off-by: Jose Alekhinne <jose@ctx.ist>
Chunk 4 (task 252, final): the recall formatter's <details>/<table>
blocks move from scattered paired-tag constants to two embedded block
templates, completing the migration.
- metaTable template ({Summary, Rows}) replaces MetaDetailsOpen +
per-row MetaRow + MetaDetailsClose in source/format (metadata and
token-stats tables): format.go builds a typed row slice (conditional
Branch/Model/Parts rows) and renders once instead of scattering
conditional Fprintf calls.
- details template ({Summary, Body}) replaces RecallDetailsOpen/Close
and RecallPlanOpen/Close across three sites: the plan block, the
collapsed tool-result block (format.go), and collapse.ToolOutputs.
Seven paired-tag consts are deleted; PlanSummary stays (Tier-3).
- tpl.RenderOr added for best-effort string builders whose callers
don't return errors (the recall formatter, the Import counter): it
logs warn.TemplateRender and returns a fallback on the parse-gated-
impossible error rather than contorting those signatures. The
error-returning tpl.Render still serves chunks 1-3.
- Byte-for-byte goldens captured from the legacy code path cover the
metadata table (all conditional rows), the plan block, fenced +
collapsed tool results, and the collapse wrap path.
Closes task 252.
Spec: specs/tpl-text-template-migration.md
Signed-off-by: Jose Alekhinne <jose@ctx.ist>
The spec described only the error-returning Render. The implementation added tpl.RenderOr for best-effort string builders (the recall formatter, the Import counter) whose signatures should not grow an error return for a parse-gated, unreachable branch: it logs warn.TemplateRender and falls back, mirroring message/render.go. Update the Rendering-helper subsection (both entry points), the Error Handling table (by caller shape), the exec-error edge case, and add Settled Decision 5 recording the split. Spec: specs/tpl-text-template-migration.md Signed-off-by: Jose Alekhinne <jose@ctx.ist>
Bring the non-error-handling sections in line with what shipped:
- Happy Path: templates load from the tpl-local embedded FS, not
assets.FS (already stated in Approach + Decision 4).
- Whitespace-fidelity edge case: the templates reproduce exact bytes
with plain {{range}}/{{if}} + literal newlines + no-trailing-newline
files; no {{-/-}} trimming was needed.
- metaTable input is MetaTableData{Summary; Rows []MetaRow}.
- Files table: separate meta-table.html.tmpl / details.html.tmpl (not
one blocks.tmpl); the tpl package is split render.go/load.go/
static.go/types.go, and TestTemplatesParse is an in-package test
reading parseErrs (no exported ParseErrors()).
Spec: specs/tpl-text-template-migration.md
Signed-off-by: Jose Alekhinne <jose@ctx.ist>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.