3 # Copyright 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.
7 '''Uses the closure compiler to check the ChromeVox javascript files.
9 With no arguments, checks all ChromeVox scripts. If any arguments are
10 specified, only scripts that include any of the specified files will be
11 compiled. A useful argument list is the output of the command
12 'git diff --name-only --relative'.
20 from multiprocessing import pool
22 from jsbundler import Bundle, CalcDeps, ReadSources
23 from jscompilerwrapper import RunCompiler
25 _SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
26 _CHROME_SOURCE_DIR = os.path.normpath(
27 os.path.join(_SCRIPT_DIR, *[os.path.pardir] * 6))
30 def CVoxPath(path='.'):
31 '''Converts a path relative to the top-level chromevox directory to a
32 path relative to the current directory.
34 return os.path.relpath(os.path.join(_SCRIPT_DIR, '..', path))
37 # Externs common to many ChromeVox scripts.
39 CVoxPath('common/externs.js'),
40 CVoxPath('common/chrome_extension_externs.js'),
41 CVoxPath('chromevox/background/externs.js'),
42 CVoxPath('chromevox/injected/externs.js'),
43 CVoxPath('liblouis_nacl/externs.js'),
44 CVoxPath('host/chrome/externs.js')]
46 # List of top-level scripts and externs that we can check.
47 _TOP_LEVEL_SCRIPTS = [
48 [[CVoxPath('chromevox/background/kbexplorer_loader.js')],
49 [CVoxPath('common/chrome_extension_externs.js')]],
50 [[CVoxPath('chromevox/background/loader.js')], _COMMON_EXTERNS],
51 [[CVoxPath('chromevox/background/options_loader.js')], _COMMON_EXTERNS],
52 [[CVoxPath('chromevox/injected/loader.js')], _COMMON_EXTERNS],
53 [[CVoxPath('cvox2/background/loader.js')], _COMMON_EXTERNS],
57 def _Compile(js_files, externs):
59 return RunCompiler(js_files, externs)
60 except KeyboardInterrupt:
61 return (False, 'KeyboardInterrupt')
64 def CheckChromeVox(changed_files=None):
65 if changed_files is not None:
66 changed_files_set = frozenset(
67 (os.path.relpath(path) for path in changed_files))
68 if len(changed_files_set) == 0:
71 changed_files_set = None
78 'chrome/third_party/chromevox/third_party/closure-library/'
80 sources = ReadSources(roots, need_source_text=True,
81 exclude=[re.compile('testing')])
82 work_pool = pool.Pool(len(_TOP_LEVEL_SCRIPTS))
85 for top_level in _TOP_LEVEL_SCRIPTS:
86 tl_files, externs = top_level
88 CalcDeps(bundle, sources, tl_files)
89 bundle.Add((sources[name] for name in tl_files))
90 ordered_paths = list(bundle.GetInPaths())
91 if (changed_files_set is not None and
92 changed_files_set.isdisjoint(ordered_paths + externs)):
94 print 'Compiling %s' % ','.join(tl_files)
95 results.append([tl_files,
96 work_pool.apply_async(
98 args=[ordered_paths, externs])])
99 for result in results:
101 success, output = result[1].get()
103 ret_output += '\nFrom compiling %s:\n%s\n' % (','.join(tl_files),
108 work_pool.terminate()
112 return (ret_success, ret_output)
116 parser = optparse.OptionParser(description=__doc__)
117 parser.usage = '%prog [<changed_file>...]'
118 _, args = parser.parse_args()
122 changed_paths = (os.path.relpath(p) for p in args)
123 success, output = CheckChromeVox(changed_paths)
126 return int(not success)
129 if __name__ == '__main__':