3 # Copyright 2015 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.
7 '''Print the dependency tree for a JavaScript module.
9 Given one or more root directories, specified by -r options and one top-level
10 file, walk the dependency tree and print all modules encountered.
11 A module is only expanded once; on a second encounter, its dependencies
12 are represented by a line containing the characters '[...]' as a short-hand.
19 from jsbundler
import ReadSources
23 '''Prints an error message and exit the program.'''
24 print >>sys
.stderr
, message
28 def CreateOptionParser():
29 parser
= optparse
.OptionParser(description
=__doc__
)
30 parser
.usage
= '%prog [options] <top_level_file>'
31 parser
.add_option('-r', '--root', dest
='roots', action
='append', default
=[],
33 help='Roots of directory trees to scan for sources. '
34 'If none specified, all of ChromeVox and closure sources '
40 script_dir
= os
.path
.dirname(os
.path
.abspath(__file__
))
41 source_root_dir
= os
.path
.join(script_dir
, *[os
.path
.pardir
] * 6)
42 return [os
.path
.relpath(os
.path
.join(script_dir
, os
.path
.pardir
)),
44 os
.path
.join(source_root_dir
, 'chrome', 'third_party',
45 'chromevox', 'third_party',
46 'closure-library', 'closure'))]
49 def WalkDeps(sources
, start_source
):
50 def Walk(source
, depth
):
52 if source
.GetInPath() in expanded
and len(source
.requires
) > 0:
53 print '%s[...]' % indent
55 expanded
.add(source
.GetInPath())
56 for require
in source
.requires
:
57 if not require
in providers
:
58 Die('%s not provided, required by %s' % (require
, source
.GetInPath()))
59 require_source
= providers
[require
]
60 print '%s%s (%s)' % (indent
, require
, require_source
.GetInPath())
61 Walk(require_source
, depth
+ 1)
63 # Create a map from provided module names to source objects.
66 for source
in sources
.values():
67 for provide
in source
.provides
:
68 if provide
in providers
:
69 Die('%s provided multiple times' % provide
)
70 providers
[provide
] = source
72 print '(%s)' % start_source
.GetInPath()
77 parser
= CreateOptionParser()
78 options
, args
= parser
.parse_args()
80 Die('Exactly one top-level source file must be specified.')
82 roots
= options
.roots
or DefaultRoots()
83 sources
= ReadSources(roots
=roots
, source_files
=[start_path
])
84 start_source
= sources
[start_path
]
85 WalkDeps(sources
, start_source
)
88 if __name__
== '__main__':