1868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)# Copyright 2013 The Chromium Authors. All rights reserved.
2868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)# Use of this source code is governed by a BSD-style license that can be
3868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)# found in the LICENSE file.
4868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
5868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)import os
6868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)import shutil
7868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)import subprocess
8868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)import sys
9868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
10868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)BASE_DIR = os.path.dirname(os.path.abspath(__file__))
12868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
13868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
14868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)def main():
15868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if len(sys.argv) != 2:
16868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    print 'usage: %s <output.html>' % sys.argv[0]
17868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return 1
18868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  env = os.environ.copy()
19868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  env['GYP_GENERATORS'] = 'dump_dependency_json'
20868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  print 'Dumping dependencies...'
21868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  popen = subprocess.Popen(
22868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      ['python', 'build/gyp_chromium'],
23868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      shell=True, env=env)
24868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  popen.communicate()
25868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if popen.returncode != 0:
26868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return popen.returncode
27868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  print 'Finding problems...'
28868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  popen = subprocess.Popen(
29868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      ['python', 'tools/gyp-explain.py', '--dot',
30868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)       'chrome.gyp:browser#', 'core.gyp:webcore#'],
31868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      stdout=subprocess.PIPE,
32868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      shell=True)
33868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  out, _ = popen.communicate()
34868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if popen.returncode != 0:
35868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return popen.returncode
36868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
37868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  # Break into pairs to uniq to make graph less of a mess.
38868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  print 'Simplifying...'
39868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  deduplicated = set()
40868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  lines = out.splitlines()[2:-1]
41868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  for line in lines:
42868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    line = line.strip('\r\n ;')
43868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    pairs = line.split(' -> ')
44868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    for i in range(len(pairs) - 1):
45868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      deduplicated.add('%s -> %s;' % (pairs[i], pairs[i + 1]))
46868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  graph = 'strict digraph {\n' + '\n'.join(sorted(deduplicated)) + '\n}'
47868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
48868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  print 'Writing report to %s...' % sys.argv[1]
49868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  path_count = len(out.splitlines())
50868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  with open(os.path.join(BASE_DIR, 'viz.js', 'viz.js')) as f:
51868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    viz_js = f.read()
52868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  with open(sys.argv[1], 'w') as f:
53868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    f.write(PREFIX % path_count)
54868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    f.write(graph)
55868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    f.write(SUFFIX % viz_js)
56868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  print 'Done.'
57868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
58868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
59868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)PREFIX = r'''<!DOCTYPE html>
60868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)<html>
61868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  <head>
62868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    <meta charset="utf-8">
63868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    <title>Undesirable Dependencies</title>
64868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  </head>
65868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  <body>
66868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    <h1>Undesirable Dependencies</h1>
67868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)<h2>browser &rarr; webcore</h2>
68868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)<h3>%d paths</h3>
69868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    <script type="text/vnd.graphviz" id="graph">
70868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)'''
71868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
72868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
73868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)SUFFIX = r'''
74868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    </script>
75868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    <script>%s</script>
76868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    <div id="output">Rendering...</div>
77868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    <script>
78868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      setTimeout(function() {
79868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          document.getElementById("output").innerHTML =
80868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)              Viz(document.getElementById("graph").innerHTML, "svg");
81868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        }, 1);
82868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    </script>
83868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  </body>
84868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)</html>
85868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)'''
86868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
87868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
88868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)if __name__ == '__main__':
89868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  sys.exit(main())
90