diff --git a/hermes_cli/update_cmd_maint.py b/hermes_cli/update_cmd_maint.py index fe7434ad72..3e23f39d46 100644 --- a/hermes_cli/update_cmd_maint.py +++ b/hermes_cli/update_cmd_maint.py @@ -36,6 +36,7 @@ _STALE_PURGE_PROTECTED = frozenset( "hermes_cli", "hermes_cli.main", "hermes_cli.update_cmd", + "hermes_cli.update_receipt", "hermes_cli.hermes_logging", } # The updater's own split modules are executing too. diff --git a/tests/hermes_cli/test_update_stale_module_purge.py b/tests/hermes_cli/test_update_stale_module_purge.py index b864bfdf84..11b4f102c8 100644 --- a/tests/hermes_cli/test_update_stale_module_purge.py +++ b/tests/hermes_cli/test_update_stale_module_purge.py @@ -16,6 +16,8 @@ module graph from the updated checkout. from __future__ import annotations +import importlib +import json import sys import types @@ -82,6 +84,31 @@ def test_purge_protects_executing_modules(): assert "hermes_cli" in sys.modules +def test_purge_preserves_active_update_receipt(tmp_path, monkeypatch): + """A receipt begun before the post-pull purge must still be finalizable.""" + import hermes_cli.update_receipt as receipt + + receipt_dir = tmp_path / "update_receipts" + monkeypatch.setattr(receipt, "_receipt_dir", lambda: receipt_dir) + receipt._current = None + post_purge_receipt = receipt + try: + receipt.begin_update_receipt() + receipt.record_step("git_pull", True, "updated checkout") + + cli_main._purge_stale_hermes_modules() + post_purge_receipt = importlib.import_module("hermes_cli.update_receipt") + path = post_purge_receipt.finalize_update_receipt("success") + + assert path is not None and path.is_file() + latest = json.loads((receipt_dir / "latest.json").read_text(encoding="utf-8")) + assert latest["outcome"] == "success" + assert latest["steps"][0]["name"] == "git_pull" + finally: + receipt._current = None + post_purge_receipt._current = None + + def test_purge_leaves_prefix_lookalikes_alone(): # `gateway_foo` starts with the string prefix "gateway" but is NOT the # gateway package — the root-segment check must spare it.