Add list-dependents subcommand for snippet/CSV preview workflow#3220
Add list-dependents subcommand for snippet/CSV preview workflow#3220theletterf wants to merge 3 commits intomainfrom
Conversation
Surfaces "which markdown pages would re-render if this snippet/CSV
changes?" so the docs-actions preview workflow can render preview URLs
on PRs that only edit non-page files. IncludeGraph walks {{include}}
and {{csv-include}} directives across pages and snippets, then resolves
transitive snippet→snippet→page chains.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@docs/cli/docset/list-dependents.md`:
- Around line 16-18: Add a language identifier to the fenced code block that
contains the usage string "docs-builder list-dependents --files <paths>
[options...] [-h|--help] [--version]" by changing the opening fence from ``` to
```bash so the block is recognized as Bash and resolves MD040.
In
`@src/authoring/Elastic.Documentation.Refactor/Tracking/ListDependentsService.cs`:
- Around line 52-55: The current logic in ListDependentsService uses format to
choose RenderText or RenderJson and silently treats unknown values as JSON; add
a guard that explicitly checks supported formats (e.g., if format equals "text"
or "json" using StringComparison.OrdinalIgnoreCase) and if not supported write
an error to Console.Error (or throw an ArgumentException) and return early; keep
the happy path last so the code calls RenderText(results) when format is "text"
and RenderJson(results) when format is "json" only after the validation guard.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: cd7f66c2-15ed-41cc-b059-fa28fbbda903
📒 Files selected for processing (8)
docs/_docset.ymldocs/cli/docset/index.mddocs/cli/docset/list-dependents.mdsrc/Elastic.Markdown/IO/IncludeGraph.cssrc/authoring/Elastic.Documentation.Refactor/Tracking/ListDependentsService.cssrc/tooling/docs-builder/Commands/ListDependentsCommand.cssrc/tooling/docs-builder/Program.cstests/Elastic.Markdown.Tests/FileInclusion/IncludeGraphTests.cs
- Tag the usage code fence as bash so it satisfies markdownlint MD040. - Reject unsupported --format values explicitly with a guard clause rather than silently falling back to JSON, so typos in CI or local use surface as errors. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Adds a new docs-builder list-dependents CLI subcommand to resolve which page markdown files transitively depend on changed snippet (_snippets/*.md) or CSV inputs, enabling preview workflows to produce meaningful entry-point URLs even when no publishable pages were directly edited.
Changes:
- Introduces
IncludeGraphto build a reverse include/csv-include dependency graph across pages and snippets. - Adds
list-dependentscommand + service to compute dependents and output them as JSON (default) or text. - Adds unit tests and CLI documentation + docset navigation entries for the new subcommand.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| tests/Elastic.Markdown.Tests/FileInclusion/IncludeGraphTests.cs | Adds unit coverage for direct + transitive snippet dependents and CSV include dependents. |
| src/tooling/docs-builder/Program.cs | Registers the new list-dependents subcommand. |
| src/tooling/docs-builder/Commands/ListDependentsCommand.cs | Implements the CLI entrypoint that wires args into the service layer. |
| src/authoring/Elastic.Documentation.Refactor/Tracking/ListDependentsService.cs | Implements dependent-resolution, input path normalization, and JSON/text rendering. |
| src/Elastic.Markdown/IO/IncludeGraph.cs | New reverse-dependency graph builder and BFS resolver for page-level dependents. |
| docs/cli/docset/list-dependents.md | Documents usage/options/output format for list-dependents. |
| docs/cli/docset/index.md | Links the new command in the docset CLI index. |
| docs/_docset.yml | Adds the new doc page to the docs site TOC. |
| Console.Out.WriteLine(output); | ||
|
|
||
| var totalDependents = results.Sum(r => r.Dependents.Count); | ||
| _logger.LogInformation( | ||
| "Resolved {Inputs} input(s) → {Pages} page dependents", results.Length, totalDependents); | ||
| return true; |
There was a problem hiding this comment.
list-dependents is documented as emitting JSON (default), but the CLI pipeline will also write non-JSON content to stdout (e.g., this service’s LogInformation plus the tooling’s console diagnostics summary printed at shutdown). With the current logging/diagnostics setup, stdout will not be valid JSON for downstream consumers. Consider isolating machine output (e.g., route logs/diagnostics to stderr, suppress them for --format json, or add a dedicated --quiet/--no-diagnostics mode and document it).
Why
The preview workflow in elastic/docs-actions builds a preview on every PR and posts a comment listing per-page URLs. Today the URL list is derived from the changed
.mdfiles. When a PR only edits snippets (_snippets/*.md) or CSV data, the list is empty — snippets aren't published pages, so contributors editing shared content get a preview with no obvious entry points.The mapping "snippet
_snippets/foo.mdis included by pages X, Y, Z" only exists inside the markdown parser. Reimplementing it in the action layer (grep, regex) misses path-resolution rules, csv-includes, and transitive snippet→snippet chains. So the dependency walk has to live next to the parser, exposed as a CLI the action can shell out to.What
New
docs-builder list-dependentssubcommand. Builds the documentation set withNoopCrossLinkResolver(no network), parses pages and snippets, capturesIncludeBlock/CsvIncludeBlockdescendants, and resolves transitive chains to produce the page-level dependents as JSON (default) or text.Build, serve, format, and other workflows are unaffected: this is a new read-only subcommand only invoked when explicitly called.
Companion PR + merge order
The matching change in
docs-actionsthat wires this into the preview-comment workflow lives in elastic/docs-actions#120 (draft).ghcr.io/elastic/docs-builder:edgeto be republisheddocker run … list-dependentsinvocation depends on the new subcommand existing in the:edgeimage.