Upstream version 5.34.92.0
[platform/framework/web/crosswalk.git] / src / native_client_sdk / src / doc / doxygen / generate_docs.py
1 #!/usr/bin/python
2
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.
6
7 import collections
8 import json
9 import optparse
10 import os
11 import shutil
12 import subprocess
13 import sys
14 import tempfile
15 import urllib2
16
17
18 SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
19 DOC_DIR = os.path.dirname(SCRIPT_DIR)
20
21
22 ChannelInfo = collections.namedtuple('ChannelInfo', ['branch', 'version'])
23
24
25 def Trace(msg):
26   if Trace.verbose:
27     sys.stderr.write(str(msg) + '\n')
28
29 Trace.verbose = False
30
31
32 def GetChannelInfo():
33   url = 'http://omahaproxy.appspot.com/json'
34   u = urllib2.urlopen(url)
35   try:
36     data = json.loads(u.read())
37   finally:
38     u.close()
39
40   channel_info = {}
41   for os_row in data:
42     osname = os_row['os']
43     if osname not in ('win', 'mac', 'linux'):
44       continue
45     for version_row in os_row['versions']:
46       channel = version_row['channel']
47       # We don't display canary docs.
48       if channel == 'canary':
49         continue
50
51       version = version_row['version'].split('.')[0]  # Major version
52       branch = version_row['true_branch']
53       if branch is None:
54         branch = 'trunk'
55
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))
62       else:
63         channel_info[channel] = ChannelInfo(branch, version)
64
65   return channel_info
66
67
68 def RemoveFile(filename):
69   if os.path.exists(filename):
70     os.remove(filename)
71
72
73 def RemoveDir(dirname):
74   if os.path.exists(dirname):
75     shutil.rmtree(dirname)
76
77
78 def GetSVNRepositoryRoot(branch):
79   if branch == 'trunk':
80     return 'http://src.chromium.org/chrome/trunk/src'
81   return 'http://src.chromium.org/chrome/branches/%s/src' % branch
82
83
84 def CheckoutPepperDocs(branch, doc_dirname):
85   Trace('Removing directory %s' % doc_dirname)
86   RemoveDir(doc_dirname)
87
88   svn_root_url = GetSVNRepositoryRoot(branch)
89
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)
95
96   # The IDL generator needs PLY (a python lexing library); check it out into
97   # generators.
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)
103
104
105 def GenerateCHeaders(pepper_version, doc_dirname):
106   script = os.path.join(os.pardir, 'generators', 'generator.py')
107   cwd = os.path.join(doc_dirname, 'api')
108   out_dirname = os.path.join(os.pardir, 'c')
109   cmd = [sys.executable, script, '--cgen', '--release', 'M' + pepper_version,
110          '--wnone', '--dstroot', out_dirname]
111   Trace('Generating C Headers for version %s\n  %s' % (
112       pepper_version, ' '.join(cmd)))
113   subprocess.check_call(cmd, cwd=cwd)
114
115
116 def GenerateDoxyfile(template_filename, out_dirname, doc_dirname, doxyfile):
117   Trace('Writing Doxyfile "%s" (from template %s)' % (
118     doxyfile, template_filename))
119
120   with open(template_filename) as f:
121     data = f.read()
122
123   with open(doxyfile, 'w') as f:
124     f.write(data % {
125       'out_dirname': out_dirname,
126       'doc_dirname': doc_dirname,
127       'script_dirname': SCRIPT_DIR})
128
129
130 def RunDoxygen(out_dirname, doxyfile):
131   Trace('Removing old output directory %s' % out_dirname)
132   RemoveDir(out_dirname)
133
134   Trace('Making new output directory %s' % out_dirname)
135   os.makedirs(out_dirname)
136
137   cmd = ['doxygen', doxyfile]
138   Trace('Running Doxygen:\n  %s' % ' '.join(cmd))
139   subprocess.check_call(cmd)
140
141
142 def RunDoxyCleanup(out_dirname):
143   script = os.path.join(SCRIPT_DIR, 'doxy_cleanup.py')
144   cmd = [sys.executable, script, out_dirname]
145   if Trace.verbose:
146     cmd.append('-v')
147   Trace('Running doxy_cleanup:\n  %s' % ' '.join(cmd))
148   subprocess.check_call(cmd)
149
150
151 def RunRstIndex(kind, channel, pepper_version, out_dirname, out_rst_filename):
152   assert kind in ('root', 'c', 'cpp')
153   script = os.path.join(SCRIPT_DIR, 'rst_index.py')
154   cmd = [sys.executable, script,
155          '--' + kind,
156          '--channel', channel,
157          '--version', pepper_version,
158          out_dirname,
159          '-o', out_rst_filename]
160   Trace('Running rst_index:\n  %s' % ' '.join(cmd))
161   subprocess.check_call(cmd)
162
163
164 def GenerateDocs(root_dirname, channel, pepper_version, branch):
165   Trace('Generating docs for %s (branch %s)' % (channel, branch))
166   pepper_dirname = 'pepper_%s' % channel
167   out_dirname = os.path.join(root_dirname, pepper_dirname)
168
169   try:
170     svn_dirname = tempfile.mkdtemp(prefix=pepper_dirname)
171     doxyfile_dirname = tempfile.mkdtemp(prefix='%s_doxyfiles' % pepper_dirname)
172
173     CheckoutPepperDocs(branch, svn_dirname)
174     GenerateCHeaders(pepper_version, svn_dirname)
175
176     doxyfile_c = ''
177     doxyfile_cpp = ''
178
179     # Generate Root index
180     rst_index_root = os.path.join(DOC_DIR, pepper_dirname, 'index.rst')
181     RunRstIndex('root', channel, pepper_version, out_dirname, rst_index_root)
182
183     # Generate C docs
184     out_dirname_c = os.path.join(out_dirname, 'c')
185     doxyfile_c = os.path.join(doxyfile_dirname, 'Doxyfile.c.%s' % channel)
186     doxyfile_c_template = os.path.join(SCRIPT_DIR, 'Doxyfile.c.template')
187     rst_index_c = os.path.join(root_dirname, pepper_dirname, 'c', 'index.rst')
188     GenerateDoxyfile(doxyfile_c_template, out_dirname_c, svn_dirname,
189                      doxyfile_c)
190     RunDoxygen(out_dirname_c, doxyfile_c)
191     RunDoxyCleanup(out_dirname_c)
192     RunRstIndex('c', channel, pepper_version, out_dirname_c, rst_index_c)
193
194     # Generate C++ docs
195     out_dirname_cpp = os.path.join(out_dirname, 'cpp')
196     doxyfile_cpp = os.path.join(doxyfile_dirname, 'Doxyfile.cpp.%s' % channel)
197     doxyfile_cpp_template = os.path.join(SCRIPT_DIR, 'Doxyfile.cpp.template')
198     rst_index_cpp = os.path.join(root_dirname, pepper_dirname, 'cpp',
199                                  'index.rst')
200     GenerateDoxyfile(doxyfile_cpp_template, out_dirname_cpp, svn_dirname,
201                      doxyfile_cpp)
202     RunDoxygen(out_dirname_cpp, doxyfile_cpp)
203     RunDoxyCleanup(out_dirname_cpp)
204     RunRstIndex('cpp', channel, pepper_version, out_dirname_cpp, rst_index_cpp)
205   finally:
206     # Cleanup
207     RemoveDir(svn_dirname)
208     RemoveDir(doxyfile_dirname)
209
210
211 def main(argv):
212   parser = optparse.OptionParser(usage='Usage: %prog [options] <out_directory>')
213   parser.add_option('-v', '--verbose',
214                     help='Verbose output', action='store_true')
215   options, dirs = parser.parse_args(argv)
216
217   if options.verbose:
218     Trace.verbose = True
219
220   if len(dirs) != 1:
221     parser.error('Expected an output directory')
222
223   channel_info = GetChannelInfo()
224   for channel, info in channel_info.iteritems():
225     GenerateDocs(dirs[0], channel, info.version, info.branch)
226
227   return 0
228
229
230 if __name__ == '__main__':
231   try:
232     rtn = main(sys.argv[1:])
233   except KeyboardInterrupt:
234     sys.stderr.write('%s: interrupted\n' % os.path.basename(__file__))
235     rtn = 1
236   sys.exit(rtn)