mirror of
https://github.com/retroSoC/retroSoC.git
synced 2026-11-04 22:32:36 +00:00
feat: enhance console output handling in run_flow script
This commit is contained in:
3 files changed
+63
-2
No files matched your search
@@ -11,6 +11,7 @@
|
||||
*.ddb
|
||||
*.fst
|
||||
*.txt
|
||||
*.demo
|
||||
!requirements/
|
||||
!requirements/*.txt
|
||||
*.gtkw
|
||||
|
||||
+19
-2
@@ -8,6 +8,7 @@ import os
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
import termios
|
||||
import time
|
||||
from datetime import datetime, timezone
|
||||
from pathlib import Path
|
||||
@@ -47,6 +48,23 @@ def jobserver_fds() -> tuple[int, ...]:
|
||||
return descriptors
|
||||
|
||||
|
||||
def terminal_requires_crlf() -> bool:
|
||||
if not sys.stdout.isatty():
|
||||
return False
|
||||
try:
|
||||
output_flags = termios.tcgetattr(sys.stdout.fileno())[1]
|
||||
except OSError:
|
||||
return False
|
||||
return not (output_flags & termios.OPOST and output_flags & termios.ONLCR)
|
||||
|
||||
|
||||
def write_console_output(line: str) -> None:
|
||||
if terminal_requires_crlf():
|
||||
line = line.replace("\n", "\r\n")
|
||||
sys.stdout.write(line)
|
||||
sys.stdout.flush()
|
||||
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser(description="Run a flow command with structured results")
|
||||
parser.add_argument("--tool", required=True)
|
||||
@@ -89,8 +107,7 @@ def main() -> int:
|
||||
log.write(line)
|
||||
log.flush()
|
||||
if should_display(args.tool, line):
|
||||
sys.stdout.write(line)
|
||||
sys.stdout.flush()
|
||||
write_console_output(line)
|
||||
returncode = process.wait()
|
||||
except KeyboardInterrupt:
|
||||
error_message = "interrupted"
|
||||
|
||||
@@ -38,6 +38,7 @@ from scripts.generate_mpw import ( # noqa: E402
|
||||
)
|
||||
from scripts.install_toolchain import safe_extract # noqa: E402
|
||||
from scripts import regress # noqa: E402
|
||||
from scripts import run_flow # noqa: E402
|
||||
from scripts.regress import ( # noqa: E402
|
||||
NIGHTLY_COMMANDS,
|
||||
PDK_PR_PROFILES,
|
||||
@@ -802,6 +803,48 @@ def test_run_flow_writes_structured_result(tmp_path: Path) -> None:
|
||||
assert log.read_text(encoding="utf-8") == "flow output\n"
|
||||
|
||||
|
||||
def test_run_flow_adds_carriage_return_when_terminal_disables_onlcr(monkeypatch) -> None:
|
||||
class Terminal(io.StringIO):
|
||||
def isatty(self) -> bool:
|
||||
return True
|
||||
|
||||
def fileno(self) -> int:
|
||||
return 42
|
||||
|
||||
terminal = Terminal()
|
||||
monkeypatch.setattr(run_flow.sys, "stdout", terminal)
|
||||
monkeypatch.setattr(
|
||||
run_flow.termios,
|
||||
"tcgetattr",
|
||||
lambda descriptor: [0, run_flow.termios.OPOST, 0, 0, 0, 0, 0],
|
||||
)
|
||||
|
||||
run_flow.write_console_output("first\nsecond\n")
|
||||
|
||||
assert terminal.getvalue() == "first\r\nsecond\r\n"
|
||||
|
||||
|
||||
def test_run_flow_keeps_newlines_when_terminal_maps_them_to_carriage_return(monkeypatch) -> None:
|
||||
class Terminal(io.StringIO):
|
||||
def isatty(self) -> bool:
|
||||
return True
|
||||
|
||||
def fileno(self) -> int:
|
||||
return 42
|
||||
|
||||
terminal = Terminal()
|
||||
monkeypatch.setattr(run_flow.sys, "stdout", terminal)
|
||||
monkeypatch.setattr(
|
||||
run_flow.termios,
|
||||
"tcgetattr",
|
||||
lambda descriptor: [0, run_flow.termios.OPOST | run_flow.termios.ONLCR, 0, 0, 0, 0, 0],
|
||||
)
|
||||
|
||||
run_flow.write_console_output("first\nsecond\n")
|
||||
|
||||
assert terminal.getvalue() == "first\nsecond\n"
|
||||
|
||||
|
||||
def test_run_flow_records_interruption(tmp_path: Path) -> None:
|
||||
log = tmp_path / "interrupted.log"
|
||||
result = tmp_path / "interrupted.json"
|
||||
|
||||
Reference in new issue
Block a user