Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1315)

Side by Side Diff: presubmit_canned_checks.py

Issue 119365: Add InputApi.AffectedSourceFile() and custom filtering support. (Closed)
Patch Set: comment Created 11 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | presubmit_support.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 8
9 ### Description checks
10
9 def CheckChangeHasTestField(input_api, output_api): 11 def CheckChangeHasTestField(input_api, output_api):
10 """Requires that the changelist have a TEST= field.""" 12 """Requires that the changelist have a TEST= field."""
11 if input_api.change.TEST: 13 if input_api.change.TEST:
12 return [] 14 return []
13 else: 15 else:
14 return [output_api.PresubmitNotifyResult( 16 return [output_api.PresubmitNotifyResult(
15 "Changelist should have a TEST= field. TEST=none is allowed.")] 17 "Changelist should have a TEST= field. TEST=none is allowed.")]
16 18
17 19
18 def CheckChangeHasBugField(input_api, output_api): 20 def CheckChangeHasBugField(input_api, output_api):
(...skipping 25 matching lines...) Expand all
44 """Checks that the user didn't add 'DO NOT ' + 'SUBMIT' to the CL description. 46 """Checks that the user didn't add 'DO NOT ' + 'SUBMIT' to the CL description.
45 """ 47 """
46 keyword = 'DO NOT ' + 'SUBMIT' 48 keyword = 'DO NOT ' + 'SUBMIT'
47 if keyword in input_api.change.DescriptionText(): 49 if keyword in input_api.change.DescriptionText():
48 return [output_api.PresubmitError( 50 return [output_api.PresubmitError(
49 keyword + " is present in the changelist description.")] 51 keyword + " is present in the changelist description.")]
50 else: 52 else:
51 return [] 53 return []
52 54
53 55
56 ### Content checks
57
54 def CheckDoNotSubmitInFiles(input_api, output_api): 58 def CheckDoNotSubmitInFiles(input_api, output_api):
55 """Checks that the user didn't add 'DO NOT ' + 'SUBMIT' to any files.""" 59 """Checks that the user didn't add 'DO NOT ' + 'SUBMIT' to any files."""
56 keyword = 'DO NOT ' + 'SUBMIT' 60 keyword = 'DO NOT ' + 'SUBMIT'
57 for f, line_num, line in input_api.RightHandSideLines(): 61 # We want to check every text files, not just source files.
62 for f, line_num, line in input_api.RightHandSideLines(lambda x: x):
58 if keyword in line: 63 if keyword in line:
59 text = 'Found ' + keyword + ' in %s, line %s' % (f.LocalPath(), line_num) 64 text = 'Found ' + keyword + ' in %s, line %s' % (f.LocalPath(), line_num)
60 return [output_api.PresubmitError(text)] 65 return [output_api.PresubmitError(text)]
61 return [] 66 return []
62 67
63 68
64 def CheckDoNotSubmit(input_api, output_api): 69 def CheckChangeHasNoCR(input_api, output_api, source_file_filter=None):
65 return (
66 CheckDoNotSubmitInDescription(input_api, output_api) +
67 CheckDoNotSubmitInFiles(input_api, output_api)
68 )
69
70
71 def CheckChangeHasNoCR(input_api, output_api):
72 """Checks that there are no \r, \r\n (CR or CRLF) characters in any of the 70 """Checks that there are no \r, \r\n (CR or CRLF) characters in any of the
73 text files to be submitted. 71 source files to be submitted.
74 """ 72 """
75 outputs = [] 73 outputs = []
76 for f in input_api.AffectedTextFiles(): 74 for f in input_api.AffectedSourceFiles(source_file_filter):
77 if '\r' in input_api.ReadFile(f, 'rb'): 75 if '\r' in input_api.ReadFile(f, 'rb'):
78 outputs.append(output_api.PresubmitPromptWarning( 76 outputs.append(output_api.PresubmitPromptWarning(
79 "Found a CR character in %s" % f.LocalPath())) 77 "Found a CR character in %s" % f.LocalPath()))
80 return outputs 78 return outputs
81 79
82 80
83 def CheckChangeHasNoTabs(input_api, output_api): 81 def CheckChangeHasNoTabs(input_api, output_api, source_file_filter=None):
84 """Checks that there are no tab characters in any of the text files to be 82 """Checks that there are no tab characters in any of the text files to be
85 submitted. 83 submitted.
86 """ 84 """
87 for f, line_num, line in input_api.RightHandSideLines(): 85 for f, line_num, line in input_api.RightHandSideLines(source_file_filter):
88 if '\t' in line: 86 if '\t' in line:
89 return [output_api.PresubmitPromptWarning( 87 return [output_api.PresubmitPromptWarning(
90 "Found a tab character in %s, line %s" % 88 "Found a tab character in %s, line %s" %
91 (f.LocalPath(), line_num))] 89 (f.LocalPath(), line_num))]
92 return [] 90 return []
93 91
94 92
95 def CheckLongLines(input_api, output_api, maxlen=80): 93 def CheckLongLines(input_api, output_api, maxlen=80, source_file_filter=None):
96 """Checks that there aren't any lines longer than maxlen characters in any of 94 """Checks that there aren't any lines longer than maxlen characters in any of
97 the text files to be submitted. 95 the text files to be submitted.
98 """ 96 """
99 bad = [] 97 bad = []
100 for f, line_num, line in input_api.RightHandSideLines(): 98 for f, line_num, line in input_api.RightHandSideLines(source_file_filter):
101 # Allow lines with http://, https:// and #define/#pragma/#include/#if/#endif 99 # Allow lines with http://, https:// and #define/#pragma/#include/#if/#endif
102 # to exceed the maxlen rule. 100 # to exceed the maxlen rule.
103 if (len(line) > maxlen and 101 if (len(line) > maxlen and
104 not 'http://' in line and 102 not 'http://' in line and
105 not 'https://' in line and 103 not 'https://' in line and
106 not line.startswith('#define') and 104 not line.startswith('#define') and
107 not line.startswith('#include') and 105 not line.startswith('#include') and
108 not line.startswith('#pragma') and 106 not line.startswith('#pragma') and
109 not line.startswith('#if') and 107 not line.startswith('#if') and
110 not line.startswith('#endif')): 108 not line.startswith('#endif')):
111 bad.append( 109 bad.append(
112 '%s, line %s, %s chars' % 110 '%s, line %s, %s chars' %
113 (f.LocalPath(), line_num, len(line))) 111 (f.LocalPath(), line_num, len(line)))
114 if len(bad) == 5: # Just show the first 5 errors. 112 if len(bad) == 5: # Just show the first 5 errors.
115 break 113 break
116 114
117 if bad: 115 if bad:
118 msg = "Found lines longer than %s characters (first 5 shown)." % maxlen 116 msg = "Found lines longer than %s characters (first 5 shown)." % maxlen
119 return [output_api.PresubmitPromptWarning(msg, items=bad)] 117 return [output_api.PresubmitPromptWarning(msg, items=bad)]
120 else: 118 else:
121 return [] 119 return []
122 120
123 121
122 ### Other checks
123
124 def CheckDoNotSubmit(input_api, output_api):
125 return (
126 CheckDoNotSubmitInDescription(input_api, output_api) +
127 CheckDoNotSubmitInFiles(input_api, output_api)
128 )
129
130
124 def CheckTreeIsOpen(input_api, output_api, url, closed): 131 def CheckTreeIsOpen(input_api, output_api, url, closed):
125 """Checks that an url's content doesn't match a regexp that would mean that 132 """Checks that an url's content doesn't match a regexp that would mean that
126 the tree is closed.""" 133 the tree is closed."""
127 assert(input_api.is_committing) 134 assert(input_api.is_committing)
128 try: 135 try:
129 connection = input_api.urllib2.urlopen(url) 136 connection = input_api.urllib2.urlopen(url)
130 status = connection.read() 137 status = connection.read()
131 connection.close() 138 connection.close()
132 if input_api.re.match(closed, status): 139 if input_api.re.match(closed, status):
133 long_text = status + '\n' + url 140 long_text = status + '\n' + url
134 return [output_api.PresubmitPromptWarning("The tree is closed.", 141 return [output_api.PresubmitPromptWarning("The tree is closed.",
135 long_text=long_text)] 142 long_text=long_text)]
136 except IOError: 143 except IOError:
137 pass 144 pass
138 return [] 145 return []
139 146
140 147
141 def _RunPythonUnitTests_LoadTests(input_api, module_name): 148 def _RunPythonUnitTests_LoadTests(input_api, module_name):
142 """Meant to be stubbed out during unit testing.""" 149 """Meant to be stubbed out during unit testing."""
143 module = __import__(module_name) 150 module = __import__(module_name)
144 for part in module_name.split('.')[1:]: 151 for part in module_name.split('.')[1:]:
145 module = getattr(module, part) 152 module = getattr(module, part)
146 return input_api.unittest.TestLoader().loadTestsFromModule(module)._tests 153 return input_api.unittest.TestLoader().loadTestsFromModule(module)._tests
147 154
155
148 def RunPythonUnitTests(input_api, output_api, unit_tests): 156 def RunPythonUnitTests(input_api, output_api, unit_tests):
149 """Imports the unit_tests modules and run them.""" 157 """Imports the unit_tests modules and run them."""
150 # We don't want to hinder users from uploading incomplete patches. 158 # We don't want to hinder users from uploading incomplete patches.
151 if input_api.is_committing: 159 if input_api.is_committing:
152 message_type = output_api.PresubmitError 160 message_type = output_api.PresubmitError
153 else: 161 else:
154 message_type = output_api.PresubmitNotifyResult 162 message_type = output_api.PresubmitNotifyResult
155 tests_suite = [] 163 tests_suite = []
156 outputs = [] 164 outputs = []
157 for unit_test in unit_tests: 165 for unit_test in unit_tests:
158 try: 166 try:
159 tests_suite.extend(_RunPythonUnitTests_LoadTests(input_api, unit_test)) 167 tests_suite.extend(_RunPythonUnitTests_LoadTests(input_api, unit_test))
160 except ImportError: 168 except ImportError:
161 outputs.append(message_type("Failed to load %s" % unit_test, 169 outputs.append(message_type("Failed to load %s" % unit_test,
162 long_text=input_api.traceback.format_exc())) 170 long_text=input_api.traceback.format_exc()))
163 171
164 results = input_api.unittest.TextTestRunner(verbosity=0).run( 172 results = input_api.unittest.TextTestRunner(verbosity=0).run(
165 input_api.unittest.TestSuite(tests_suite)) 173 input_api.unittest.TestSuite(tests_suite))
166 if not results.wasSuccessful(): 174 if not results.wasSuccessful():
167 outputs.append(message_type("%d unit tests failed." % 175 outputs.append(message_type("%d unit tests failed." %
168 (len(results.failures) + len(results.errors)))) 176 (len(results.failures) + len(results.errors))))
169 return outputs 177 return outputs
OLDNEW
« no previous file with comments | « no previous file | presubmit_support.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698