refactor(update): table-drive the steward refusal rungs
The sealed-tree steward ladder in evaluate_update_admission was four if-rungs that differed only in the install method whose command remediates the tree. A steward -> method table plus one helper replaces them; the refusal code, message and command are unchanged for docker, nix, apt-termux, desktop-app and unknown future stewards.
This commit is contained in:
@@ -12,6 +12,8 @@ from dataclasses import dataclass
|
||||
from pathlib import Path
|
||||
from typing import Callable, Optional
|
||||
|
||||
from hermes_cli.steward import STEWARD_APT_TERMUX, STEWARD_DESKTOP, STEWARD_DOCKER, STEWARD_NIX
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
COMMIT_BUILD_UPDATE_MESSAGE = (
|
||||
@@ -25,7 +27,6 @@ def is_commit_build(project_root: Path) -> bool:
|
||||
return read_install_stamp(project_root).get("source") == "commit-build"
|
||||
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class UpdateRefusal:
|
||||
"""Why an in-place update is refused, and what to run instead."""
|
||||
@@ -47,6 +48,37 @@ def _refusal(code: str, method: str, message: Optional[Callable[[str], str]] = N
|
||||
return UpdateRefusal(code=code, message=text, update_command=command)
|
||||
|
||||
|
||||
# Sealed-tree steward -> install method whose CLI command remediates it. The
|
||||
# refusal code is the steward name itself. APT owns the Termux code tree:
|
||||
# ``pkg upgrade`` replaces it wholesale, so it must never update in place.
|
||||
_STEWARD_UPDATE_METHODS: dict[str, str] = {
|
||||
STEWARD_DOCKER: "docker",
|
||||
STEWARD_NIX: "nix",
|
||||
STEWARD_APT_TERMUX: "apt",
|
||||
}
|
||||
|
||||
|
||||
def _steward_refusal(steward: str) -> UpdateRefusal:
|
||||
"""Refusal for a tree sealed by ``steward``."""
|
||||
from hermes_cli.steward import steward_update_message
|
||||
|
||||
method = _STEWARD_UPDATE_METHODS.get(steward)
|
||||
if method == "docker":
|
||||
return _refusal(steward, method)
|
||||
if method is not None:
|
||||
return _refusal(steward, method, lambda _command: steward_update_message(steward))
|
||||
# desktop-app and future package managers have no CLI remediation: the
|
||||
# steward's own instructions are the remediation, and
|
||||
# recommended_update_command_for_method would falsely answer "hermes
|
||||
# update" for methods it doesn't know.
|
||||
command = (
|
||||
"Manage updates from within the desktop app"
|
||||
if steward == STEWARD_DESKTOP
|
||||
else f"update via {steward}"
|
||||
)
|
||||
return UpdateRefusal(code=steward, message=steward_update_message(steward), update_command=command)
|
||||
|
||||
|
||||
def evaluate_update_admission(project_root: Path) -> Optional[UpdateRefusal]:
|
||||
"""Return an :class:`UpdateRefusal` when in-place update must not run.
|
||||
|
||||
@@ -81,14 +113,7 @@ def evaluate_update_admission(project_root: Path) -> Optional[UpdateRefusal]:
|
||||
# rung that covers ``desktop-app``, which the heuristics below never
|
||||
# detect (the payload has no .install_method stamp and no .git).
|
||||
try:
|
||||
from hermes_cli.steward import (
|
||||
STEWARD_APT_TERMUX,
|
||||
STEWARD_DESKTOP,
|
||||
STEWARD_DOCKER,
|
||||
STEWARD_NIX,
|
||||
sealed_steward,
|
||||
steward_update_message,
|
||||
)
|
||||
from hermes_cli.steward import sealed_steward
|
||||
|
||||
steward = sealed_steward(project_root)
|
||||
if steward is None:
|
||||
@@ -102,45 +127,8 @@ def evaluate_update_admission(project_root: Path) -> Optional[UpdateRefusal]:
|
||||
message=SOURCE_ON_TERMUX_UPDATE_MESSAGE,
|
||||
update_command=SOURCE_ON_TERMUX_UPDATE_COMMAND,
|
||||
)
|
||||
if steward is not None and steward != "unknown":
|
||||
from hermes_cli.config import recommended_update_command_for_method
|
||||
|
||||
if steward == STEWARD_DOCKER:
|
||||
from hermes_cli.config import format_docker_update_message
|
||||
|
||||
return UpdateRefusal(
|
||||
code="docker",
|
||||
message=format_docker_update_message(),
|
||||
update_command=recommended_update_command_for_method("docker"),
|
||||
)
|
||||
if steward == STEWARD_NIX:
|
||||
return UpdateRefusal(
|
||||
code="nix",
|
||||
message=steward_update_message(steward),
|
||||
update_command=recommended_update_command_for_method("nix"),
|
||||
)
|
||||
if steward == STEWARD_APT_TERMUX:
|
||||
# The APT repo owns the code tree; `hermes update` must
|
||||
# never run in place — `pkg upgrade` replaces it wholesale.
|
||||
return UpdateRefusal(
|
||||
code=steward,
|
||||
message=steward_update_message(steward),
|
||||
update_command=recommended_update_command_for_method("apt"),
|
||||
)
|
||||
# desktop-app and future package managers: there is no CLI
|
||||
# remediation command — the steward's own instructions ARE the
|
||||
# remediation (recommended_update_command_for_method would
|
||||
# falsely answer "hermes update" for methods it doesn't know).
|
||||
command = (
|
||||
"Manage updates from within the desktop app"
|
||||
if steward == STEWARD_DESKTOP
|
||||
else f"update via {steward}"
|
||||
)
|
||||
return UpdateRefusal(
|
||||
code=steward,
|
||||
message=steward_update_message(steward),
|
||||
update_command=command,
|
||||
)
|
||||
elif steward != "unknown":
|
||||
return _steward_refusal(steward)
|
||||
except Exception as exc:
|
||||
logger.debug("Steward admission check failed: %s", exc)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user