blob: 2dfcdb577abdc095915ae18497d77b65b06a82cf [file] [log] [blame]
[email protected]a18130a2012-01-03 17:52:081# Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]ca8d1982009-02-19 16:33:122# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5"""Top-level presubmit script for Chromium.
6
[email protected]f1293792009-07-31 18:09:567See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts
[email protected]50d7d721e2009-11-15 17:56:188for more details about the presubmit API built into gcl.
[email protected]ca8d1982009-02-19 16:33:129"""
10
[email protected]eea609a2011-11-18 13:10:1211
[email protected]9d16ad12011-12-14 20:49:4712import re
[email protected]fbcafe5a2012-08-08 15:31:2213import subprocess
[email protected]55f9f382012-07-31 11:02:1814import sys
[email protected]9d16ad12011-12-14 20:49:4715
16
[email protected]379e7dd2010-01-28 17:39:2117_EXCLUDED_PATHS = (
[email protected]3e4eb112011-01-18 03:29:5418 r"^breakpad[\\\/].*",
[email protected]40d1dbb2012-10-26 07:18:0019 r"^native_client_sdk[\\\/]src[\\\/]build_tools[\\\/]make_rules.py",
20 r"^native_client_sdk[\\\/]src[\\\/]build_tools[\\\/]make_simple.py",
[email protected]a18130a2012-01-03 17:52:0821 r"^net[\\\/]tools[\\\/]spdyshark[\\\/].*",
[email protected]3e4eb112011-01-18 03:29:5422 r"^skia[\\\/].*",
23 r"^v8[\\\/].*",
24 r".*MakeFile$",
[email protected]1084ccc2012-03-14 03:22:5325 r".+_autogen\.h$",
[email protected]94f206c12012-08-25 00:09:1426 r"^cc[\\\/].*",
[email protected]39849c6c2012-09-14 22:15:5927 r"^webkit[\\\/]compositor_bindings[\\\/].*",
[email protected]ce145c02012-09-06 09:49:3428 r".+[\\\/]pnacl_shim\.c$",
[email protected]4306417642009-06-11 00:33:4029)
[email protected]ca8d1982009-02-19 16:33:1230
[email protected]ca8d1982009-02-19 16:33:1231
[email protected]eea609a2011-11-18 13:10:1232_TEST_ONLY_WARNING = (
33 'You might be calling functions intended only for testing from\n'
34 'production code. It is OK to ignore this warning if you know what\n'
35 'you are doing, as the heuristics used to detect the situation are\n'
36 'not perfect. The commit queue will not block on this warning.\n'
37 'Email [email protected] if you have questions.')
38
39
[email protected]127f18ec2012-06-16 05:05:5940_BANNED_OBJC_FUNCTIONS = (
41 (
42 'addTrackingRect:',
[email protected]23e6cbc2012-06-16 18:51:2043 (
44 'The use of -[NSView addTrackingRect:owner:userData:assumeInside:] is'
[email protected]127f18ec2012-06-16 05:05:5945 'prohibited. Please use CrTrackingArea instead.',
46 'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts',
47 ),
48 False,
49 ),
50 (
51 'NSTrackingArea',
[email protected]23e6cbc2012-06-16 18:51:2052 (
53 'The use of NSTrackingAreas is prohibited. Please use CrTrackingArea',
[email protected]127f18ec2012-06-16 05:05:5954 'instead.',
55 'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts',
56 ),
57 False,
58 ),
59 (
60 'convertPointFromBase:',
[email protected]23e6cbc2012-06-16 18:51:2061 (
62 'The use of -[NSView convertPointFromBase:] is almost certainly wrong.',
[email protected]127f18ec2012-06-16 05:05:5963 'Please use |convertPoint:(point) fromView:nil| instead.',
64 'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts',
65 ),
66 True,
67 ),
68 (
69 'convertPointToBase:',
[email protected]23e6cbc2012-06-16 18:51:2070 (
71 'The use of -[NSView convertPointToBase:] is almost certainly wrong.',
[email protected]127f18ec2012-06-16 05:05:5972 'Please use |convertPoint:(point) toView:nil| instead.',
73 'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts',
74 ),
75 True,
76 ),
77 (
78 'convertRectFromBase:',
[email protected]23e6cbc2012-06-16 18:51:2079 (
80 'The use of -[NSView convertRectFromBase:] is almost certainly wrong.',
[email protected]127f18ec2012-06-16 05:05:5981 'Please use |convertRect:(point) fromView:nil| instead.',
82 'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts',
83 ),
84 True,
85 ),
86 (
87 'convertRectToBase:',
[email protected]23e6cbc2012-06-16 18:51:2088 (
89 'The use of -[NSView convertRectToBase:] is almost certainly wrong.',
[email protected]127f18ec2012-06-16 05:05:5990 'Please use |convertRect:(point) toView:nil| instead.',
91 'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts',
92 ),
93 True,
94 ),
95 (
96 'convertSizeFromBase:',
[email protected]23e6cbc2012-06-16 18:51:2097 (
98 'The use of -[NSView convertSizeFromBase:] is almost certainly wrong.',
[email protected]127f18ec2012-06-16 05:05:5999 'Please use |convertSize:(point) fromView:nil| instead.',
100 'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts',
101 ),
102 True,
103 ),
104 (
105 'convertSizeToBase:',
[email protected]23e6cbc2012-06-16 18:51:20106 (
107 'The use of -[NSView convertSizeToBase:] is almost certainly wrong.',
[email protected]127f18ec2012-06-16 05:05:59108 'Please use |convertSize:(point) toView:nil| instead.',
109 'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts',
110 ),
111 True,
112 ),
113)
114
115
116_BANNED_CPP_FUNCTIONS = (
[email protected]23e6cbc2012-06-16 18:51:20117 # Make sure that gtest's FRIEND_TEST() macro is not used; the
118 # FRIEND_TEST_ALL_PREFIXES() macro from base/gtest_prod_util.h should be
[email protected]e00ccc92012-11-01 17:32:30119 # used instead since that allows for FLAKY_ and DISABLED_ prefixes.
[email protected]23e6cbc2012-06-16 18:51:20120 (
121 'FRIEND_TEST(',
122 (
[email protected]e3c945502012-06-26 20:01:49123 'Chromium code should not use gtest\'s FRIEND_TEST() macro. Include',
[email protected]23e6cbc2012-06-16 18:51:20124 'base/gtest_prod_util.h and use FRIEND_TEST_ALL_PREFIXES() instead.',
125 ),
126 False,
127 ),
128 (
129 'ScopedAllowIO',
130 (
[email protected]e3c945502012-06-26 20:01:49131 'New code should not use ScopedAllowIO. Post a task to the blocking',
132 'pool or the FILE thread instead.',
[email protected]23e6cbc2012-06-16 18:51:20133 ),
[email protected]e3c945502012-06-26 20:01:49134 True,
[email protected]23e6cbc2012-06-16 18:51:20135 ),
136 (
137 'FilePathWatcher::Delegate',
138 (
[email protected]e3c945502012-06-26 20:01:49139 'New code should not use FilePathWatcher::Delegate. Use the callback',
[email protected]23e6cbc2012-06-16 18:51:20140 'interface instead.',
141 ),
142 False,
143 ),
[email protected]e3c945502012-06-26 20:01:49144 (
145 'browser::FindLastActiveWithProfile',
146 (
147 'This function is deprecated and we\'re working on removing it. Pass',
148 'more context to get a Browser*, like a WebContents, window, or session',
149 'id. Talk to ben@ or jam@ for more information.',
150 ),
151 True,
152 ),
153 (
[email protected]e3c945502012-06-26 20:01:49154 'browser::FindAnyBrowser',
155 (
156 'This function is deprecated and we\'re working on removing it. Pass',
157 'more context to get a Browser*, like a WebContents, window, or session',
158 'id. Talk to ben@ or jam@ for more information.',
159 ),
160 True,
161 ),
162 (
163 'browser::FindOrCreateTabbedBrowser',
164 (
165 'This function is deprecated and we\'re working on removing it. Pass',
166 'more context to get a Browser*, like a WebContents, window, or session',
167 'id. Talk to ben@ or jam@ for more information.',
168 ),
169 True,
170 ),
171 (
172 'browser::FindTabbedBrowser',
173 (
174 'This function is deprecated and we\'re working on removing it. Pass',
175 'more context to get a Browser*, like a WebContents, window, or session',
176 'id. Talk to ben@ or jam@ for more information.',
177 ),
178 True,
179 ),
[email protected]127f18ec2012-06-16 05:05:59180)
181
182
[email protected]eea609a2011-11-18 13:10:12183
[email protected]55459852011-08-10 15:17:19184def _CheckNoProductionCodeUsingTestOnlyFunctions(input_api, output_api):
185 """Attempts to prevent use of functions intended only for testing in
186 non-testing code. For now this is just a best-effort implementation
187 that ignores header files and may have some false positives. A
188 better implementation would probably need a proper C++ parser.
189 """
190 # We only scan .cc files and the like, as the declaration of
191 # for-testing functions in header files are hard to distinguish from
192 # calls to such functions without a proper C++ parser.
[email protected]403bfbc92012-06-11 23:30:09193 platform_specifiers = r'(_(android|chromeos|gtk|mac|posix|win))?'
[email protected]55459852011-08-10 15:17:19194 source_extensions = r'\.(cc|cpp|cxx|mm)$'
195 file_inclusion_pattern = r'.+%s' % source_extensions
[email protected]19e77fd2011-10-20 05:24:05196 file_exclusion_patterns = (
[email protected]44e376e2012-10-26 19:40:21197 r'.*[/\\](fake_|test_|mock_).+%s' % source_extensions,
[email protected]c762d252012-02-28 02:07:24198 r'.+_test_(base|support|util)%s' % source_extensions,
[email protected]403bfbc92012-06-11 23:30:09199 r'.+_(api|browser|perf|unit|ui)?test%s%s' % (platform_specifiers,
200 source_extensions),
[email protected]19e77fd2011-10-20 05:24:05201 r'.+profile_sync_service_harness%s' % source_extensions,
202 )
203 path_exclusion_patterns = (
204 r'.*[/\\](test|tool(s)?)[/\\].*',
205 # At request of folks maintaining this folder.
206 r'chrome[/\\]browser[/\\]automation[/\\].*',
207 )
[email protected]55459852011-08-10 15:17:19208
209 base_function_pattern = r'ForTest(ing)?|for_test(ing)?'
210 inclusion_pattern = input_api.re.compile(r'(%s)\s*\(' % base_function_pattern)
211 exclusion_pattern = input_api.re.compile(
212 r'::[A-Za-z0-9_]+(%s)|(%s)[^;]+\{' % (
213 base_function_pattern, base_function_pattern))
214
215 def FilterFile(affected_file):
[email protected]19e77fd2011-10-20 05:24:05216 black_list = (file_exclusion_patterns + path_exclusion_patterns +
[email protected]3afb12a42011-08-15 13:48:33217 _EXCLUDED_PATHS + input_api.DEFAULT_BLACK_LIST)
[email protected]55459852011-08-10 15:17:19218 return input_api.FilterSourceFile(
219 affected_file,
220 white_list=(file_inclusion_pattern, ),
221 black_list=black_list)
222
223 problems = []
224 for f in input_api.AffectedSourceFiles(FilterFile):
225 local_path = f.LocalPath()
226 lines = input_api.ReadFile(f).splitlines()
227 line_number = 0
228 for line in lines:
229 if (inclusion_pattern.search(line) and
230 not exclusion_pattern.search(line)):
231 problems.append(
232 '%s:%d\n %s' % (local_path, line_number, line.strip()))
233 line_number += 1
234
235 if problems:
[email protected]eea609a2011-11-18 13:10:12236 if not input_api.is_committing:
237 return [output_api.PresubmitPromptWarning(_TEST_ONLY_WARNING, problems)]
238 else:
239 # We don't warn on commit, to avoid stopping commits going through CQ.
240 return [output_api.PresubmitNotifyResult(_TEST_ONLY_WARNING, problems)]
[email protected]55459852011-08-10 15:17:19241 else:
242 return []
243
244
[email protected]10689ca2011-09-02 02:31:54245def _CheckNoIOStreamInHeaders(input_api, output_api):
246 """Checks to make sure no .h files include <iostream>."""
247 files = []
248 pattern = input_api.re.compile(r'^#include\s*<iostream>',
249 input_api.re.MULTILINE)
250 for f in input_api.AffectedSourceFiles(input_api.FilterSourceFile):
251 if not f.LocalPath().endswith('.h'):
252 continue
253 contents = input_api.ReadFile(f)
254 if pattern.search(contents):
255 files.append(f)
256
257 if len(files):
258 return [ output_api.PresubmitError(
[email protected]6c063c62012-07-11 19:11:06259 'Do not #include <iostream> in header files, since it inserts static '
260 'initialization into every file including the header. Instead, '
[email protected]10689ca2011-09-02 02:31:54261 '#include <ostream>. See http://crbug.com/94794',
262 files) ]
263 return []
264
265
[email protected]72df4e782012-06-21 16:28:18266def _CheckNoUNIT_TESTInSourceFiles(input_api, output_api):
267 """Checks to make sure no source files use UNIT_TEST"""
268 problems = []
269 for f in input_api.AffectedFiles():
270 if (not f.LocalPath().endswith(('.cc', '.mm'))):
271 continue
272
273 for line_num, line in f.ChangedContents():
274 if 'UNIT_TEST' in line:
275 problems.append(' %s:%d' % (f.LocalPath(), line_num))
276
277 if not problems:
278 return []
279 return [output_api.PresubmitPromptWarning('UNIT_TEST is only for headers.\n' +
280 '\n'.join(problems))]
281
282
[email protected]8ea5d4b2011-09-13 21:49:22283def _CheckNoNewWStrings(input_api, output_api):
284 """Checks to make sure we don't introduce use of wstrings."""
[email protected]55463aa62011-10-12 00:48:27285 problems = []
[email protected]8ea5d4b2011-09-13 21:49:22286 for f in input_api.AffectedFiles():
[email protected]b5c24292011-11-28 14:38:20287 if (not f.LocalPath().endswith(('.cc', '.h')) or
288 f.LocalPath().endswith('test.cc')):
289 continue
[email protected]8ea5d4b2011-09-13 21:49:22290
[email protected]a11dbe9b2012-08-07 01:32:58291 allowWString = False
[email protected]b5c24292011-11-28 14:38:20292 for line_num, line in f.ChangedContents():
[email protected]a11dbe9b2012-08-07 01:32:58293 if 'presubmit: allow wstring' in line:
294 allowWString = True
295 elif not allowWString and 'wstring' in line:
[email protected]55463aa62011-10-12 00:48:27296 problems.append(' %s:%d' % (f.LocalPath(), line_num))
[email protected]a11dbe9b2012-08-07 01:32:58297 allowWString = False
298 else:
299 allowWString = False
[email protected]8ea5d4b2011-09-13 21:49:22300
[email protected]55463aa62011-10-12 00:48:27301 if not problems:
302 return []
303 return [output_api.PresubmitPromptWarning('New code should not use wstrings.'
[email protected]a11dbe9b2012-08-07 01:32:58304 ' If you are calling a cross-platform API that accepts a wstring, '
305 'fix the API.\n' +
[email protected]55463aa62011-10-12 00:48:27306 '\n'.join(problems))]
[email protected]8ea5d4b2011-09-13 21:49:22307
308
[email protected]2a8ac9c2011-10-19 17:20:44309def _CheckNoDEPSGIT(input_api, output_api):
310 """Make sure .DEPS.git is never modified manually."""
311 if any(f.LocalPath().endswith('.DEPS.git') for f in
312 input_api.AffectedFiles()):
313 return [output_api.PresubmitError(
314 'Never commit changes to .DEPS.git. This file is maintained by an\n'
315 'automated system based on what\'s in DEPS and your changes will be\n'
316 'overwritten.\n'
317 'See http://code.google.com/p/chromium/wiki/UsingNewGit#Rolling_DEPS\n'
318 'for more information')]
319 return []
320
321
[email protected]127f18ec2012-06-16 05:05:59322def _CheckNoBannedFunctions(input_api, output_api):
323 """Make sure that banned functions are not used."""
324 warnings = []
325 errors = []
326
327 file_filter = lambda f: f.LocalPath().endswith(('.mm', '.m', '.h'))
328 for f in input_api.AffectedFiles(file_filter=file_filter):
329 for line_num, line in f.ChangedContents():
330 for func_name, message, error in _BANNED_OBJC_FUNCTIONS:
331 if func_name in line:
332 problems = warnings;
333 if error:
334 problems = errors;
335 problems.append(' %s:%d:' % (f.LocalPath(), line_num))
336 for message_line in message:
337 problems.append(' %s' % message_line)
338
339 file_filter = lambda f: f.LocalPath().endswith(('.cc', '.mm', '.h'))
340 for f in input_api.AffectedFiles(file_filter=file_filter):
341 for line_num, line in f.ChangedContents():
342 for func_name, message, error in _BANNED_CPP_FUNCTIONS:
343 if func_name in line:
344 problems = warnings;
345 if error:
346 problems = errors;
347 problems.append(' %s:%d:' % (f.LocalPath(), line_num))
348 for message_line in message:
349 problems.append(' %s' % message_line)
350
351 result = []
352 if (warnings):
353 result.append(output_api.PresubmitPromptWarning(
354 'Banned functions were used.\n' + '\n'.join(warnings)))
355 if (errors):
356 result.append(output_api.PresubmitError(
357 'Banned functions were used.\n' + '\n'.join(errors)))
358 return result
359
360
[email protected]6c063c62012-07-11 19:11:06361def _CheckNoPragmaOnce(input_api, output_api):
362 """Make sure that banned functions are not used."""
363 files = []
364 pattern = input_api.re.compile(r'^#pragma\s+once',
365 input_api.re.MULTILINE)
366 for f in input_api.AffectedSourceFiles(input_api.FilterSourceFile):
367 if not f.LocalPath().endswith('.h'):
368 continue
369 contents = input_api.ReadFile(f)
370 if pattern.search(contents):
371 files.append(f)
372
373 if files:
374 return [output_api.PresubmitError(
375 'Do not use #pragma once in header files.\n'
376 'See http://www.chromium.org/developers/coding-style#TOC-File-headers',
377 files)]
378 return []
379
[email protected]127f18ec2012-06-16 05:05:59380
[email protected]e7479052012-09-19 00:26:12381def _CheckNoTrinaryTrueFalse(input_api, output_api):
382 """Checks to make sure we don't introduce use of foo ? true : false."""
383 problems = []
384 pattern = input_api.re.compile(r'\?\s*(true|false)\s*:\s*(true|false)')
385 for f in input_api.AffectedFiles():
386 if not f.LocalPath().endswith(('.cc', '.h', '.inl', '.m', '.mm')):
387 continue
388
389 for line_num, line in f.ChangedContents():
390 if pattern.match(line):
391 problems.append(' %s:%d' % (f.LocalPath(), line_num))
392
393 if not problems:
394 return []
395 return [output_api.PresubmitPromptWarning(
396 'Please consider avoiding the "? true : false" pattern if possible.\n' +
397 '\n'.join(problems))]
398
399
[email protected]55f9f382012-07-31 11:02:18400def _CheckUnwantedDependencies(input_api, output_api):
401 """Runs checkdeps on #include statements added in this
402 change. Breaking - rules is an error, breaking ! rules is a
403 warning.
404 """
405 # We need to wait until we have an input_api object and use this
406 # roundabout construct to import checkdeps because this file is
407 # eval-ed and thus doesn't have __file__.
408 original_sys_path = sys.path
409 try:
410 sys.path = sys.path + [input_api.os_path.join(
411 input_api.PresubmitLocalPath(), 'tools', 'checkdeps')]
412 import checkdeps
413 from cpp_checker import CppChecker
414 from rules import Rule
415 finally:
416 # Restore sys.path to what it was before.
417 sys.path = original_sys_path
418
419 added_includes = []
420 for f in input_api.AffectedFiles():
421 if not CppChecker.IsCppFile(f.LocalPath()):
422 continue
423
424 changed_lines = [line for line_num, line in f.ChangedContents()]
425 added_includes.append([f.LocalPath(), changed_lines])
426
427 deps_checker = checkdeps.DepsChecker()
428
429 error_descriptions = []
430 warning_descriptions = []
431 for path, rule_type, rule_description in deps_checker.CheckAddedCppIncludes(
432 added_includes):
433 description_with_path = '%s\n %s' % (path, rule_description)
434 if rule_type == Rule.DISALLOW:
435 error_descriptions.append(description_with_path)
436 else:
437 warning_descriptions.append(description_with_path)
438
439 results = []
440 if error_descriptions:
441 results.append(output_api.PresubmitError(
442 'You added one or more #includes that violate checkdeps rules.',
443 error_descriptions))
444 if warning_descriptions:
[email protected]779caa52012-08-21 17:05:59445 if not input_api.is_committing:
446 warning_factory = output_api.PresubmitPromptWarning
447 else:
448 # We don't want to block use of the CQ when there is a warning
449 # of this kind, so we only show a message when committing.
450 warning_factory = output_api.PresubmitNotifyResult
451 results.append(warning_factory(
[email protected]55f9f382012-07-31 11:02:18452 'You added one or more #includes of files that are temporarily\n'
453 'allowed but being removed. Can you avoid introducing the\n'
454 '#include? See relevant DEPS file(s) for details and contacts.',
455 warning_descriptions))
456 return results
457
458
[email protected]fbcafe5a2012-08-08 15:31:22459def _CheckFilePermissions(input_api, output_api):
460 """Check that all files have their permissions properly set."""
461 args = [sys.executable, 'tools/checkperms/checkperms.py', '--root',
462 input_api.change.RepositoryRoot()]
463 for f in input_api.AffectedFiles():
464 args += ['--file', f.LocalPath()]
465 errors = []
466 (errors, stderrdata) = subprocess.Popen(args).communicate()
467
468 results = []
469 if errors:
[email protected]c8278b32012-10-30 20:35:49470 results.append(output_api.PresubmitError('checkperms.py failed.',
[email protected]fbcafe5a2012-08-08 15:31:22471 errors))
472 return results
473
474
[email protected]c8278b32012-10-30 20:35:49475def _CheckNoAuraWindowPropertyHInHeaders(input_api, output_api):
476 """Makes sure we don't include ui/aura/window_property.h
477 in header files.
478 """
479 pattern = input_api.re.compile(r'^#include\s*"ui/aura/window_property.h"')
480 errors = []
481 for f in input_api.AffectedFiles():
482 if not f.LocalPath().endswith('.h'):
483 continue
484 for line_num, line in f.ChangedContents():
485 if pattern.match(line):
486 errors.append(' %s:%d' % (f.LocalPath(), line_num))
487
488 results = []
489 if errors:
490 results.append(output_api.PresubmitError(
491 'Header files should not include ui/aura/window_property.h', errors))
492 return results
493
494
[email protected]22c9bd72011-03-27 16:47:39495def _CommonChecks(input_api, output_api):
496 """Checks common to both upload and commit."""
497 results = []
498 results.extend(input_api.canned_checks.PanProjectChecks(
499 input_api, output_api, excluded_paths=_EXCLUDED_PATHS))
[email protected]66daa702011-05-28 14:41:46500 results.extend(_CheckAuthorizedAuthor(input_api, output_api))
[email protected]55459852011-08-10 15:17:19501 results.extend(
502 _CheckNoProductionCodeUsingTestOnlyFunctions(input_api, output_api))
[email protected]10689ca2011-09-02 02:31:54503 results.extend(_CheckNoIOStreamInHeaders(input_api, output_api))
[email protected]72df4e782012-06-21 16:28:18504 results.extend(_CheckNoUNIT_TESTInSourceFiles(input_api, output_api))
[email protected]8ea5d4b2011-09-13 21:49:22505 results.extend(_CheckNoNewWStrings(input_api, output_api))
[email protected]2a8ac9c2011-10-19 17:20:44506 results.extend(_CheckNoDEPSGIT(input_api, output_api))
[email protected]127f18ec2012-06-16 05:05:59507 results.extend(_CheckNoBannedFunctions(input_api, output_api))
[email protected]6c063c62012-07-11 19:11:06508 results.extend(_CheckNoPragmaOnce(input_api, output_api))
[email protected]e7479052012-09-19 00:26:12509 results.extend(_CheckNoTrinaryTrueFalse(input_api, output_api))
[email protected]55f9f382012-07-31 11:02:18510 results.extend(_CheckUnwantedDependencies(input_api, output_api))
[email protected]fbcafe5a2012-08-08 15:31:22511 results.extend(_CheckFilePermissions(input_api, output_api))
[email protected]c8278b32012-10-30 20:35:49512 results.extend(_CheckNoAuraWindowPropertyHInHeaders(input_api, output_api))
[email protected]22c9bd72011-03-27 16:47:39513 return results
[email protected]1f7b4172010-01-28 01:17:34514
[email protected]b337cb5b2011-01-23 21:24:05515
516def _CheckSubversionConfig(input_api, output_api):
517 """Verifies the subversion config file is correctly setup.
518
519 Checks that autoprops are enabled, returns an error otherwise.
520 """
521 join = input_api.os_path.join
522 if input_api.platform == 'win32':
523 appdata = input_api.environ.get('APPDATA', '')
524 if not appdata:
525 return [output_api.PresubmitError('%APPDATA% is not configured.')]
526 path = join(appdata, 'Subversion', 'config')
527 else:
528 home = input_api.environ.get('HOME', '')
529 if not home:
530 return [output_api.PresubmitError('$HOME is not configured.')]
531 path = join(home, '.subversion', 'config')
532
533 error_msg = (
534 'Please look at http://dev.chromium.org/developers/coding-style to\n'
535 'configure your subversion configuration file. This enables automatic\n'
[email protected]c6a3c10b2011-01-24 16:14:20536 'properties to simplify the project maintenance.\n'
537 'Pro-tip: just download and install\n'
538 'http://src.chromium.org/viewvc/chrome/trunk/tools/build/slave/config\n')
[email protected]b337cb5b2011-01-23 21:24:05539
540 try:
541 lines = open(path, 'r').read().splitlines()
542 # Make sure auto-props is enabled and check for 2 Chromium standard
543 # auto-prop.
544 if (not '*.cc = svn:eol-style=LF' in lines or
545 not '*.pdf = svn:mime-type=application/pdf' in lines or
546 not 'enable-auto-props = yes' in lines):
547 return [
[email protected]79ed7e62011-02-21 21:08:53548 output_api.PresubmitNotifyResult(
[email protected]b337cb5b2011-01-23 21:24:05549 'It looks like you have not configured your subversion config '
[email protected]b5359c02011-02-01 20:29:56550 'file or it is not up-to-date.\n' + error_msg)
[email protected]b337cb5b2011-01-23 21:24:05551 ]
552 except (OSError, IOError):
553 return [
[email protected]79ed7e62011-02-21 21:08:53554 output_api.PresubmitNotifyResult(
[email protected]b337cb5b2011-01-23 21:24:05555 'Can\'t find your subversion config file.\n' + error_msg)
556 ]
557 return []
558
559
[email protected]66daa702011-05-28 14:41:46560def _CheckAuthorizedAuthor(input_api, output_api):
561 """For non-googler/chromites committers, verify the author's email address is
562 in AUTHORS.
563 """
[email protected]9bb9cb82011-06-13 20:43:01564 # TODO(maruel): Add it to input_api?
565 import fnmatch
566
[email protected]66daa702011-05-28 14:41:46567 author = input_api.change.author_email
[email protected]9bb9cb82011-06-13 20:43:01568 if not author:
569 input_api.logging.info('No author, skipping AUTHOR check')
[email protected]66daa702011-05-28 14:41:46570 return []
[email protected]c99663292011-05-31 19:46:08571 authors_path = input_api.os_path.join(
[email protected]66daa702011-05-28 14:41:46572 input_api.PresubmitLocalPath(), 'AUTHORS')
573 valid_authors = (
574 input_api.re.match(r'[^#]+\s+\<(.+?)\>\s*$', line)
575 for line in open(authors_path))
[email protected]ac54b132011-06-06 18:11:18576 valid_authors = [item.group(1).lower() for item in valid_authors if item]
[email protected]9bb9cb82011-06-13 20:43:01577 if input_api.verbose:
578 print 'Valid authors are %s' % ', '.join(valid_authors)
[email protected]d8b50be2011-06-15 14:19:44579 if not any(fnmatch.fnmatch(author.lower(), valid) for valid in valid_authors):
[email protected]66daa702011-05-28 14:41:46580 return [output_api.PresubmitPromptWarning(
581 ('%s is not in AUTHORS file. If you are a new contributor, please visit'
582 '\n'
583 'http://www.chromium.org/developers/contributing-code and read the '
584 '"Legal" section\n'
585 'If you are a chromite, verify the contributor signed the CLA.') %
586 author)]
587 return []
588
589
[email protected]1f7b4172010-01-28 01:17:34590def CheckChangeOnUpload(input_api, output_api):
591 results = []
592 results.extend(_CommonChecks(input_api, output_api))
[email protected]fe5f57c52009-06-05 14:25:54593 return results
[email protected]ca8d1982009-02-19 16:33:12594
595
596def CheckChangeOnCommit(input_api, output_api):
[email protected]fe5f57c52009-06-05 14:25:54597 results = []
[email protected]1f7b4172010-01-28 01:17:34598 results.extend(_CommonChecks(input_api, output_api))
[email protected]dd805fe2009-10-01 08:11:51599 # TODO(thestig) temporarily disabled, doesn't work in third_party/
600 #results.extend(input_api.canned_checks.CheckSvnModifiedDirectories(
601 # input_api, output_api, sources))
[email protected]fe5f57c52009-06-05 14:25:54602 # Make sure the tree is 'open'.
[email protected]806e98e2010-03-19 17:49:27603 results.extend(input_api.canned_checks.CheckTreeIsOpen(
[email protected]7f238152009-08-12 19:00:34604 input_api,
605 output_api,
[email protected]4efa42142010-08-26 01:29:26606 json_url='http://chromium-status.appspot.com/current?format=json'))
[email protected]806e98e2010-03-19 17:49:27607 results.extend(input_api.canned_checks.CheckRietveldTryJobExecution(input_api,
[email protected]4ddc5df2011-12-12 03:05:04608 output_api, 'http://codereview.chromium.org',
[email protected]c1ba4c52012-03-09 14:23:28609 ('win_rel', 'linux_rel', 'mac_rel, win:compile'),
610 '[email protected]'))
[email protected]806e98e2010-03-19 17:49:27611
[email protected]3e4eb112011-01-18 03:29:54612 results.extend(input_api.canned_checks.CheckChangeHasBugField(
613 input_api, output_api))
[email protected]c4b47562011-12-05 23:39:41614 results.extend(input_api.canned_checks.CheckChangeHasDescription(
615 input_api, output_api))
[email protected]b337cb5b2011-01-23 21:24:05616 results.extend(_CheckSubversionConfig(input_api, output_api))
[email protected]fe5f57c52009-06-05 14:25:54617 return results
[email protected]ca8d1982009-02-19 16:33:12618
619
[email protected]5efb2a822011-09-27 23:06:13620def GetPreferredTrySlaves(project, change):
[email protected]4ce995ea2012-06-27 02:13:10621 files = change.LocalPaths()
622
[email protected]3019c902012-06-29 00:09:03623 if not files:
624 return []
625
[email protected]d668899a2012-09-06 18:16:59626 if all(re.search('\.(m|mm)$|(^|[/_])mac[/_.]', f) for f in files):
[email protected]641f2e3e2012-09-03 11:16:24627 return ['mac_rel', 'mac_asan']
[email protected]d668899a2012-09-06 18:16:59628 if all(re.search('(^|[/_])win[/_.]', f) for f in files):
[email protected]4ce995ea2012-06-27 02:13:10629 return ['win_rel']
[email protected]d668899a2012-09-06 18:16:59630 if all(re.search('(^|[/_])android[/_.]', f) for f in files):
[email protected]c4781e52012-09-13 18:24:38631 return ['android_dbg']
[email protected]356aa542012-09-19 23:31:29632 if all(re.search('^native_client_sdk', f) for f in files):
633 return ['linux_nacl_sdk', 'win_nacl_sdk', 'mac_nacl_sdk']
[email protected]de142152012-10-03 23:02:45634 if all(re.search('[/_]ios[/_.]', f) for f in files):
635 return ['ios_rel_device', 'ios_dbg_simulator']
[email protected]4ce995ea2012-06-27 02:13:10636
[email protected]d602b902012-07-19 16:30:31637 trybots = ['win_rel', 'linux_rel', 'mac_rel', 'linux_clang:compile',
[email protected]de142152012-10-03 23:02:45638 'linux_chromeos', 'android_dbg', 'linux_asan', 'mac_asan',
639 'ios_rel_device', 'ios_dbg_simulator']
[email protected]911753b2012-08-02 12:11:54640
641 # Match things like path/aura/file.cc and path/file_aura.cc.
[email protected]0be9553a2012-08-10 00:14:45642 # Same for ash and chromeos.
643 if any(re.search('[/_](ash|aura)', f) for f in files):
[email protected]641f2e3e2012-09-03 11:16:24644 trybots += ['linux_chromeos', 'linux_chromeos_clang:compile', 'win_aura',
645 'linux_chromeos_asan']
[email protected]0be9553a2012-08-10 00:14:45646 else:
647 if any(re.search('[/_]chromeos', f) for f in files):
[email protected]641f2e3e2012-09-03 11:16:24648 trybots += ['linux_chromeos', 'linux_chromeos_clang:compile',
649 'linux_chromeos_asan']
[email protected]4ce995ea2012-06-27 02:13:10650
[email protected]4ce995ea2012-06-27 02:13:10651 return trybots