Chromium Code Reviews| 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 |