Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(28)

Side by Side Diff: third_party/closure_compiler/compile.py

Issue 1152583011: Refactor compile_js.gypi to support script_args and closure_args (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Use script_args and closure_args Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 #!/usr/bin/python 1 #!/usr/bin/python
2 # Copyright 2014 The Chromium Authors. All rights reserved. 2 # Copyright 2014 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 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
51 _POLYMER_EXTRA_ANNOTATIONS = [ 51 _POLYMER_EXTRA_ANNOTATIONS = [
52 "attribute", 52 "attribute",
53 "status", 53 "status",
54 "element", 54 "element",
55 "homepage", 55 "homepage",
56 "submodule", 56 "submodule",
57 "group", 57 "group",
58 ] 58 ]
59 59
60 _COMMON_CLOSURE_ARGS = [ 60 _COMMON_CLOSURE_ARGS = [
61 "--accept_const_keyword",
62 "--language_in=ECMASCRIPT5_STRICT",
63 "--summary_detail_level=3",
64 "--compilation_level=SIMPLE_OPTIMIZATIONS",
65 "--source_map_format=V3",
66 "--polymer_pass",
67 ] + [
68 "--jscomp_error=%s" % err for err in _COMMON_JSCOMP_ERRORS 61 "--jscomp_error=%s" % err for err in _COMMON_JSCOMP_ERRORS
69 ] + [ 62 ] + [
70 "--extra_annotation_name=%s" % a for a in _POLYMER_EXTRA_ANNOTATIONS 63 "--extra_annotation_name=%s" % a for a in _POLYMER_EXTRA_ANNOTATIONS
71 ] 64 ]
72 65
73 # These are the extra flags used when compiling in strict mode. 66 # These are the extra flags used when compiling in strict mode.
74 # Flags that are normally disabled are turned on for strict mode. 67 # Flags that are normally disabled are turned on for strict mode.
75 _STRICT_CLOSURE_ARGS = [ 68 _STRICT_CLOSURE_ARGS = [
76 "--jscomp_error=reportUnknownTypes", 69 "--jscomp_error=reportUnknownTypes",
77 "--jscomp_error=duplicate", 70 "--jscomp_error=duplicate",
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
246 239
247 Return: 240 Return:
248 The filepath of the newly created, written, and closed temporary file. 241 The filepath of the newly created, written, and closed temporary file.
249 """ 242 """
250 with tempfile.NamedTemporaryFile(mode="wt", delete=False) as tmp_file: 243 with tempfile.NamedTemporaryFile(mode="wt", delete=False) as tmp_file:
251 self._temp_files.append(tmp_file.name) 244 self._temp_files.append(tmp_file.name)
252 tmp_file.write(contents) 245 tmp_file.write(contents)
253 return tmp_file.name 246 return tmp_file.name
254 247
255 def _run_js_check(self, sources, out_file=None, externs=None, 248 def _run_js_check(self, sources, out_file=None, externs=None,
256 output_wrapper=None): 249 closure_args=None):
257 """Check |sources| for type errors. 250 """Check |sources| for type errors.
258 251
259 Args: 252 Args:
260 sources: Files to check. 253 sources: Files to check.
261 out_file: A file where the compiled output is written to. 254 out_file: A file where the compiled output is written to.
262 externs: @extern files that inform the compiler about custom globals. 255 externs: @extern files that inform the compiler about custom globals.
263 output_wrapper: Wraps output into this string at the place denoted by the 256 closure_args: Arguments passed directly to the closure compiler.
264 marker token %output%.
265 257
266 Returns: 258 Returns:
267 (errors, stderr) A parsed list of errors (strings) found by the compiler 259 (errors, stderr) A parsed list of errors (strings) found by the compiler
268 and the raw stderr (as a string). 260 and the raw stderr (as a string).
269 """ 261 """
270 args = ["--js=%s" % s for s in sources] 262 args = ["--js=%s" % s for s in sources]
271 263
272 if out_file: 264 if out_file:
273 out_dir = os.path.dirname(out_file) 265 out_dir = os.path.dirname(out_file)
274 if not os.path.exists(out_dir): 266 if not os.path.exists(out_dir):
275 os.makedirs(out_dir) 267 os.makedirs(out_dir)
276 args += ["--js_output_file=%s" % out_file] 268 args += ["--js_output_file=%s" % out_file]
277 args += ["--create_source_map=%s" % (self._MAP_FILE_FORMAT % out_file)] 269 args += ["--create_source_map=%s" % (self._MAP_FILE_FORMAT % out_file)]
278 270
279 if externs: 271 if externs:
280 args += ["--externs=%s" % e for e in externs] 272 args += ["--externs=%s" % e for e in externs]
281 273
282 if output_wrapper: 274 args += closure_args
283 args += ['--output_wrapper="%s"' % output_wrapper]
284 275
285 args_file_content = " %s" % " ".join(self._common_args() + args) 276 args_file_content = " %s" % " ".join(self._common_args() + args)
286 self._log_debug("Args: %s" % args_file_content.strip()) 277 self._log_debug("Args: %s" % args_file_content.strip())
287 278
288 args_file = self._create_temp_file(args_file_content) 279 args_file = self._create_temp_file(args_file_content)
289 self._log_debug("Args file: %s" % args_file) 280 self._log_debug("Args file: %s" % args_file)
290 281
291 runner_args = ["--compiler-args-file=%s" % args_file] 282 runner_args = ["--compiler-args-file=%s" % args_file]
292 _, stderr = self._run_jar(self._runner_jar, runner_args) 283 _, stderr = self._run_jar(self._runner_jar, runner_args)
293 284
(...skipping 10 matching lines...) Expand all
304 295
305 if errors and out_file: 296 if errors and out_file:
306 if os.path.exists(out_file): 297 if os.path.exists(out_file):
307 os.remove(out_file) 298 os.remove(out_file)
308 if os.path.exists(self._MAP_FILE_FORMAT % out_file): 299 if os.path.exists(self._MAP_FILE_FORMAT % out_file):
309 os.remove(self._MAP_FILE_FORMAT % out_file) 300 os.remove(self._MAP_FILE_FORMAT % out_file)
310 301
311 return errors, stderr 302 return errors, stderr
312 303
313 def check(self, source_file, out_file=None, depends=None, externs=None, 304 def check(self, source_file, out_file=None, depends=None, externs=None,
314 output_wrapper=None): 305 closure_args=None):
315 """Closure compiler |source_file| while checking for errors. 306 """Closure compiler |source_file| while checking for errors.
316 307
317 Args: 308 Args:
318 source_file: A file to check. 309 source_file: A file to check.
319 out_file: A file where the compiled output is written to. 310 out_file: A file where the compiled output is written to.
320 depends: Files that |source_file| requires to run (e.g. earlier <script>). 311 depends: Files that |source_file| requires to run (e.g. earlier <script>).
321 externs: @extern files that inform the compiler about custom globals. 312 externs: @extern files that inform the compiler about custom globals.
322 output_wrapper: Wraps output into this string at the place denoted by the 313 closure_args: Arguments passed directly to the closure compiler.
323 marker token %output%.
324 314
325 Returns: 315 Returns:
326 (found_errors, stderr) A boolean indicating whether errors were found and 316 (found_errors, stderr) A boolean indicating whether errors were found and
327 the raw Closure compiler stderr (as a string). 317 the raw Closure compiler stderr (as a string).
328 """ 318 """
329 self._log_debug("FILE: %s" % source_file) 319 self._log_debug("FILE: %s" % source_file)
330 320
331 if source_file.endswith("_externs.js"): 321 if source_file.endswith("_externs.js"):
332 self._log_debug("Skipping externs: %s" % source_file) 322 self._log_debug("Skipping externs: %s" % source_file)
333 return 323 return
334 324
335 self._file_arg = source_file 325 self._file_arg = source_file
336 326
337 cwd, tmp_dir = os.getcwd(), tempfile.gettempdir() 327 cwd, tmp_dir = os.getcwd(), tempfile.gettempdir()
338 rel_path = lambda f: os.path.join(os.path.relpath(cwd, tmp_dir), f) 328 rel_path = lambda f: os.path.join(os.path.relpath(cwd, tmp_dir), f)
339 329
340 depends = depends or [] 330 depends = depends or []
341 includes = [rel_path(f) for f in depends + [source_file]] 331 includes = [rel_path(f) for f in depends + [source_file]]
342 contents = ['<include src="%s">' % i for i in includes] 332 contents = ['<include src="%s">' % i for i in includes]
343 meta_file = self._create_temp_file("\n".join(contents)) 333 meta_file = self._create_temp_file("\n".join(contents))
344 self._log_debug("Meta file: %s" % meta_file) 334 self._log_debug("Meta file: %s" % meta_file)
345 335
346 self._processor = processor.Processor(meta_file) 336 self._processor = processor.Processor(meta_file)
347 self._expanded_file = self._create_temp_file(self._processor.contents) 337 self._expanded_file = self._create_temp_file(self._processor.contents)
348 self._log_debug("Expanded file: %s" % self._expanded_file) 338 self._log_debug("Expanded file: %s" % self._expanded_file)
349 339
350 errors, stderr = self._run_js_check([self._expanded_file], 340 errors, stderr = self._run_js_check([self._expanded_file],
351 out_file=out_file, externs=externs, 341 out_file=out_file, externs=externs,
352 output_wrapper=output_wrapper) 342 closure_args=closure_args)
353 filtered_errors = self._filter_errors(errors) 343 filtered_errors = self._filter_errors(errors)
354 cleaned_errors = map(self._clean_up_error, filtered_errors) 344 cleaned_errors = map(self._clean_up_error, filtered_errors)
355 output = self._format_errors(cleaned_errors) 345 output = self._format_errors(cleaned_errors)
356 346
357 if cleaned_errors: 347 if cleaned_errors:
358 prefix = "\n" if output else "" 348 prefix = "\n" if output else ""
359 self._log_error("Error in: %s%s%s" % (source_file, prefix, output)) 349 self._log_error("Error in: %s%s%s" % (source_file, prefix, output))
360 elif output: 350 elif output:
361 self._log_debug("Output: %s" % output) 351 self._log_debug("Output: %s" % output)
362 352
363 self._nuke_temp_files() 353 self._nuke_temp_files()
364 return bool(cleaned_errors), stderr 354 return bool(cleaned_errors), stderr
365 355
366 def check_multiple(self, sources, out_file=None, output_wrapper=None, 356 def check_multiple(self, sources, out_file=None, closure_args=None,
367 externs=None): 357 externs=None):
368 """Closure compile a set of files and check for errors. 358 """Closure compile a set of files and check for errors.
369 359
370 Args: 360 Args:
371 sources: An array of files to check. 361 sources: An array of files to check.
372 out_file: A file where the compiled output is written to. 362 out_file: A file where the compiled output is written to.
373 output_wrapper: Wraps output into this string at the place denoted by the 363 closure_args: Arguments passed directly to the closure compiler.
374 marker token %output%.
375 externs: @extern files that inform the compiler about custom globals. 364 externs: @extern files that inform the compiler about custom globals.
376 365
377 Returns: 366 Returns:
378 (found_errors, stderr) A boolean indicating whether errors were found and 367 (found_errors, stderr) A boolean indicating whether errors were found and
379 the raw Closure Compiler stderr (as a string). 368 the raw Closure Compiler stderr (as a string).
380 """ 369 """
381 errors, stderr = self._run_js_check(sources, out_file=out_file, 370 errors, stderr = self._run_js_check(sources, out_file=out_file,
382 output_wrapper=output_wrapper, 371 closure_args=closure_args,
383 externs=externs) 372 externs=externs)
384 self._nuke_temp_files() 373 self._nuke_temp_files()
385 return bool(errors), stderr 374 return bool(errors), stderr
386 375
387 376
388 if __name__ == "__main__": 377 if __name__ == "__main__":
389 parser = argparse.ArgumentParser( 378 parser = argparse.ArgumentParser(
390 description="Typecheck JavaScript using Closure compiler") 379 description="Typecheck JavaScript using Closure compiler")
391 parser.add_argument("sources", nargs=argparse.ONE_OR_MORE, 380 parser.add_argument("sources", nargs=argparse.ONE_OR_MORE,
392 help="Path to a source file to typecheck") 381 help="Path to a source file to typecheck")
393 single_file_group = parser.add_mutually_exclusive_group() 382 single_file_group = parser.add_mutually_exclusive_group()
394 single_file_group.add_argument("--single-file", dest="single_file", 383 single_file_group.add_argument("--single-file", dest="single_file",
395 action="store_true", 384 action="store_true",
396 help="Process each source file individually") 385 help="Process each source file individually")
397 single_file_group.add_argument("--no-single-file", dest="single_file", 386 single_file_group.add_argument("--no-single-file", dest="single_file",
398 action="store_false", 387 action="store_false",
399 help="Process all source files as a group") 388 help="Process all source files as a group")
400 parser.add_argument("-d", "--depends", nargs=argparse.ZERO_OR_MORE) 389 parser.add_argument("-d", "--depends", nargs=argparse.ZERO_OR_MORE)
401 parser.add_argument("-e", "--externs", nargs=argparse.ZERO_OR_MORE) 390 parser.add_argument("-e", "--externs", nargs=argparse.ZERO_OR_MORE)
402 parser.add_argument("-o", "--out_file", 391 parser.add_argument("-o", "--out_file",
403 help="A file where the compiled output is written to") 392 help="A file where the compiled output is written to")
404 parser.add_argument("-w", "--output_wrapper", 393 parser.add_argument("-c", "--closure_args",
405 help="Wraps output into this string at the place" 394 help="Arguments passed directly to the closure compiler")
406 + " denoted by the marker token %output%")
407 parser.add_argument("-v", "--verbose", action="store_true", 395 parser.add_argument("-v", "--verbose", action="store_true",
408 help="Show more information as this script runs") 396 help="Show more information as this script runs")
409 parser.add_argument("--strict", action="store_true", 397 parser.add_argument("--strict", action="store_true",
410 help="Enable strict type checking") 398 help="Enable strict type checking")
411 parser.add_argument("--success-stamp", 399 parser.add_argument("--success-stamp",
412 help="Timestamp file to update upon success") 400 help="Timestamp file to update upon success")
413 401
414 parser.set_defaults(single_file=True, strict=False) 402 parser.set_defaults(single_file=True, strict=False)
415 opts = parser.parse_args() 403 opts = parser.parse_args()
416 404
417 depends = opts.depends or [] 405 depends = opts.depends or []
418 externs = set(opts.externs or []) 406 externs = set(opts.externs or [])
419 407
420 polymer_externs = os.path.join(os.path.dirname(_CURRENT_DIR), 'polymer', 408 polymer_externs = os.path.join(os.path.dirname(_CURRENT_DIR), 'polymer',
421 'v0_8', 'components-chromium', 409 'v0_8', 'components-chromium',
422 'polymer-externs', 'polymer.externs.js') 410 'polymer-externs', 'polymer.externs.js')
423 externs.add(polymer_externs) 411 externs.add(polymer_externs)
424 412
425 checker = Checker(verbose=opts.verbose, strict=opts.strict) 413 checker = Checker(verbose=opts.verbose, strict=opts.strict)
426 if opts.single_file: 414 if opts.single_file:
427 for source in opts.sources: 415 for source in opts.sources:
428 depends, externs = build.inputs.resolve_recursive_dependencies( 416 depends, externs = build.inputs.resolve_recursive_dependencies(
429 source, depends, externs) 417 source, depends, externs)
430 found_errors, _ = checker.check(source, out_file=opts.out_file, 418 found_errors, _ = checker.check(source, out_file=opts.out_file,
431 depends=depends, externs=externs, 419 depends=depends, externs=externs,
432 output_wrapper=opts.output_wrapper) 420 closure_args=opts.closure_args)
433 if found_errors: 421 if found_errors:
434 sys.exit(1) 422 sys.exit(1)
435 else: 423 else:
436 found_errors, stderr = checker.check_multiple( 424 found_errors, stderr = checker.check_multiple(
437 opts.sources, 425 opts.sources,
438 out_file=opts.out_file, 426 out_file=opts.out_file,
439 output_wrapper=opts.output_wrapper, 427 closure_args=opts.closure_args,
440 externs=externs) 428 externs=externs)
441 if found_errors: 429 if found_errors:
442 print stderr 430 print stderr
443 sys.exit(1) 431 sys.exit(1)
444 432
445 if opts.success_stamp: 433 if opts.success_stamp:
446 with open(opts.success_stamp, "w"): 434 with open(opts.success_stamp, "w"):
447 os.utime(opts.success_stamp, None) 435 os.utime(opts.success_stamp, None)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698