OLD | NEW |
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2006-2009 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 """Generic presubmit checks that can be reused by other presubmit checks.""" | 6 """Generic presubmit checks that can be reused by other presubmit checks.""" |
7 | 7 |
8 | |
9 ### Description checks | 8 ### Description checks |
10 | 9 |
11 def CheckChangeHasTestField(input_api, output_api): | 10 def CheckChangeHasTestField(input_api, output_api): |
12 """Requires that the changelist have a TEST= field.""" | 11 """Requires that the changelist have a TEST= field.""" |
13 if input_api.change.TEST: | 12 if input_api.change.TEST: |
14 return [] | 13 return [] |
15 else: | 14 else: |
16 return [output_api.PresubmitNotifyResult( | 15 return [output_api.PresubmitNotifyResult( |
17 "Changelist should have a TEST= field. TEST=none is allowed.")] | 16 "Changelist should have a TEST= field. TEST=none is allowed.")] |
18 | 17 |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
69 """Checks that the user didn't add 'DO NOT ' + 'SUBMIT' to any files.""" | 68 """Checks that the user didn't add 'DO NOT ' + 'SUBMIT' to any files.""" |
70 keyword = 'DO NOT ' + 'SUBMIT' | 69 keyword = 'DO NOT ' + 'SUBMIT' |
71 # We want to check every text files, not just source files. | 70 # We want to check every text files, not just source files. |
72 for f, line_num, line in input_api.RightHandSideLines(lambda x: x): | 71 for f, line_num, line in input_api.RightHandSideLines(lambda x: x): |
73 if keyword in line: | 72 if keyword in line: |
74 text = 'Found ' + keyword + ' in %s, line %s' % (f.LocalPath(), line_num) | 73 text = 'Found ' + keyword + ' in %s, line %s' % (f.LocalPath(), line_num) |
75 return [output_api.PresubmitError(text)] | 74 return [output_api.PresubmitError(text)] |
76 return [] | 75 return [] |
77 | 76 |
78 | 77 |
| 78 def CheckChangeLintsClean(input_api, output_api, source_file_filter=None): |
| 79 """Checks that all ".cc" and ".h" files pass cpplint.py.""" |
| 80 _RE_IS_TEST = input_api.re.compile(r'.*tests?.(cc|h)$') |
| 81 result = [] |
| 82 |
| 83 # Initialize cpplint. |
| 84 import cpplint |
| 85 cpplint._cpplint_state.ResetErrorCounts() |
| 86 |
| 87 # Justifications for each filter: |
| 88 # |
| 89 # - build/include : Too many; fix in the future. |
| 90 # - build/include_order : Not happening; #ifdefed includes. |
| 91 # - build/namespace : I'm surprised by how often we violate this rule. |
| 92 # - readability/casting : Mistakes a whole bunch of function pointer. |
| 93 # - runtime/int : Can be fixed long term; volume of errors too high |
| 94 # - runtime/virtual : Broken now, but can be fixed in the future? |
| 95 # - whitespace/braces : We have a lot of explicit scoping in chrome code. |
| 96 cpplint._SetFilters("-build/include,-build/include_order,-build/namespace," |
| 97 "-readability/casting,-runtime/int,-runtime/virtual," |
| 98 "-whitespace/braces") |
| 99 |
| 100 # We currently are more strict with normal code than unit tests; 4 and 5 are |
| 101 # the verbosity level that would normally be passed to cpplint.py through |
| 102 # --verbose=#. Hopefully, in the future, we can be more verbose. |
| 103 files = [f.AbsoluteLocalPath() for f in |
| 104 input_api.AffectedSourceFiles(source_file_filter)] |
| 105 for file_name in files: |
| 106 if _RE_IS_TEST.match(file_name): |
| 107 level = 5 |
| 108 else: |
| 109 level = 4 |
| 110 |
| 111 cpplint.ProcessFile(file_name, level) |
| 112 |
| 113 if cpplint._cpplint_state.error_count > 0: |
| 114 if input_api.is_committing: |
| 115 res_type = output_api.PresubmitError |
| 116 else: |
| 117 res_type = output_api.PresubmitPromptWarning |
| 118 result = [res_type("Changelist failed cpplint.py check.")] |
| 119 |
| 120 return result |
| 121 |
| 122 |
79 def CheckChangeHasNoCR(input_api, output_api, source_file_filter=None): | 123 def CheckChangeHasNoCR(input_api, output_api, source_file_filter=None): |
80 """Checks no '\r' (CR) character is in any source files.""" | 124 """Checks no '\r' (CR) character is in any source files.""" |
81 cr_files = [] | 125 cr_files = [] |
82 for f in input_api.AffectedSourceFiles(source_file_filter): | 126 for f in input_api.AffectedSourceFiles(source_file_filter): |
83 if '\r' in input_api.ReadFile(f, 'rb'): | 127 if '\r' in input_api.ReadFile(f, 'rb'): |
84 cr_files.append(f.LocalPath()) | 128 cr_files.append(f.LocalPath()) |
85 if cr_files: | 129 if cr_files: |
86 return [output_api.PresubmitPromptWarning( | 130 return [output_api.PresubmitPromptWarning( |
87 "Found a CR character in these files:", items=cr_files)] | 131 "Found a CR character in these files:", items=cr_files)] |
88 return [] | 132 return [] |
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
342 stderr=input_api.subprocess.PIPE) | 386 stderr=input_api.subprocess.PIPE) |
343 stdoutdata, stderrdata = subproc.communicate() | 387 stdoutdata, stderrdata = subproc.communicate() |
344 # Discard the output if returncode == 0 | 388 # Discard the output if returncode == 0 |
345 if subproc.returncode: | 389 if subproc.returncode: |
346 outputs.append("Test '%s' failed with code %d\n%s\n%s\n" % ( | 390 outputs.append("Test '%s' failed with code %d\n%s\n%s\n" % ( |
347 unit_test_name, subproc.returncode, stdoutdata, stderrdata)) | 391 unit_test_name, subproc.returncode, stdoutdata, stderrdata)) |
348 if outputs: | 392 if outputs: |
349 return [message_type("%d unit tests failed." % len(outputs), | 393 return [message_type("%d unit tests failed." % len(outputs), |
350 long_text='\n'.join(outputs))] | 394 long_text='\n'.join(outputs))] |
351 return [] | 395 return [] |
OLD | NEW |