diff options
| -rw-r--r-- | abusectl/cli.py | 6 | ||||
| -rw-r--r-- | abusectl/init.py | 6 | ||||
| -rw-r--r-- | tests/test_init.py | 27 |
3 files changed, 35 insertions, 4 deletions
diff --git a/abusectl/cli.py b/abusectl/cli.py index 36a12ec..3065c34 100644 --- a/abusectl/cli.py +++ b/abusectl/cli.py @@ -128,7 +128,7 @@ def _pick_hops(hops: list[str]) -> list[str]: while True: picks = _ask( - "\nWhich of these are YOUR OWN servers? (comma-separated numbers): " + "\nWhich of these are YOUR OWN servers? (comma-separated numbers, required): " ) chosen = [] for token in picks.split(","): @@ -164,7 +164,7 @@ def _ask_relays() -> list[str]: while True: answer = _ask( - f"Your relays as CIDRs, or a provider name ({known}): " + f"Your relays as CIDRs, or a provider name, required ({known}): " ) if not answer: print(" Needed: a CIDR such as 192.0.2.0/24, or a provider name.") @@ -256,7 +256,7 @@ def _prompt_answers(sample: Path | None) -> dict: else: trusted_relays = _ask_relays() - cases = _ask(f"\nCases directory [{config.DEFAULT_CASES}]: ") + cases = _ask(f"\nCases directory (Enter for {config.DEFAULT_CASES}): ") return {"trusted_relays": trusted_relays, "cases": cases, **_ask_reporter()} diff --git a/abusectl/init.py b/abusectl/init.py index 626dd41..27a4385 100644 --- a/abusectl/init.py +++ b/abusectl/init.py @@ -306,7 +306,11 @@ def _preserved_sections(path: pathlib.Path, built: set) -> str: lines = text.splitlines(keepends=True) kept = [] - skipping = False + # Skip until the first table: text before it is build()'s own preamble, + # which this run has already rendered. Carrying it duplicated the header + # on every re-init, and a comment block trailing the last table rode + # along with it. + skipping = True for line in lines: stripped = line.strip() if stripped.startswith("[") and stripped.endswith("]"): diff --git a/tests/test_init.py b/tests/test_init.py index 46b1a26..4f2042c 100644 --- a/tests/test_init.py +++ b/tests/test_init.py @@ -321,3 +321,30 @@ class TestWriteGuard(unittest.TestCase): if __name__ == "__main__": unittest.main() + + +class TestRepeatedInit(unittest.TestCase): + """build()'s own preamble and footer must not accrete across rewrites. + + Found by hand test, not by the suite: a single rewrite looks fine, and + the file still parses, so only the third run makes it obvious. The + carried text is build()'s, not the user's, so preserving it duplicated + the header once per run. + """ + + def test_the_preamble_and_footer_survive_four_rewrites_exactly_once(self): + answers = {"trusted_relays": ["192.0.2.0/24"], "cases": ""} + with tempfile.TemporaryDirectory() as tmp: + path = pathlib.Path(tmp) / "config.toml" + init.write(path, answers) + path.write_text( + path.read_text() + '\n[misp]\napi_key = "SECRET"\n' + ) + for _ in range(3): + init.write(path, answers, force=True) + + text = path.read_text() + self.assertEqual(text.count("# abusectl configuration."), 1) + 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") |
