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 17 matching lines...) Expand all Loading... |
28 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 28 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
29 | 29 |
30 try: | 30 try: |
31 import hashlib | 31 import hashlib |
32 md5er = hashlib.md5 | 32 md5er = hashlib.md5 |
33 except ImportError, e: | 33 except ImportError, e: |
34 import md5 | 34 import md5 |
35 md5er = md5.new | 35 md5er = md5.new |
36 | 36 |
37 | 37 |
| 38 import json |
38 import optparse | 39 import optparse |
39 import os | 40 import os |
40 from os.path import abspath, join, dirname, basename, exists | 41 from os.path import abspath, join, dirname, basename, exists |
41 import pickle | 42 import pickle |
42 import re | 43 import re |
43 import sys | 44 import sys |
44 import subprocess | 45 import subprocess |
45 import multiprocessing | 46 import multiprocessing |
46 from subprocess import PIPE | 47 from subprocess import PIPE |
47 | 48 |
(...skipping 352 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
400 handle.close() | 401 handle.close() |
401 print "Total violating files: %s" % violations | 402 print "Total violating files: %s" % violations |
402 return success | 403 return success |
403 | 404 |
404 | 405 |
405 def CheckExternalReferenceRegistration(workspace): | 406 def CheckExternalReferenceRegistration(workspace): |
406 code = subprocess.call( | 407 code = subprocess.call( |
407 [sys.executable, join(workspace, "tools", "external-reference-check.py")]) | 408 [sys.executable, join(workspace, "tools", "external-reference-check.py")]) |
408 return code == 0 | 409 return code == 0 |
409 | 410 |
| 411 |
| 412 def _CheckStatusFileForDuplicateKeys(filepath): |
| 413 comma_space_bracket = re.compile(", *]") |
| 414 lines = [] |
| 415 with open(filepath) as f: |
| 416 for line in f.readlines(): |
| 417 # Skip all-comment lines. |
| 418 if line.lstrip().startswith("#"): continue |
| 419 # Strip away comments at the end of the line. |
| 420 comment_start = line.find("#") |
| 421 if comment_start != -1: |
| 422 line = line[:comment_start] |
| 423 line = line.strip() |
| 424 # Strip away trailing commas within the line. |
| 425 line = comma_space_bracket.sub("]", line) |
| 426 if len(line) > 0: |
| 427 lines.append(line) |
| 428 |
| 429 # Strip away trailing commas at line ends. Ugh. |
| 430 for i in range(len(lines) - 1): |
| 431 if (lines[i].endswith(",") and len(lines[i + 1]) > 0 and |
| 432 lines[i + 1][0] in ("}", "]")): |
| 433 lines[i] = lines[i][:-1] |
| 434 |
| 435 contents = "\n".join(lines) |
| 436 # JSON wants double-quotes. |
| 437 contents = contents.replace("'", '"') |
| 438 # Fill in keywords (like PASS, SKIP). |
| 439 for key in statusfile.KEYWORDS: |
| 440 contents = re.sub(r"\b%s\b" % key, "\"%s\"" % key, contents) |
| 441 |
| 442 status = {"success": True} |
| 443 def check_pairs(pairs): |
| 444 keys = {} |
| 445 for key, value in pairs: |
| 446 if key in keys: |
| 447 print("%s: Error: duplicate key %s" % (filepath, key)) |
| 448 status["success"] = False |
| 449 keys[key] = True |
| 450 |
| 451 json.loads(contents, object_pairs_hook=check_pairs) |
| 452 return status["success"] |
| 453 |
410 def CheckStatusFiles(workspace): | 454 def CheckStatusFiles(workspace): |
| 455 success = True |
411 suite_paths = utils.GetSuitePaths(join(workspace, "test")) | 456 suite_paths = utils.GetSuitePaths(join(workspace, "test")) |
412 for root in suite_paths: | 457 for root in suite_paths: |
413 suite_path = join(workspace, "test", root) | 458 suite_path = join(workspace, "test", root) |
414 status_file_path = join(suite_path, root + ".status") | 459 status_file_path = join(suite_path, root + ".status") |
415 suite = testsuite.TestSuite.LoadTestSuite(suite_path) | 460 suite = testsuite.TestSuite.LoadTestSuite(suite_path) |
416 if suite and exists(status_file_path): | 461 if suite and exists(status_file_path): |
417 if not statusfile.PresubmitCheck(status_file_path): | 462 success &= statusfile.PresubmitCheck(status_file_path) |
418 return False | 463 success &= _CheckStatusFileForDuplicateKeys(status_file_path) |
419 return True | 464 return success |
420 | 465 |
421 def CheckAuthorizedAuthor(input_api, output_api): | 466 def CheckAuthorizedAuthor(input_api, output_api): |
422 """For non-googler/chromites committers, verify the author's email address is | 467 """For non-googler/chromites committers, verify the author's email address is |
423 in AUTHORS. | 468 in AUTHORS. |
424 """ | 469 """ |
425 # TODO(maruel): Add it to input_api? | 470 # TODO(maruel): Add it to input_api? |
426 import fnmatch | 471 import fnmatch |
427 | 472 |
428 author = input_api.change.author_email | 473 author = input_api.change.author_email |
429 if not author: | 474 if not author: |
(...skipping 23 matching lines...) Expand all Loading... |
453 return result | 498 return result |
454 | 499 |
455 | 500 |
456 def Main(): | 501 def Main(): |
457 workspace = abspath(join(dirname(sys.argv[0]), '..')) | 502 workspace = abspath(join(dirname(sys.argv[0]), '..')) |
458 parser = GetOptions() | 503 parser = GetOptions() |
459 (options, args) = parser.parse_args() | 504 (options, args) = parser.parse_args() |
460 success = True | 505 success = True |
461 print "Running C++ lint check..." | 506 print "Running C++ lint check..." |
462 if not options.no_lint: | 507 if not options.no_lint: |
463 success = CppLintProcessor().Run(workspace) and success | 508 success &= CppLintProcessor().Run(workspace) |
464 print "Running copyright header, trailing whitespaces and " \ | 509 print "Running copyright header, trailing whitespaces and " \ |
465 "two empty lines between declarations check..." | 510 "two empty lines between declarations check..." |
466 success = SourceProcessor().Run(workspace) and success | 511 success &= SourceProcessor().Run(workspace) |
467 success = CheckExternalReferenceRegistration(workspace) and success | 512 success &= CheckExternalReferenceRegistration(workspace) |
468 success = CheckStatusFiles(workspace) and success | 513 success &= CheckStatusFiles(workspace) |
469 if success: | 514 if success: |
470 return 0 | 515 return 0 |
471 else: | 516 else: |
472 return 1 | 517 return 1 |
473 | 518 |
474 | 519 |
475 if __name__ == '__main__': | 520 if __name__ == '__main__': |
476 sys.exit(Main()) | 521 sys.exit(Main()) |
OLD | NEW |