3 # Copyright (c) 2014 The Chromium Authors. All rights reserved.
4 # Use of this source code is governed by a BSD-style license that can be
5 # found in the LICENSE file.
18 SCRIPT_DIR
= os
.path
.dirname(os
.path
.abspath(__file__
))
19 DOC_DIR
= os
.path
.dirname(SCRIPT_DIR
)
22 ChannelInfo
= collections
.namedtuple('ChannelInfo', ['branch', 'version'])
27 sys
.stderr
.write(str(msg
) + '\n')
33 url
= 'http://omahaproxy.appspot.com/json'
34 u
= urllib2
.urlopen(url
)
36 data
= json
.loads(u
.read())
43 if osname
not in ('win', 'mac', 'linux'):
45 for version_row
in os_row
['versions']:
46 channel
= version_row
['channel']
47 # We don't display canary docs.
48 if channel
== 'canary':
51 version
= version_row
['version'].split('.')[0] # Major version
52 branch
= version_row
['true_branch']
56 if channel
in channel_info
:
57 existing_info
= channel_info
[channel
]
58 if branch
!= existing_info
.branch
:
59 sys
.stderr
.write('Warning: found different branch numbers for '
60 'channel %s: %s vs %s. Using %s.\n' % (
61 channel
, branch
, existing_info
.branch
, existing_info
.branch
))
63 channel_info
[channel
] = ChannelInfo(branch
, version
)
68 def RemoveFile(filename
):
69 if os
.path
.exists(filename
):
73 def RemoveDir(dirname
):
74 if os
.path
.exists(dirname
):
75 shutil
.rmtree(dirname
)
78 def GetSVNRepositoryRoot(branch
):
80 return 'http://src.chromium.org/chrome/trunk/src'
81 return 'http://src.chromium.org/chrome/branches/%s/src' % branch
84 def CheckoutPepperDocs(branch
, doc_dirname
):
85 Trace('Removing directory %s' % doc_dirname
)
86 RemoveDir(doc_dirname
)
88 svn_root_url
= GetSVNRepositoryRoot(branch
)
90 for subdir
in ('api', 'generators', 'cpp', 'utility'):
91 url
= svn_root_url
+ '/ppapi/%s' % subdir
92 cmd
= ['svn', 'co', url
, os
.path
.join(doc_dirname
, subdir
)]
93 Trace('Checking out docs into %s:\n %s' % (doc_dirname
, ' '.join(cmd
)))
94 subprocess
.check_call(cmd
)
96 # The IDL generator needs PLY (a python lexing library); check it out into
98 url
= svn_root_url
+ '/third_party/ply'
99 ply_dirname
= os
.path
.join(doc_dirname
, 'generators', 'ply')
100 cmd
= ['svn', 'co', url
, ply_dirname
]
101 Trace('Checking out PLY into %s:\n %s' % (ply_dirname
, ' '.join(cmd
)))
102 subprocess
.check_call(cmd
)
105 def FixPepperDocLinks(doc_dirname
):
106 # TODO(binji): We can remove this step when the correct links are in the
108 Trace('Looking for links to fix in Pepper headers...')
109 for root
, dirs
, filenames
in os
.walk(doc_dirname
):
110 # Don't recurse into .svn
114 for filename
in filenames
:
115 header_filename
= os
.path
.join(root
, filename
)
116 Trace(' Checking file %r...' % header_filename
)
118 '<a href="/native-client/{{pepperversion}}/devguide/coding/audio">':
119 '<a href="/native-client/devguide/coding/audio.html">',
120 '<a href="/native-client/devguide/coding/audio">':
121 '<a href="/native-client/devguide/coding/audio.html">',
122 '<a href="/native-client/{{pepperversion}}/pepperc/globals_defs"':
123 '<a href="globals_defs.html"',
124 '<a href="../pepperc/ppb__image__data_8h.html">':
125 '<a href="../c/ppb__image__data_8h.html">'}
127 with
open(header_filename
) as f
:
131 for find
, replace
in replacements
.iteritems():
132 pos
= line
.find(find
)
134 Trace(' Found %r...' % find
)
136 line
= line
[:pos
] + replace
+ line
[pos
+ len(find
):]
140 Trace(' Writing new file.')
141 with
open(header_filename
, 'w') as f
:
145 def GenerateCHeaders(pepper_version
, doc_dirname
):
146 script
= os
.path
.join(os
.pardir
, 'generators', 'generator.py')
147 cwd
= os
.path
.join(doc_dirname
, 'api')
148 out_dirname
= os
.path
.join(os
.pardir
, 'c')
149 cmd
= [sys
.executable
, script
, '--cgen', '--release', 'M' + pepper_version
,
150 '--wnone', '--dstroot', out_dirname
]
151 Trace('Generating C Headers for version %s\n %s' % (
152 pepper_version
, ' '.join(cmd
)))
153 subprocess
.check_call(cmd
, cwd
=cwd
)
156 def GenerateDoxyfile(template_filename
, out_dirname
, doc_dirname
, doxyfile
):
157 Trace('Writing Doxyfile "%s" (from template %s)' % (
158 doxyfile
, template_filename
))
160 with
open(template_filename
) as f
:
163 with
open(doxyfile
, 'w') as f
:
165 'out_dirname': out_dirname
,
166 'doc_dirname': doc_dirname
,
167 'script_dirname': SCRIPT_DIR
})
170 def RunDoxygen(out_dirname
, doxyfile
):
171 Trace('Removing old output directory %s' % out_dirname
)
172 RemoveDir(out_dirname
)
174 Trace('Making new output directory %s' % out_dirname
)
175 os
.makedirs(out_dirname
)
177 cmd
= ['doxygen', doxyfile
]
178 Trace('Running Doxygen:\n %s' % ' '.join(cmd
))
179 subprocess
.check_call(cmd
)
182 def RunDoxyCleanup(out_dirname
):
183 script
= os
.path
.join(SCRIPT_DIR
, 'doxy_cleanup.py')
184 cmd
= [sys
.executable
, script
, out_dirname
]
187 Trace('Running doxy_cleanup:\n %s' % ' '.join(cmd
))
188 subprocess
.check_call(cmd
)
191 def RunRstIndex(kind
, channel
, pepper_version
, out_dirname
, out_rst_filename
):
192 assert kind
in ('root', 'c', 'cpp')
193 script
= os
.path
.join(SCRIPT_DIR
, 'rst_index.py')
194 cmd
= [sys
.executable
, script
,
196 '--channel', channel
,
197 '--version', pepper_version
,
199 '-o', out_rst_filename
]
200 Trace('Running rst_index:\n %s' % ' '.join(cmd
))
201 subprocess
.check_call(cmd
)
204 def GenerateDocs(root_dirname
, channel
, pepper_version
, branch
):
205 Trace('Generating docs for %s (branch %s)' % (channel
, branch
))
206 pepper_dirname
= 'pepper_%s' % channel
207 out_dirname
= os
.path
.join(root_dirname
, pepper_dirname
)
210 svn_dirname
= tempfile
.mkdtemp(prefix
=pepper_dirname
)
211 doxyfile_dirname
= tempfile
.mkdtemp(prefix
='%s_doxyfiles' % pepper_dirname
)
213 CheckoutPepperDocs(branch
, svn_dirname
)
214 FixPepperDocLinks(svn_dirname
)
215 GenerateCHeaders(pepper_version
, svn_dirname
)
220 # Generate Root index
221 rst_index_root
= os
.path
.join(DOC_DIR
, pepper_dirname
, 'index.rst')
222 RunRstIndex('root', channel
, pepper_version
, out_dirname
, rst_index_root
)
225 out_dirname_c
= os
.path
.join(out_dirname
, 'c')
226 doxyfile_c
= os
.path
.join(doxyfile_dirname
, 'Doxyfile.c.%s' % channel
)
227 doxyfile_c_template
= os
.path
.join(SCRIPT_DIR
, 'Doxyfile.c.template')
228 rst_index_c
= os
.path
.join(DOC_DIR
, pepper_dirname
, 'c', 'index.rst')
229 GenerateDoxyfile(doxyfile_c_template
, out_dirname_c
, svn_dirname
,
231 RunDoxygen(out_dirname_c
, doxyfile_c
)
232 RunDoxyCleanup(out_dirname_c
)
233 RunRstIndex('c', channel
, pepper_version
, out_dirname_c
, rst_index_c
)
236 out_dirname_cpp
= os
.path
.join(out_dirname
, 'cpp')
237 doxyfile_cpp
= os
.path
.join(doxyfile_dirname
, 'Doxyfile.cpp.%s' % channel
)
238 doxyfile_cpp_template
= os
.path
.join(SCRIPT_DIR
, 'Doxyfile.cpp.template')
239 rst_index_cpp
= os
.path
.join(DOC_DIR
, pepper_dirname
, 'cpp', 'index.rst')
240 GenerateDoxyfile(doxyfile_cpp_template
, out_dirname_cpp
, svn_dirname
,
242 RunDoxygen(out_dirname_cpp
, doxyfile_cpp
)
243 RunDoxyCleanup(out_dirname_cpp
)
244 RunRstIndex('cpp', channel
, pepper_version
, out_dirname_cpp
, rst_index_cpp
)
247 RemoveDir(svn_dirname
)
248 RemoveDir(doxyfile_dirname
)
252 parser
= optparse
.OptionParser(usage
='Usage: %prog [options] <out_directory>')
253 parser
.add_option('-v', '--verbose',
254 help='Verbose output', action
='store_true')
255 options
, dirs
= parser
.parse_args(argv
)
261 parser
.error('Expected an output directory')
263 channel_info
= GetChannelInfo()
264 for channel
, info
in channel_info
.iteritems():
265 GenerateDocs(dirs
[0], channel
, info
.version
, info
.branch
)
270 if __name__
== '__main__':
272 rtn
= main(sys
.argv
[1:])
273 except KeyboardInterrupt:
274 sys
.stderr
.write('%s: interrupted\n' % os
.path
.basename(__file__
))