97 lines
2.8 KiB
Python
Executable file
97 lines
2.8 KiB
Python
Executable file
#!/usr/bin/env python3
|
|
import re
|
|
import sys
|
|
import subprocess
|
|
from typing import Iterable
|
|
from string import printable
|
|
from subprocess import CompletedProcess
|
|
|
|
ENCODING = 'utf-8'
|
|
ANSI_RE = re.compile(rb'\x1B\[[0-?]*[ -/]*[@-~]')
|
|
|
|
def zip_n(l: Iterable, n: int) -> zip:
|
|
return zip(*[l[i:] for i in range(n)])
|
|
|
|
def run_tests() -> CompletedProcess:
|
|
return subprocess.run(
|
|
["nix-unit", "tests"],
|
|
capture_output=True)
|
|
|
|
def sanitize_bytes(b: bytes, encoding='utf-8', errors='replace') -> str:
|
|
# remove ANSI escapes first
|
|
b = ANSI_RE.sub(b'', b)
|
|
# decode (replace undecodable bytes)
|
|
s = b.decode(encoding, errors=errors)
|
|
# remove control chars except newline/tab
|
|
s = ''.join(ch for ch in s if ch.isprintable() or ch in '\n\t')
|
|
return s
|
|
|
|
def sanitize_nix(s: str) -> str:
|
|
s = s.replace('«', '"«').replace('»', '»"')
|
|
return s
|
|
|
|
def parse_result(stderr: bytes, index: int) -> None:
|
|
line_start = index
|
|
line_end = 0
|
|
line = '' # exists solely for debugging
|
|
lines_lhs = []
|
|
lines_rhs = []
|
|
|
|
find_newline = lambda: stderr.index('\n', line_start)
|
|
def progress() -> None:
|
|
nonlocal line_start, line_end, line
|
|
nonlocal lines_lhs, lines_rhs
|
|
line_end = find_newline()
|
|
line = stderr[line_start:line_end]
|
|
line_start = line_end + 1
|
|
# NOTE: exploit the fact that nix-unit always aligns
|
|
# NOTE: itself to the $COLUMNS environment variable
|
|
# NOTE: rounded down to the nearest odd number
|
|
midpoint = len(line) // 2 + 1
|
|
lhs = line[2 : midpoint - 1]
|
|
rhs = line[midpoint + 2 : ]
|
|
lines_lhs.append(lhs)
|
|
lines_rhs.append(rhs)
|
|
|
|
# header is two lines
|
|
for i in range(2):
|
|
line_start = find_newline() + 1
|
|
|
|
progress()
|
|
while True:
|
|
progress()
|
|
if not len(line) or line[0] != '.':
|
|
break
|
|
|
|
lines_lhs = sanitize_nix(''.join(lines_lhs))
|
|
lines_rhs = sanitize_nix(''.join(lines_rhs))
|
|
return lines_lhs, lines_rhs
|
|
|
|
def main() -> None:
|
|
result = run_tests()
|
|
stderr = sanitize_bytes(result.stderr)
|
|
|
|
# delimiter = '❌'.encode(ENCODING)
|
|
# error_indices = [i for i, b in enumerate(zip_n(stderr, len(delimiter))) if bytes(b) == delimiter]
|
|
# for index in error_indices:
|
|
# parse_result(stderr, index)
|
|
|
|
error_indices = [i for i, c in enumerate(stderr) if c == '❌']
|
|
for index in error_indices:
|
|
lhs, rhs = parse_result(stderr, index)
|
|
print(lhs)
|
|
print()
|
|
print(rhs)
|
|
print('\n\n\n')
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
try:
|
|
main()
|
|
except KeyboardInterrupt:
|
|
print('[!] Interrupt (SIGINT)', file=sys.stderr)
|
|
sys.exit(1)
|
|
except EOFError:
|
|
print('[!] Interrupt (EOF)', file=sys.stderr)
|
|
sys.exit(1)
|