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
|
**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)
|
- 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)
|
- 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
|
- 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 -->
|
<!-- /wikitool:bumps -->
|
||||||
|
|
||||||
**Migration:** none required - Betrifft nur AGENTS.md, die Stage-/Collection-Contracts und instructions/; kb/-Inhalt bleibt unberuehrt, keine Migration noetig.
|
**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.
|
in `tools/CONTRACT.md`, statt sie mit einer falschen Faustregel zu umschreiben.
|
||||||
Kein Versionsbezug — reine Prosa-Korrektur, im selben Bump mitgeführt.
|
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
|
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
|
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
|
`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
|
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
|
from chemenu.commands._util import console, fail, rel_path, success, today_iso
|
||||||
|
|
||||||
app = typer.Typer(help="Build a distributable copy of the wiki machinery.")
|
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":
|
if path.suffix != ".md":
|
||||||
return PlannedFile(text, executable)
|
return PlannedFile(text, executable)
|
||||||
_validate_markers(text, label)
|
_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(
|
def _copy_tree(
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ from pathlib import Path
|
|||||||
import pytest
|
import pytest
|
||||||
import typer
|
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
|
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
|
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):
|
def test_plan_excludes_venv_and_pycache(repo):
|
||||||
plan = dist_cmd.build_plan()
|
plan = dist_cmd.build_plan()
|
||||||
assert not any(".venv" in relative for relative in plan)
|
assert not any(".venv" in relative for relative in plan)
|
||||||
|
|||||||
Reference in New Issue
Block a user