From 965610f922be5b2afb6fa412205077486734a433 Mon Sep 17 00:00:00 2001 From: Austin Pickett Date: Fri, 15 May 2026 23:57:30 -0400 Subject: [PATCH] fix(cli): tolerate unreadable dirs when building systemd PATH MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit generate_systemd_unit runs _build_service_path_dirs(); tests that mimic sudo (Path.home → /root) caused is_dir() to raise PermissionError for unprivileged users on /root/.hermes/..., failing CI. Treat inaccessible paths like missing. Co-authored-by: Cursor --- hermes_cli/gateway.py | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/hermes_cli/gateway.py b/hermes_cli/gateway.py index a865bcaf8be..f2d6223f3de 100644 --- a/hermes_cli/gateway.py +++ b/hermes_cli/gateway.py @@ -2103,6 +2103,19 @@ def _hermes_home_for_target_user(target_home_dir: str) -> str: return str(current_hermes) +def _path_usable_bindir(path: Path) -> bool: + """True iff ``path`` exists as a dir and we could stat/read it. + + systemd unit generation may run under simulated ``sudo`` in tests via + ``Path.home()`` → ``/root``; unprivileged users get ``PermissionError`` on + ``/root/.hermes/…`` probes. Missing/unreadable dirs are treated as absent. + """ + try: + return path.is_dir() + except OSError: + return False + + def _build_service_path_dirs(project_root: Path | None = None) -> list[str]: """Build PATH directory list for service units, excluding non-existent dirs.""" if project_root is None: @@ -2111,21 +2124,21 @@ def _build_service_path_dirs(project_root: Path | None = None) -> list[str]: candidates = [] venv_bin = project_root / "venv" / "bin" - if venv_bin.is_dir(): + if _path_usable_bindir(venv_bin): candidates.append(str(venv_bin)) elif sys.prefix != sys.base_prefix: candidates.append(str(Path(sys.prefix) / "bin")) node_bin = project_root / "node_modules" / ".bin" - if node_bin.is_dir(): + if _path_usable_bindir(node_bin): candidates.append(str(node_bin)) hermes_home = get_hermes_home() hermes_node = hermes_home / "node" / "bin" - if hermes_node.is_dir(): + if _path_usable_bindir(hermes_node): candidates.append(str(hermes_node)) hermes_nm = hermes_home / "node_modules" / ".bin" - if hermes_nm.is_dir(): + if _path_usable_bindir(hermes_nm): candidates.append(str(hermes_nm)) return candidates