refactor(hclib): remaining hermes_cli library modules — dead code, unified helpers, flattened branches
This commit is contained in:
@@ -16,9 +16,7 @@ from typing import BinaryIO, Sequence, TextIO
|
||||
EXTERNAL_SUPERVISOR_FLAG = "--external-supervisor"
|
||||
|
||||
|
||||
_TIMESTAMP_PREFIX = re.compile(
|
||||
r"^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2},\d{3}(?:\s|$)"
|
||||
)
|
||||
_TIMESTAMP_PREFIX = re.compile(r"^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2},\d{3}(?:\s|$)")
|
||||
|
||||
|
||||
def _timestamp() -> str:
|
||||
@@ -33,18 +31,15 @@ def _write_timestamped_line(log_file: TextIO, line: str) -> None:
|
||||
log_file.flush()
|
||||
|
||||
|
||||
def _copy_stderr_with_timestamps(stderr: BinaryIO, log_path: Path) -> None:
|
||||
def _open_log(log_path: Path) -> TextIO:
|
||||
log_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
with log_path.open("a", encoding="utf-8", buffering=1) as log_file:
|
||||
return log_path.open("a", encoding="utf-8", buffering=1)
|
||||
|
||||
|
||||
def _copy_stderr_with_timestamps(stderr: BinaryIO, log_path: Path) -> None:
|
||||
with _open_log(log_path) as log_file:
|
||||
for raw_line in iter(stderr.readline, b""):
|
||||
line = raw_line.decode("utf-8", errors="replace")
|
||||
_write_timestamped_line(log_file, line)
|
||||
|
||||
|
||||
def _command_exit_code(returncode: int) -> int:
|
||||
if returncode < 0:
|
||||
return 128 + abs(returncode)
|
||||
return returncode
|
||||
_write_timestamped_line(log_file, raw_line.decode("utf-8", errors="replace"))
|
||||
|
||||
|
||||
def _install_signal_forwarders(proc: subprocess.Popen[bytes]) -> dict[int, object]:
|
||||
@@ -65,24 +60,11 @@ def _install_signal_forwarders(proc: subprocess.Popen[bytes]) -> dict[int, objec
|
||||
return previous
|
||||
|
||||
|
||||
def _restore_signal_handlers(previous: dict[int, object]) -> None:
|
||||
for signum, handler in previous.items():
|
||||
signal.signal(signum, handler)
|
||||
|
||||
|
||||
def _is_launchd_supervised(environ: Mapping[str, str] | None = None) -> bool:
|
||||
"""True when this process is launchd's direct child (not an interactive shell)."""
|
||||
env = os.environ if environ is None else environ
|
||||
xpc_service = str(env.get("XPC_SERVICE_NAME", "")).strip()
|
||||
return bool(xpc_service and xpc_service != "0")
|
||||
|
||||
|
||||
def _is_hermes_gateway_run_argv(command: Sequence[str]) -> bool:
|
||||
"""True for Hermes ``gateway run`` argv this wrapper is allowed to upgrade.
|
||||
|
||||
The wrapper is generic. Only historical/current Hermes gateway shapes
|
||||
get ``--external-supervisor``; an arbitrary launchd child must not be
|
||||
marked as gateway-supervised (#87005).
|
||||
The wrapper is generic. Only historical/current Hermes gateway shapes get ``--external-
|
||||
supervisor``; an arbitrary launchd child must not be marked as gateway-supervised (#87005).
|
||||
"""
|
||||
try:
|
||||
from gateway.status import looks_like_gateway_command_line
|
||||
@@ -91,32 +73,27 @@ def _is_hermes_gateway_run_argv(command: Sequence[str]) -> bool:
|
||||
return bool(looks_like_gateway_command_line(" ".join(str(part) for part in command)))
|
||||
|
||||
|
||||
def _with_external_supervisor_flag(command: Sequence[str]) -> list[str]:
|
||||
argv = [str(part) for part in command]
|
||||
if EXTERNAL_SUPERVISOR_FLAG not in argv:
|
||||
argv.append(EXTERNAL_SUPERVISOR_FLAG)
|
||||
return argv
|
||||
|
||||
|
||||
def _prepare_child_command(
|
||||
command: Sequence[str],
|
||||
environ: Mapping[str, str] | None = None,
|
||||
) -> list[str]:
|
||||
"""Return the argv to exec, upgrading stale launchd-wrapped gateway commands.
|
||||
|
||||
launchd stamps ``XPC_SERVICE_NAME=<job label>`` only on this wrapper.
|
||||
The grandchild sees ``XPC_SERVICE_NAME=0``. Newly generated plists put
|
||||
``--external-supervisor`` on the inner ``gateway run`` so ``hermes update``
|
||||
can see the flag on the live process argv. Stale plists still wrap the
|
||||
historical ``gateway run --replace`` shape without that flag; append it
|
||||
here, and only for that shape.
|
||||
launchd stamps ``XPC_SERVICE_NAME=<job label>`` only on this wrapper (its direct child; an
|
||||
interactive shell has none, the grandchild sees ``XPC_SERVICE_NAME=0``). Newly generated
|
||||
plists put ``--external-supervisor`` on the inner ``gateway run`` so ``hermes update`` can see
|
||||
the flag on the live process argv.
|
||||
"""
|
||||
argv = [str(part) for part in command]
|
||||
if not _is_launchd_supervised(environ):
|
||||
return argv
|
||||
if not _is_hermes_gateway_run_argv(argv):
|
||||
return argv
|
||||
return _with_external_supervisor_flag(argv)
|
||||
env = os.environ if environ is None else environ
|
||||
xpc_service = str(env.get("XPC_SERVICE_NAME", "")).strip()
|
||||
if (
|
||||
EXTERNAL_SUPERVISOR_FLAG not in argv
|
||||
and xpc_service and xpc_service != "0"
|
||||
and _is_hermes_gateway_run_argv(argv)
|
||||
):
|
||||
argv.append(EXTERNAL_SUPERVISOR_FLAG)
|
||||
return argv
|
||||
|
||||
|
||||
def _parse_args(argv: Sequence[str] | None) -> argparse.Namespace:
|
||||
@@ -138,17 +115,10 @@ def main(argv: Sequence[str] | None = None) -> int:
|
||||
log_path: Path = args.error_log
|
||||
|
||||
try:
|
||||
proc = subprocess.Popen(
|
||||
_prepare_child_command(args.command),
|
||||
stderr=subprocess.PIPE,
|
||||
)
|
||||
proc = subprocess.Popen(_prepare_child_command(args.command), stderr=subprocess.PIPE)
|
||||
except OSError as exc:
|
||||
log_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
with log_path.open("a", encoding="utf-8", buffering=1) as log_file:
|
||||
_write_timestamped_line(
|
||||
log_file,
|
||||
f"failed to start stderr-timestamped command: {exc}",
|
||||
)
|
||||
with _open_log(log_path) as log_file:
|
||||
_write_timestamped_line(log_file, f"failed to start stderr-timestamped command: {exc}")
|
||||
return 127
|
||||
|
||||
assert proc.stderr is not None
|
||||
@@ -157,8 +127,10 @@ def main(argv: Sequence[str] | None = None) -> int:
|
||||
_copy_stderr_with_timestamps(proc.stderr, log_path)
|
||||
finally:
|
||||
proc.stderr.close()
|
||||
_restore_signal_handlers(previous_handlers)
|
||||
return _command_exit_code(proc.wait())
|
||||
for signum, handler in previous_handlers.items():
|
||||
signal.signal(signum, handler)
|
||||
returncode = proc.wait()
|
||||
return 128 + abs(returncode) if returncode < 0 else returncode
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
Reference in New Issue
Block a user