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

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

Issue 2117653002: Add the ability to pass arguments to runner.jar (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@enable-chrome-pass
Patch Set: asdf Created 4 years, 4 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 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
179 179
180 Return: 180 Return:
181 The filepath of the newly created, written, and closed temporary file. 181 The filepath of the newly created, written, and closed temporary file.
182 """ 182 """
183 with tempfile.NamedTemporaryFile(mode="wt", delete=False) as tmp_file: 183 with tempfile.NamedTemporaryFile(mode="wt", delete=False) as tmp_file:
184 self._temp_files.append(tmp_file.name) 184 self._temp_files.append(tmp_file.name)
185 tmp_file.write(contents) 185 tmp_file.write(contents)
186 return tmp_file.name 186 return tmp_file.name
187 187
188 def _run_js_check(self, sources, out_file=None, externs=None, 188 def _run_js_check(self, sources, out_file=None, externs=None,
189 closure_args=None): 189 runner_args=None, closure_args=None):
190 """Check |sources| for type errors. 190 """Check |sources| for type errors.
191 191
192 Args: 192 Args:
193 sources: Files to check. 193 sources: Files to check.
194 out_file: A file where the compiled output is written to. 194 out_file: A file where the compiled output is written to.
195 externs: @extern files that inform the compiler about custom globals. 195 externs: @extern files that inform the compiler about custom globals.
196 runner_args: Arguments passed to runner.jar.
196 closure_args: Arguments passed directly to the Closure compiler. 197 closure_args: Arguments passed directly to the Closure compiler.
197 198
198 Returns: 199 Returns:
199 (errors, stderr) A parsed list of errors (strings) found by the compiler 200 (errors, stderr) A parsed list of errors (strings) found by the compiler
200 and the raw stderr (as a string). 201 and the raw stderr (as a string).
201 """ 202 """
202 args = ["--js=%s" % s for s in sources] 203 args = ["--js=%s" % s for s in sources]
203 204
204 if out_file: 205 if out_file:
205 out_dir = os.path.dirname(out_file) 206 out_dir = os.path.dirname(out_file)
206 if not os.path.exists(out_dir): 207 if not os.path.exists(out_dir):
207 os.makedirs(out_dir) 208 os.makedirs(out_dir)
208 args += ["--js_output_file=%s" % out_file] 209 args += ["--js_output_file=%s" % out_file]
209 args += ["--create_source_map=%s" % (self._MAP_FILE_FORMAT % out_file)] 210 args += ["--create_source_map=%s" % (self._MAP_FILE_FORMAT % out_file)]
210 211
211 args += ["--externs=%s" % e for e in externs or []] 212 args += ["--externs=%s" % e for e in externs or []]
212 213
213 closure_args = closure_args or [] 214 closure_args = closure_args or []
214 closure_args += ["summary_detail_level=3"] 215 closure_args += ["summary_detail_level=3"]
215 args += ["--%s" % arg for arg in closure_args] 216 args += ["--%s" % arg for arg in closure_args]
216 217
217 args_file_content = " %s" % " ".join(args) 218 args_file_content = " %s" % " ".join(args)
218 self._log_debug("Args: %s" % args_file_content.strip()) 219 self._log_debug("Args: %s" % args_file_content.strip())
219 220
220 args_file = self._create_temp_file(args_file_content) 221 args_file = self._create_temp_file(args_file_content)
221 self._log_debug("Args file: %s" % args_file) 222 self._log_debug("Args file: %s" % args_file)
222 223
223 runner_args = ["--compiler-args-file=%s" % args_file] 224 runner_args = ["--%s" % arg for arg in runner_args or []]
aberent 2016/08/02 10:52:24 Using the same variable for both the processed and
Dan Beam 2016/08/02 19:36:33 Done.
225 runner_args += ["--compiler-args-file=%s" % args_file]
224 _, stderr = self._run_jar(self._runner_jar, runner_args) 226 _, stderr = self._run_jar(self._runner_jar, runner_args)
225 227
226 errors = stderr.strip().split("\n\n") 228 errors = stderr.strip().split("\n\n")
227 maybe_summary = errors.pop() 229 maybe_summary = errors.pop()
228 230
229 if re.search(".*error.*warning.*typed", maybe_summary): 231 if re.search(".*error.*warning.*typed", maybe_summary):
230 self._log_debug("Summary: %s" % maybe_summary) 232 self._log_debug("Summary: %s" % maybe_summary)
231 else: 233 else:
232 # Not a summary. Running the jar failed. Bail. 234 # Not a summary. Running the jar failed. Bail.
233 self._log_error(stderr) 235 self._log_error(stderr)
234 self._nuke_temp_files() 236 self._nuke_temp_files()
235 sys.exit(1) 237 sys.exit(1)
236 238
237 if errors and out_file: 239 if errors and out_file:
238 if os.path.exists(out_file): 240 if os.path.exists(out_file):
239 os.remove(out_file) 241 os.remove(out_file)
240 if os.path.exists(self._MAP_FILE_FORMAT % out_file): 242 if os.path.exists(self._MAP_FILE_FORMAT % out_file):
241 os.remove(self._MAP_FILE_FORMAT % out_file) 243 os.remove(self._MAP_FILE_FORMAT % out_file)
242 244
243 return errors, stderr 245 return errors, stderr
244 246
245 def check(self, source_file, out_file=None, depends=None, externs=None, 247 def check(self, source_file, out_file=None, depends=None, externs=None,
246 closure_args=None): 248 runner_args=None, closure_args=None):
247 """Closure compiler |source_file| while checking for errors. 249 """Closure compiler |source_file| while checking for errors.
248 250
249 Args: 251 Args:
250 source_file: A file to check. 252 source_file: A file to check.
251 out_file: A file where the compiled output is written to. 253 out_file: A file where the compiled output is written to.
252 depends: Files that |source_file| requires to run (e.g. earlier <script>). 254 depends: Files that |source_file| requires to run (e.g. earlier <script>).
253 externs: @extern files that inform the compiler about custom globals. 255 externs: @extern files that inform the compiler about custom globals.
256 runner_args: Arguments passed to runner.jar.
254 closure_args: Arguments passed directly to the Closure compiler. 257 closure_args: Arguments passed directly to the Closure compiler.
255 258
256 Returns: 259 Returns:
257 (found_errors, stderr) A boolean indicating whether errors were found and 260 (found_errors, stderr) A boolean indicating whether errors were found and
258 the raw Closure compiler stderr (as a string). 261 the raw Closure compiler stderr (as a string).
259 """ 262 """
260 self._log_debug("FILE: %s" % source_file) 263 self._log_debug("FILE: %s" % source_file)
261 264
262 if source_file.endswith("_externs.js"): 265 if source_file.endswith("_externs.js"):
263 self._log_debug("Skipping externs: %s" % source_file) 266 self._log_debug("Skipping externs: %s" % source_file)
264 return 267 return
265 268
266 self._file_arg = source_file 269 self._file_arg = source_file
267 270
268 cwd, tmp_dir = os.getcwd(), tempfile.gettempdir() 271 cwd, tmp_dir = os.getcwd(), tempfile.gettempdir()
269 rel_path = lambda f: os.path.join(os.path.relpath(cwd, tmp_dir), f) 272 rel_path = lambda f: os.path.join(os.path.relpath(cwd, tmp_dir), f)
270 273
271 depends = depends or [] 274 depends = depends or []
272 includes = [rel_path(f) for f in depends + [source_file]] 275 includes = [rel_path(f) for f in depends + [source_file]]
273 contents = ['<include src="%s">' % i for i in includes] 276 contents = ['<include src="%s">' % i for i in includes]
274 meta_file = self._create_temp_file("\n".join(contents)) 277 meta_file = self._create_temp_file("\n".join(contents))
275 self._log_debug("Meta file: %s" % meta_file) 278 self._log_debug("Meta file: %s" % meta_file)
276 279
277 self._processor = processor.Processor(meta_file) 280 self._processor = processor.Processor(meta_file)
278 self._expanded_file = self._create_temp_file(self._processor.contents) 281 self._expanded_file = self._create_temp_file(self._processor.contents)
279 self._log_debug("Expanded file: %s" % self._expanded_file) 282 self._log_debug("Expanded file: %s" % self._expanded_file)
280 283
281 errors, stderr = self._run_js_check([self._expanded_file], 284 errors, stderr = self._run_js_check([self._expanded_file],
282 out_file=out_file, externs=externs, 285 out_file=out_file, externs=externs,
286 runner_args=runner_args,
283 closure_args=closure_args) 287 closure_args=closure_args)
284 filtered_errors = self._filter_errors(errors) 288 filtered_errors = self._filter_errors(errors)
285 cleaned_errors = map(self._clean_up_error, filtered_errors) 289 cleaned_errors = map(self._clean_up_error, filtered_errors)
286 output = self._format_errors(cleaned_errors) 290 output = self._format_errors(cleaned_errors)
287 291
288 if cleaned_errors: 292 if cleaned_errors:
289 prefix = "\n" if output else "" 293 prefix = "\n" if output else ""
290 self._log_error("Error in: %s%s%s" % (source_file, prefix, output)) 294 self._log_error("Error in: %s%s%s" % (source_file, prefix, output))
291 elif output: 295 elif output:
292 self._log_debug("Output: %s" % output) 296 self._log_debug("Output: %s" % output)
293 297
294 self._nuke_temp_files() 298 self._nuke_temp_files()
295 return bool(cleaned_errors), stderr 299 return bool(cleaned_errors), stderr
296 300
297 def check_multiple(self, sources, out_file=None, externs=None, 301 def check_multiple(self, sources, out_file=None, externs=None,
298 closure_args=None): 302 runner_args=None, closure_args=None):
299 """Closure compile a set of files and check for errors. 303 """Closure compile a set of files and check for errors.
300 304
301 Args: 305 Args:
302 sources: An array of files to check. 306 sources: An array of files to check.
303 out_file: A file where the compiled output is written to. 307 out_file: A file where the compiled output is written to.
304 externs: @extern files that inform the compiler about custom globals. 308 externs: @extern files that inform the compiler about custom globals.
309 runner_args: Arguments passed to runner.jar.
305 closure_args: Arguments passed directly to the Closure compiler. 310 closure_args: Arguments passed directly to the Closure compiler.
306 311
307 Returns: 312 Returns:
308 (found_errors, stderr) A boolean indicating whether errors were found and 313 (found_errors, stderr) A boolean indicating whether errors were found and
309 the raw Closure Compiler stderr (as a string). 314 the raw Closure Compiler stderr (as a string).
310 """ 315 """
311 errors, stderr = self._run_js_check(sources, out_file=out_file, 316 errors, stderr = self._run_js_check(sources, out_file=out_file,
312 externs=externs, 317 externs=externs,
318 runner_args=runner_args,
313 closure_args=closure_args) 319 closure_args=closure_args)
314 self._nuke_temp_files() 320 self._nuke_temp_files()
315 return bool(errors), stderr 321 return bool(errors), stderr
316 322
317 323
318 if __name__ == "__main__": 324 if __name__ == "__main__":
319 parser = argparse.ArgumentParser( 325 parser = argparse.ArgumentParser(
320 description="Typecheck JavaScript using Closure compiler") 326 description="Typecheck JavaScript using Closure compiler")
321 parser.add_argument("sources", nargs=argparse.ONE_OR_MORE, 327 parser.add_argument("sources", nargs=argparse.ONE_OR_MORE,
322 help="Path to a source file to typecheck") 328 help="Path to a source file to typecheck")
323 single_file_group = parser.add_mutually_exclusive_group() 329 single_file_group = parser.add_mutually_exclusive_group()
324 single_file_group.add_argument("--single-file", dest="single_file", 330 single_file_group.add_argument("--single-file", dest="single_file",
325 action="store_true", 331 action="store_true",
326 help="Process each source file individually") 332 help="Process each source file individually")
327 # TODO(twellington): remove --no-single-file and use len(opts.sources). 333 # TODO(twellington): remove --no-single-file and use len(opts.sources).
328 single_file_group.add_argument("--no-single-file", dest="single_file", 334 single_file_group.add_argument("--no-single-file", dest="single_file",
329 action="store_false", 335 action="store_false",
330 help="Process all source files as a group") 336 help="Process all source files as a group")
331 parser.add_argument("-d", "--depends", nargs=argparse.ZERO_OR_MORE) 337 parser.add_argument("-d", "--depends", nargs=argparse.ZERO_OR_MORE)
332 parser.add_argument("-e", "--externs", nargs=argparse.ZERO_OR_MORE) 338 parser.add_argument("-e", "--externs", nargs=argparse.ZERO_OR_MORE)
333 parser.add_argument("-o", "--out-file", dest="out_file", 339 parser.add_argument("-o", "--out_file", dest="out_file",
aberent 2016/08/02 10:52:24 Why the change? A '-' is conventional for multi-wo
Dan Beam 2016/08/02 19:36:33 switching to _ consistently everywhere to: a) be
334 help="A file where the compiled output is written to") 340 help="A file where the compiled output is written to")
335 parser.add_argument("-c", "--closure-args", dest="closure_args", 341 parser.add_argument("-r", "--runner_args", dest="runner_args",
342 nargs=argparse.ZERO_OR_MORE,
343 help="Arguments passed to runner.jar")
344 parser.add_argument("-c", "--closure_args", dest="closure_args",
aberent 2016/08/02 10:52:24 Ditto.
Dan Beam 2016/08/02 19:36:33 Done.
336 nargs=argparse.ZERO_OR_MORE, 345 nargs=argparse.ZERO_OR_MORE,
337 help="Arguments passed directly to the Closure compiler") 346 help="Arguments passed directly to the Closure compiler")
338 parser.add_argument("-v", "--verbose", action="store_true", 347 parser.add_argument("-v", "--verbose", action="store_true",
339 help="Show more information as this script runs") 348 help="Show more information as this script runs")
340 349
341 parser.set_defaults(single_file=True, strict=False) 350 parser.set_defaults(single_file=True, strict=False)
342 opts = parser.parse_args() 351 opts = parser.parse_args()
343 352
344 depends = opts.depends or [] 353 depends = opts.depends or []
345 # TODO(devlin): should we run normpath() on this first and/or do this for 354 # TODO(devlin): should we run normpath() on this first and/or do this for
346 # depends as well? 355 # depends as well?
347 externs = set(opts.externs or []) 356 externs = set(opts.externs or [])
348 sources = set(opts.sources) 357 sources = set(opts.sources)
349 358
350 externs.add(os.path.join(_CURRENT_DIR, "externs", "polymer-1.0.js")) 359 externs.add(os.path.join(_CURRENT_DIR, "externs", "polymer-1.0.js"))
351 360
352 checker = Checker(verbose=opts.verbose, strict=opts.strict) 361 checker = Checker(verbose=opts.verbose, strict=opts.strict)
353 if opts.single_file: 362 if opts.single_file:
354 for source in sources: 363 for source in sources:
355 # Normalize source to the current directory. 364 # Normalize source to the current directory.
356 source = os.path.normpath(os.path.join(os.getcwd(), source)) 365 source = os.path.normpath(os.path.join(os.getcwd(), source))
357 depends, externs = build.inputs.resolve_recursive_dependencies( 366 depends, externs = build.inputs.resolve_recursive_dependencies(
358 source, depends, externs) 367 source, depends, externs)
359 368
360 found_errors, _ = checker.check(source, out_file=opts.out_file, 369 found_errors, _ = checker.check(source, out_file=opts.out_file,
361 depends=depends, externs=externs, 370 depends=depends, externs=externs,
371 runner_args=opts.runner_args,
362 closure_args=opts.closure_args) 372 closure_args=opts.closure_args)
363 if found_errors: 373 if found_errors:
364 sys.exit(1) 374 sys.exit(1)
365 else: 375 else:
366 found_errors, stderr = checker.check_multiple( 376 found_errors, stderr = checker.check_multiple(
367 sources, 377 sources,
368 out_file=opts.out_file, 378 out_file=opts.out_file,
369 externs=externs, 379 externs=externs,
380 runner_args=opts.runner_args,
370 closure_args=opts.closure_args) 381 closure_args=opts.closure_args)
371 if found_errors: 382 if found_errors:
372 print stderr 383 print stderr
373 sys.exit(1) 384 sys.exit(1)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698