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

Side by Side Diff: presubmit_canned_checks.py

Issue 6896004: Revert 82559. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/depot_tools/
Patch Set: Created 9 years, 8 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | tests/presubmit_unittest.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 # Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 # Copyright (c) 2010 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 4
5 """Generic presubmit checks that can be reused by other presubmit checks.""" 5 """Generic presubmit checks that can be reused by other presubmit checks."""
6 6
7 7
8 ### Description checks 8 ### Description checks
9 9
10 def CheckChangeHasTestField(input_api, output_api): 10 def CheckChangeHasTestField(input_api, output_api):
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
60 if input_api.is_committing: 60 if input_api.is_committing:
61 return [output_api.PresubmitError('Add a description.')] 61 return [output_api.PresubmitError('Add a description.')]
62 else: 62 else:
63 return [output_api.PresubmitNotifyResult('Add a description.')] 63 return [output_api.PresubmitNotifyResult('Add a description.')]
64 return [] 64 return []
65 65
66 ### Content checks 66 ### Content checks
67 67
68 def CheckDoNotSubmitInFiles(input_api, output_api): 68 def CheckDoNotSubmitInFiles(input_api, output_api):
69 """Checks that the user didn't add 'DO NOT ' + 'SUBMIT' to any files.""" 69 """Checks that the user didn't add 'DO NOT ' + 'SUBMIT' to any files."""
70 # We want to check every text file, not just source files.
71 file_filter = lambda x : x
72 keyword = 'DO NOT ' + 'SUBMIT' 70 keyword = 'DO NOT ' + 'SUBMIT'
73 errors = _FindNewViolationsOfRule(lambda line : keyword not in line, 71 # We want to check every text files, not just source files.
74 input_api, file_filter) 72 for f, line_num, line in input_api.RightHandSideLines(lambda x: x):
75 text = '\n'.join('Found %s in %s' % (keyword, loc) for loc in errors) 73 if keyword in line:
76 if text: 74 text = 'Found ' + keyword + ' in %s, line %s' % (f.LocalPath(), line_num)
77 return [output_api.PresubmitError(text)] 75 return [output_api.PresubmitError(text)]
78 return [] 76 return []
79 77
80 78
81 def CheckChangeLintsClean(input_api, output_api, source_file_filter=None): 79 def CheckChangeLintsClean(input_api, output_api, source_file_filter=None):
82 """Checks that all '.cc' and '.h' files pass cpplint.py.""" 80 """Checks that all '.cc' and '.h' files pass cpplint.py."""
83 _RE_IS_TEST = input_api.re.compile(r'.*tests?.(cc|h)$') 81 _RE_IS_TEST = input_api.re.compile(r'.*tests?.(cc|h)$')
84 result = [] 82 result = []
85 83
86 # Initialize cpplint. 84 # Initialize cpplint.
87 import cpplint 85 import cpplint
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
208 if cr_files: 206 if cr_files:
209 outputs.append(output_api.PresubmitPromptWarning( 207 outputs.append(output_api.PresubmitPromptWarning(
210 'Found a CR character in these files:', items=cr_files)) 208 'Found a CR character in these files:', items=cr_files))
211 if eof_files: 209 if eof_files:
212 outputs.append(output_api.PresubmitPromptWarning( 210 outputs.append(output_api.PresubmitPromptWarning(
213 'These files should end in one (and only one) newline character:', 211 'These files should end in one (and only one) newline character:',
214 items=eof_files)) 212 items=eof_files))
215 return outputs 213 return outputs
216 214
217 215
218 def _ReportErrorFileAndLine(filename, line_num, line):
219 """Default error formatter for _FindNewViolationsOfRule."""
220 return '%s, line %s' % (filename, line_num)
221
222
223 def _FindNewViolationsOfRule(callable_rule, input_api, source_file_filter=None,
224 error_formatter=_ReportErrorFileAndLine):
225 """Find all newly introduced violations of a per-line rule (a callable).
226
227 Arguments:
228 callable_rule: a callable taking a line of input and returning True
229 if the rule is satisfied and False if there was a problem.
230 input_api: object to enumerate the affected files.
231 source_file_filter: a filter to be passed to the input api.
232 error_formatter: a callable taking (filename, line_number, line) and
233 returning a formatted error string.
234
235 Returns:
236 A list of the newly-introduced violations reported by the rule.
237 """
238 errors = []
239 for f in input_api.AffectedFiles(source_file_filter):
240 # For speed, we do two passes, checking first the full file. Shelling out
241 # to the SCM to determine the changed region can be quite expensive on
242 # Win32. Assuming that most files will be kept problem-free, we can
243 # skip the SCM operations most of the time.
244 for line in f.NewContents():
245 if not callable_rule(line):
246 # Violation found in full text; re-run on just the changed contents.
247 for line_num, line in f.ChangedContents():
248 if not callable_rule(line):
249 errors.append(error_formatter(f.LocalPath(), line_num, line))
250 return errors
251
252
253 def CheckChangeHasNoTabs(input_api, output_api, source_file_filter=None): 216 def CheckChangeHasNoTabs(input_api, output_api, source_file_filter=None):
254 """Checks that there are no tab characters in any of the text files to be 217 """Checks that there are no tab characters in any of the text files to be
255 submitted. 218 submitted.
256 """ 219 """
257 # In addition to the filter, make sure that makefiles are blacklisted. 220 # In addition to the filter, make sure that makefiles are blacklisted.
258 if not source_file_filter: 221 if not source_file_filter:
259 # It's the default filter. 222 # It's the default filter.
260 source_file_filter = input_api.FilterSourceFile 223 source_file_filter = input_api.FilterSourceFile
261 def filter_more(affected_file): 224 def filter_more(affected_file):
262 return (not input_api.os_path.basename(affected_file.LocalPath()) in 225 return (not input_api.os_path.basename(affected_file.LocalPath()) in
263 ('Makefile', 'makefile') and 226 ('Makefile', 'makefile') and
264 source_file_filter(affected_file)) 227 source_file_filter(affected_file))
265 228 tabs = []
266 tabs = _FindNewViolationsOfRule(lambda line : '\t' not in line, 229 for f, line_num, line in input_api.RightHandSideLines(filter_more):
267 input_api, filter_more) 230 if '\t' in line:
268 231 tabs.append('%s, line %s' % (f.LocalPath(), line_num))
269 if tabs: 232 if tabs:
270 return [output_api.PresubmitPromptWarning('Found a tab character in:', 233 return [output_api.PresubmitPromptWarning('Found a tab character in:',
271 long_text='\n'.join(tabs))] 234 long_text='\n'.join(tabs))]
272 return [] 235 return []
273 236
274 237
275 def CheckChangeTodoHasOwner(input_api, output_api, source_file_filter=None): 238 def CheckChangeTodoHasOwner(input_api, output_api, source_file_filter=None):
276 """Checks that the user didn't add TODO(name) without an owner.""" 239 """Checks that the user didn't add TODO(name) without an owner."""
277 240
278 unowned_todo = input_api.re.compile('TO' + 'DO[^(]') 241 unowned_todo = input_api.re.compile('TO' + 'DO[^(]')
279 errors = _FindNewViolationsOfRule(lambda x : not unowned_todo.search(x), 242 for f, line_num, line in input_api.RightHandSideLines(source_file_filter):
280 input_api, source_file_filter) 243 if unowned_todo.search(line):
281 errors = ['Found TO' + 'DO with no owner in ' + x for x in errors] 244 text = ('Found TO' + 'DO with no owner in %s, line %s' %
282 if errors: 245 (f.LocalPath(), line_num))
283 return [output_api.PresubmitPromptWarning('\n'.join(errors))] 246 return [output_api.PresubmitPromptWarning(text)]
284 return [] 247 return []
285 248
286 249
287 def CheckChangeHasNoStrayWhitespace(input_api, output_api, 250 def CheckChangeHasNoStrayWhitespace(input_api, output_api,
288 source_file_filter=None): 251 source_file_filter=None):
289 """Checks that there is no stray whitespace at source lines end.""" 252 """Checks that there is no stray whitespace at source lines end."""
290 errors = _FindNewViolationsOfRule(lambda line : line.rstrip() == line, 253 errors = []
291 input_api, source_file_filter) 254 for f, line_num, line in input_api.RightHandSideLines(source_file_filter):
255 if line.rstrip() != line:
256 errors.append('%s, line %s' % (f.LocalPath(), line_num))
292 if errors: 257 if errors:
293 return [output_api.PresubmitPromptWarning( 258 return [output_api.PresubmitPromptWarning(
294 'Found line ending with white spaces in:', 259 'Found line ending with white spaces in:',
295 long_text='\n'.join(errors))] 260 long_text='\n'.join(errors))]
296 return [] 261 return []
297 262
298 263
299 def CheckLongLines(input_api, output_api, maxlen=80, source_file_filter=None): 264 def CheckLongLines(input_api, output_api, maxlen=80, source_file_filter=None):
300 """Checks that there aren't any lines longer than maxlen characters in any of 265 """Checks that there aren't any lines longer than maxlen characters in any of
301 the text files to be submitted. 266 the text files to be submitted.
302 """ 267 """
303 def no_long_lines(line): 268 bad = []
269 for f, line_num, line in input_api.RightHandSideLines(source_file_filter):
304 # Allow lines with http://, https:// and #define/#pragma/#include/#if/#endif 270 # Allow lines with http://, https:// and #define/#pragma/#include/#if/#endif
305 # to exceed the maxlen rule. 271 # to exceed the maxlen rule.
306 return (len(line) <= maxlen or 272 if (len(line) > maxlen and
307 any((url in line) for url in ('http://', 'https://')) or 273 not 'http://' in line and
308 line.startswith(('#define', '#include', '#import', '#pragma', 274 not 'https://' in line and
309 '#if', '#endif'))) 275 not line.startswith('#define') and
276 not line.startswith('#include') and
277 not line.startswith('#import') and
278 not line.startswith('#pragma') and
279 not line.startswith('#if') and
280 not line.startswith('#endif')):
281 bad.append(
282 '%s, line %s, %s chars' %
283 (f.LocalPath(), line_num, len(line)))
284 if len(bad) == 5: # Just show the first 5 errors.
285 break
310 286
311 def format_error(filename, line_num, line): 287 if bad:
312 return '%s, line %s, %s chars' % (filename, line_num, len(line))
313
314 errors = _FindNewViolationsOfRule(no_long_lines, input_api,
315 source_file_filter,
316 error_formatter=format_error)
317 if errors:
318 msg = 'Found lines longer than %s characters (first 5 shown).' % maxlen 288 msg = 'Found lines longer than %s characters (first 5 shown).' % maxlen
319 return [output_api.PresubmitPromptWarning(msg, items=errors[:5])] 289 return [output_api.PresubmitPromptWarning(msg, items=bad)]
320 else: 290 else:
321 return [] 291 return []
322 292
323 293
324 def CheckLicense(input_api, output_api, license_re, source_file_filter=None, 294 def CheckLicense(input_api, output_api, license_re, source_file_filter=None,
325 accept_empty_files=True): 295 accept_empty_files=True):
326 """Verifies the license header. 296 """Verifies the license header.
327 """ 297 """
328 license_re = input_api.re.compile(license_re, input_api.re.MULTILINE) 298 license_re = input_api.re.compile(license_re, input_api.re.MULTILINE)
329 bad_files = [] 299 bad_files = []
(...skipping 573 matching lines...) Expand 10 before | Expand all | Expand 10 after
903 # This code loads the default black list (e.g. third_party, experimental, etc) 873 # This code loads the default black list (e.g. third_party, experimental, etc)
904 # and add our black list (breakpad, skia and v8 are still not following 874 # and add our black list (breakpad, skia and v8 are still not following
905 # google style and are not really living this repository). 875 # google style and are not really living this repository).
906 # See presubmit_support.py InputApi.FilterSourceFile for the (simple) usage. 876 # See presubmit_support.py InputApi.FilterSourceFile for the (simple) usage.
907 black_list = input_api.DEFAULT_BLACK_LIST + excluded_paths 877 black_list = input_api.DEFAULT_BLACK_LIST + excluded_paths
908 white_list = input_api.DEFAULT_WHITE_LIST + text_files 878 white_list = input_api.DEFAULT_WHITE_LIST + text_files
909 sources = lambda x: input_api.FilterSourceFile(x, black_list=black_list) 879 sources = lambda x: input_api.FilterSourceFile(x, black_list=black_list)
910 text_files = lambda x: input_api.FilterSourceFile(x, black_list=black_list, 880 text_files = lambda x: input_api.FilterSourceFile(x, black_list=black_list,
911 white_list=white_list) 881 white_list=white_list)
912 882
913
914 snapshot_memory = []
915 def snapshot(msg):
916 """Measures & prints performance warning if a rule is running slow."""
917 dt2 = input_api.time.clock()
918 if snapshot_memory:
919 delta_ms = int(1000*(dt2 - snapshot_memory[0]))
920 if delta_ms > 500:
921 print " %s took a long time: %dms" % (snapshot_memory[1], delta_ms)
922 snapshot_memory[:] = (dt2, msg)
923
924 if owners_check: 883 if owners_check:
925 snapshot("checking owners")
926 results.extend(input_api.canned_checks.CheckOwners( 884 results.extend(input_api.canned_checks.CheckOwners(
927 input_api, output_api, source_file_filter=sources)) 885 input_api, output_api, source_file_filter=sources))
928 886
929 snapshot("checking long lines")
930 results.extend(input_api.canned_checks.CheckLongLines( 887 results.extend(input_api.canned_checks.CheckLongLines(
931 input_api, output_api, source_file_filter=sources)) 888 input_api, output_api, source_file_filter=sources))
932 snapshot( "checking tabs")
933 results.extend(input_api.canned_checks.CheckChangeHasNoTabs( 889 results.extend(input_api.canned_checks.CheckChangeHasNoTabs(
934 input_api, output_api, source_file_filter=sources)) 890 input_api, output_api, source_file_filter=sources))
935 snapshot( "checking stray whitespace")
936 results.extend(input_api.canned_checks.CheckChangeHasNoStrayWhitespace( 891 results.extend(input_api.canned_checks.CheckChangeHasNoStrayWhitespace(
937 input_api, output_api, source_file_filter=sources)) 892 input_api, output_api, source_file_filter=sources))
938 snapshot("checking eol style")
939 results.extend(input_api.canned_checks.CheckChangeSvnEolStyle( 893 results.extend(input_api.canned_checks.CheckChangeSvnEolStyle(
940 input_api, output_api, source_file_filter=text_files)) 894 input_api, output_api, source_file_filter=text_files))
941 snapshot("checking svn mime types")
942 results.extend(input_api.canned_checks.CheckSvnForCommonMimeTypes( 895 results.extend(input_api.canned_checks.CheckSvnForCommonMimeTypes(
943 input_api, output_api)) 896 input_api, output_api))
944 snapshot("checking license")
945 results.extend(input_api.canned_checks.CheckLicense( 897 results.extend(input_api.canned_checks.CheckLicense(
946 input_api, output_api, license_header, source_file_filter=sources)) 898 input_api, output_api, license_header, source_file_filter=sources))
947 snapshot("checking nsobjects")
948 results.extend(_CheckConstNSObject( 899 results.extend(_CheckConstNSObject(
949 input_api, output_api, source_file_filter=sources)) 900 input_api, output_api, source_file_filter=sources))
950 snapshot("checking singletons")
951 results.extend(_CheckSingletonInHeaders( 901 results.extend(_CheckSingletonInHeaders(
952 input_api, output_api, source_file_filter=sources)) 902 input_api, output_api, source_file_filter=sources))
953 snapshot("done")
954 return results 903 return results
OLDNEW
« no previous file with comments | « no previous file | tests/presubmit_unittest.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698