| OLD | NEW |
| 1 #!/usr/bin/python | 1 #!/usr/bin/python |
| 2 # Copyright 2015 The Chromium Authors. All rights reserved. | 2 # Copyright 2015 The Chromium Authors. All rights reserved. |
| 3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
| 4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
| 5 | 5 |
| 6 """Runs Closure compiler on JavaScript files to check for errors and produce | 6 """Runs Closure compiler on JavaScript files to check for errors and produce |
| 7 minified output.""" | 7 minified output.""" |
| 8 | 8 |
| 9 import argparse | 9 import argparse |
| 10 import os | 10 import os |
| (...skipping 24 matching lines...) Expand all Loading... |
| 35 | 35 |
| 36 _MAP_FILE_FORMAT = "%s.map" | 36 _MAP_FILE_FORMAT = "%s.map" |
| 37 | 37 |
| 38 _POLYMER_EXTERNS = os.path.join(_CURRENT_DIR, "externs", "polymer-1.0.js") | 38 _POLYMER_EXTERNS = os.path.join(_CURRENT_DIR, "externs", "polymer-1.0.js") |
| 39 | 39 |
| 40 def __init__(self, verbose=False): | 40 def __init__(self, verbose=False): |
| 41 """ | 41 """ |
| 42 Args: | 42 Args: |
| 43 verbose: Whether this class should output diagnostic messages. | 43 verbose: Whether this class should output diagnostic messages. |
| 44 """ | 44 """ |
| 45 self._runner_jar = os.path.join(_CURRENT_DIR, "runner", "runner.jar") | 45 self._compiler_jar = os.path.join(_CURRENT_DIR, "compiler", "compiler.jar") |
| 46 self._target = None | 46 self._target = None |
| 47 self._temp_files = [] | 47 self._temp_files = [] |
| 48 self._verbose = verbose | 48 self._verbose = verbose |
| 49 self._error_filter = error_filter.PromiseErrorFilter() | 49 self._error_filter = error_filter.PromiseErrorFilter() |
| 50 | 50 |
| 51 def _nuke_temp_files(self): | 51 def _nuke_temp_files(self): |
| 52 """Deletes any temp files this class knows about.""" | 52 """Deletes any temp files this class knows about.""" |
| 53 if not self._temp_files: | 53 if not self._temp_files: |
| 54 return | 54 return |
| 55 | 55 |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 181 content: A string of the file contens to write to a temporary file. | 181 content: A string of the file contens to write to a temporary file. |
| 182 | 182 |
| 183 Return: | 183 Return: |
| 184 The filepath of the newly created, written, and closed temporary file. | 184 The filepath of the newly created, written, and closed temporary file. |
| 185 """ | 185 """ |
| 186 with tempfile.NamedTemporaryFile(mode="wt", delete=False) as tmp_file: | 186 with tempfile.NamedTemporaryFile(mode="wt", delete=False) as tmp_file: |
| 187 self._temp_files.append(tmp_file.name) | 187 self._temp_files.append(tmp_file.name) |
| 188 tmp_file.write(contents) | 188 tmp_file.write(contents) |
| 189 return tmp_file.name | 189 return tmp_file.name |
| 190 | 190 |
| 191 def check(self, sources, out_file=None, runner_args=None, closure_args=None, | 191 def check(self, sources, out_file=None, closure_args=None, |
| 192 custom_sources=True): | 192 custom_sources=True): |
| 193 """Closure compile |sources| while checking for errors. | 193 """Closure compile |sources| while checking for errors. |
| 194 | 194 |
| 195 Args: | 195 Args: |
| 196 sources: Files to check. sources[0] is the typically the target file. | 196 sources: Files to check. sources[0] is the typically the target file. |
| 197 sources[1:] are externs and dependencies in topological order. Order | 197 sources[1:] are externs and dependencies in topological order. Order |
| 198 is not guaranteed if custom_sources is True. | 198 is not guaranteed if custom_sources is True. |
| 199 out_file: A file where the compiled output is written to. | 199 out_file: A file where the compiled output is written to. |
| 200 runner_args: Arguments passed to runner.jar. | |
| 201 closure_args: Arguments passed directly to the Closure compiler. | 200 closure_args: Arguments passed directly to the Closure compiler. |
| 202 custom_sources: Whether |sources| was customized by the target (e.g. not | 201 custom_sources: Whether |sources| was customized by the target (e.g. not |
| 203 in GYP dependency order). | 202 in GYP dependency order). |
| 204 | 203 |
| 205 Returns: | 204 Returns: |
| 206 (found_errors, stderr) A boolean indicating whether errors were found and | 205 (found_errors, stderr) A boolean indicating whether errors were found and |
| 207 the raw Closure compiler stderr (as a string). | 206 the raw Closure compiler stderr (as a string). |
| 208 """ | 207 """ |
| 209 is_extern = lambda f: 'externs' in f | 208 is_extern = lambda f: 'externs' in f |
| 210 externs_and_deps = [self._POLYMER_EXTERNS] | 209 externs_and_deps = [self._POLYMER_EXTERNS] |
| (...skipping 27 matching lines...) Expand all Loading... |
| 238 meta_file = self._create_temp_file("\n".join(contents)) | 237 meta_file = self._create_temp_file("\n".join(contents)) |
| 239 self._log_debug("Meta file: %s" % meta_file) | 238 self._log_debug("Meta file: %s" % meta_file) |
| 240 | 239 |
| 241 self._processor = processor.Processor(meta_file) | 240 self._processor = processor.Processor(meta_file) |
| 242 self._expanded_file = self._create_temp_file(self._processor.contents) | 241 self._expanded_file = self._create_temp_file(self._processor.contents) |
| 243 self._log_debug("Expanded file: %s" % self._expanded_file) | 242 self._log_debug("Expanded file: %s" % self._expanded_file) |
| 244 | 243 |
| 245 js_args = [self._expanded_file] | 244 js_args = [self._expanded_file] |
| 246 | 245 |
| 247 closure_args = closure_args or [] | 246 closure_args = closure_args or [] |
| 248 closure_args += ["summary_detail_level=3"] | 247 closure_args += ["summary_detail_level=3", "continue_after_errors"] |
| 249 | 248 |
| 250 args = ["--externs=%s" % e for e in externs] + \ | 249 args = ["--externs=%s" % e for e in externs] + \ |
| 251 ["--js=%s" % s for s in js_args] + \ | 250 ["--js=%s" % s for s in js_args] + \ |
| 252 ["--%s" % arg for arg in closure_args] | 251 ["--%s" % arg for arg in closure_args] |
| 253 | 252 |
| 254 if out_file: | 253 if out_file: |
| 255 out_dir = os.path.dirname(out_file) | 254 out_dir = os.path.dirname(out_file) |
| 256 if not os.path.exists(out_dir): | 255 if not os.path.exists(out_dir): |
| 257 os.makedirs(out_dir) | 256 os.makedirs(out_dir) |
| 258 args += ["--js_output_file=%s" % out_file] | 257 args += ["--js_output_file=%s" % out_file] |
| 259 args += ["--create_source_map=%s" % (self._MAP_FILE_FORMAT % out_file)] | 258 args += ["--create_source_map=%s" % (self._MAP_FILE_FORMAT % out_file)] |
| 260 | 259 |
| 261 args_file_content = " %s" % " ".join(args) | 260 self._log_debug("Args: %s" % " ".join(args)) |
| 262 self._log_debug("Args: %s" % args_file_content.strip()) | |
| 263 | 261 |
| 264 args_file = self._create_temp_file(args_file_content) | 262 _, stderr = self._run_jar(self._compiler_jar, args) |
| 265 self._log_debug("Args file: %s" % args_file) | |
| 266 | |
| 267 processed_runner_args = ["--%s" % arg for arg in runner_args or []] | |
| 268 processed_runner_args += ["--compiler-args-file=%s" % args_file] | |
| 269 _, stderr = self._run_jar(self._runner_jar, processed_runner_args) | |
| 270 | 263 |
| 271 errors = stderr.strip().split("\n\n") | 264 errors = stderr.strip().split("\n\n") |
| 272 maybe_summary = errors.pop() | 265 maybe_summary = errors.pop() |
| 273 | 266 |
| 274 summary = re.search("(?P<error_count>\d+).*error.*warning", maybe_summary) | 267 summary = re.search("(?P<error_count>\d+).*error.*warning", maybe_summary) |
| 275 if summary: | 268 if summary: |
| 276 self._log_debug("Summary: %s" % maybe_summary) | 269 self._log_debug("Summary: %s" % maybe_summary) |
| 277 else: | 270 else: |
| 278 # Not a summary. Running the jar failed. Bail. | 271 # Not a summary. Running the jar failed. Bail. |
| 279 self._log_error(stderr) | 272 self._log_error(stderr) |
| (...skipping 23 matching lines...) Expand all Loading... |
| 303 | 296 |
| 304 if __name__ == "__main__": | 297 if __name__ == "__main__": |
| 305 parser = argparse.ArgumentParser( | 298 parser = argparse.ArgumentParser( |
| 306 description="Typecheck JavaScript using Closure compiler") | 299 description="Typecheck JavaScript using Closure compiler") |
| 307 parser.add_argument("sources", nargs=argparse.ONE_OR_MORE, | 300 parser.add_argument("sources", nargs=argparse.ONE_OR_MORE, |
| 308 help="Path to a source file to typecheck") | 301 help="Path to a source file to typecheck") |
| 309 parser.add_argument("--custom_sources", action="store_true", | 302 parser.add_argument("--custom_sources", action="store_true", |
| 310 help="Whether this rules has custom sources.") | 303 help="Whether this rules has custom sources.") |
| 311 parser.add_argument("-o", "--out_file", | 304 parser.add_argument("-o", "--out_file", |
| 312 help="A file where the compiled output is written to") | 305 help="A file where the compiled output is written to") |
| 313 parser.add_argument("-r", "--runner_args", nargs=argparse.ZERO_OR_MORE, | |
| 314 help="Arguments passed to runner.jar") | |
| 315 parser.add_argument("-c", "--closure_args", nargs=argparse.ZERO_OR_MORE, | 306 parser.add_argument("-c", "--closure_args", nargs=argparse.ZERO_OR_MORE, |
| 316 help="Arguments passed directly to the Closure compiler") | 307 help="Arguments passed directly to the Closure compiler") |
| 317 parser.add_argument("-v", "--verbose", action="store_true", | 308 parser.add_argument("-v", "--verbose", action="store_true", |
| 318 help="Show more information as this script runs") | 309 help="Show more information as this script runs") |
| 319 opts = parser.parse_args() | 310 opts = parser.parse_args() |
| 320 | 311 |
| 321 checker = Checker(verbose=opts.verbose) | 312 checker = Checker(verbose=opts.verbose) |
| 322 | 313 |
| 323 found_errors, stderr = checker.check(opts.sources, out_file=opts.out_file, | 314 found_errors, stderr = checker.check(opts.sources, out_file=opts.out_file, |
| 324 closure_args=opts.closure_args, | 315 closure_args=opts.closure_args, |
| 325 runner_args=opts.runner_args, | |
| 326 custom_sources=opts.custom_sources) | 316 custom_sources=opts.custom_sources) |
| 327 | 317 |
| 328 if found_errors: | 318 if found_errors: |
| 329 if opts.custom_sources: | 319 if opts.custom_sources: |
| 330 print stderr | 320 print stderr |
| 331 sys.exit(1) | 321 sys.exit(1) |
| OLD | NEW |