blob: 3418265fffbbabb901e9108a69bdcf43939542f2 [file] [log] [blame]
[email protected]a18130a2012-01-03 17:52:081# Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]ca8d19842009-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]ca8d19842009-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]8886ffcb2013-02-12 04:56:2821 r"^native_client_sdk[\\\/]src[\\\/]tools[\\\/].*.mk",
[email protected]a18130a2012-01-03 17:52:0822 r"^net[\\\/]tools[\\\/]spdyshark[\\\/].*",
[email protected]3e4eb112011-01-18 03:29:5423 r"^skia[\\\/].*",
24 r"^v8[\\\/].*",
25 r".*MakeFile$",
[email protected]1084ccc2012-03-14 03:22:5326 r".+_autogen\.h$",
[email protected]ce145c02012-09-06 09:49:3427 r".+[\\\/]pnacl_shim\.c$",
[email protected]4306417642009-06-11 00:33:4028)
[email protected]ca8d19842009-02-19 16:33:1229
[email protected]06e6d0ff2012-12-11 01:36:4430# Fragment of a regular expression that matches C++ and Objective-C++
31# implementation files.
32_IMPLEMENTATION_EXTENSIONS = r'\.(cc|cpp|cxx|mm)$'
33
34# Regular expression that matches code only used for test binaries
35# (best effort).
36_TEST_CODE_EXCLUDED_PATHS = (
37 r'.*[/\\](fake_|test_|mock_).+%s' % _IMPLEMENTATION_EXTENSIONS,
38 r'.+_test_(base|support|util)%s' % _IMPLEMENTATION_EXTENSIONS,
[email protected]11e06082013-04-26 19:09:0339 r'.+_(api|browser|perf|pixel|unit|ui)?test(_[a-z]+)?%s' %
[email protected]e2d7e6f2013-04-23 12:57:1240 _IMPLEMENTATION_EXTENSIONS,
[email protected]06e6d0ff2012-12-11 01:36:4441 r'.+profile_sync_service_harness%s' % _IMPLEMENTATION_EXTENSIONS,
42 r'.*[/\\](test|tool(s)?)[/\\].*',
[email protected]ef070cc2013-05-03 11:53:0543 # content_shell is used for running layout tests.
44 r'content[/\\]shell[/\\].*',
[email protected]06e6d0ff2012-12-11 01:36:4445 # At request of folks maintaining this folder.
46 r'chrome[/\\]browser[/\\]automation[/\\].*',
47)
[email protected]ca8d19842009-02-19 16:33:1248
[email protected]eea609a2011-11-18 13:10:1249_TEST_ONLY_WARNING = (
50 'You might be calling functions intended only for testing from\n'
51 'production code. It is OK to ignore this warning if you know what\n'
52 'you are doing, as the heuristics used to detect the situation are\n'
53 'not perfect. The commit queue will not block on this warning.\n'
54 'Email [email protected] if you have questions.')
55
56
[email protected]cf9b78f2012-11-14 11:40:2857_INCLUDE_ORDER_WARNING = (
58 'Your #include order seems to be broken. Send mail to\n'
59 '[email protected] if this is not the case.')
60
61
[email protected]127f18ec2012-06-16 05:05:5962_BANNED_OBJC_FUNCTIONS = (
63 (
64 'addTrackingRect:',
[email protected]23e6cbc2012-06-16 18:51:2065 (
66 'The use of -[NSView addTrackingRect:owner:userData:assumeInside:] is'
[email protected]127f18ec2012-06-16 05:05:5967 'prohibited. Please use CrTrackingArea instead.',
68 'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts',
69 ),
70 False,
71 ),
72 (
73 'NSTrackingArea',
[email protected]23e6cbc2012-06-16 18:51:2074 (
75 'The use of NSTrackingAreas is prohibited. Please use CrTrackingArea',
[email protected]127f18ec2012-06-16 05:05:5976 'instead.',
77 'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts',
78 ),
79 False,
80 ),
81 (
82 'convertPointFromBase:',
[email protected]23e6cbc2012-06-16 18:51:2083 (
84 'The use of -[NSView convertPointFromBase:] is almost certainly wrong.',
[email protected]127f18ec2012-06-16 05:05:5985 'Please use |convertPoint:(point) fromView:nil| instead.',
86 'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts',
87 ),
88 True,
89 ),
90 (
91 'convertPointToBase:',
[email protected]23e6cbc2012-06-16 18:51:2092 (
93 'The use of -[NSView convertPointToBase:] is almost certainly wrong.',
[email protected]127f18ec2012-06-16 05:05:5994 'Please use |convertPoint:(point) toView:nil| instead.',
95 'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts',
96 ),
97 True,
98 ),
99 (
100 'convertRectFromBase:',
[email protected]23e6cbc2012-06-16 18:51:20101 (
102 'The use of -[NSView convertRectFromBase:] is almost certainly wrong.',
[email protected]127f18ec2012-06-16 05:05:59103 'Please use |convertRect:(point) fromView:nil| instead.',
104 'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts',
105 ),
106 True,
107 ),
108 (
109 'convertRectToBase:',
[email protected]23e6cbc2012-06-16 18:51:20110 (
111 'The use of -[NSView convertRectToBase:] is almost certainly wrong.',
[email protected]127f18ec2012-06-16 05:05:59112 'Please use |convertRect:(point) toView:nil| instead.',
113 'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts',
114 ),
115 True,
116 ),
117 (
118 'convertSizeFromBase:',
[email protected]23e6cbc2012-06-16 18:51:20119 (
120 'The use of -[NSView convertSizeFromBase:] is almost certainly wrong.',
[email protected]127f18ec2012-06-16 05:05:59121 'Please use |convertSize:(point) fromView:nil| instead.',
122 'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts',
123 ),
124 True,
125 ),
126 (
127 'convertSizeToBase:',
[email protected]23e6cbc2012-06-16 18:51:20128 (
129 'The use of -[NSView convertSizeToBase:] is almost certainly wrong.',
[email protected]127f18ec2012-06-16 05:05:59130 'Please use |convertSize:(point) toView:nil| instead.',
131 'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts',
132 ),
133 True,
134 ),
135)
136
137
138_BANNED_CPP_FUNCTIONS = (
[email protected]23e6cbc2012-06-16 18:51:20139 # Make sure that gtest's FRIEND_TEST() macro is not used; the
140 # FRIEND_TEST_ALL_PREFIXES() macro from base/gtest_prod_util.h should be
[email protected]e00ccc92012-11-01 17:32:30141 # used instead since that allows for FLAKY_ and DISABLED_ prefixes.
[email protected]23e6cbc2012-06-16 18:51:20142 (
143 'FRIEND_TEST(',
144 (
[email protected]e3c945502012-06-26 20:01:49145 'Chromium code should not use gtest\'s FRIEND_TEST() macro. Include',
[email protected]23e6cbc2012-06-16 18:51:20146 'base/gtest_prod_util.h and use FRIEND_TEST_ALL_PREFIXES() instead.',
147 ),
148 False,
[email protected]7345da02012-11-27 14:31:49149 (),
[email protected]23e6cbc2012-06-16 18:51:20150 ),
151 (
152 'ScopedAllowIO',
153 (
[email protected]e3c945502012-06-26 20:01:49154 'New code should not use ScopedAllowIO. Post a task to the blocking',
155 'pool or the FILE thread instead.',
[email protected]23e6cbc2012-06-16 18:51:20156 ),
[email protected]e3c945502012-06-26 20:01:49157 True,
[email protected]7345da02012-11-27 14:31:49158 (
159 r"^content[\\\/]shell[\\\/]shell_browser_main\.cc$",
[email protected]398ad132013-04-02 15:11:01160 r"^net[\\\/]disk_cache[\\\/]cache_util\.cc$",
[email protected]7345da02012-11-27 14:31:49161 ),
[email protected]23e6cbc2012-06-16 18:51:20162 ),
[email protected]52657f62013-05-20 05:30:31163 (
164 'SkRefPtr',
165 (
166 'The use of SkRefPtr is prohibited. ',
167 'Please use skia::RefPtr instead.'
168 ),
169 True,
170 (),
171 ),
172 (
173 'SkAutoRef',
174 (
175 'The indirect use of SkRefPtr via SkAutoRef is prohibited. ',
176 'Please use skia::RefPtr instead.'
177 ),
178 True,
179 (),
180 ),
181 (
182 'SkAutoTUnref',
183 (
184 'The use of SkAutoTUnref is dangerous because it implicitly ',
185 'converts to a raw pointer. Please use skia::RefPtr instead.'
186 ),
187 True,
188 (),
189 ),
190 (
191 'SkAutoUnref',
192 (
193 'The indirect use of SkAutoTUnref through SkAutoUnref is dangerous ',
194 'because it implicitly converts to a raw pointer. ',
195 'Please use skia::RefPtr instead.'
196 ),
197 True,
198 (),
199 ),
[email protected]127f18ec2012-06-16 05:05:59200)
201
202
[email protected]b00342e7f2013-03-26 16:21:54203_VALID_OS_MACROS = (
204 # Please keep sorted.
205 'OS_ANDROID',
206 'OS_BSD',
207 'OS_CAT', # For testing.
208 'OS_CHROMEOS',
209 'OS_FREEBSD',
210 'OS_IOS',
211 'OS_LINUX',
212 'OS_MACOSX',
213 'OS_NACL',
214 'OS_OPENBSD',
215 'OS_POSIX',
216 'OS_SOLARIS',
[email protected]b00342e7f2013-03-26 16:21:54217 'OS_WIN',
218)
219
220
[email protected]55459852011-08-10 15:17:19221def _CheckNoProductionCodeUsingTestOnlyFunctions(input_api, output_api):
222 """Attempts to prevent use of functions intended only for testing in
223 non-testing code. For now this is just a best-effort implementation
224 that ignores header files and may have some false positives. A
225 better implementation would probably need a proper C++ parser.
226 """
227 # We only scan .cc files and the like, as the declaration of
228 # for-testing functions in header files are hard to distinguish from
229 # calls to such functions without a proper C++ parser.
[email protected]06e6d0ff2012-12-11 01:36:44230 file_inclusion_pattern = r'.+%s' % _IMPLEMENTATION_EXTENSIONS
[email protected]55459852011-08-10 15:17:19231
232 base_function_pattern = r'ForTest(ing)?|for_test(ing)?'
233 inclusion_pattern = input_api.re.compile(r'(%s)\s*\(' % base_function_pattern)
234 exclusion_pattern = input_api.re.compile(
235 r'::[A-Za-z0-9_]+(%s)|(%s)[^;]+\{' % (
236 base_function_pattern, base_function_pattern))
237
238 def FilterFile(affected_file):
[email protected]06e6d0ff2012-12-11 01:36:44239 black_list = (_EXCLUDED_PATHS +
240 _TEST_CODE_EXCLUDED_PATHS +
241 input_api.DEFAULT_BLACK_LIST)
[email protected]55459852011-08-10 15:17:19242 return input_api.FilterSourceFile(
243 affected_file,
244 white_list=(file_inclusion_pattern, ),
245 black_list=black_list)
246
247 problems = []
248 for f in input_api.AffectedSourceFiles(FilterFile):
249 local_path = f.LocalPath()
[email protected]2fdd1f362013-01-16 03:56:03250 lines = input_api.ReadFile(f).splitlines()
251 line_number = 0
252 for line in lines:
253 if (inclusion_pattern.search(line) and
254 not exclusion_pattern.search(line)):
[email protected]55459852011-08-10 15:17:19255 problems.append(
[email protected]2fdd1f362013-01-16 03:56:03256 '%s:%d\n %s' % (local_path, line_number, line.strip()))
257 line_number += 1
[email protected]55459852011-08-10 15:17:19258
259 if problems:
[email protected]f7051d52013-04-02 18:31:42260 return [output_api.PresubmitPromptOrNotify(_TEST_ONLY_WARNING, problems)]
[email protected]2fdd1f362013-01-16 03:56:03261 else:
262 return []
[email protected]55459852011-08-10 15:17:19263
264
[email protected]10689ca2011-09-02 02:31:54265def _CheckNoIOStreamInHeaders(input_api, output_api):
266 """Checks to make sure no .h files include <iostream>."""
267 files = []
268 pattern = input_api.re.compile(r'^#include\s*<iostream>',
269 input_api.re.MULTILINE)
270 for f in input_api.AffectedSourceFiles(input_api.FilterSourceFile):
271 if not f.LocalPath().endswith('.h'):
272 continue
273 contents = input_api.ReadFile(f)
274 if pattern.search(contents):
275 files.append(f)
276
277 if len(files):
278 return [ output_api.PresubmitError(
[email protected]6c063c62012-07-11 19:11:06279 'Do not #include <iostream> in header files, since it inserts static '
280 'initialization into every file including the header. Instead, '
[email protected]10689ca2011-09-02 02:31:54281 '#include <ostream>. See http://crbug.com/94794',
282 files) ]
283 return []
284
285
[email protected]72df4e782012-06-21 16:28:18286def _CheckNoUNIT_TESTInSourceFiles(input_api, output_api):
287 """Checks to make sure no source files use UNIT_TEST"""
288 problems = []
289 for f in input_api.AffectedFiles():
290 if (not f.LocalPath().endswith(('.cc', '.mm'))):
291 continue
292
293 for line_num, line in f.ChangedContents():
294 if 'UNIT_TEST' in line:
295 problems.append(' %s:%d' % (f.LocalPath(), line_num))
296
297 if not problems:
298 return []
299 return [output_api.PresubmitPromptWarning('UNIT_TEST is only for headers.\n' +
300 '\n'.join(problems))]
301
302
[email protected]8ea5d4b2011-09-13 21:49:22303def _CheckNoNewWStrings(input_api, output_api):
304 """Checks to make sure we don't introduce use of wstrings."""
[email protected]55463aa62011-10-12 00:48:27305 problems = []
[email protected]8ea5d4b2011-09-13 21:49:22306 for f in input_api.AffectedFiles():
[email protected]b5c24292011-11-28 14:38:20307 if (not f.LocalPath().endswith(('.cc', '.h')) or
308 f.LocalPath().endswith('test.cc')):
309 continue
[email protected]8ea5d4b2011-09-13 21:49:22310
[email protected]a11dbe9b2012-08-07 01:32:58311 allowWString = False
[email protected]b5c24292011-11-28 14:38:20312 for line_num, line in f.ChangedContents():
[email protected]a11dbe9b2012-08-07 01:32:58313 if 'presubmit: allow wstring' in line:
314 allowWString = True
315 elif not allowWString and 'wstring' in line:
[email protected]55463aa62011-10-12 00:48:27316 problems.append(' %s:%d' % (f.LocalPath(), line_num))
[email protected]a11dbe9b2012-08-07 01:32:58317 allowWString = False
318 else:
319 allowWString = False
[email protected]8ea5d4b2011-09-13 21:49:22320
[email protected]55463aa62011-10-12 00:48:27321 if not problems:
322 return []
323 return [output_api.PresubmitPromptWarning('New code should not use wstrings.'
[email protected]a11dbe9b2012-08-07 01:32:58324 ' If you are calling a cross-platform API that accepts a wstring, '
325 'fix the API.\n' +
[email protected]55463aa62011-10-12 00:48:27326 '\n'.join(problems))]
[email protected]8ea5d4b2011-09-13 21:49:22327
328
[email protected]2a8ac9c2011-10-19 17:20:44329def _CheckNoDEPSGIT(input_api, output_api):
330 """Make sure .DEPS.git is never modified manually."""
331 if any(f.LocalPath().endswith('.DEPS.git') for f in
332 input_api.AffectedFiles()):
333 return [output_api.PresubmitError(
334 'Never commit changes to .DEPS.git. This file is maintained by an\n'
335 'automated system based on what\'s in DEPS and your changes will be\n'
336 'overwritten.\n'
337 'See http://code.google.com/p/chromium/wiki/UsingNewGit#Rolling_DEPS\n'
338 'for more information')]
339 return []
340
341
[email protected]127f18ec2012-06-16 05:05:59342def _CheckNoBannedFunctions(input_api, output_api):
343 """Make sure that banned functions are not used."""
344 warnings = []
345 errors = []
346
347 file_filter = lambda f: f.LocalPath().endswith(('.mm', '.m', '.h'))
348 for f in input_api.AffectedFiles(file_filter=file_filter):
349 for line_num, line in f.ChangedContents():
350 for func_name, message, error in _BANNED_OBJC_FUNCTIONS:
351 if func_name in line:
352 problems = warnings;
353 if error:
354 problems = errors;
355 problems.append(' %s:%d:' % (f.LocalPath(), line_num))
356 for message_line in message:
357 problems.append(' %s' % message_line)
358
359 file_filter = lambda f: f.LocalPath().endswith(('.cc', '.mm', '.h'))
360 for f in input_api.AffectedFiles(file_filter=file_filter):
361 for line_num, line in f.ChangedContents():
[email protected]7345da02012-11-27 14:31:49362 for func_name, message, error, excluded_paths in _BANNED_CPP_FUNCTIONS:
363 def IsBlacklisted(affected_file, blacklist):
364 local_path = affected_file.LocalPath()
365 for item in blacklist:
366 if input_api.re.match(item, local_path):
367 return True
368 return False
369 if IsBlacklisted(f, excluded_paths):
370 continue
[email protected]127f18ec2012-06-16 05:05:59371 if func_name in line:
372 problems = warnings;
373 if error:
374 problems = errors;
375 problems.append(' %s:%d:' % (f.LocalPath(), line_num))
376 for message_line in message:
377 problems.append(' %s' % message_line)
378
379 result = []
380 if (warnings):
381 result.append(output_api.PresubmitPromptWarning(
382 'Banned functions were used.\n' + '\n'.join(warnings)))
383 if (errors):
384 result.append(output_api.PresubmitError(
385 'Banned functions were used.\n' + '\n'.join(errors)))
386 return result
387
388
[email protected]6c063c62012-07-11 19:11:06389def _CheckNoPragmaOnce(input_api, output_api):
390 """Make sure that banned functions are not used."""
391 files = []
392 pattern = input_api.re.compile(r'^#pragma\s+once',
393 input_api.re.MULTILINE)
394 for f in input_api.AffectedSourceFiles(input_api.FilterSourceFile):
395 if not f.LocalPath().endswith('.h'):
396 continue
397 contents = input_api.ReadFile(f)
398 if pattern.search(contents):
399 files.append(f)
400
401 if files:
402 return [output_api.PresubmitError(
403 'Do not use #pragma once in header files.\n'
404 'See http://www.chromium.org/developers/coding-style#TOC-File-headers',
405 files)]
406 return []
407
[email protected]127f18ec2012-06-16 05:05:59408
[email protected]e7479052012-09-19 00:26:12409def _CheckNoTrinaryTrueFalse(input_api, output_api):
410 """Checks to make sure we don't introduce use of foo ? true : false."""
411 problems = []
412 pattern = input_api.re.compile(r'\?\s*(true|false)\s*:\s*(true|false)')
413 for f in input_api.AffectedFiles():
414 if not f.LocalPath().endswith(('.cc', '.h', '.inl', '.m', '.mm')):
415 continue
416
417 for line_num, line in f.ChangedContents():
418 if pattern.match(line):
419 problems.append(' %s:%d' % (f.LocalPath(), line_num))
420
421 if not problems:
422 return []
423 return [output_api.PresubmitPromptWarning(
424 'Please consider avoiding the "? true : false" pattern if possible.\n' +
425 '\n'.join(problems))]
426
427
[email protected]55f9f382012-07-31 11:02:18428def _CheckUnwantedDependencies(input_api, output_api):
429 """Runs checkdeps on #include statements added in this
430 change. Breaking - rules is an error, breaking ! rules is a
431 warning.
432 """
433 # We need to wait until we have an input_api object and use this
434 # roundabout construct to import checkdeps because this file is
435 # eval-ed and thus doesn't have __file__.
436 original_sys_path = sys.path
437 try:
438 sys.path = sys.path + [input_api.os_path.join(
439 input_api.PresubmitLocalPath(), 'tools', 'checkdeps')]
440 import checkdeps
441 from cpp_checker import CppChecker
442 from rules import Rule
443 finally:
444 # Restore sys.path to what it was before.
445 sys.path = original_sys_path
446
447 added_includes = []
448 for f in input_api.AffectedFiles():
449 if not CppChecker.IsCppFile(f.LocalPath()):
450 continue
451
452 changed_lines = [line for line_num, line in f.ChangedContents()]
453 added_includes.append([f.LocalPath(), changed_lines])
454
[email protected]26385172013-05-09 23:11:35455 deps_checker = checkdeps.DepsChecker(input_api.PresubmitLocalPath())
[email protected]55f9f382012-07-31 11:02:18456
457 error_descriptions = []
458 warning_descriptions = []
459 for path, rule_type, rule_description in deps_checker.CheckAddedCppIncludes(
460 added_includes):
461 description_with_path = '%s\n %s' % (path, rule_description)
462 if rule_type == Rule.DISALLOW:
463 error_descriptions.append(description_with_path)
464 else:
465 warning_descriptions.append(description_with_path)
466
467 results = []
468 if error_descriptions:
469 results.append(output_api.PresubmitError(
470 'You added one or more #includes that violate checkdeps rules.',
471 error_descriptions))
472 if warning_descriptions:
[email protected]f7051d52013-04-02 18:31:42473 results.append(output_api.PresubmitPromptOrNotify(
[email protected]55f9f382012-07-31 11:02:18474 'You added one or more #includes of files that are temporarily\n'
475 'allowed but being removed. Can you avoid introducing the\n'
476 '#include? See relevant DEPS file(s) for details and contacts.',
477 warning_descriptions))
478 return results
479
480
[email protected]fbcafe5a2012-08-08 15:31:22481def _CheckFilePermissions(input_api, output_api):
482 """Check that all files have their permissions properly set."""
483 args = [sys.executable, 'tools/checkperms/checkperms.py', '--root',
484 input_api.change.RepositoryRoot()]
485 for f in input_api.AffectedFiles():
486 args += ['--file', f.LocalPath()]
487 errors = []
488 (errors, stderrdata) = subprocess.Popen(args).communicate()
489
490 results = []
491 if errors:
[email protected]c8278b32012-10-30 20:35:49492 results.append(output_api.PresubmitError('checkperms.py failed.',
[email protected]fbcafe5a2012-08-08 15:31:22493 errors))
494 return results
495
496
[email protected]c8278b32012-10-30 20:35:49497def _CheckNoAuraWindowPropertyHInHeaders(input_api, output_api):
498 """Makes sure we don't include ui/aura/window_property.h
499 in header files.
500 """
501 pattern = input_api.re.compile(r'^#include\s*"ui/aura/window_property.h"')
502 errors = []
503 for f in input_api.AffectedFiles():
504 if not f.LocalPath().endswith('.h'):
505 continue
506 for line_num, line in f.ChangedContents():
507 if pattern.match(line):
508 errors.append(' %s:%d' % (f.LocalPath(), line_num))
509
510 results = []
511 if errors:
512 results.append(output_api.PresubmitError(
513 'Header files should not include ui/aura/window_property.h', errors))
514 return results
515
516
[email protected]cf9b78f2012-11-14 11:40:28517def _CheckIncludeOrderForScope(scope, input_api, file_path, changed_linenums):
518 """Checks that the lines in scope occur in the right order.
519
520 1. C system files in alphabetical order
521 2. C++ system files in alphabetical order
522 3. Project's .h files
523 """
524
525 c_system_include_pattern = input_api.re.compile(r'\s*#include <.*\.h>')
526 cpp_system_include_pattern = input_api.re.compile(r'\s*#include <.*>')
527 custom_include_pattern = input_api.re.compile(r'\s*#include ".*')
528
529 C_SYSTEM_INCLUDES, CPP_SYSTEM_INCLUDES, CUSTOM_INCLUDES = range(3)
530
531 state = C_SYSTEM_INCLUDES
532
533 previous_line = ''
[email protected]728b9bb2012-11-14 20:38:57534 previous_line_num = 0
[email protected]cf9b78f2012-11-14 11:40:28535 problem_linenums = []
536 for line_num, line in scope:
537 if c_system_include_pattern.match(line):
538 if state != C_SYSTEM_INCLUDES:
[email protected]728b9bb2012-11-14 20:38:57539 problem_linenums.append((line_num, previous_line_num))
[email protected]cf9b78f2012-11-14 11:40:28540 elif previous_line and previous_line > line:
[email protected]728b9bb2012-11-14 20:38:57541 problem_linenums.append((line_num, previous_line_num))
[email protected]cf9b78f2012-11-14 11:40:28542 elif cpp_system_include_pattern.match(line):
543 if state == C_SYSTEM_INCLUDES:
544 state = CPP_SYSTEM_INCLUDES
545 elif state == CUSTOM_INCLUDES:
[email protected]728b9bb2012-11-14 20:38:57546 problem_linenums.append((line_num, previous_line_num))
[email protected]cf9b78f2012-11-14 11:40:28547 elif previous_line and previous_line > line:
[email protected]728b9bb2012-11-14 20:38:57548 problem_linenums.append((line_num, previous_line_num))
[email protected]cf9b78f2012-11-14 11:40:28549 elif custom_include_pattern.match(line):
550 if state != CUSTOM_INCLUDES:
551 state = CUSTOM_INCLUDES
552 elif previous_line and previous_line > line:
[email protected]728b9bb2012-11-14 20:38:57553 problem_linenums.append((line_num, previous_line_num))
[email protected]cf9b78f2012-11-14 11:40:28554 else:
555 problem_linenums.append(line_num)
556 previous_line = line
[email protected]728b9bb2012-11-14 20:38:57557 previous_line_num = line_num
[email protected]cf9b78f2012-11-14 11:40:28558
559 warnings = []
[email protected]728b9bb2012-11-14 20:38:57560 for (line_num, previous_line_num) in problem_linenums:
561 if line_num in changed_linenums or previous_line_num in changed_linenums:
[email protected]cf9b78f2012-11-14 11:40:28562 warnings.append(' %s:%d' % (file_path, line_num))
563 return warnings
564
565
[email protected]ac294a12012-12-06 16:38:43566def _CheckIncludeOrderInFile(input_api, f, changed_linenums):
[email protected]cf9b78f2012-11-14 11:40:28567 """Checks the #include order for the given file f."""
568
[email protected]2299dcf2012-11-15 19:56:24569 system_include_pattern = input_api.re.compile(r'\s*#include \<.*')
[email protected]962f117e2012-11-22 18:11:56570 # Exclude #include <.../...> includes from the check; e.g., <sys/...> includes
571 # often need to appear in a specific order.
572 excluded_include_pattern = input_api.re.compile(r'\s*#include \<.*/.*')
[email protected]2299dcf2012-11-15 19:56:24573 custom_include_pattern = input_api.re.compile(r'\s*#include "(?P<FILE>.*)"')
[email protected]0e5c1852012-12-18 20:17:11574 if_pattern = input_api.re.compile(
575 r'\s*#\s*(if|elif|else|endif|define|undef).*')
576 # Some files need specialized order of includes; exclude such files from this
577 # check.
578 uncheckable_includes_pattern = input_api.re.compile(
579 r'\s*#include '
580 '("ipc/.*macros\.h"|<windows\.h>|".*gl.*autogen.h")\s*')
[email protected]cf9b78f2012-11-14 11:40:28581
582 contents = f.NewContents()
583 warnings = []
584 line_num = 0
585
[email protected]ac294a12012-12-06 16:38:43586 # Handle the special first include. If the first include file is
587 # some/path/file.h, the corresponding including file can be some/path/file.cc,
588 # some/other/path/file.cc, some/path/file_platform.cc, some/path/file-suffix.h
589 # etc. It's also possible that no special first include exists.
590 for line in contents:
591 line_num += 1
592 if system_include_pattern.match(line):
593 # No special first include -> process the line again along with normal
594 # includes.
595 line_num -= 1
596 break
597 match = custom_include_pattern.match(line)
598 if match:
599 match_dict = match.groupdict()
600 header_basename = input_api.os_path.basename(
601 match_dict['FILE']).replace('.h', '')
602 if header_basename not in input_api.os_path.basename(f.LocalPath()):
[email protected]2299dcf2012-11-15 19:56:24603 # No special first include -> process the line again along with normal
604 # includes.
605 line_num -= 1
[email protected]ac294a12012-12-06 16:38:43606 break
[email protected]cf9b78f2012-11-14 11:40:28607
608 # Split into scopes: Each region between #if and #endif is its own scope.
609 scopes = []
610 current_scope = []
611 for line in contents[line_num:]:
612 line_num += 1
[email protected]0e5c1852012-12-18 20:17:11613 if uncheckable_includes_pattern.match(line):
614 return []
[email protected]2309b0fa02012-11-16 12:18:27615 if if_pattern.match(line):
[email protected]cf9b78f2012-11-14 11:40:28616 scopes.append(current_scope)
617 current_scope = []
[email protected]962f117e2012-11-22 18:11:56618 elif ((system_include_pattern.match(line) or
619 custom_include_pattern.match(line)) and
620 not excluded_include_pattern.match(line)):
[email protected]cf9b78f2012-11-14 11:40:28621 current_scope.append((line_num, line))
622 scopes.append(current_scope)
623
624 for scope in scopes:
625 warnings.extend(_CheckIncludeOrderForScope(scope, input_api, f.LocalPath(),
626 changed_linenums))
627 return warnings
628
629
630def _CheckIncludeOrder(input_api, output_api):
631 """Checks that the #include order is correct.
632
633 1. The corresponding header for source files.
634 2. C system files in alphabetical order
635 3. C++ system files in alphabetical order
636 4. Project's .h files in alphabetical order
637
[email protected]ac294a12012-12-06 16:38:43638 Each region separated by #if, #elif, #else, #endif, #define and #undef follows
639 these rules separately.
[email protected]cf9b78f2012-11-14 11:40:28640 """
641
642 warnings = []
643 for f in input_api.AffectedFiles():
[email protected]ac294a12012-12-06 16:38:43644 if f.LocalPath().endswith(('.cc', '.h')):
645 changed_linenums = set(line_num for line_num, _ in f.ChangedContents())
646 warnings.extend(_CheckIncludeOrderInFile(input_api, f, changed_linenums))
[email protected]cf9b78f2012-11-14 11:40:28647
648 results = []
649 if warnings:
[email protected]f7051d52013-04-02 18:31:42650 results.append(output_api.PresubmitPromptOrNotify(_INCLUDE_ORDER_WARNING,
[email protected]120cf540d2012-12-10 17:55:53651 warnings))
[email protected]cf9b78f2012-11-14 11:40:28652 return results
653
654
[email protected]70ca77752012-11-20 03:45:03655def _CheckForVersionControlConflictsInFile(input_api, f):
656 pattern = input_api.re.compile('^(?:<<<<<<<|>>>>>>>) |^=======$')
657 errors = []
658 for line_num, line in f.ChangedContents():
659 if pattern.match(line):
660 errors.append(' %s:%d %s' % (f.LocalPath(), line_num, line))
661 return errors
662
663
664def _CheckForVersionControlConflicts(input_api, output_api):
665 """Usually this is not intentional and will cause a compile failure."""
666 errors = []
667 for f in input_api.AffectedFiles():
668 errors.extend(_CheckForVersionControlConflictsInFile(input_api, f))
669
670 results = []
671 if errors:
672 results.append(output_api.PresubmitError(
673 'Version control conflict markers found, please resolve.', errors))
674 return results
675
676
[email protected]06e6d0ff2012-12-11 01:36:44677def _CheckHardcodedGoogleHostsInLowerLayers(input_api, output_api):
678 def FilterFile(affected_file):
679 """Filter function for use with input_api.AffectedSourceFiles,
680 below. This filters out everything except non-test files from
681 top-level directories that generally speaking should not hard-code
682 service URLs (e.g. src/android_webview/, src/content/ and others).
683 """
684 return input_api.FilterSourceFile(
685 affected_file,
[email protected]78bb39d62012-12-11 15:11:56686 white_list=(r'^(android_webview|base|content|net)[\\\/].*', ),
[email protected]06e6d0ff2012-12-11 01:36:44687 black_list=(_EXCLUDED_PATHS +
688 _TEST_CODE_EXCLUDED_PATHS +
689 input_api.DEFAULT_BLACK_LIST))
690
691 pattern = input_api.re.compile('"[^"]*google\.com[^"]*"')
692 problems = [] # items are (filename, line_number, line)
693 for f in input_api.AffectedSourceFiles(FilterFile):
694 for line_num, line in f.ChangedContents():
695 if pattern.search(line):
696 problems.append((f.LocalPath(), line_num, line))
697
698 if problems:
[email protected]f7051d52013-04-02 18:31:42699 return [output_api.PresubmitPromptOrNotify(
[email protected]06e6d0ff2012-12-11 01:36:44700 'Most layers below src/chrome/ should not hardcode service URLs.\n'
701 'Are you sure this is correct? (Contact: [email protected])',
702 [' %s:%d: %s' % (
703 problem[0], problem[1], problem[2]) for problem in problems])]
[email protected]2fdd1f362013-01-16 03:56:03704 else:
705 return []
[email protected]06e6d0ff2012-12-11 01:36:44706
707
[email protected]d2530012013-01-25 16:39:27708def _CheckNoAbbreviationInPngFileName(input_api, output_api):
709 """Makes sure there are no abbreviations in the name of PNG files.
710 """
[email protected]4053a48e2013-01-25 21:43:04711 pattern = input_api.re.compile(r'.*_[a-z]_.*\.png$|.*_[a-z]\.png$')
[email protected]d2530012013-01-25 16:39:27712 errors = []
713 for f in input_api.AffectedFiles(include_deletes=False):
714 if pattern.match(f.LocalPath()):
715 errors.append(' %s' % f.LocalPath())
716
717 results = []
718 if errors:
719 results.append(output_api.PresubmitError(
720 'The name of PNG files should not have abbreviations. \n'
721 'Use _hover.png, _center.png, instead of _h.png, _c.png.\n'
722 'Contact [email protected] if you have questions.', errors))
723 return results
724
725
[email protected]e871964c2013-05-13 14:14:55726def _CheckAddedDepsHaveTargetApprovals(input_api, output_api):
727 """When a dependency prefixed with + is added to a DEPS file, we
728 want to make sure that the change is reviewed by an OWNER of the
729 target file or directory, to avoid layering violations from being
730 introduced. This check verifies that this happens.
731 """
732 changed_lines = set()
733 for f in input_api.AffectedFiles():
734 filename = input_api.os_path.basename(f.LocalPath())
735 if filename == 'DEPS':
736 changed_lines |= set(line.strip()
737 for line_num, line
738 in f.ChangedContents())
739 if not changed_lines:
740 return []
741
742 virtual_depended_on_files = set()
743 # This pattern grabs the path without basename in the first
744 # parentheses, and the basename (if present) in the second. It
745 # relies on the simple heuristic that if there is a basename it will
746 # be a header file ending in ".h".
747 pattern = input_api.re.compile(
748 r"""['"]\+([^'"]+?)(/[a-zA-Z0-9_]+\.h)?['"].*""")
749 for changed_line in changed_lines:
750 m = pattern.match(changed_line)
751 if m:
752 virtual_depended_on_files.add('%s/DEPS' % m.group(1))
753
754 if not virtual_depended_on_files:
755 return []
756
757 if input_api.is_committing:
758 if input_api.tbr:
759 return [output_api.PresubmitNotifyResult(
760 '--tbr was specified, skipping OWNERS check for DEPS additions')]
761 if not input_api.change.issue:
762 return [output_api.PresubmitError(
763 "DEPS approval by OWNERS check failed: this change has "
764 "no Rietveld issue number, so we can't check it for approvals.")]
765 output = output_api.PresubmitError
766 else:
767 output = output_api.PresubmitNotifyResult
768
769 owners_db = input_api.owners_db
770 owner_email, reviewers = input_api.canned_checks._RietveldOwnerAndReviewers(
771 input_api,
772 owners_db.email_regexp,
773 approval_needed=input_api.is_committing)
774
775 owner_email = owner_email or input_api.change.author_email
776
777 reviewers_plus_owner = set([owner_email]).union(reviewers)
778 missing_files = owners_db.files_not_covered_by(virtual_depended_on_files,
779 reviewers_plus_owner)
780 unapproved_dependencies = ["'+%s'," % path[:-len('/DEPS')]
781 for path in missing_files]
782
783 if unapproved_dependencies:
784 output_list = [
785 output('Missing LGTM from OWNERS of directories added to DEPS:\n %s' %
786 '\n '.join(sorted(unapproved_dependencies)))]
787 if not input_api.is_committing:
788 suggested_owners = owners_db.reviewers_for(missing_files, owner_email)
789 output_list.append(output(
790 'Suggested missing target path OWNERS:\n %s' %
791 '\n '.join(suggested_owners or [])))
792 return output_list
793
794 return []
795
796
[email protected]22c9bd72011-03-27 16:47:39797def _CommonChecks(input_api, output_api):
798 """Checks common to both upload and commit."""
799 results = []
800 results.extend(input_api.canned_checks.PanProjectChecks(
801 input_api, output_api, excluded_paths=_EXCLUDED_PATHS))
[email protected]66daa702011-05-28 14:41:46802 results.extend(_CheckAuthorizedAuthor(input_api, output_api))
[email protected]55459852011-08-10 15:17:19803 results.extend(
804 _CheckNoProductionCodeUsingTestOnlyFunctions(input_api, output_api))
[email protected]10689ca2011-09-02 02:31:54805 results.extend(_CheckNoIOStreamInHeaders(input_api, output_api))
[email protected]72df4e782012-06-21 16:28:18806 results.extend(_CheckNoUNIT_TESTInSourceFiles(input_api, output_api))
[email protected]8ea5d4b2011-09-13 21:49:22807 results.extend(_CheckNoNewWStrings(input_api, output_api))
[email protected]2a8ac9c2011-10-19 17:20:44808 results.extend(_CheckNoDEPSGIT(input_api, output_api))
[email protected]127f18ec2012-06-16 05:05:59809 results.extend(_CheckNoBannedFunctions(input_api, output_api))
[email protected]6c063c62012-07-11 19:11:06810 results.extend(_CheckNoPragmaOnce(input_api, output_api))
[email protected]e7479052012-09-19 00:26:12811 results.extend(_CheckNoTrinaryTrueFalse(input_api, output_api))
[email protected]55f9f382012-07-31 11:02:18812 results.extend(_CheckUnwantedDependencies(input_api, output_api))
[email protected]fbcafe5a2012-08-08 15:31:22813 results.extend(_CheckFilePermissions(input_api, output_api))
[email protected]c8278b32012-10-30 20:35:49814 results.extend(_CheckNoAuraWindowPropertyHInHeaders(input_api, output_api))
[email protected]2309b0fa02012-11-16 12:18:27815 results.extend(_CheckIncludeOrder(input_api, output_api))
[email protected]70ca77752012-11-20 03:45:03816 results.extend(_CheckForVersionControlConflicts(input_api, output_api))
[email protected]b8079ae4a2012-12-05 19:56:49817 results.extend(_CheckPatchFiles(input_api, output_api))
[email protected]06e6d0ff2012-12-11 01:36:44818 results.extend(_CheckHardcodedGoogleHostsInLowerLayers(input_api, output_api))
[email protected]d2530012013-01-25 16:39:27819 results.extend(_CheckNoAbbreviationInPngFileName(input_api, output_api))
[email protected]b00342e7f2013-03-26 16:21:54820 results.extend(_CheckForInvalidOSMacros(input_api, output_api))
[email protected]e871964c2013-05-13 14:14:55821 results.extend(_CheckAddedDepsHaveTargetApprovals(input_api, output_api))
[email protected]2299dcf2012-11-15 19:56:24822
823 if any('PRESUBMIT.py' == f.LocalPath() for f in input_api.AffectedFiles()):
824 results.extend(input_api.canned_checks.RunUnitTestsInDirectory(
825 input_api, output_api,
826 input_api.PresubmitLocalPath(),
[email protected]6be63382013-01-21 15:42:38827 whitelist=[r'^PRESUBMIT_test\.py$']))
[email protected]22c9bd72011-03-27 16:47:39828 return results
[email protected]1f7b4172010-01-28 01:17:34829
[email protected]b337cb5b2011-01-23 21:24:05830
831def _CheckSubversionConfig(input_api, output_api):
832 """Verifies the subversion config file is correctly setup.
833
834 Checks that autoprops are enabled, returns an error otherwise.
835 """
836 join = input_api.os_path.join
837 if input_api.platform == 'win32':
838 appdata = input_api.environ.get('APPDATA', '')
839 if not appdata:
840 return [output_api.PresubmitError('%APPDATA% is not configured.')]
841 path = join(appdata, 'Subversion', 'config')
842 else:
843 home = input_api.environ.get('HOME', '')
844 if not home:
845 return [output_api.PresubmitError('$HOME is not configured.')]
846 path = join(home, '.subversion', 'config')
847
848 error_msg = (
849 'Please look at http://dev.chromium.org/developers/coding-style to\n'
850 'configure your subversion configuration file. This enables automatic\n'
[email protected]c6a3c10b2011-01-24 16:14:20851 'properties to simplify the project maintenance.\n'
852 'Pro-tip: just download and install\n'
853 'http://src.chromium.org/viewvc/chrome/trunk/tools/build/slave/config\n')
[email protected]b337cb5b2011-01-23 21:24:05854
855 try:
856 lines = open(path, 'r').read().splitlines()
857 # Make sure auto-props is enabled and check for 2 Chromium standard
858 # auto-prop.
859 if (not '*.cc = svn:eol-style=LF' in lines or
860 not '*.pdf = svn:mime-type=application/pdf' in lines or
861 not 'enable-auto-props = yes' in lines):
862 return [
[email protected]79ed7e62011-02-21 21:08:53863 output_api.PresubmitNotifyResult(
[email protected]b337cb5b2011-01-23 21:24:05864 'It looks like you have not configured your subversion config '
[email protected]b5359c02011-02-01 20:29:56865 'file or it is not up-to-date.\n' + error_msg)
[email protected]b337cb5b2011-01-23 21:24:05866 ]
867 except (OSError, IOError):
868 return [
[email protected]79ed7e62011-02-21 21:08:53869 output_api.PresubmitNotifyResult(
[email protected]b337cb5b2011-01-23 21:24:05870 'Can\'t find your subversion config file.\n' + error_msg)
871 ]
872 return []
873
874
[email protected]66daa702011-05-28 14:41:46875def _CheckAuthorizedAuthor(input_api, output_api):
876 """For non-googler/chromites committers, verify the author's email address is
877 in AUTHORS.
878 """
[email protected]9bb9cb82011-06-13 20:43:01879 # TODO(maruel): Add it to input_api?
880 import fnmatch
881
[email protected]66daa702011-05-28 14:41:46882 author = input_api.change.author_email
[email protected]9bb9cb82011-06-13 20:43:01883 if not author:
884 input_api.logging.info('No author, skipping AUTHOR check')
[email protected]66daa702011-05-28 14:41:46885 return []
[email protected]c99663292011-05-31 19:46:08886 authors_path = input_api.os_path.join(
[email protected]66daa702011-05-28 14:41:46887 input_api.PresubmitLocalPath(), 'AUTHORS')
888 valid_authors = (
889 input_api.re.match(r'[^#]+\s+\<(.+?)\>\s*$', line)
890 for line in open(authors_path))
[email protected]ac54b132011-06-06 18:11:18891 valid_authors = [item.group(1).lower() for item in valid_authors if item]
[email protected]d8b50be2011-06-15 14:19:44892 if not any(fnmatch.fnmatch(author.lower(), valid) for valid in valid_authors):
[email protected]5861efb2013-01-07 18:33:23893 input_api.logging.info('Valid authors are %s', ', '.join(valid_authors))
[email protected]66daa702011-05-28 14:41:46894 return [output_api.PresubmitPromptWarning(
895 ('%s is not in AUTHORS file. If you are a new contributor, please visit'
896 '\n'
897 'http://www.chromium.org/developers/contributing-code and read the '
898 '"Legal" section\n'
899 'If you are a chromite, verify the contributor signed the CLA.') %
900 author)]
901 return []
902
903
[email protected]b8079ae4a2012-12-05 19:56:49904def _CheckPatchFiles(input_api, output_api):
905 problems = [f.LocalPath() for f in input_api.AffectedFiles()
906 if f.LocalPath().endswith(('.orig', '.rej'))]
907 if problems:
908 return [output_api.PresubmitError(
909 "Don't commit .rej and .orig files.", problems)]
[email protected]2fdd1f362013-01-16 03:56:03910 else:
911 return []
[email protected]b8079ae4a2012-12-05 19:56:49912
913
[email protected]b00342e7f2013-03-26 16:21:54914def _DidYouMeanOSMacro(bad_macro):
915 try:
916 return {'A': 'OS_ANDROID',
917 'B': 'OS_BSD',
918 'C': 'OS_CHROMEOS',
919 'F': 'OS_FREEBSD',
920 'L': 'OS_LINUX',
921 'M': 'OS_MACOSX',
922 'N': 'OS_NACL',
923 'O': 'OS_OPENBSD',
924 'P': 'OS_POSIX',
925 'S': 'OS_SOLARIS',
926 'W': 'OS_WIN'}[bad_macro[3].upper()]
927 except KeyError:
928 return ''
929
930
931def _CheckForInvalidOSMacrosInFile(input_api, f):
932 """Check for sensible looking, totally invalid OS macros."""
933 preprocessor_statement = input_api.re.compile(r'^\s*#')
934 os_macro = input_api.re.compile(r'defined\((OS_[^)]+)\)')
935 results = []
936 for lnum, line in f.ChangedContents():
937 if preprocessor_statement.search(line):
938 for match in os_macro.finditer(line):
939 if not match.group(1) in _VALID_OS_MACROS:
940 good = _DidYouMeanOSMacro(match.group(1))
941 did_you_mean = ' (did you mean %s?)' % good if good else ''
942 results.append(' %s:%d %s%s' % (f.LocalPath(),
943 lnum,
944 match.group(1),
945 did_you_mean))
946 return results
947
948
949def _CheckForInvalidOSMacros(input_api, output_api):
950 """Check all affected files for invalid OS macros."""
951 bad_macros = []
952 for f in input_api.AffectedFiles():
953 if not f.LocalPath().endswith(('.py', '.js', '.html', '.css')):
954 bad_macros.extend(_CheckForInvalidOSMacrosInFile(input_api, f))
955
956 if not bad_macros:
957 return []
958
959 return [output_api.PresubmitError(
960 'Possibly invalid OS macro[s] found. Please fix your code\n'
961 'or add your macro to src/PRESUBMIT.py.', bad_macros)]
962
963
[email protected]1f7b4172010-01-28 01:17:34964def CheckChangeOnUpload(input_api, output_api):
965 results = []
966 results.extend(_CommonChecks(input_api, output_api))
[email protected]fe5f57c52009-06-05 14:25:54967 return results
[email protected]ca8d19842009-02-19 16:33:12968
969
970def CheckChangeOnCommit(input_api, output_api):
[email protected]fe5f57c52009-06-05 14:25:54971 results = []
[email protected]1f7b4172010-01-28 01:17:34972 results.extend(_CommonChecks(input_api, output_api))
[email protected]dd805fe2009-10-01 08:11:51973 # TODO(thestig) temporarily disabled, doesn't work in third_party/
974 #results.extend(input_api.canned_checks.CheckSvnModifiedDirectories(
975 # input_api, output_api, sources))
[email protected]fe5f57c52009-06-05 14:25:54976 # Make sure the tree is 'open'.
[email protected]806e98e2010-03-19 17:49:27977 results.extend(input_api.canned_checks.CheckTreeIsOpen(
[email protected]7f238152009-08-12 19:00:34978 input_api,
979 output_api,
[email protected]2fdd1f362013-01-16 03:56:03980 json_url='http://chromium-status.appspot.com/current?format=json'))
[email protected]806e98e2010-03-19 17:49:27981 results.extend(input_api.canned_checks.CheckRietveldTryJobExecution(input_api,
[email protected]2fdd1f362013-01-16 03:56:03982 output_api, 'http://codereview.chromium.org',
[email protected]c1ba4c52012-03-09 14:23:28983 ('win_rel', 'linux_rel', 'mac_rel, win:compile'),
984 '[email protected]'))
[email protected]806e98e2010-03-19 17:49:27985
[email protected]3e4eb112011-01-18 03:29:54986 results.extend(input_api.canned_checks.CheckChangeHasBugField(
987 input_api, output_api))
[email protected]c4b47562011-12-05 23:39:41988 results.extend(input_api.canned_checks.CheckChangeHasDescription(
989 input_api, output_api))
[email protected]b337cb5b2011-01-23 21:24:05990 results.extend(_CheckSubversionConfig(input_api, output_api))
[email protected]fe5f57c52009-06-05 14:25:54991 return results
[email protected]ca8d19842009-02-19 16:33:12992
993
[email protected]5efb2a822011-09-27 23:06:13994def GetPreferredTrySlaves(project, change):
[email protected]4ce995ea2012-06-27 02:13:10995 files = change.LocalPaths()
996
[email protected]751b05f2013-01-10 23:12:17997 if not files or all(re.search(r'[\\/]OWNERS$', f) for f in files):
[email protected]3019c902012-06-29 00:09:03998 return []
999
[email protected]d668899a2012-09-06 18:16:591000 if all(re.search('\.(m|mm)$|(^|[/_])mac[/_.]', f) for f in files):
[email protected]7fab6202013-02-21 17:54:351001 return ['mac_rel', 'mac_asan', 'mac:compile']
[email protected]d668899a2012-09-06 18:16:591002 if all(re.search('(^|[/_])win[/_.]', f) for f in files):
[email protected]7fab6202013-02-21 17:54:351003 return ['win_rel', 'win7_aura', 'win:compile']
[email protected]d668899a2012-09-06 18:16:591004 if all(re.search('(^|[/_])android[/_.]', f) for f in files):
[email protected]3e2f0402012-11-02 16:28:011005 return ['android_dbg', 'android_clang_dbg']
[email protected]356aa542012-09-19 23:31:291006 if all(re.search('^native_client_sdk', f) for f in files):
1007 return ['linux_nacl_sdk', 'win_nacl_sdk', 'mac_nacl_sdk']
[email protected]de142152012-10-03 23:02:451008 if all(re.search('[/_]ios[/_.]', f) for f in files):
1009 return ['ios_rel_device', 'ios_dbg_simulator']
[email protected]4ce995ea2012-06-27 02:13:101010
[email protected]3e2f0402012-11-02 16:28:011011 trybots = [
1012 'android_clang_dbg',
1013 'android_dbg',
1014 'ios_dbg_simulator',
1015 'ios_rel_device',
1016 'linux_asan',
[email protected]95c989162012-11-29 05:58:251017 'linux_aura',
[email protected]3e2f0402012-11-02 16:28:011018 'linux_chromeos',
1019 'linux_clang:compile',
1020 'linux_rel',
1021 'mac_asan',
1022 'mac_rel',
[email protected]7fab6202013-02-21 17:54:351023 'mac:compile',
[email protected]aa85c8b2013-01-11 04:20:281024 'win7_aura',
[email protected]3e2f0402012-11-02 16:28:011025 'win_rel',
[email protected]7fab6202013-02-21 17:54:351026 'win:compile',
[email protected]3e2f0402012-11-02 16:28:011027 ]
[email protected]911753b2012-08-02 12:11:541028
1029 # Match things like path/aura/file.cc and path/file_aura.cc.
[email protected]95c989162012-11-29 05:58:251030 # Same for chromeos.
1031 if any(re.search('[/_](aura|chromeos)', f) for f in files):
[email protected]3e2f0402012-11-02 16:28:011032 trybots += ['linux_chromeos_clang:compile', 'linux_chromeos_asan']
[email protected]4ce995ea2012-06-27 02:13:101033
[email protected]4ce995ea2012-06-27 02:13:101034 return trybots