7
7
# build_docs.py [-h] [-d] [-q] [-b 3.6] [-r BUILD_ROOT] [-w WWW_ROOT]
8
8
# [--devguide-checkout DEVGUIDE_CHECKOUT]
9
9
# [--devguide-target DEVGUIDE_TARGET]
10
+ # [--skip-cache-invalidation] [--group GROUP] [--git]
11
+ # [--log-directory LOG_DIRECTORY]
12
+ # [--languages [fr [fr ...]]]
13
+ #
10
14
#
11
15
# Without any arguments builds docs for all branches configured in the
12
16
# global BRANCHES value, ignoring the -d flag as it's given in the
17
21
# -d allow the docs to be built even if the branch is in
18
22
# development mode (i.e. version contains a, b or c).
19
23
#
24
+ # Translations are fetched from github repositories according to PEP
25
+ # 545. --languages allow select translations, use "--languages" to
26
+ # build all translations (default) or "--languages en" to skip all
27
+ # translations (as en is the untranslated version)..
28
+ #
20
29
# This script was originally created and by Georg Brandl in March 2010. Modified
21
30
# by Benjamin Peterson to do CDN cache invalidation.
22
31
25
34
import os
26
35
import subprocess
27
36
import sys
37
+ import shutil
28
38
29
39
30
40
BRANCHES = [
35
45
(2.7 , False )
36
46
]
37
47
48
+ LANGUAGES = [
49
+ 'en' ,
50
+ 'fr'
51
+ ]
52
+
38
53
39
54
def _file_unchanged (old , new ):
40
55
with open (old , "rb" ) as fp1 , open (new , "rb" ) as fp2 :
@@ -80,11 +95,57 @@ def changed_files(directory, other):
80
95
return changed
81
96
82
97
98
+ def git_clone (repository , directory , branch = 'master' ):
99
+ """Clone or update the given branch of the given repository in the
100
+ given directory.
101
+ """
102
+ logging .info ("Updating repository %s in %s" , repository , directory )
103
+ try :
104
+ shell_out ("git -C {} checkout {}" .format (directory , branch ))
105
+ shell_out ("git -C {} pull --ff-only" .format (directory ))
106
+ except subprocess .CalledProcessError :
107
+ if os .path .exists (directory ):
108
+ shutil .rmtree (directory )
109
+ logging .info ("Cloning %s into %s" , repository , repository )
110
+ os .makedirs (directory , mode = 0o775 )
111
+ shell_out ("git clone --depth 1 --no-single-branch {} {}" .format (
112
+ repository , directory ))
113
+ shell_out ("git -C {} checkout {}" .format (directory , branch ))
114
+
115
+
116
+ def pep_545_tag_to_gettext_tag (tag ):
117
+ """Transforms PEP 545 language tags like "pt-br" to gettext language
118
+ tags like "pt_BR". (Note that none of those are IETF language tags
119
+ like "pt-BR").
120
+ """
121
+ if '-' not in tag :
122
+ return tag
123
+ language , region = tag .split ('-' )
124
+ return language + '_' + region .upper ()
125
+
126
+
83
127
def build_one (version , isdev , quick , sphinxbuild , build_root , www_root ,
84
128
skip_cache_invalidation = False , group = 'docs' , git = False ,
85
- log_directory = '/var/log/docsbuild/' ):
129
+ log_directory = '/var/log/docsbuild/' , language = 'en' ):
86
130
checkout = build_root + "/python" + str (version ).replace ('.' , '' )
87
- target = www_root + "/" + str (version )
131
+ sphinxopts = ''
132
+ if not language or language == 'en' :
133
+ target = os .path .join (www_root , str (version ))
134
+ else :
135
+ target = os .path .join (www_root , language , str (version ))
136
+ gettext_language_tag = pep_545_tag_to_gettext_tag (language )
137
+ locale_dirs = os .path .join (build_root , 'locale' )
138
+ locale_clone_dir = os .path .join (
139
+ locale_dirs , gettext_language_tag , 'LC_MESSAGES' )
140
+ locale_repo = 'https://github.com/python/python-docs-{}.git' .format (
141
+ language )
142
+ git_clone (locale_repo , locale_clone_dir , version )
143
+ sphinxopts += ('-D locale_dirs={} '
144
+ '-D language={} '
145
+ '-D gettext_compact=0' ).format (locale_dirs ,
146
+ gettext_language_tag )
147
+ if not os .path .exists (target ):
148
+ os .makedirs (target , mode = 0o775 )
88
149
logging .info ("Doc autobuild started in %s" , checkout )
89
150
os .chdir (checkout )
90
151
@@ -98,8 +159,9 @@ def build_one(version, isdev, quick, sphinxbuild, build_root, www_root,
98
159
maketarget = "autobuild-" + ("dev" if isdev else "stable" ) + ("-html" if quick else "" )
99
160
logging .info ("Running make %s" , maketarget )
100
161
logname = os .path .basename (checkout ) + ".log"
101
- shell_out ("cd Doc; make SPHINXBUILD=%s %s >> %s 2>&1" %
102
- (sphinxbuild , maketarget , os .path .join (log_directory , logname )))
162
+ shell_out ("cd Doc; make SPHINXBUILD=%s SPHINXOPTS='%s' %s >> %s 2>&1" %
163
+ (sphinxbuild , sphinxopts , maketarget ,
164
+ os .path .join (log_directory , logname )))
103
165
104
166
changed = changed_files (os .path .join (checkout , "Doc/build/html" ), target )
105
167
logging .info ("Copying HTML files to %s" , target )
@@ -203,10 +265,17 @@ def parse_args():
203
265
"--log-directory" ,
204
266
help = "Directory used to store logs." ,
205
267
default = "/var/log/docsbuild/" )
268
+ parser .add_argument (
269
+ "--languages" ,
270
+ nargs = '*' ,
271
+ default = LANGUAGES ,
272
+ help = "Language translation, as a PEP 545 language tag like"
273
+ " 'fr' or 'pt-br'." ,
274
+ metavar = 'fr' )
206
275
return parser .parse_args ()
207
276
208
277
209
- if __name__ == '__main__' :
278
+ def main () :
210
279
args = parse_args ()
211
280
if sys .stderr .isatty ():
212
281
logging .basicConfig (format = "%(levelname)s:%(message)s" ,
@@ -217,19 +286,27 @@ def parse_args():
217
286
"docsbuild.log" ))
218
287
logging .root .setLevel (logging .DEBUG )
219
288
sphinxbuild = os .path .join (args .build_root , "environment/bin/sphinx-build" )
220
- try :
221
- if args .branch :
222
- build_one (args .branch , args .devel , args .quick , sphinxbuild ,
223
- args .build_root , args .www_root ,
224
- args .skip_cache_invalidation ,
225
- args .group , args .git , args .log_directory )
226
- else :
227
- for version , devel in BRANCHES :
289
+ if args .branch :
290
+ branches_to_do = [(args .branch , args .devel )]
291
+ else :
292
+ branches_to_do = BRANCHES
293
+ if not args .languages :
294
+ # Allow "--languages" to build all languages (as if not given)
295
+ # instead of none. "--languages en" builds *no* translation,
296
+ # as "en" is the untranslated one.
297
+ args .languages = LANGUAGES
298
+ for version , devel in branches_to_do :
299
+ for language in args .languages :
300
+ try :
228
301
build_one (version , devel , args .quick , sphinxbuild ,
229
302
args .build_root , args .www_root ,
230
303
args .skip_cache_invalidation , args .group , args .git ,
231
- args .log_directory )
232
- build_devguide (args .devguide_checkout , args .devguide_target ,
233
- sphinxbuild , args .skip_cache_invalidation )
234
- except Exception :
235
- logging .exception ("docs build raised exception" )
304
+ args .log_directory , language )
305
+ except Exception :
306
+ logging .exception ("docs build raised exception" )
307
+ build_devguide (args .devguide_checkout , args .devguide_target ,
308
+ sphinxbuild , args .skip_cache_invalidation )
309
+
310
+
311
+ if __name__ == '__main__' :
312
+ main ()
0 commit comments