in builder/core/util.py [0:0]
def run_command(*command, **kwargs):
if not kwargs.get('quiet', False):
log_command(*command)
dryrun = kwargs.get('dryrun', False)
if dryrun:
return None
tries = kwargs.get('retries', 1)
working_dir = kwargs.get('working_dir', os.getcwd())
output = None
while tries > 0:
tries -= 1
try:
cmds = _flatten_command(*command)
if sys.platform == 'win32':
cmds = [cmd.encode('ascii', 'ignore').decode()
for cmd in cmds]
cmd = subprocess.list2cmdline(cmds)
# force the working directory
cwd = os.getcwd()
os.chdir(working_dir)
proc = subprocess.Popen(
cmd,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
shell=True,
bufsize=0) # do not buffer output
with proc:
# Convert all output to strings, which makes it much easier to both print
# and process, since all known uses of parsing output want strings anyway
output = ""
line = proc.stdout.readline()
while (line):
# ignore weird characters coming back from the shell (colors, etc)
if not isinstance(line, str):
line = line.decode('ascii', 'ignore')
# We're reading in binary mode, so no automatic newline translation
if sys.platform == 'win32':
line = line.replace('\r\n', '\n')
output += line
if not kwargs.get('quiet', False):
print(line, end='', flush=True)
line = proc.stdout.readline()
proc.wait()
# restore working directory before exiting the function
os.chdir(cwd)
if proc.returncode != 0:
raise Exception(
'Command exited with code {}:\n{}'.format(proc.returncode, output))
return ExecResult(proc.returncode, proc.pid, output)
except Exception as ex:
print('Failed to run {}: {}'.format(
' '.join(_flatten_command(*command)), ex))
if kwargs.get('check', False) and tries == 0:
raise
output = ex
if tries > 0:
print('Waiting {} seconds to try again'.format(
_retry_wait_secs))
sleep(_retry_wait_secs)
return ExecResult(-1, -1, output)