This is an automated email from the ASF dual-hosted git repository.

wuwei pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tvm.git


The following commit(s) were added to refs/heads/main by this push:
     new ae8d398b88 [CI] In jenkins.cmd_utils.Sh.tee, check for failing 
subprocess (#16382)
ae8d398b88 is described below

commit ae8d398b8852ac84823facd6d58b229e92a8bca3
Author: Eric Lunderberg <[email protected]>
AuthorDate: Thu Jan 11 19:25:28 2024 -0600

    [CI] In jenkins.cmd_utils.Sh.tee, check for failing subprocess (#16382)
    
    Prior to this commit, the `Sh.tee` method was implemented by calling
    `f"{cmd} | tee"` in `subprocess.run`.  While the `check=True` flag was
    used, the return code was from `tee`, not from the command itself.
    This causes failures in the command itself to be silently ignored,
    such as in [this CI
    
pipeline](https://ci.tlcpack.ai/blue/organizations/jenkins/tvm-i386/detail/PR-16183/37/pipeline)
    in the `ci/scripts/jenkins/s3.py` step.
    
    This commit updates `Sh.tee` to call `subprocess.Popen` for `cmd`, tee
    the stdout, and check the return code.  (Roughly adapted from [this
    stackoverflow post](https://stackoverflow.com/a/56484734).)
---
 ci/scripts/jenkins/cmd_utils.py | 44 ++++++++++++++++++++++++++++++++---------
 1 file changed, 35 insertions(+), 9 deletions(-)

diff --git a/ci/scripts/jenkins/cmd_utils.py b/ci/scripts/jenkins/cmd_utils.py
index 1b282c50ba..57ec399731 100644
--- a/ci/scripts/jenkins/cmd_utils.py
+++ b/ci/scripts/jenkins/cmd_utils.py
@@ -58,24 +58,50 @@ class Sh:
         """
         Run 'cmd' in a shell then return the (process, stdout) as a tuple
         """
-        with tempfile.NamedTemporaryFile(delete=False) as f:
-            proc = self.run(f"{cmd} | tee {f.name}", **kwargs)
-            with open(f.name, "r") as f:
-                output = f.read()
-            return proc, output
+
+        logging.info(f"+ {cmd}")
+
+        kwargs = {
+            **self._default_popen_flags(),
+            **kwargs,
+            "stdout": subprocess.PIPE,
+        }
+        proc = subprocess.Popen(cmd, **kwargs)
+
+        stdout = []
+
+        def _tee_output(s):
+            stdout.append(s)
+            print(s, end="")
+
+        while proc.poll() is None:
+            _tee_output(proc.stdout.readline())
+        _tee_output(proc.stdout.read())
+
+        stdout = "".join(stdout)
+        if proc.returncode:
+            raise subprocess.CalledProcessError(proc.returncode, proc.args, 
stdout)
+
+        return proc, stdout
 
     def run(self, cmd: str, **kwargs):
         logging.info(f"+ {cmd}")
-        defaults = {
+
+        kwargs = {
+            **self._default_popen_flags(),
             "check": True,
+            **kwargs,
+        }
+
+        return subprocess.run(cmd, **kwargs)
+
+    def _default_popen_flags(self):
+        return {
             "shell": True,
             "env": self.env,
             "encoding": "utf-8",
             "cwd": self.cwd,
         }
-        defaults.update(kwargs)
-
-        return subprocess.run(cmd, **defaults)
 
 
 def tags_from_title(title: str) -> List[str]:

Reply via email to