Fix run_command sometimes stops

This commit is contained in:
Melissa LeBlanc-Williams 2022-11-10 12:43:27 -08:00
parent c6581122fa
commit 0bc10b7dc0

View file

@ -25,6 +25,8 @@ import sys
import os import os
import shutil import shutil
import subprocess import subprocess
import shlex
import fcntl
import platform import platform
import fileinput import fileinput
import re import re
@ -67,75 +69,76 @@ class Shell:
""" """
Run a shell command and show the output as it runs Run a shell command and show the output as it runs
""" """
original_stdout = sys.stdout def non_block_read(output):
original_stderr = sys.stderr fd = output.fileno()
fl = fcntl.fcntl(fd, fcntl.F_GETFL)
fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NONBLOCK)
try: try:
# pylint: disable=consider-using-with return output.read()
proc = subprocess.Popen( except:
cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE return ""
)
# pylint: enable=consider-using-with
full_output = "" full_output = ""
while True: with subprocess.Popen(
output = proc.stdout.readline() cmd,
err = proc.stderr.read() shell=True,
if err and not suppress_message: stdout=subprocess.PIPE,
self.error(err.decode("utf-8", errors="ignore")) stderr=subprocess.PIPE,
if len(output) == 0 and proc.poll() is not None: universal_newlines=True
break ) as proc:
if output: while proc.poll() is None:
decoded_output = output.decode("utf-8", errors="ignore").strip() err = non_block_read(proc.stderr)
if not suppress_message: if err != "" and not suppress_message:
self.info(decoded_output) self.error(err.strip(), end="\n\r")
full_output += decoded_output output = non_block_read(proc.stdout)
except Exception: # pylint: disable=broad-except if output != "" and not suppress_message:
pass self.info(output.strip(), end="\n\r")
finally: full_output += output
sys.stdout = original_stdout return_code = proc.poll()
sys.stderr = original_stderr proc.stdout.close()
proc.stderr.close()
if return_output: if return_output:
return full_output return full_output
r = proc.poll() if return_code:
if r == 0:
return True
return False return False
return True
def info(self, message): def info(self, message, **kwargs):
""" """
Display a message with the group in green Display a message with the group in green
""" """
if self._group is not None: if self._group is not None:
print(colored.green(self._group) + " " + message) print(colored.green(self._group) + " " + message, **kwargs)
else: else:
print(message) print(message, **kwargs)
def warn(self, message): def warn(self, message, **kwargs):
""" """
Display a message with the group in yellow Display a message with the group in yellow
""" """
if self._group is not None: if self._group is not None:
print(colored.yellow(self._group) + " " + message) print(colored.yellow(self._group) + " " + message, **kwargs)
else: else:
print(message) print(message, **kwargs)
def bail(self, message=None): def bail(self, message=None, **kwargs):
""" """
Exit and display an error message if given Exit and display an error message if given
""" """
if message is None: if message is None:
self.error("Exiting due to error") self.error("Exiting due to error", **kwargs)
else: else:
self.error(f"Exiting due to error: {message}") self.error(f"Exiting due to error: {message}", **kwargs)
sys.exit(1) sys.exit(1)
def error(self, message): def error(self, message, **kwargs):
""" """
Display some inforrmation Display some information
""" """
if self._group is not None: if self._group is not None:
print(colored.red(self._group) + " " + message) print(colored.red(self._group) + " " + message, **kwargs)
else: else:
print(message) print(message, **kwargs)
@staticmethod @staticmethod
def print_colored(message, color): def print_colored(message, color):