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

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

Issue 472613003: Change string concatentation from + to % in part of third_party/closure_compiler. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: asdf Created 6 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 a JavaScript file to check for errors.""" 6 """Runs Closure compiler on a JavaScript file to check for errors."""
7 7
8 import argparse 8 import argparse
9 import os 9 import os
10 import re 10 import re
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
61 current_dir = os.path.join(os.path.dirname(__file__)) 61 current_dir = os.path.join(os.path.dirname(__file__))
62 self._compiler_jar = os.path.join(current_dir, "lib", "compiler.jar") 62 self._compiler_jar = os.path.join(current_dir, "lib", "compiler.jar")
63 self._runner_jar = os.path.join(current_dir, "runner", "runner.jar") 63 self._runner_jar = os.path.join(current_dir, "runner", "runner.jar")
64 self._temp_files = [] 64 self._temp_files = []
65 self._verbose = verbose 65 self._verbose = verbose
66 66
67 def _clean_up(self): 67 def _clean_up(self):
68 if not self._temp_files: 68 if not self._temp_files:
69 return 69 return
70 70
71 self._debug("Deleting temporary files: " + ", ".join(self._temp_files)) 71 self._debug("Deleting temporary files: %s" % ", ".join(self._temp_files))
72 for f in self._temp_files: 72 for f in self._temp_files:
73 os.remove(f) 73 os.remove(f)
74 self._temp_files = [] 74 self._temp_files = []
75 75
76 def _debug(self, msg, error=False): 76 def _debug(self, msg, error=False):
77 if self._verbose: 77 if self._verbose:
78 print "(INFO) " + msg 78 print "(INFO) %s" % msg
79 79
80 def _error(self, msg): 80 def _error(self, msg):
81 print >> sys.stderr, "(ERROR) " + msg 81 print >> sys.stderr, "(ERROR) %s" % msg
82 self._clean_up() 82 self._clean_up()
83 83
84 def _run_command(self, cmd): 84 def _run_command(self, cmd):
85 """Runs a shell command. 85 """Runs a shell command.
86 86
87 Args: 87 Args:
88 cmd: A list of tokens to be joined into a shell command. 88 cmd: A list of tokens to be joined into a shell command.
89 89
90 Return: 90 Return:
91 True if the exit code was 0, else False. 91 True if the exit code was 0, else False.
92 """ 92 """
93 cmd_str = " ".join(cmd) 93 cmd_str = " ".join(cmd)
94 self._debug("Running command: " + cmd_str) 94 self._debug("Running command: %s" % cmd_str)
95 95
96 devnull = open(os.devnull, "w") 96 devnull = open(os.devnull, "w")
97 return subprocess.Popen( 97 return subprocess.Popen(
98 cmd_str, stdout=devnull, stderr=subprocess.PIPE, shell=True) 98 cmd_str, stdout=devnull, stderr=subprocess.PIPE, shell=True)
99 99
100 def _check_java_path(self): 100 def _check_java_path(self):
101 """Checks that `java` is on the system path.""" 101 """Checks that `java` is on the system path."""
102 if not self._found_java: 102 if not self._found_java:
103 proc = self._run_command(["which", "java"]) 103 proc = self._run_command(["which", "java"])
104 proc.communicate() 104 proc.communicate()
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
139 # Ignore "Variable x first declared in /same/file". 139 # Ignore "Variable x first declared in /same/file".
140 return "" 140 return ""
141 141
142 expanded_file = self._expanded_file 142 expanded_file = self._expanded_file
143 fixed = re.sub("%s:(\d+)" % expanded_file, self._fix_line_number, error) 143 fixed = re.sub("%s:(\d+)" % expanded_file, self._fix_line_number, error)
144 return fixed.replace(expanded_file, os.path.abspath(self._file_arg)) 144 return fixed.replace(expanded_file, os.path.abspath(self._file_arg))
145 145
146 def _format_errors(self, errors): 146 def _format_errors(self, errors):
147 """Formats Closure compiler errors to easily spot compiler output.""" 147 """Formats Closure compiler errors to easily spot compiler output."""
148 errors = filter(None, errors) 148 errors = filter(None, errors)
149 contents = ("\n" + "## ").join("\n\n".join(errors).splitlines()) 149 contents = "\n## ".join("\n\n".join(errors).splitlines())
150 return "## " + contents if contents else "" 150 return "## %s" % contents if contents else ""
151 151
152 def _create_temp_file(self, contents): 152 def _create_temp_file(self, contents):
153 with tempfile.NamedTemporaryFile(mode="wt", delete=False) as tmp_file: 153 with tempfile.NamedTemporaryFile(mode="wt", delete=False) as tmp_file:
154 self._temp_files.append(tmp_file.name) 154 self._temp_files.append(tmp_file.name)
155 tmp_file.write(contents) 155 tmp_file.write(contents)
156 return tmp_file.name 156 return tmp_file.name
157 157
158 def check(self, source_file, depends=None, externs=None): 158 def check(self, source_file, depends=None, externs=None):
159 """Closure compile a file and check for errors. 159 """Closure compile a file and check for errors.
160 160
161 Args: 161 Args:
162 source_file: A file to check. 162 source_file: A file to check.
163 depends: Other files that would be included with a <script> earlier in 163 depends: Other files that would be included with a <script> earlier in
164 the page. 164 the page.
165 externs: @extern files that inform the compiler about custom globals. 165 externs: @extern files that inform the compiler about custom globals.
166 166
167 Returns: 167 Returns:
168 (exitcode, output) The exit code of the Closure compiler (as a number) 168 (exitcode, output) The exit code of the Closure compiler (as a number)
169 and its output (as a string). 169 and its output (as a string).
170 """ 170 """
171 depends = depends or [] 171 depends = depends or []
172 externs = externs or [] 172 externs = externs or []
173 173
174 if not self._check_java_path(): 174 if not self._check_java_path():
175 return 1, "" 175 return 1, ""
176 176
177 self._debug("FILE: " + source_file) 177 self._debug("FILE: %s" % source_file)
178 178
179 if source_file.endswith("_externs.js"): 179 if source_file.endswith("_externs.js"):
180 self._debug("Skipping externs: " + source_file) 180 self._debug("Skipping externs: %s" % source_file)
181 return 181 return
182 182
183 self._file_arg = source_file 183 self._file_arg = source_file
184 184
185 tmp_dir = tempfile.gettempdir() 185 tmp_dir = tempfile.gettempdir()
186 rel_path = lambda f: os.path.join(os.path.relpath(os.getcwd(), tmp_dir), f) 186 rel_path = lambda f: os.path.join(os.path.relpath(os.getcwd(), tmp_dir), f)
187 187
188 includes = [rel_path(f) for f in depends + [source_file]] 188 includes = [rel_path(f) for f in depends + [source_file]]
189 contents = ['<include src="%s">' % i for i in includes] 189 contents = ['<include src="%s">' % i for i in includes]
190 meta_file = self._create_temp_file("\n".join(contents)) 190 meta_file = self._create_temp_file("\n".join(contents))
191 self._debug("Meta file: " + meta_file) 191 self._debug("Meta file: %s" % meta_file)
192 192
193 self._processor = processor.Processor(meta_file) 193 self._processor = processor.Processor(meta_file)
194 self._expanded_file = self._create_temp_file(self._processor.contents) 194 self._expanded_file = self._create_temp_file(self._processor.contents)
195 self._debug("Expanded file: " + self._expanded_file) 195 self._debug("Expanded file: %s" % self._expanded_file)
196 196
197 args = ["--js=" + self._expanded_file] + ["--externs=" + e for e in externs] 197 args = ["--js=%s" % self._expanded_file]
198 args_file_content = " " + " ".join(self._COMMON_CLOSURE_ARGS + args) 198 args += ["--externs=%s" % e for e in externs]
199 self._debug("Args: " + args_file_content.strip()) 199 args_file_content = " %s" % " ".join(self._COMMON_CLOSURE_ARGS + args)
200 self._debug("Args: %s" % args_file_content.strip())
200 201
201 args_file = self._create_temp_file(args_file_content) 202 args_file = self._create_temp_file(args_file_content)
202 self._debug("Args file: " + args_file) 203 self._debug("Args file: %s" % args_file)
203 204
204 runner_args = ["--compiler-args-file=" + args_file] 205 runner_args = ["--compiler-args-file=%s" % args_file]
205 runner_cmd = self._run_jar(self._runner_jar, args=runner_args) 206 runner_cmd = self._run_jar(self._runner_jar, args=runner_args)
206 (_, stderr) = runner_cmd.communicate() 207 (_, stderr) = runner_cmd.communicate()
207 208
208 errors = stderr.strip().split("\n\n") 209 errors = stderr.strip().split("\n\n")
209 self._debug("Summary: " + errors.pop()) 210 self._debug("Summary: %s" % errors.pop())
210 211
211 output = self._format_errors(map(self._fix_up_error, errors)) 212 output = self._format_errors(map(self._fix_up_error, errors))
212 if runner_cmd.returncode: 213 if runner_cmd.returncode:
213 self._error("Error in: " + source_file + ("\n" + output if output else "") ) 214 self._error("Error in: %s%s" % (source_file, "\n" + output if output else ""))
214 elif output: 215 elif output:
215 self._debug("Output: " + output) 216 self._debug("Output: %s" % output)
216 217
217 self._clean_up() 218 self._clean_up()
218 219
219 return runner_cmd.returncode, output 220 return runner_cmd.returncode, output
220 221
221 222
222 if __name__ == "__main__": 223 if __name__ == "__main__":
223 parser = argparse.ArgumentParser( 224 parser = argparse.ArgumentParser(
224 description="Typecheck JavaScript using Closure compiler") 225 description="Typecheck JavaScript using Closure compiler")
225 parser.add_argument("sources", nargs=argparse.ONE_OR_MORE, 226 parser.add_argument("sources", nargs=argparse.ONE_OR_MORE,
226 help="Path to a source file to typecheck") 227 help="Path to a source file to typecheck")
227 parser.add_argument("-d", "--depends", nargs=argparse.ZERO_OR_MORE) 228 parser.add_argument("-d", "--depends", nargs=argparse.ZERO_OR_MORE)
228 parser.add_argument("-e", "--externs", nargs=argparse.ZERO_OR_MORE) 229 parser.add_argument("-e", "--externs", nargs=argparse.ZERO_OR_MORE)
229 parser.add_argument("-o", "--out_file", help="A place to output results") 230 parser.add_argument("-o", "--out_file", help="A place to output results")
230 parser.add_argument("-v", "--verbose", action="store_true", 231 parser.add_argument("-v", "--verbose", action="store_true",
231 help="Show more information as this script runs") 232 help="Show more information as this script runs")
232 opts = parser.parse_args() 233 opts = parser.parse_args()
233 234
234 checker = Checker(verbose=opts.verbose) 235 checker = Checker(verbose=opts.verbose)
235 for source in opts.sources: 236 for source in opts.sources:
236 if not checker.check(source, depends=opts.depends, externs=opts.externs): 237 if not checker.check(source, depends=opts.depends, externs=opts.externs):
237 sys.exit(1) 238 sys.exit(1)
238 239
239 if opts.out_file: 240 if opts.out_file:
240 out_dir = os.path.dirname(opts.out_file) 241 out_dir = os.path.dirname(opts.out_file)
241 if not os.path.exists(out_dir): 242 if not os.path.exists(out_dir):
242 os.makedirs(out_dir) 243 os.makedirs(out_dir)
243 # TODO(dbeam): write compiled file to |opts.out_file|. 244 # TODO(dbeam): write compiled file to |opts.out_file|.
244 open(opts.out_file, "w").write("") 245 open(opts.out_file, "w").write("")
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698