|
25 | 25 | import os
|
26 | 26 | import shutil
|
27 | 27 | import subprocess
|
| 28 | +import shlex |
| 29 | +import fcntl |
28 | 30 | import platform
|
29 | 31 | import fileinput
|
30 | 32 | import re
|
@@ -67,75 +69,76 @@ def run_command(self, cmd, suppress_message=False, return_output=False):
|
67 | 69 | """
|
68 | 70 | Run a shell command and show the output as it runs
|
69 | 71 | """
|
70 |
| - original_stdout = sys.stdout |
71 |
| - original_stderr = sys.stderr |
72 |
| - try: |
73 |
| - # pylint: disable=consider-using-with |
74 |
| - proc = subprocess.Popen( |
75 |
| - cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE |
76 |
| - ) |
77 |
| - # pylint: enable=consider-using-with |
78 |
| - full_output = "" |
79 |
| - while True: |
80 |
| - output = proc.stdout.readline() |
81 |
| - err = proc.stderr.read() |
82 |
| - if err and not suppress_message: |
83 |
| - self.error(err.decode("utf-8", errors="ignore")) |
84 |
| - if len(output) == 0 and proc.poll() is not None: |
85 |
| - break |
86 |
| - if output: |
87 |
| - decoded_output = output.decode("utf-8", errors="ignore").strip() |
88 |
| - if not suppress_message: |
89 |
| - self.info(decoded_output) |
90 |
| - full_output += decoded_output |
91 |
| - except Exception: # pylint: disable=broad-except |
92 |
| - pass |
93 |
| - finally: |
94 |
| - sys.stdout = original_stdout |
95 |
| - sys.stderr = original_stderr |
96 |
| - if return_output: |
97 |
| - return full_output |
98 |
| - r = proc.poll() |
99 |
| - if r == 0: |
| 72 | + def non_block_read(output): |
| 73 | + fd = output.fileno() |
| 74 | + fl = fcntl.fcntl(fd, fcntl.F_GETFL) |
| 75 | + fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NONBLOCK) |
| 76 | + try: |
| 77 | + return output.read() |
| 78 | + except: |
| 79 | + return "" |
| 80 | + |
| 81 | + full_output = "" |
| 82 | + with subprocess.Popen( |
| 83 | + cmd, |
| 84 | + shell=True, |
| 85 | + stdout=subprocess.PIPE, |
| 86 | + stderr=subprocess.PIPE, |
| 87 | + universal_newlines=True |
| 88 | + ) as proc: |
| 89 | + while proc.poll() is None: |
| 90 | + err = non_block_read(proc.stderr) |
| 91 | + if err != "" and not suppress_message: |
| 92 | + self.error(err.strip(), end="\n\r") |
| 93 | + output = non_block_read(proc.stdout) |
| 94 | + if output != "" and not suppress_message: |
| 95 | + self.info(output.strip(), end="\n\r") |
| 96 | + full_output += output |
| 97 | + return_code = proc.poll() |
| 98 | + proc.stdout.close() |
| 99 | + proc.stderr.close() |
| 100 | + if return_output: |
| 101 | + return full_output |
| 102 | + if return_code: |
| 103 | + return False |
100 | 104 | return True
|
101 |
| - return False |
102 | 105 |
|
103 |
| - def info(self, message): |
| 106 | + def info(self, message, **kwargs): |
104 | 107 | """
|
105 | 108 | Display a message with the group in green
|
106 | 109 | """
|
107 | 110 | if self._group is not None:
|
108 |
| - print(colored.green(self._group) + " " + message) |
| 111 | + print(colored.green(self._group) + " " + message, **kwargs) |
109 | 112 | else:
|
110 |
| - print(message) |
| 113 | + print(message, **kwargs) |
111 | 114 |
|
112 |
| - def warn(self, message): |
| 115 | + def warn(self, message, **kwargs): |
113 | 116 | """
|
114 | 117 | Display a message with the group in yellow
|
115 | 118 | """
|
116 | 119 | if self._group is not None:
|
117 |
| - print(colored.yellow(self._group) + " " + message) |
| 120 | + print(colored.yellow(self._group) + " " + message, **kwargs) |
118 | 121 | else:
|
119 |
| - print(message) |
| 122 | + print(message, **kwargs) |
120 | 123 |
|
121 |
| - def bail(self, message=None): |
| 124 | + def bail(self, message=None, **kwargs): |
122 | 125 | """
|
123 | 126 | Exit and display an error message if given
|
124 | 127 | """
|
125 | 128 | if message is None:
|
126 |
| - self.error("Exiting due to error") |
| 129 | + self.error("Exiting due to error", **kwargs) |
127 | 130 | else:
|
128 |
| - self.error(f"Exiting due to error: {message}") |
| 131 | + self.error(f"Exiting due to error: {message}", **kwargs) |
129 | 132 | sys.exit(1)
|
130 | 133 |
|
131 |
| - def error(self, message): |
| 134 | + def error(self, message, **kwargs): |
132 | 135 | """
|
133 |
| - Display some inforrmation |
| 136 | + Display some information |
134 | 137 | """
|
135 | 138 | if self._group is not None:
|
136 |
| - print(colored.red(self._group) + " " + message) |
| 139 | + print(colored.red(self._group) + " " + message, **kwargs) |
137 | 140 | else:
|
138 |
| - print(message) |
| 141 | + print(message, **kwargs) |
139 | 142 |
|
140 | 143 | @staticmethod
|
141 | 144 | def print_colored(message, color):
|
|
0 commit comments