mirror of
https://github.com/AdaCore/langkit.git
synced 2026-02-12 12:28:12 -08:00
gh_wrap_errors.py: make sure all output is processed
The current select-based code to consume subprocess output on the fly sometimes misses the end of the output. Rework it to consume mixed stdout+stderr until the end of output instead.
This commit is contained in:
committed by
Pierre-Marie de Rodat
parent
6ae6d9923a
commit
eb01f28b04
@@ -8,7 +8,6 @@ GitHub workflow commands.
|
||||
import argparse
|
||||
from os import path as P
|
||||
import re
|
||||
import select
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
@@ -21,56 +20,22 @@ msg_re = re.compile(r"(.*?):(\d+):(?:(d+)\:)?(.*)?$")
|
||||
|
||||
p = subprocess.Popen(
|
||||
extra_args, universal_newlines=True,
|
||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
||||
stdin=subprocess.DEVNULL, stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
|
||||
)
|
||||
|
||||
# If a line is a GNU style error message, emit a corresponding workflow
|
||||
# command and trigger an error status.
|
||||
exit_status = 0
|
||||
|
||||
|
||||
def emit_workflow_command_for_line(line):
|
||||
"""
|
||||
If line is a GNU style error message, emit a corresponding workflow
|
||||
command.
|
||||
"""
|
||||
global exit_status
|
||||
m = msg_re.match(line)
|
||||
for line in p.stdout:
|
||||
m = msg_re.match(line.rstrip())
|
||||
if m:
|
||||
exit_status = 1
|
||||
file, line, _, msg = m.groups()
|
||||
if file.startswith('/'):
|
||||
if file.startswith("/"):
|
||||
file = P.relpath(file)
|
||||
print(f"::error file={file},line={line}::{msg}")
|
||||
sys.stdout.write(line)
|
||||
sys.stdout.flush()
|
||||
|
||||
|
||||
stdout = []
|
||||
stderr = []
|
||||
|
||||
# Record the subprocess's stdout & stderr while still feeding them to this
|
||||
# process' out & err.
|
||||
while True:
|
||||
descs, _, _ = select.select((p.stdout.fileno(), p.stderr.fileno()), [], [])
|
||||
|
||||
# Record stdout and stderr, while still forwarding them to this process'
|
||||
# stdout and stderr.
|
||||
for fd in descs:
|
||||
if fd == p.stdout.fileno():
|
||||
read = p.stdout.read()
|
||||
sys.stdout.write(read)
|
||||
stdout.append(read)
|
||||
elif fd == p.stderr.fileno():
|
||||
read = p.stderr.read()
|
||||
sys.stderr.write(read)
|
||||
stderr.append(read)
|
||||
|
||||
returncode = p.poll()
|
||||
if returncode is not None:
|
||||
# Process has terminated, check if the return code is non zero, and if
|
||||
# it is, propagate to exit_status.
|
||||
if returncode != 0:
|
||||
exit_status = returncode
|
||||
break
|
||||
|
||||
for line in "".join(stdout + stderr).splitlines():
|
||||
emit_workflow_command_for_line(line)
|
||||
|
||||
sys.exit(exit_status)
|
||||
p.wait()
|
||||
sys.exit(p.returncode if exit_status == 0 else exit_status)
|
||||
|
||||
Reference in New Issue
Block a user