aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--abusectl/cli.py6
-rw-r--r--abusectl/init.py6
-rw-r--r--tests/test_init.py27
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")