Compare commits
3 Commits
exports-en
...
ke-fix-cr
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cb2054ff10 | ||
|
|
841a8edbdd | ||
|
|
27d9a805d9 |
@@ -74,6 +74,9 @@ def handle_io(
|
||||
) # wlist is a list of file descriptors to be monitored for write events
|
||||
stdout_buf = b""
|
||||
stderr_buf = b""
|
||||
# Buffers for incomplete lines (no trailing newline yet)
|
||||
stdout_line_buf = ""
|
||||
stderr_line_buf = ""
|
||||
start = time.time()
|
||||
|
||||
# Function to handle file descriptors
|
||||
@@ -85,6 +88,40 @@ def handle_io(
|
||||
rlist.remove(fd)
|
||||
return b""
|
||||
|
||||
# Function to process output with proper carriage return handling
|
||||
def process_output(
|
||||
chunk: bytes, line_buf: str, extra: dict[str, str], cmdlog_func: Any
|
||||
) -> str:
|
||||
"""Process output chunk, handling carriage returns properly.
|
||||
Returns the updated line buffer (incomplete lines).
|
||||
"""
|
||||
if not chunk:
|
||||
return line_buf
|
||||
|
||||
# Decode the chunk and append to line buffer
|
||||
decoded = chunk.decode("utf-8", "replace")
|
||||
line_buf += decoded
|
||||
|
||||
# Split by newlines to get complete lines
|
||||
lines = line_buf.split("\n")
|
||||
|
||||
# The last element might be an incomplete line
|
||||
line_buf = lines[-1]
|
||||
complete_lines = lines[:-1]
|
||||
|
||||
# Process each complete line
|
||||
for line in complete_lines:
|
||||
if "\r" in line:
|
||||
# Handle carriage return: only keep the last segment after final \r
|
||||
# This is what would be visible on a terminal
|
||||
visible_line = line.split("\r")[-1]
|
||||
if visible_line: # Only log non-empty lines
|
||||
cmdlog_func(visible_line, extra=extra)
|
||||
elif line: # Only log non-empty lines
|
||||
cmdlog_func(line, extra=extra)
|
||||
|
||||
return line_buf
|
||||
|
||||
# Extra information passed to the logger
|
||||
stdout_extra = {}
|
||||
stderr_extra = {}
|
||||
@@ -126,9 +163,9 @@ def handle_io(
|
||||
|
||||
# If Log.STDOUT is set, log the stdout output
|
||||
if ret and log in [Log.STDOUT, Log.BOTH]:
|
||||
lines = ret.decode("utf-8", "replace").rstrip("\n").rstrip().split("\n")
|
||||
for line in lines:
|
||||
cmdlog.info(line, extra=stdout_extra)
|
||||
stdout_line_buf = process_output(
|
||||
ret, stdout_line_buf, stdout_extra, cmdlog.info
|
||||
)
|
||||
|
||||
# If stdout file is set, stream the stdout output
|
||||
if ret and stdout:
|
||||
@@ -143,9 +180,9 @@ def handle_io(
|
||||
|
||||
# If Log.STDERR is set, log the stderr output
|
||||
if ret and log in [Log.STDERR, Log.BOTH]:
|
||||
lines = ret.decode("utf-8", "replace").rstrip("\n").rstrip().split("\n")
|
||||
for line in lines:
|
||||
cmdlog.info(line, extra=stderr_extra)
|
||||
stderr_line_buf = process_output(
|
||||
ret, stderr_line_buf, stderr_extra, cmdlog.info
|
||||
)
|
||||
|
||||
# If stderr file is set, stream the stderr output
|
||||
if ret and stderr:
|
||||
@@ -173,6 +210,24 @@ def handle_io(
|
||||
process.stdin.close()
|
||||
else:
|
||||
wlist.remove(process.stdin)
|
||||
|
||||
# Flush any remaining buffered lines at the end
|
||||
if stdout_line_buf and log in [Log.STDOUT, Log.BOTH]:
|
||||
if "\r" in stdout_line_buf:
|
||||
visible_line = stdout_line_buf.split("\r")[-1]
|
||||
if visible_line:
|
||||
cmdlog.info(visible_line, extra=stdout_extra)
|
||||
elif stdout_line_buf:
|
||||
cmdlog.info(stdout_line_buf, extra=stdout_extra)
|
||||
|
||||
if stderr_line_buf and log in [Log.STDERR, Log.BOTH]:
|
||||
if "\r" in stderr_line_buf:
|
||||
visible_line = stderr_line_buf.split("\r")[-1]
|
||||
if visible_line:
|
||||
cmdlog.info(visible_line, extra=stderr_extra)
|
||||
elif stderr_line_buf:
|
||||
cmdlog.info(stderr_line_buf, extra=stderr_extra)
|
||||
|
||||
return stdout_buf.decode("utf-8", "replace"), stderr_buf.decode("utf-8", "replace")
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user