-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathbuild_docs.py
117 lines (97 loc) · 3.47 KB
/
build_docs.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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#!/usr/bin/env python
import logging
import subprocess
import os
try:
from cStringIO import StringIO
except ImportError:
from StringIO import StringIO
class LogStream(object):
def __init__(self, log_func):
self.log_func = log_func
def log_line(self, line):
self.log_func(line)
def writelines(self, sequence):
for line in sequence:
self.log_line(line)
def write(self, string):
self.log_line(string)
class TaskLogger(logging.Logger):
def __init__(self, *args, **kwargs):
logging.Logger.__init__(self, *args, **kwargs)
self.log_stream = StringIO()
handler = logging.StreamHandler(self.log_stream)
handler.setLevel(logging.INFO)
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)
self.addHandler(handler)
def read_log(self):
return self.log_stream.getvalue()
def get_stdout_object(self):
return LogStream(self.info)
def get_stderr_object(self):
return LogStream(self.error)
class CommandResponse(object):
def __init__(self, session, cmd, popen, block, logger):
self.session = session
self.cmd = cmd
self.popen = popen
self.joined = False
self.logger = logger
if block:
self.join()
def join(self):
if self.joined:
return
self.joined = True
self.stdout, self.stderr = self.popen.communicate()
if self.stdout:
self.logger.info(self.stdout)
if self.stderr:
self.logger.error(self.stderr)
self.logger.debug('Return Code: %s' % self.returncode)
@property
def returncode(self):
return self.popen.returncode
class CommandFailure(Exception):
pass
class ShellSession(object):
def __init__(self, logger, cwd=None, **popen_kwargs):
self.popen_kwargs = {
'cwd': cwd or os.getcwd(),
'stdout': subprocess.PIPE,
'stderr': subprocess.PIPE,
}
self.popen_kwargs.update(popen_kwargs)
self.logger = logger
def run(self, cmd, block=True):
kwargs = dict(self.popen_kwargs)
if isinstance(cmd, basestring):
kwargs['shell'] = True
self.logger.info(cmd)
result = subprocess.Popen(cmd, **kwargs)
return CommandResponse(self, cmd, result, block, self.logger)
def run_with_retries(self, cmd, retries=3):
attempts = list()
while retries:
response = self.run(cmd)
if response.returncode:
retries -= 1
attempts.append(response)
else:
return response
raise CommandFailure('Failed to run command, # of attempts: %s' % len(attempts), attempts)
def cd(self, directory):
if directory.startswith('/'):
self.popen_kwargs['cwd'] = directory
else:
self.popen_kwargs['cwd'] = os.path.join(self.popen_kwargs['cwd'], directory)
self.logger.info('cd %s' % self.popen_kwargs['cwd'])
if __name__ == '__main__':
import sys
logger = TaskLogger('docbuilder')
shell = ShellSession(logger, stdout=sys.stdout, stderr=sys.stderr)
shell.run('virtualenv --system-site-packages .')
shell.run_with_retries('bin/pip install -q -r doc_requirements.txt')
shell.run_with_retries('bin/pip install -q Sphinx')
shell.run('bin/python setup.py build_sphinx -E')