fix: dist export erzeugt die TOC-Region nach dem Marker-Strip neu (CI-Fund im Export-Replay)
Files changed: - CHANGES.md - VERSION - tools/chemenu/commands/dist_cmd.py - tools/chemenu/tests/test_dist_cmd.py
This commit is contained in:
+13
-1
@@ -35,7 +35,7 @@ dev-checkout concern - readable here, never shipped as something to parse.
|
||||
|
||||
---
|
||||
|
||||
## 5.0.0-beta.2 - 2026-09-09 - tools/CONTRACT.md: docs toc im Fehlerkontrakt, docs-verify-Zeile nennt die TOC-Pruefung; tools/README.md korrigiert das --major-Kriterium
|
||||
## 5.0.0-beta.3 - 2026-09-09 - dist export erzeugt die TOC-Region nach dem Marker-Strip neu (CI-Fund im Export-Replay)
|
||||
|
||||
**Author:** Torben Nehmer
|
||||
|
||||
@@ -55,6 +55,7 @@ dev-checkout concern - readable here, never shipped as something to parse.
|
||||
- Ausgelieferte Doku zitiert keine Issue-Nummern mehr, docs verify prueft es (schliesst #77)
|
||||
- TOC-Pflicht fuer Referenzdateien ueber 100 Zeilen; session-setup.md/gates.md nennen die tatsaechliche Budget-Ausnahmeliste (schliesst #73, #76)
|
||||
- tools/CONTRACT.md: docs toc im Fehlerkontrakt, docs-verify-Zeile nennt die TOC-Pruefung; tools/README.md korrigiert das --major-Kriterium
|
||||
- dist export erzeugt die TOC-Region nach dem Marker-Strip neu (CI-Fund im Export-Replay)
|
||||
<!-- /wikitool:bumps -->
|
||||
|
||||
**Migration:** none required - Betrifft nur AGENTS.md, die Stage-/Collection-Contracts und instructions/; kb/-Inhalt bleibt unberuehrt, keine Migration noetig.
|
||||
@@ -917,6 +918,17 @@ zählt wie jedes mutierende Kommando. Beide Dateien verweisen jetzt auf die List
|
||||
in `tools/CONTRACT.md`, statt sie mit einer falschen Faustregel zu umschreiben.
|
||||
Kein Versionsbezug — reine Prosa-Korrektur, im selben Bump mitgeführt.
|
||||
|
||||
Nachgezogen in `-beta.3`: `dist export` erzeugt die TOC-Region jetzt **nach**
|
||||
dem Marker-Strip neu. Ein `<!-- dist:strip-start/end -->`-Block kann eine ganze
|
||||
Sektion umschließen — der in `AGENTS.md` umschließt `## Developing this stack` —,
|
||||
sodass die ausgelieferte Datei eine Überschrift weniger hat, als das im
|
||||
Arbeitsbaum erzeugte Inhaltsverzeichnis auflistet. Die frische Instanz wäre
|
||||
damit beim allerersten `docs verify` über eine Datei gefallen, die niemand
|
||||
angefasst hat. Gefunden hat das die CI im Export-Replay („The distribution works
|
||||
as a fresh instance"), nicht `pytest` und nicht `docs verify` im Arbeitsbaum —
|
||||
beide sehen den gestrippten Text nie. Der Regressionstest sitzt jetzt in
|
||||
`test_dist_cmd.py`.
|
||||
|
||||
Nachgezogen in `-beta.2`, weil `docs verify` die eigene Dokumentationstreue nur
|
||||
für die *Existenz* einer Kommandozeile prüft, nicht für deren Inhalt: die
|
||||
`docs verify`-Zeile in `tools/CONTRACT.md` nennt jetzt die TOC-Prüfung, die
|
||||
|
||||
@@ -45,7 +45,16 @@ from typing import Callable, NamedTuple, Optional, Union
|
||||
|
||||
import typer
|
||||
|
||||
from chemenu import config, conventions, kb_collections, kb_state, ownership, version as version_mod
|
||||
from chemenu import (
|
||||
blocks,
|
||||
config,
|
||||
conventions,
|
||||
kb_collections,
|
||||
kb_state,
|
||||
ownership,
|
||||
toc,
|
||||
version as version_mod,
|
||||
)
|
||||
from chemenu.commands._util import console, fail, rel_path, success, today_iso
|
||||
|
||||
app = typer.Typer(help="Build a distributable copy of the wiki machinery.")
|
||||
@@ -213,7 +222,18 @@ def _read_planned_file(path: Path, label: str) -> PlannedFile:
|
||||
if path.suffix != ".md":
|
||||
return PlannedFile(text, executable)
|
||||
_validate_markers(text, label)
|
||||
return PlannedFile(strip_markers(text), executable)
|
||||
stripped = strip_markers(text)
|
||||
# A table-of-contents region describes the file it sits in, and stripping
|
||||
# just changed that file: `AGENTS.md`'s marked block wraps the whole
|
||||
# `## Developing this stack` section, so the shipped copy has one heading
|
||||
# fewer than the working tree's TOC lists. Regenerating here - after the
|
||||
# strip, on the text that actually ships - is what keeps a fresh
|
||||
# instance's own `docs verify` green on the very first run. A file with
|
||||
# no region, or one the strip pushed under the threshold, is handled by
|
||||
# `toc.upsert` itself.
|
||||
if blocks.find(stripped, toc.REGION_NAME) is not None:
|
||||
stripped = toc.upsert(stripped)
|
||||
return PlannedFile(stripped, executable)
|
||||
|
||||
|
||||
def _copy_tree(
|
||||
|
||||
@@ -12,7 +12,7 @@ from pathlib import Path
|
||||
import pytest
|
||||
import typer
|
||||
|
||||
from chemenu import config, version as version_mod
|
||||
from chemenu import config, toc, version as version_mod
|
||||
from chemenu.commands import dist_cmd
|
||||
|
||||
|
||||
@@ -183,6 +183,36 @@ def test_plan_strips_markers_but_keeps_surrounding_content(repo):
|
||||
assert "Knowledge base (vendored)" not in agents
|
||||
|
||||
|
||||
def test_plan_refreshes_a_table_of_contents_after_stripping(repo):
|
||||
"""A marked block can wrap a whole section - the real `AGENTS.md`'s wraps
|
||||
`## Developing this stack` - so the shipped copy has one heading fewer
|
||||
than the working tree's TOC lists. The plan regenerates the region on the
|
||||
stripped text; without that, a fresh instance's very first `docs verify`
|
||||
fails on a file nobody touched, which is how CI's export replay caught
|
||||
this and pytest did not."""
|
||||
path = repo / "AGENTS.md"
|
||||
filler = "\n".join(f"Line {i}." for i in range(120))
|
||||
path.write_text(
|
||||
"# AGENTS\n\nCore rules.\n\n"
|
||||
f"## Kept\n\n{filler}\n\n"
|
||||
"<!-- dist:strip-start -->\n"
|
||||
"## Dev only\n\nNot shipped.\n"
|
||||
"<!-- dist:strip-end -->\n\n"
|
||||
"## Changelog\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
# The region as `docs toc --apply` writes it in the working tree, where
|
||||
# the stripped section is still present and so belongs in the TOC.
|
||||
path.write_text(toc.upsert(path.read_text(encoding="utf-8")), encoding="utf-8")
|
||||
assert "[Dev only](#dev-only)" in path.read_text(encoding="utf-8")
|
||||
|
||||
agents = dist_cmd.build_plan()["AGENTS.md"].content
|
||||
assert "## Dev only" not in agents
|
||||
assert "[Dev only](#dev-only)" not in agents
|
||||
assert "[Kept](#kept)" in agents
|
||||
assert "[Changelog](#changelog)" in agents
|
||||
|
||||
|
||||
def test_plan_excludes_venv_and_pycache(repo):
|
||||
plan = dist_cmd.build_plan()
|
||||
assert not any(".venv" in relative for relative in plan)
|
||||
|
||||
Reference in New Issue
Block a user