fix(gateway): don't ask the Windows login question when stdout is captured
#122234 gave Desktop update steps NUL stdin, but the hand-off script that runs is the one from the checkout being updated FROM. Every update that starts on an older commit still runs the old script, which gives steps the hand-off console as stdin and captures their stdout until they exit. Only the steps after `hermes update` run new code. So `gateway start --all` from the new checkout still saw an interactive console, asked "Install it now so the gateway starts on login?" into the captured stdout, and waited forever. The update never relaunched. start() now asks only when stdout is a terminal too. Nobody can answer a question they cannot see.
This commit is contained in:
@@ -756,6 +756,13 @@ def _stdin_is_interactive(*, isatty: bool, console_mode_ok: bool | None) -> bool
|
||||
return isatty and console_mode_ok is not False
|
||||
|
||||
|
||||
def _stdout_isatty() -> bool:
|
||||
"""The question is printed to stdout. When stdout is captured, nobody sees it. Desktop update
|
||||
hand-offs before #122234 captured each step's stdout while leaving it the console's stdin, so a
|
||||
prompt there waited forever for an answer to a question nobody saw."""
|
||||
return sys.stdout is not None and sys.stdout.isatty()
|
||||
|
||||
|
||||
def _stdin_console_mode_ok() -> bool | None:
|
||||
if sys.platform != "win32":
|
||||
return None
|
||||
@@ -1592,7 +1599,7 @@ def start() -> None:
|
||||
from hermes_cli.setup import is_interactive_stdin, is_noninteractive, prompt_yes_no
|
||||
|
||||
print("✗ Gateway service is not installed")
|
||||
if is_noninteractive() or not _stdin_is_interactive(
|
||||
if is_noninteractive() or not _stdout_isatty() or not _stdin_is_interactive(
|
||||
isatty=is_interactive_stdin(), console_mode_ok=_stdin_console_mode_ok()
|
||||
):
|
||||
start_on_login = False
|
||||
|
||||
@@ -616,6 +616,7 @@ def _arrange_uninstalled_start(monkeypatch):
|
||||
monkeypatch.setattr(gateway_windows, "_spawn_detached", lambda: spawns.append(1) or 4242)
|
||||
monkeypatch.setattr(gateway_windows, "_report_gateway_start", lambda via: None)
|
||||
monkeypatch.setattr(gateway_windows, "_stdin_console_mode_ok", lambda: True)
|
||||
monkeypatch.setattr(gateway_windows, "_stdout_isatty", lambda: True)
|
||||
return installs, spawns
|
||||
|
||||
|
||||
@@ -641,6 +642,20 @@ def test_start_with_nul_stdin_starts_the_gateway_but_never_installs_login_persis
|
||||
assert "hermes gateway install" in capsys.readouterr().out
|
||||
|
||||
|
||||
def test_start_with_captured_stdout_never_asks_even_on_a_console_stdin(monkeypatch, capsys):
|
||||
"""Pre-#122234 Desktop update hand-offs run the NEW `gateway start --all` with the hand-off
|
||||
console as stdin and stdout captured until exit. A question there is invisible and never answered."""
|
||||
installs, spawns = _arrange_uninstalled_start(monkeypatch)
|
||||
monkeypatch.setattr(setup, "is_interactive_stdin", lambda: True)
|
||||
monkeypatch.setattr(gateway_windows, "_stdout_isatty", lambda: False)
|
||||
monkeypatch.setattr(setup, "prompt_yes_no", lambda *a, **k: pytest.fail("no prompt into captured stdout"))
|
||||
|
||||
gateway_windows.start()
|
||||
|
||||
assert installs == [] and spawns == [1]
|
||||
assert "hermes gateway install" in capsys.readouterr().out
|
||||
|
||||
|
||||
def test_start_without_tty_starts_the_gateway_but_never_installs_login_persistence(monkeypatch, capsys):
|
||||
"""`hermes gateway start < /dev/null` must not answer the persistence question with a default Yes
|
||||
(#113977); it starts the gateway once and points at the explicit install command."""
|
||||
|
||||
Reference in New Issue
Block a user