From e66a2e08264ddd6c05a0a08e1eab65ae68be76c0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Eric=20M=C3=BCller?= <mueller@kip.uni-heidelberg.de>
Date: Mon, 6 May 2024 10:18:06 +0200
Subject: [PATCH] feat: Add support for stdout forwarding in run()

Change-Id: Ie0937143bdd8fcc05898e38d8785daadb1fa7816
---
 bin/yashchiki | 47 ++++++++++++++++++++++++++---------------------
 1 file changed, 26 insertions(+), 21 deletions(-)

diff --git a/bin/yashchiki b/bin/yashchiki
index 53c68f26..63234d47 100644
--- a/bin/yashchiki
+++ b/bin/yashchiki
@@ -5,6 +5,7 @@ import os
 import pathlib
 import subprocess
 import shutil
+import sys
 import tempfile
 import textwrap
 import yaml
@@ -179,33 +180,37 @@ pathlib.Path(env["TMPDIR"]).mkdir(exist_ok=True, parents=True)
 def run(script: str, env: dict, script_args: list = []):
     """
     Execute the given script.
+    If global args.debug is set, we pass stdout through line-wise.
 
     :param script: Script to execute.
     :param env: Enviroment to use for execution.
     :param script_args: Arguments to supply to the script.
     """
-    stdout = ""
-    try:
-        if args.debug:
-            print(f"executing: {script} {script_args}")
-        out = subprocess.run(
-            ["bash", os.path.join(root_dir, script)] + script_args,
-            env=env, check=True, stdout=subprocess.PIPE,
-            stderr=subprocess.STDOUT, encoding="utf-8")
-        stdout = out.stdout
-        if args.debug:
+    stdout = b""
+    if args.debug:
+        print(f"executing: {script} {script_args}")
+    cmd  =["bash", os.path.join(root_dir, script)] + script_args
+    out = subprocess.Popen(
+        cmd, env=env, stdout=subprocess.PIPE,
+        stderr=subprocess.STDOUT)
+    while True:
+        line = out.stdout.readline()
+        if line:
+            if args.debug:
+                sys.stdout.buffer.write(line)
+                sys.stdout.flush()
+            stdout += line
+        else:
+            break
+    out.wait()
+    stdout = str(stdout, encoding="utf-8")
+    with args.log_dir.joinpath(
+            script.replace("/", "_") + ".log").open("w+") as file:
+        file.write(stdout)
+    if out.returncode != 0:
+        if not args.debug:
             print(stdout)
-    except subprocess.CalledProcessError as error:
-        stdout = error.stdout
-        print(stdout)
-        with args.log_dir.joinpath(
-                script.replace("/", "_") + ".log").open("w+") as file:
-            file.write(stdout)
-        raise
-    else:
-        with args.log_dir.joinpath(
-                script.replace("/", "_") + ".log").open("w+") as file:
-            file.write(stdout)
+        raise subprocess.CalledProcessError(out.returncode, cmd)
 
 
 with tempfile.TemporaryDirectory(prefix="spack-", dir=env["TMPDIR"]) \
-- 
GitLab