feat(#1512): remove abandoned generated documentation files#3383
feat(#1512): remove abandoned generated documentation files#3383fullsend-ai-coder[bot] wants to merge 3 commits into
Conversation
Add cleanup logic to the documentation generation process that removes stale generated .adoc files when their corresponding CLI commands, Rego builtins, or Tekton tasks are removed. Each documentation template now includes a generated-file marker comment at the top of each output file. The GenerateAsciidoc function collects all file paths written by the CLI, Rego, and Tekton generators, then scans the pages directory for .adoc files with the marker that were not produced in the current run. These stale files are removed automatically. Handwritten documentation files (which lack the marker) are never touched. The generator functions (GenerateCommandLineDocumentation, GenerateRegoReference, GenerateTektonDocumentation) now return the list of page file paths they wrote, enabling the cleanup logic in the parent GenerateAsciidoc function. Closes #1512
|
🤖 Finished Review · ✅ Success · Started 9:55 AM UTC · Completed 10:06 AM UTC |
Codecov Report❌ Patch coverage is
Flags with carried forward coverage won't be shown. Click here to find out more.
... and 1 file with indirect coverage changes 🚀 New features to boost your workflow:
|
ReviewVerdict: approve Clean, well-structured implementation that correctly addresses #1512. All prior review feedback (marker duplication, premature append, defer-in-loop, logging, error-path test coverage) has been resolved across the three commits. CorrectnessThe cleanup logic in
The The deferred-close-in-loop fix in The append-after-Execute fix in Path construction is consistent between generators (
Tests cover: stale file removal, handwritten file preservation, non-adoc file preservation, mixed scenarios, empty directory, non-existent directory error path, and the SecurityNo concerns. The function operates exclusively on Intent & coherenceThe change precisely matches the scope described in #1512: detect and remove stale generated documentation files when the corresponding CLI commands, Rego builtins, or Tekton tasks are removed. The marker-based approach is a sensible choice — it's simple, deterministic, and leaves handwritten documentation untouched. Style / conventionsFollows project conventions: proper error wrapping with Previous runReview — approveClean, well-structured implementation of stale generated-doc cleanup for #1512. The marker-based approach is sound, the code is correct, and the tests cover the important scenarios. What the PR does
Reviewed dimensions
Findings
|
|
/fs-fix |
|
🤖 Finished Fix · ✅ Success · Started 12:32 PM UTC · Completed 12:53 PM UTC |
Replace defer f.Close() with explicit f.Close() calls in generateRegoReference and generateTektonReference to prevent file handle accumulation during loop iterations. Addresses review feedback on #3383
|
🤖 Finished Review · ✅ Success · Started 12:53 PM UTC · Completed 1:00 PM UTC |
|
|
||
| // GeneratedMarker is the comment placed at the top of generated Asciidoc files | ||
| // to distinguish them from handwritten documentation. | ||
| const GeneratedMarker = "// Generated by conforma CLI documentation tooling. DO NOT EDIT." |
There was a problem hiding this comment.
This marker string is duplicated independently in the Go constant here and in 4 template files (cli.tmpl, rego.tmpl, builtins.tmpl, task.tmpl). If either side drifts, hasGeneratedMarker silently stops matching and stale files accumulate. No test catches this because the tests use the constant directly, never the rendered template output.
Consider injecting the marker via a template function (e.g. {{ generatedMarker }}) so the string lives in one place. That way the constant is the single source of truth and template drift is impossible.
| *generated = append(*generated, docpath) | ||
|
|
||
| return commandTemplate.Execute(f, cmd) |
There was a problem hiding this comment.
This appends docpath to the generated list before commandTemplate.Execute runs. In rego.go and tekton.go, the append happens after Execute succeeds. If Execute fails here, the path ends up in the generated list anyway, so removeAbandonedPages will skip the file even though it wasn't written correctly.
Worth matching the pattern used by the other two generators: append after Execute.
| {{- end }}{{- /* range */ -}} | ||
| {{- end -}}{{- /* "properties" */ -}} | ||
|
|
||
| // Generated by conforma CLI documentation tooling. DO NOT EDIT. |
There was a problem hiding this comment.
No test renders any template and verifies its first output line matches GeneratedMarker. This is especially risky here in rego.tmpl where the marker sits on line 42 of the template source, relying on whitespace trimming to land it at the start of the rendered output. If that trimming behavior changes, the marker moves and hasGeneratedMarker stops matching.
I know this is arguably out of scope, but since you're already modifying this rarely-touched code, a test that renders each template and asserts the first line matches the constant would catch future drift and would leave this code better than you found it.
| if err := os.Remove(path); err != nil { | ||
| return fmt.Errorf("removing abandoned file %q: %w", path, err) | ||
| } |
There was a problem hiding this comment.
This deletes files with no logging. If a handwritten file is mistakenly detected as generated (e.g. someone copies the marker line into a doc), it vanishes with no trace.
A simple stderr log after a successful removal would leave a breadcrumb:
| if err := os.Remove(path); err != nil { | |
| return fmt.Errorf("removing abandoned file %q: %w", path, err) | |
| } | |
| if err := os.Remove(path); err != nil { | |
| return fmt.Errorf("removing abandoned file %q: %w", path, err) | |
| } | |
| fmt.Fprintf(os.Stderr, "Removed abandoned generated file: %s\n", path) |
| entries, err := os.ReadDir(pagesDir) | ||
| if err != nil { | ||
| return fmt.Errorf("reading pages directory %q: %w", pagesDir, err) | ||
| } |
There was a problem hiding this comment.
The os.ReadDir error path here has no test coverage. A test that passes a non-existent pagesDir (e.g. a module path where pages/ doesn't exist) would exercise it and confirm the error wrapping works as expected.
|
/fs-fix |
|
🤖 Finished Fix · ✅ Success · Started 3:49 PM UTC · Completed 4:16 PM UTC |
- Eliminate marker duplication: remove hardcoded marker from all 4 templates (cli.tmpl, rego.tmpl, builtins.tmpl, task.tmpl) and write it programmatically via fmt.Fprintln before template execution. The GeneratedMarker constant is now the single source of truth, passed as a parameter to each generator function. - Fix premature append in cli.go: move generated-path append after successful commandTemplate.Execute so failed writes do not appear in the generated list. - Add logging on abandoned file removal: emit a message to stderr after each successful os.Remove in removeAbandonedPages. - Add test for os.ReadDir error path: verify removeAbandonedPages returns an error when the pages directory does not exist. Addresses review feedback on #3383
|
🤖 Finished Review · ✅ Success · Started 4:17 PM UTC · Completed 4:22 PM UTC |
Add cleanup logic to the documentation generation process that removes stale generated .adoc files when their corresponding CLI commands, Rego builtins, or Tekton tasks are removed.
Each documentation template now includes a generated-file marker comment at the top of each output file. The GenerateAsciidoc function collects all file paths written by the CLI, Rego, and Tekton generators, then scans the pages directory for .adoc files with the marker that were not produced in the current run. These stale files are removed automatically. Handwritten documentation files (which lack the marker) are never touched.
The generator functions (GenerateCommandLineDocumentation, GenerateRegoReference, GenerateTektonDocumentation) now return the list of page file paths they wrote, enabling the cleanup logic in the parent GenerateAsciidoc function.
Closes #1512
Post-script verification
agent/1512-abandoned-doc-removal)d134e495b18cf8493cfea8791e310b58f0320797..HEAD)