Index: tools/presubmit.py |
diff --git a/tools/presubmit.py b/tools/presubmit.py |
index 0e86063d6de89f2ef8911c4b721ca36d62c54c0b..cdffc0cdcd8dc44601ab6da3a99ac87608b325d1 100755 |
--- a/tools/presubmit.py |
+++ b/tools/presubmit.py |
@@ -35,6 +35,7 @@ except ImportError, e: |
md5er = md5.new |
+import json |
import optparse |
import os |
from os.path import abspath, join, dirname, basename, exists |
@@ -407,16 +408,60 @@ def CheckExternalReferenceRegistration(workspace): |
[sys.executable, join(workspace, "tools", "external-reference-check.py")]) |
return code == 0 |
+ |
+def _CheckStatusFileForDuplicateKeys(filepath): |
+ comma_space_bracket = re.compile(", *]") |
+ lines = [] |
+ with open(filepath) as f: |
+ for line in f.readlines(): |
+ # Skip all-comment lines. |
+ if line.lstrip().startswith("#"): continue |
+ # Strip away comments at the end of the line. |
+ comment_start = line.find("#") |
+ if comment_start != -1: |
+ line = line[:comment_start] |
+ line = line.strip() |
+ # Strip away trailing commas within the line. |
+ line = comma_space_bracket.sub("]", line) |
+ if len(line) > 0: |
+ lines.append(line) |
+ |
+ # Strip away trailing commas at line ends. Ugh. |
+ for i in range(len(lines) - 1): |
+ if (lines[i].endswith(",") and len(lines[i + 1]) > 0 and |
+ lines[i + 1][0] in ("}", "]")): |
+ lines[i] = lines[i][:-1] |
+ |
+ contents = "\n".join(lines) |
+ # JSON wants double-quotes. |
+ contents = contents.replace("'", '"') |
+ # Fill in keywords (like PASS, SKIP). |
+ for key in statusfile.KEYWORDS: |
+ contents = re.sub(r"\b%s\b" % key, "\"%s\"" % key, contents) |
+ |
+ status = {"success": True} |
+ def check_pairs(pairs): |
+ keys = {} |
+ for key, value in pairs: |
+ if key in keys: |
+ print("%s: Error: duplicate key %s" % (filepath, key)) |
+ status["success"] = False |
+ keys[key] = True |
+ |
+ json.loads(contents, object_pairs_hook=check_pairs) |
+ return status["success"] |
+ |
def CheckStatusFiles(workspace): |
+ success = True |
suite_paths = utils.GetSuitePaths(join(workspace, "test")) |
for root in suite_paths: |
suite_path = join(workspace, "test", root) |
status_file_path = join(suite_path, root + ".status") |
suite = testsuite.TestSuite.LoadTestSuite(suite_path) |
if suite and exists(status_file_path): |
- if not statusfile.PresubmitCheck(status_file_path): |
- return False |
- return True |
+ success &= statusfile.PresubmitCheck(status_file_path) |
+ success &= _CheckStatusFileForDuplicateKeys(status_file_path) |
+ return success |
def CheckAuthorizedAuthor(input_api, output_api): |
"""For non-googler/chromites committers, verify the author's email address is |
@@ -460,12 +505,12 @@ def Main(): |
success = True |
print "Running C++ lint check..." |
if not options.no_lint: |
- success = CppLintProcessor().Run(workspace) and success |
+ success &= CppLintProcessor().Run(workspace) |
print "Running copyright header, trailing whitespaces and " \ |
"two empty lines between declarations check..." |
- success = SourceProcessor().Run(workspace) and success |
- success = CheckExternalReferenceRegistration(workspace) and success |
- success = CheckStatusFiles(workspace) and success |
+ success &= SourceProcessor().Run(workspace) |
+ success &= CheckExternalReferenceRegistration(workspace) |
+ success &= CheckStatusFiles(workspace) |
if success: |
return 0 |
else: |