OLD | NEW |
---|---|
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # | 2 # |
3 # Copyright 2012 the V8 project authors. All rights reserved. | 3 # Copyright 2012 the V8 project authors. All rights reserved. |
4 # Redistribution and use in source and binary forms, with or without | 4 # Redistribution and use in source and binary forms, with or without |
5 # modification, are permitted provided that the following conditions are | 5 # modification, are permitted provided that the following conditions are |
6 # met: | 6 # met: |
7 # | 7 # |
8 # * Redistributions of source code must retain the above copyright | 8 # * Redistributions of source code must retain the above copyright |
9 # notice, this list of conditions and the following disclaimer. | 9 # notice, this list of conditions and the following disclaimer. |
10 # * Redistributions in binary form must reproduce the above | 10 # * Redistributions in binary form must reproduce the above |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
64 -build/namespaces | 64 -build/namespaces |
65 -readability/check | 65 -readability/check |
66 -readability/fn_size | 66 -readability/fn_size |
67 +readability/streams | 67 +readability/streams |
68 -runtime/references | 68 -runtime/references |
69 """.split() | 69 """.split() |
70 | 70 |
71 LINT_OUTPUT_PATTERN = re.compile(r'^.+[:(]\d+[:)]|^Done processing') | 71 LINT_OUTPUT_PATTERN = re.compile(r'^.+[:(]\d+[:)]|^Done processing') |
72 FLAGS_LINE = re.compile("//\s*Flags:.*--([A-z0-9-])+_[A-z0-9].*\n") | 72 FLAGS_LINE = re.compile("//\s*Flags:.*--([A-z0-9-])+_[A-z0-9].*\n") |
73 | 73 |
74 TOOLS_PATH = dirname(abspath(__file__)) | |
75 | |
74 def CppLintWorker(command): | 76 def CppLintWorker(command): |
75 try: | 77 try: |
76 process = subprocess.Popen(command, stderr=subprocess.PIPE) | 78 process = subprocess.Popen(command, stderr=subprocess.PIPE) |
77 process.wait() | 79 process.wait() |
78 out_lines = "" | 80 out_lines = "" |
79 error_count = -1 | 81 error_count = -1 |
80 while True: | 82 while True: |
81 out_line = process.stderr.readline() | 83 out_line = process.stderr.readline() |
82 if out_line == '' and process.poll() != None: | 84 if out_line == '' and process.poll() != None: |
83 if error_count == -1: | 85 if error_count == -1: |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
149 if file in self.sums: | 151 if file in self.sums: |
150 self.sums.pop(file) | 152 self.sums.pop(file) |
151 | 153 |
152 | 154 |
153 class SourceFileProcessor(object): | 155 class SourceFileProcessor(object): |
154 """ | 156 """ |
155 Utility class that can run through a directory structure, find all relevant | 157 Utility class that can run through a directory structure, find all relevant |
156 files and invoke a custom check on the files. | 158 files and invoke a custom check on the files. |
157 """ | 159 """ |
158 | 160 |
159 def Run(self, path): | 161 def RunOnPath(self, path): |
162 """Runs processor on all files under the given path.""" | |
163 | |
160 all_files = [] | 164 all_files = [] |
161 for file in self.GetPathsToSearch(): | 165 for file in self.GetPathsToSearch(): |
162 all_files += self.FindFilesIn(join(path, file)) | 166 all_files += self.FindFilesIn(join(path, file)) |
163 if not self.ProcessFiles(all_files, path): | 167 return self.ProcessFiles(all_files) |
164 return False | 168 |
165 return True | 169 def RunOnFiles(self, files): |
170 """Runs processor only on affected files.""" | |
171 | |
172 # Helper for getting directory pieces. | |
173 dirs = lambda f: dirname(f).split(os.sep) | |
174 | |
175 # Path offsets where to look (to be in sync with RunOnPath). | |
176 # Normalize '.' to check for it with str.startswith. | |
177 search_paths = [('' if p == '.' else p) for p in self.GetPathsToSearch()] | |
178 | |
179 all_files = [ | |
180 f.AbsoluteLocalPath() | |
181 for f in files | |
182 if (not self.IgnoreFile(f.LocalPath()) and | |
183 self.IsRelevant(f.LocalPath()) and | |
184 all(not self.IgnoreDir(d) for d in dirs(f.LocalPath())) and | |
185 any(map(f.LocalPath().startswith, search_paths))) | |
186 ] | |
187 | |
188 return self.ProcessFiles(all_files) | |
166 | 189 |
167 def IgnoreDir(self, name): | 190 def IgnoreDir(self, name): |
168 return (name.startswith('.') or | 191 return (name.startswith('.') or |
169 name in ('buildtools', 'data', 'gmock', 'gtest', 'kraken', | 192 name in ('buildtools', 'data', 'gmock', 'gtest', 'kraken', |
170 'octane', 'sunspider')) | 193 'octane', 'sunspider')) |
171 | 194 |
172 def IgnoreFile(self, name): | 195 def IgnoreFile(self, name): |
173 return name.startswith('.') | 196 return name.startswith('.') |
174 | 197 |
175 def FindFilesIn(self, path): | 198 def FindFilesIn(self, path): |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
207 | 230 |
208 def GetCpplintScript(self, prio_path): | 231 def GetCpplintScript(self, prio_path): |
209 for path in [prio_path] + os.environ["PATH"].split(os.pathsep): | 232 for path in [prio_path] + os.environ["PATH"].split(os.pathsep): |
210 path = path.strip('"') | 233 path = path.strip('"') |
211 cpplint = os.path.join(path, "cpplint.py") | 234 cpplint = os.path.join(path, "cpplint.py") |
212 if os.path.isfile(cpplint): | 235 if os.path.isfile(cpplint): |
213 return cpplint | 236 return cpplint |
214 | 237 |
215 return None | 238 return None |
216 | 239 |
217 def ProcessFiles(self, files, path): | 240 def ProcessFiles(self, files): |
218 good_files_cache = FileContentsCache('.cpplint-cache') | 241 good_files_cache = FileContentsCache('.cpplint-cache') |
219 good_files_cache.Load() | 242 good_files_cache.Load() |
220 files = good_files_cache.FilterUnchangedFiles(files) | 243 files = good_files_cache.FilterUnchangedFiles(files) |
221 if len(files) == 0: | 244 if len(files) == 0: |
222 print 'No changes in files detected. Skipping cpplint check.' | 245 print 'No changes in files detected. Skipping cpplint check.' |
223 return True | 246 return True |
224 | 247 |
225 filters = ",".join([n for n in LINT_RULES]) | 248 filters = ",".join([n for n in LINT_RULES]) |
226 command = [sys.executable, 'cpplint.py', '--filter', filters] | 249 command = [sys.executable, 'cpplint.py', '--filter', filters] |
227 cpplint = self.GetCpplintScript(join(path, "tools")) | 250 cpplint = self.GetCpplintScript(TOOLS_PATH) |
228 if cpplint is None: | 251 if cpplint is None: |
229 print('Could not find cpplint.py. Make sure ' | 252 print('Could not find cpplint.py. Make sure ' |
230 'depot_tools is installed and in the path.') | 253 'depot_tools is installed and in the path.') |
231 sys.exit(1) | 254 sys.exit(1) |
232 | 255 |
233 command = [sys.executable, cpplint, '--filter', filters] | 256 command = [sys.executable, cpplint, '--filter', filters] |
234 | 257 |
235 commands = join([command + [file] for file in files]) | 258 commands = join([command + [file] for file in files]) |
236 count = multiprocessing.cpu_count() | 259 count = multiprocessing.cpu_count() |
237 pool = multiprocessing.Pool(count) | 260 pool = multiprocessing.Pool(count) |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
374 print "%s does not end with a single new line." % name | 397 print "%s does not end with a single new line." % name |
375 result = False | 398 result = False |
376 # Sanitize flags for fuzzer. | 399 # Sanitize flags for fuzzer. |
377 if "mjsunit" in name: | 400 if "mjsunit" in name: |
378 match = FLAGS_LINE.search(contents) | 401 match = FLAGS_LINE.search(contents) |
379 if match: | 402 if match: |
380 print "%s Flags should use '-' (not '_')" % name | 403 print "%s Flags should use '-' (not '_')" % name |
381 result = False | 404 result = False |
382 return result | 405 return result |
383 | 406 |
384 def ProcessFiles(self, files, path): | 407 def ProcessFiles(self, files): |
385 success = True | 408 success = True |
386 violations = 0 | 409 violations = 0 |
387 for file in files: | 410 for file in files: |
388 try: | 411 try: |
389 handle = open(file) | 412 handle = open(file) |
390 contents = handle.read() | 413 contents = handle.read() |
391 if not self.ProcessContents(file, contents): | 414 if not self.ProcessContents(file, contents): |
392 success = False | 415 success = False |
393 violations += 1 | 416 violations += 1 |
394 finally: | 417 finally: |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
431 keys = {} | 454 keys = {} |
432 for key, value in pairs: | 455 for key, value in pairs: |
433 if key in keys: | 456 if key in keys: |
434 print("%s: Error: duplicate key %s" % (filepath, key)) | 457 print("%s: Error: duplicate key %s" % (filepath, key)) |
435 status["success"] = False | 458 status["success"] = False |
436 keys[key] = True | 459 keys[key] = True |
437 | 460 |
438 json.loads(contents, object_pairs_hook=check_pairs) | 461 json.loads(contents, object_pairs_hook=check_pairs) |
439 return status["success"] | 462 return status["success"] |
440 | 463 |
441 def CheckStatusFiles(workspace): | 464 def CheckStatusFiles(workspace): |
Michael Achenbach
2016/11/23 20:18:25
Will also change this one in a follow up CL. Proba
| |
442 success = True | 465 success = True |
443 suite_paths = utils.GetSuitePaths(join(workspace, "test")) | 466 suite_paths = utils.GetSuitePaths(join(workspace, "test")) |
444 for root in suite_paths: | 467 for root in suite_paths: |
445 suite_path = join(workspace, "test", root) | 468 suite_path = join(workspace, "test", root) |
446 status_file_path = join(suite_path, root + ".status") | 469 status_file_path = join(suite_path, root + ".status") |
447 suite = testsuite.TestSuite.LoadTestSuite(suite_path) | 470 suite = testsuite.TestSuite.LoadTestSuite(suite_path) |
448 if suite and exists(status_file_path): | 471 if suite and exists(status_file_path): |
449 success &= statusfile.PresubmitCheck(status_file_path) | 472 success &= statusfile.PresubmitCheck(status_file_path) |
450 success &= _CheckStatusFileForDuplicateKeys(status_file_path) | 473 success &= _CheckStatusFileForDuplicateKeys(status_file_path) |
451 return success | 474 return success |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
485 return result | 508 return result |
486 | 509 |
487 | 510 |
488 def Main(): | 511 def Main(): |
489 workspace = abspath(join(dirname(sys.argv[0]), '..')) | 512 workspace = abspath(join(dirname(sys.argv[0]), '..')) |
490 parser = GetOptions() | 513 parser = GetOptions() |
491 (options, args) = parser.parse_args() | 514 (options, args) = parser.parse_args() |
492 success = True | 515 success = True |
493 print "Running C++ lint check..." | 516 print "Running C++ lint check..." |
494 if not options.no_lint: | 517 if not options.no_lint: |
495 success &= CppLintProcessor().Run(workspace) | 518 success &= CppLintProcessor().RunOnPath(workspace) |
496 print "Running copyright header, trailing whitespaces and " \ | 519 print "Running copyright header, trailing whitespaces and " \ |
497 "two empty lines between declarations check..." | 520 "two empty lines between declarations check..." |
498 success &= SourceProcessor().Run(workspace) | 521 success &= SourceProcessor().RunOnPath(workspace) |
499 success &= CheckStatusFiles(workspace) | 522 success &= CheckStatusFiles(workspace) |
500 if success: | 523 if success: |
501 return 0 | 524 return 0 |
502 else: | 525 else: |
503 return 1 | 526 return 1 |
504 | 527 |
505 | 528 |
506 if __name__ == '__main__': | 529 if __name__ == '__main__': |
507 sys.exit(Main()) | 530 sys.exit(Main()) |
OLD | NEW |