fix(template): use sys.stdin.readline() for snapshot confirm prompt
input() with a prompt string on some terminals (zsh + Linux Mint) echoes ^M and the prompt doesn't flush before reading, causing the prompt to appear stuck or not accept input. Replace with explicit sys.stdout.write()+flush() + sys.stdin.readline() which guarantees the prompt is flushed before blocking on stdin, and readline() + .strip() handles both \n and \r\n line endings correctly. Tests updated to use CliRunner(input=) which populates sys.stdin inside the runner context (monkeypatching sys.stdin.readline directly is ignored by CliRunner which replaces sys.stdin entirely). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -60,6 +60,7 @@ import json
|
|||||||
import shutil
|
import shutil
|
||||||
import socket
|
import socket
|
||||||
import subprocess
|
import subprocess
|
||||||
|
import sys
|
||||||
import threading
|
import threading
|
||||||
import time
|
import time
|
||||||
from datetime import UTC, datetime
|
from datetime import UTC, datetime
|
||||||
@@ -671,8 +672,10 @@ Register-ScheduledTask -TaskName 'CI-StaticIp' `
|
|||||||
if recreate_snapshot:
|
if recreate_snapshot:
|
||||||
do_recreate = True
|
do_recreate = True
|
||||||
else:
|
else:
|
||||||
raw = input(f"[prepare-win] Delete and recreate '{snapshot}'? [y/N] ")
|
sys.stdout.write(f"[prepare-win] Delete and recreate '{snapshot}'? [y/N] ")
|
||||||
do_recreate = raw.strip().rstrip("\r").lower() in ("y", "yes")
|
sys.stdout.flush()
|
||||||
|
raw = sys.stdin.readline()
|
||||||
|
do_recreate = raw.strip().lower() in ("y", "yes")
|
||||||
if not do_recreate:
|
if not do_recreate:
|
||||||
click.echo("[prepare-win] Keeping existing snapshot. Provisioning complete.")
|
click.echo("[prepare-win] Keeping existing snapshot. Provisioning complete.")
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -613,8 +613,6 @@ def test_prepare_win_snapshot_exists_skip(
|
|||||||
backend.list_snapshots.return_value = ["BaseClean"]
|
backend.list_snapshots.return_value = ["BaseClean"]
|
||||||
transport = _make_transport()
|
transport = _make_transport()
|
||||||
_patch_prepare(monkeypatch, backend, transport)
|
_patch_prepare(monkeypatch, backend, transport)
|
||||||
monkeypatch.setattr("builtins.input", lambda _prompt="": "N")
|
|
||||||
|
|
||||||
result = CliRunner().invoke(
|
result = CliRunner().invoke(
|
||||||
cli,
|
cli,
|
||||||
[
|
[
|
||||||
@@ -624,6 +622,7 @@ def test_prepare_win_snapshot_exists_skip(
|
|||||||
"--admin-password", "adminpass",
|
"--admin-password", "adminpass",
|
||||||
"--build-password", "buildpass",
|
"--build-password", "buildpass",
|
||||||
],
|
],
|
||||||
|
input="N\n",
|
||||||
)
|
)
|
||||||
assert result.exit_code == 0, result.output
|
assert result.exit_code == 0, result.output
|
||||||
assert "Keeping existing snapshot" in result.output
|
assert "Keeping existing snapshot" in result.output
|
||||||
@@ -644,8 +643,6 @@ def test_prepare_win_snapshot_exists_recreate(
|
|||||||
monkeypatch.setattr(tmpl_mod, "_wait_tcp", lambda *_: True)
|
monkeypatch.setattr(tmpl_mod, "_wait_tcp", lambda *_: True)
|
||||||
monkeypatch.setattr(tmpl_mod, "_wait_winrm", lambda *_: None)
|
monkeypatch.setattr(tmpl_mod, "_wait_winrm", lambda *_: None)
|
||||||
monkeypatch.setattr(tmpl_mod.time, "sleep", lambda _: None)
|
monkeypatch.setattr(tmpl_mod.time, "sleep", lambda _: None)
|
||||||
monkeypatch.setattr("builtins.input", lambda _prompt="": "Y")
|
|
||||||
|
|
||||||
def _sp_run(cmd: list[str], **_: object) -> None:
|
def _sp_run(cmd: list[str], **_: object) -> None:
|
||||||
sp_calls.append(cmd)
|
sp_calls.append(cmd)
|
||||||
|
|
||||||
@@ -660,6 +657,7 @@ def test_prepare_win_snapshot_exists_recreate(
|
|||||||
"--admin-password", "adminpass",
|
"--admin-password", "adminpass",
|
||||||
"--build-password", "buildpass",
|
"--build-password", "buildpass",
|
||||||
],
|
],
|
||||||
|
input="Y\n",
|
||||||
)
|
)
|
||||||
assert result.exit_code == 0, result.output
|
assert result.exit_code == 0, result.output
|
||||||
assert any("deleteSnapshot" in " ".join(c) for c in sp_calls)
|
assert any("deleteSnapshot" in " ".join(c) for c in sp_calls)
|
||||||
|
|||||||
Reference in New Issue
Block a user