diff options
| author | Danilo M. <danix@danix.xyz> | 2026-09-10 11:02:46 +0200 |
|---|---|---|
| committer | Danilo M. <danix@danix.xyz> | 2026-09-10 11:02:46 +0200 |
| commit | a5bf22b9eefa32322b2587ac930e5680d97500be (patch) | |
| tree | 2e84821704a94825d4a7117eac61d576e7aefd9f | |
| parent | ae1b825b458d14cc1fa251a56331767d5fcf4ec6 (diff) | |
| download | abusectl-a5bf22b9eefa32322b2587ac930e5680d97500be.tar.gz abusectl-a5bf22b9eefa32322b2587ac930e5680d97500be.zip | |
fix: restore the footer guard, with the sequence that needs it
The previous commit removed this guard after a mutation check said it was
redundant. The check was wrong: it only exercised runs that skipped the
identity from the start, where [reporter] is never written and the footer
always trails a rendered table.
The sequence that breaks is answering the identity and then re-running and
skipping it. [reporter] is then PRESERVED rather than rendered, so the
footer that trailed it in the old file rides across while this run emits
its own, and the file grows a second copy per run.
Covered by a test naming that sequence, and both guards now fail when
removed.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LByBnw83xr9YP85nskzkyE
| -rw-r--r-- | abusectl/init.py | 7 | ||||
| -rw-r--r-- | tests/test_init.py | 21 |
2 files changed, 28 insertions, 0 deletions
diff --git a/abusectl/init.py b/abusectl/init.py index 27a4385..0e185c0 100644 --- a/abusectl/init.py +++ b/abusectl/init.py @@ -317,6 +317,13 @@ def _preserved_sections(path: pathlib.Path, built: set) -> str: skipping = stripped.lstrip("[").rstrip("]").strip() in built if skipping: continue + # build()'s own footer, not a user comment. It trails whichever + # table came last, so when that table is PRESERVED rather than + # rendered (identity answered once, then skipped on a later run) + # it rides across and this run emits a second copy. + if stripped.startswith("# Later parts of abusectl"): + skipping = True + continue if not skipping: kept.append(line) diff --git a/tests/test_init.py b/tests/test_init.py index 4f2042c..55153f4 100644 --- a/tests/test_init.py +++ b/tests/test_init.py @@ -348,3 +348,24 @@ class TestRepeatedInit(unittest.TestCase): self.assertEqual(text.count("# Later parts of abusectl"), 1) # The unknown section still rides across untouched. self.assertEqual(tomllib.loads(text)["misp"]["api_key"], "SECRET") + + def test_the_footer_survives_an_identity_answered_then_skipped(self): + # The sequence a hand test actually hit, and the one the first fix + # missed: answering the identity, then re-running and skipping it, + # leaves [reporter] PRESERVED rather than rendered, so the footer + # trailing it rides across while this run emits its own. + relays = {"trusted_relays": ["192.0.2.0/24"], "cases": ""} + answered = dict(relays, reporter_name="A Reporter", + reporter_org="example.org", + reporter_email="r@example.org") + with tempfile.TemporaryDirectory() as tmp: + path = pathlib.Path(tmp) / "config.toml" + init.write(path, answered) + init.write(path, relays, force=True) + + text = path.read_text() + self.assertEqual(text.count("# Later parts of abusectl"), 1) + self.assertEqual(text.count("# abusectl configuration."), 1) + self.assertEqual( + tomllib.loads(text)["reporter"]["name"], "A Reporter" + ) |
