This repository has been archived by the owner on May 17, 2021. It is now read-only.
/
call.py
89 lines (79 loc) · 2.32 KB
/
call.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# Copyright (c) 2014-2015, Ruslan Baratov
# All rights reserved.
# Adapted to python3 version of: http://stackoverflow.com/questions/4984428
import os
import subprocess
import sys
import threading
import time
def tee(infile, discard, log_file, console=None):
"""Print `infile` to `files` in a separate thread."""
def fanout():
discard_counter = 0
for line in iter(infile.readline, b''):
s = line.decode('utf-8')
s = s.replace('\r', '')
s = s.replace('\t', ' ')
s = s.rstrip() # strip spaces and EOL
s += '\n' # append stripped EOL back
log_file.write(s)
if console is None:
continue
if discard is None:
console.write(s)
continue
if discard_counter == 0:
console.write(s)
discard_counter += 1
if discard_counter == discard:
discard_counter = 0
infile.close()
t = threading.Thread(target=fanout)
t.daemon = True
t.start()
return t
def teed_call(cmd_args, logging):
p = subprocess.Popen(
cmd_args,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
env=os.environ,
bufsize=0
)
threads = []
if logging.verbose:
threads.append(tee(p.stdout, logging.discard, logging.log_file, sys.stdout))
threads.append(tee(p.stderr, logging.discard, logging.log_file, sys.stderr))
else:
threads.append(tee(p.stdout, logging.discard, logging.log_file))
threads.append(tee(p.stderr, logging.discard, logging.log_file))
for t in threads:
t.join() # wait for IO completion
return p.wait()
def call(call_args, logging, cache_file='', ignore=False, sleep=0):
pretty = 'Execute command: [\n'
for i in call_args:
pretty += ' `{}`\n'.format(i)
pretty += ']\n'
print(pretty)
logging.log_file.write(pretty)
# print one line version
oneline = ''
for i in call_args:
oneline += ' "{}"'.format(i)
oneline = "[{}]>{}\n".format(os.getcwd(), oneline)
if logging.verbose:
print(oneline)
logging.log_file.write(oneline)
x = teed_call(call_args, logging)
if x == 0 or ignore:
time.sleep(sleep)
return
if os.path.exists(cache_file):
os.unlink(cache_file)
logging.log_file.close()
print('Command exit with status "{}": {}'.format(x, oneline))
print('Log: {}'.format(logging.log_path))
logging.print_last_lines()
print('*** FAILED ***')
sys.exit(1)