Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 #!/usr/bin/python | |
| 2 | |
| 3 # Copyright (c) 2011 Google Inc. 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 """Using the JSON dumped by the dump-dependency-json generator, | |
| 8 generate input suitable for graphviz to render a dependency graph of | |
| 9 targets.""" | |
| 10 | |
| 11 import collections | |
| 12 import json | |
| 13 import sys | |
| 14 | |
| 15 def ParseTarget(target): | |
| 16 target, _, suffix = target.partition('#') | |
| 17 filename, _, target = target.partition(':') | |
| 18 return filename, target, suffix | |
| 19 | |
| 20 | |
| 21 def LoadEdges(filename, targets): | |
| 22 """Load the edges map from the dump file, and filter it to only | |
| 23 show targets in |targets| and their depedendents.""" | |
| 24 | |
| 25 file = open('dump.json') | |
| 26 edges = json.load(file) | |
| 27 file.close() | |
| 28 | |
| 29 # Copy out only the edges we're interested in from the full edge list. | |
| 30 target_edges = {} | |
| 31 to_visit = targets[:] | |
| 32 while to_visit: | |
| 33 src = to_visit.pop() | |
| 34 if src in target_edges: | |
| 35 continue | |
| 36 target_edges[src] = edges[src] | |
| 37 to_visit.extend(edges[src]) | |
| 38 | |
| 39 return target_edges | |
| 40 | |
| 41 | |
| 42 def WriteGraph(edges): | |
| 43 """Print a graphviz graph to stdout. | |
| 44 |edges| is a map of target to a list of other targets it depends on.""" | |
| 45 | |
| 46 # Bucket targets by file. | |
| 47 files = collections.defaultdict(list) | |
| 48 for src, dst in edges.items(): | |
| 49 build_file, target_name, toolset = ParseTarget(src) | |
| 50 files[build_file].append(src) | |
| 51 | |
| 52 print 'digraph D {' | |
| 53 print ' fontsize=8' # Used by subgraphs. | |
| 54 print ' node [fontsize=8]' | |
| 55 | |
| 56 # Output nodes by file. We must first write out each node within | |
| 57 # its file grouping before writing out any edges that may refer | |
| 58 # to those nodes. | |
| 59 for filename, targets in files.items(): | |
| 60 if len(targets) == 1: | |
| 61 # If there's only one node for this file, simplify | |
| 62 # the display by making it a box without an internal node. | |
| 63 target = targets[0] | |
| 64 build_file, target_name, toolset = ParseTarget(target) | |
| 65 print ' "%s" [shape=box, label="%s\\n%s"]' % (target, filename, | |
| 66 target_name) | |
| 67 else: | |
| 68 # Group multiple nodes together in a subgraph. | |
| 69 print ' subgraph "cluster_%s" {' % filename | |
| 70 print ' label = "%s"' % filename | |
| 71 for target in targets: | |
| 72 build_file, target_name, toolset = ParseTarget(target) | |
| 73 print ' "%s" [label="%s"]' % (target, target_name) | |
| 74 print ' }' | |
| 75 | |
| 76 # Now that we've placed all the nodes within subgraphs, output all | |
| 77 # the edges between nodes. | |
| 78 for src, dsts in edges.items(): | |
| 79 for dst in dsts: | |
| 80 print ' "%s" -> "%s"' % (src, dst) | |
| 81 | |
| 82 print '}' | |
| 83 | |
| 84 | |
| 85 if __name__ == '__main__': | |
| 86 if len(sys.argv) < 2: | |
| 87 print __doc__ | |
|
Mark Mentovai
2011/05/26 00:38:13
I’d send this stuff to sys.stderr.
| |
| 88 print | |
| 89 print 'usage: %s target1 target2...' % (sys.argv[0]) | |
| 90 sys.exit(1) | |
| 91 | |
| 92 edges = LoadEdges('dump.json', sys.argv[1:]) | |
| 93 | |
| 94 WriteGraph(edges) | |
| OLD | NEW |