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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
|
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Runs the daily build of the Python docs on dinsdale.python.org.
#
# Usages:
#
# dailybuild.py [-q]
#
# without any arguments builds docs for all branches configured in the global
# BRANCHES value. -q selects "quick build", which means to build only HTML.
#
# dailybuild.py [-q] [-d] <checkout> <target>
#
# builds one version, where <checkout> is an SVN checkout directory of the
# Python branch to build docs for, and <target> is the directory where the
# result should be placed. If -d is given, the docs are built even if the
# branch is in development mode (i.e. version contains a, b or c).
#
# This script is not run from the checkout, so if you want to change how the
# daily build is run, you must replace it on dinsdale. This is necessary, for
# example, after the release of a new minor version.
#
# 03/2010, Georg Brandl
import os
import sys
import getopt
BUILDROOT = '/home/gbrandl/docbuild'
SPHINXBUILD = os.path.join(BUILDROOT, 'sphinx-env/bin/sphinx-build')
WWWROOT = '/data/ftp.python.org/pub/docs.python.org'
BRANCHES = [
# checkout, target, isdev
(BUILDROOT + '/python34', WWWROOT + '/3.4', False),
(BUILDROOT + '/python35', WWWROOT + '/3.5', True),
(BUILDROOT + '/python27', WWWROOT + '/2.7', False),
]
def _files_changed(old, new):
with open(old, 'rb') as fp1, open(new, 'rb') as fp2:
st1 = os.fstat(fp1.fileno())
st2 = os.fstat(fp2.fileno())
if st1.st_size != st2.st_size:
return False
if st1.st_mtime >= st2.st_mtime:
return True
while True:
one = fp1.read(4096)
two = fp2.read(4096)
if one != two:
return False
if one == '':
break
return True
def build_one(checkout, target, isdev, quick):
print 'Doc autobuild started in %s' % checkout
os.chdir(checkout)
print 'Running hg pull --update'
os.system('hg pull --update')
print 'Running make autobuild'
maketarget = 'autobuild-' + ('html' if quick else
('dev' if isdev else 'stable'))
if os.WEXITSTATUS(os.system('cd Doc; make SPHINXBUILD=%s %s' % (SPHINXBUILD, maketarget))) == 2:
print '*' * 80
return
print('Computing changed files')
changed = []
for dirpath, dirnames, filenames in os.walk('Doc/build/html/'):
dir_rel = dirpath[len('Doc/build/html/'):]
for fn in filenames:
local_path = os.path.join(dirpath, fn)
rel_path = os.path.join(dir_rel, fn)
target_path = os.path.join(target, rel_path)
if (os.path.exists(target_path) and
not _files_changed(target_path, local_path)):
changed.append(rel_path)
print 'Copying HTML files to %s' % target
os.system('cp -a Doc/build/html/* %s' % target)
if not quick:
print 'Copying dist files'
os.system('mkdir -p %s/archives' % target)
os.system('cp -a Doc/dist/* %s/archives' % target)
changed.append('archives/')
for fn in os.listdir(os.path.join(target, 'archives')):
changed.append('archives/' + fn)
print '%s files changed' % len(changed)
if changed:
target_ino = os.stat(target).st_ino
targets_dir = os.path.dirname(target)
prefixes = []
for fn in os.listdir(targets_dir):
if os.stat(os.path.join(targets_dir, fn)).st_ino == target_ino:
prefixes.append(fn)
to_purge = []
for prefix in prefixes:
to_purge.extend(prefix + "/" + p for p in changed)
purge_cmd = 'curl -X PURGE "https://docs.python.org/{%s}"' % ','.join(to_purge)
print("Running CDN purge")
os.system(purge_cmd)
print 'Finished'
print '=' * 80
def usage():
print 'Usage:'
print ' %s' % sys.argv[0]
print 'or'
print ' %s [-d] <checkout> <target>' % sys.argv[0]
sys.exit(1)
if __name__ == '__main__':
try:
opts, args = getopt.getopt(sys.argv[1:], 'dq')
except getopt.error:
usage()
quick = devel = False
for opt, _ in opts:
if opt == '-q':
quick = True
if opt == '-d':
devel = True
if devel and not args:
usage()
if args:
if len(args) != 2:
usage()
build_one(os.path.abspath(args[0]), os.path.abspath(args[1]), devel, quick)
else:
for checkout, dest, devel in BRANCHES:
build_one(checkout, dest, devel, quick)
|