fix(pm): resolve the install stamp in pm.paths so sealed stages can read it
b207701287 routed PM's stamp reads through hermes_cli.steward.install_stamp_path.
The Docker runtime base runs PM before hermes_cli ships (only __init__ and
runtime_state are copied), so ensure() died with No module named
'hermes_cli.steward'. The resolver is an install-root path built only on
pm.paths.install_root/repo_root; move it there and point every reader at it.
This commit is contained in:
@@ -186,7 +186,7 @@ def step_adopt_blessed_checkout(project_root: Path | None = None) -> dict:
|
||||
|
||||
if not (root / ".git").exists():
|
||||
return {"ok": True, "skipped": "not-a-checkout"}
|
||||
from hermes_cli.steward import install_stamp_path
|
||||
from pm.paths import install_stamp_path
|
||||
stamp_path = install_stamp_path(root)
|
||||
if stamp_path.exists():
|
||||
return {"ok": True, "skipped": "already-stamped"}
|
||||
|
||||
@@ -24,7 +24,6 @@ import sys
|
||||
from pathlib import Path
|
||||
from typing import Optional
|
||||
|
||||
BUILD_INFO_NAME = "install-stamp.json"
|
||||
UPDATE_MECHANISMS = ("self", "app-installer", "electron-updater", "external", "microsoft-store")
|
||||
|
||||
STEWARD_DESKTOP = "desktop-app"
|
||||
@@ -177,23 +176,6 @@ def steward_uninstall_message(steward: str, platform: "str | None" = None) -> st
|
||||
return _STEWARD_UNINSTALL_FALLBACK.format(steward=steward)
|
||||
|
||||
|
||||
def install_stamp_path(project_root: Path) -> Path:
|
||||
"""THE stamp location for ``project_root``, shared by every stamp reader.
|
||||
|
||||
Beside the code in checkouts, Docker and desktop payloads. A Nix package
|
||||
bakes the stamp outside the store's package dir and its wrapper carries
|
||||
``HERMES_INSTALL_ROOT`` for the executing tree only — so the executing
|
||||
tree resolves through pm.paths.install_root, any other tree is taken
|
||||
literally. Two resolvers here once classified Nix as "unknown".
|
||||
"""
|
||||
from pm.paths import install_root, repo_root
|
||||
|
||||
root = Path(project_root)
|
||||
if root.resolve() == repo_root():
|
||||
root = install_root()
|
||||
return root / BUILD_INFO_NAME
|
||||
|
||||
|
||||
def read_install_stamp(project_root: Path) -> dict:
|
||||
"""The build stamp of ``project_root``, or ``{}``.
|
||||
|
||||
@@ -201,6 +183,8 @@ def read_install_stamp(project_root: Path) -> dict:
|
||||
path on a malformed stamp — a tree we cannot prove is ours still
|
||||
refuses (see :func:`sealed_steward`), so garbage degrades safely.
|
||||
"""
|
||||
from pm.paths import install_stamp_path
|
||||
|
||||
try:
|
||||
data = json.loads(install_stamp_path(project_root).read_text(encoding="utf-8-sig"))
|
||||
except (OSError, ValueError):
|
||||
|
||||
@@ -32,7 +32,8 @@ def _is_sealed(project_root: Path) -> bool:
|
||||
"""
|
||||
if (project_root / ".git").exists():
|
||||
return False
|
||||
from hermes_cli.steward import install_stamp_path, read_install_stamp
|
||||
from hermes_cli.steward import read_install_stamp
|
||||
from pm.paths import install_stamp_path
|
||||
stamp_path = install_stamp_path(project_root)
|
||||
data = read_install_stamp(project_root)
|
||||
if not data:
|
||||
|
||||
@@ -109,9 +109,8 @@ def _calver_release_version(repo_dir: Path) -> tuple[str, int] | None:
|
||||
# --- Install stamp reader ---------------------------------------------------
|
||||
|
||||
def _resolve_stamp_file() -> Path | None:
|
||||
"""The executing tree's stamp (steward.install_stamp_path owns the location)."""
|
||||
from hermes_cli.steward import install_stamp_path
|
||||
from pm.paths import repo_root
|
||||
"""The executing tree's stamp (pm.paths.install_stamp_path owns the location)."""
|
||||
from pm.paths import install_stamp_path, repo_root
|
||||
|
||||
p = install_stamp_path(repo_root())
|
||||
return p if p.is_file() else None
|
||||
|
||||
@@ -107,7 +107,7 @@ def store_root(project_root: Path) -> Path:
|
||||
if not store.is_relative_to(root.parent):
|
||||
raise RuntimeError("payload store escapes its root")
|
||||
return store
|
||||
from hermes_cli.steward import install_stamp_path
|
||||
from pm.paths import install_stamp_path
|
||||
|
||||
for directory in (root, *root.parents):
|
||||
stamp = install_stamp_path(directory)
|
||||
|
||||
16
pm/paths.py
16
pm/paths.py
@@ -18,6 +18,22 @@ def install_root() -> Path:
|
||||
return Path(env) if env else repo_root()
|
||||
|
||||
|
||||
def install_stamp_path(project_root: Path) -> Path:
|
||||
"""THE stamp location for ``project_root``, shared by every stamp reader.
|
||||
|
||||
Beside the code in checkouts, Docker and desktop payloads. A Nix package
|
||||
bakes the stamp outside the store's package dir and its wrapper carries
|
||||
``HERMES_INSTALL_ROOT`` for the executing tree only — so the executing
|
||||
tree resolves through install_root, any other tree is taken literally.
|
||||
PM reads it in sealed stages (the Docker runtime base) before hermes_cli
|
||||
ships, so it lives here rather than beside the stewards.
|
||||
"""
|
||||
root = Path(project_root)
|
||||
if root.resolve() == repo_root():
|
||||
root = install_root()
|
||||
return root / "install-stamp.json"
|
||||
|
||||
|
||||
def lockfile_path() -> Path:
|
||||
return Path(__file__).resolve().parent / "lock.json"
|
||||
|
||||
|
||||
@@ -61,7 +61,7 @@ def _resident_runtime() -> tuple[Path, Path] | None:
|
||||
if payload is not None:
|
||||
runtime = payload / "pm-runtime"
|
||||
else:
|
||||
from hermes_cli.steward import install_stamp_path
|
||||
from pm.paths import install_stamp_path
|
||||
|
||||
stamp_path = install_stamp_path(project)
|
||||
try:
|
||||
|
||||
@@ -23,7 +23,7 @@ def embedded_context(tmp_path, monkeypatch):
|
||||
"""Running tree = sealed desktop-app; legacy checkout at the managed root."""
|
||||
bundle = tmp_path / "bundle" / "repo"
|
||||
bundle.mkdir(parents=True)
|
||||
# The code-scoped stamp (hermes_cli.steward.BUILD_INFO_NAME).
|
||||
# The code-scoped stamp (pm.paths.install_stamp_path).
|
||||
(bundle / "install-stamp.json").write_text(
|
||||
json.dumps({"commit": "a" * 40, "distribution": "desktop-app", "updateMechanism": "electron-updater"})
|
||||
)
|
||||
|
||||
@@ -68,7 +68,7 @@ def _fake_project_root(monkeypatch, tmp_path: Path, *, git: bool, distribution:
|
||||
if git:
|
||||
(root / ".git").mkdir()
|
||||
if distribution is not None:
|
||||
# The code-scoped stamp (see hermes_cli.steward.BUILD_INFO_NAME).
|
||||
# The code-scoped stamp (see pm.paths.install_stamp_path).
|
||||
(root / "install-stamp.json").write_text(
|
||||
json.dumps({"distribution": distribution, "updateMechanism": "external"})
|
||||
, encoding="utf-8")
|
||||
|
||||
Reference in New Issue
Block a user