Skip to content

Commit 84fb093

Browse files
cursoragentjmjava
andcommitted
Fail closed on nested docgen.yaml mappings and empty lint/compose
Reject list or scalar values for dirs, segments, visual_map, and related keys. segments.all must be a YAML list. lint and compose error when there are no segment ids to process. Co-authored-by: jmjava <jmjava@gmail.com>
1 parent 26122f6 commit 84fb093

8 files changed

Lines changed: 320 additions & 39 deletions

File tree

‎milestones/README.md‎

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,14 @@ repositories that install `docgen` and maintain their own demo bundle. The
55
library no longer ships an in-repo dogfood; consumers are the integration test
66
of record.
77

8-
**Active:** **[manim-lint-config.md](manim-lint-config.md)** — missing
9-
`scenes.py` must fail `validate`; invalid `docgen.yaml` must not traceback
10-
or be rewritten as `{}`; TTS empty-all must not succeed.
8+
**Active:** **[config-mapping-keys.md](config-mapping-keys.md)** — nested
9+
`docgen.yaml` mapping/list keys must not traceback; lint/compose empty-all
10+
must not succeed.
1111

1212
**Shipped:**
13+
- **[manim-lint-config.md](manim-lint-config.md)** — missing `scenes.py`
14+
fails validate; invalid `docgen.yaml` is `ConfigError`; TTS empty-all
15+
fails (#82).
1316
- **[wizard-narration-paths.md](wizard-narration-paths.md)** — wizard
1417
generate-narration must not drop missing sources; timestamps must not wipe
1518
corrupt `timing.json` (#81).

‎milestones/config-mapping-keys.md‎

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# Milestone — Nested config mappings and empty lint/compose
2+
3+
**Goal:** Nested `docgen.yaml` keys that must be mappings or lists must not
4+
traceback (`AttributeError` / `TypeError`). `docgen lint` and `docgen compose`
5+
must not exit 0 when there are no segments to process.
6+
7+
**Branch / PR:** `cursor/config-mapping-keys-2ccd`
8+
9+
Follows **[manim-lint-config.md](manim-lint-config.md)** (#82).
10+
11+
## Shipped
12+
13+
- [x] `dirs`, `segments`, `visual_map`, `tts`, `manim`, `validation`, and
14+
related keys reject list/scalar values (`ConfigError`)
15+
- [x] `segments.all` / `segments.default` must be YAML lists (a string is not
16+
iterated as characters)
17+
- [x] Null mapping keys still mean “use defaults”
18+
- [x] `docgen lint` with empty `segments.all` (no `--segment`) is an error
19+
- [x] `docgen compose` with no remaining segment ids is an error
20+
21+
## Not this milestone
22+
23+
- Missing recordings stay a pre-push **warning**
24+
- `timestamps` with empty `segments.all` still leaves `timing.json`
25+
unchanged (#78)
26+
- Archived Playwright / Embabel / slides

‎src/docgen/cli.py‎

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -499,6 +499,11 @@ def compose(
499499
"[compose] No segments left after --only-visual-type filter "
500500
f"({', '.join(only_visual_types)})."
501501
)
502+
if not target:
503+
raise click.ClickException(
504+
"[compose] no segments to compose — set segments.default or "
505+
"segments.all, or pass segment ids"
506+
)
502507
click.echo(f"=== Composing {len(target)} segments ===")
503508
composed = comp.compose_segments(target)
504509
mapped = [
@@ -541,7 +546,11 @@ def lint(ctx: click.Context, segment: str | None) -> None:
541546

542547
cfg = _require_config(ctx)
543548
linter = NarrationLinter(cfg)
544-
segments = [segment] if segment else cfg.segments_all
549+
segments = [segment] if segment else list(cfg.segments_all)
550+
if not segments:
551+
raise click.ClickException(
552+
"segments.all is empty — add segment ids in docgen.yaml before lint"
553+
)
545554
issues_total = 0
546555

547556
missing = 0

‎src/docgen/compose.py‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,9 @@ def filter_segments_by_visual_types(
2929
return list(segment_ids)
3030
out: list[str] = []
3131
for sid in segment_ids:
32-
vm = config.visual_map.get(sid, {})
32+
vm = config.visual_map.get(sid)
33+
if not isinstance(vm, dict):
34+
continue
3335
vt = str(vm.get("type", "")).strip().lower()
3436
if vt in allowed:
3537
out.append(sid)

0 commit comments

Comments
 (0)