blob: 3c62eb245846fb019f0d1f07264aadde06d84f16 [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 file name suffixes
31# used to indicate different platforms.
32_PLATFORM_SPECIFIERS = r'(_(android|chromeos|gtk|mac|posix|win))?'
33
34# Fragment of a regular expression that matches C++ and Objective-C++
35# implementation files.
36_IMPLEMENTATION_EXTENSIONS = r'\.(cc|cpp|cxx|mm)$'
37
38# Regular expression that matches code only used for test binaries
39# (best effort).
40_TEST_CODE_EXCLUDED_PATHS = (
41 r'.*[/\\](fake_|test_|mock_).+%s' % _IMPLEMENTATION_EXTENSIONS,
42 r'.+_test_(base|support|util)%s' % _IMPLEMENTATION_EXTENSIONS,
43 r'.+_(api|browser|perf|unit|ui)?test%s%s' % (_PLATFORM_SPECIFIERS,
44 _IMPLEMENTATION_EXTENSIONS),
45 r'.+profile_sync_service_harness%s' % _IMPLEMENTATION_EXTENSIONS,
46 r'.*[/\\](test|tool(s)?)[/\\].*',
47 # At request of folks maintaining this folder.
48 r'chrome[/\\]browser[/\\]automation[/\\].*',
49)
[email protected]ca8d19842009-02-19 16:33:1250
[email protected]eea609a2011-11-18 13:10:1251_TEST_ONLY_WARNING = (
52 'You might be calling functions intended only for testing from\n'
53 'production code. It is OK to ignore this warning if you know what\n'
54 'you are doing, as the heuristics used to detect the situation are\n'
55 'not perfect. The commit queue will not block on this warning.\n'
56 'Email [email protected] if you have questions.')
57
58
[email protected]cf9b78f2012-11-14 11:40:2859_INCLUDE_ORDER_WARNING = (
60 'Your #include order seems to be broken. Send mail to\n'
61 '[email protected] if this is not the case.')
62
63
[email protected]127f18ec2012-06-16 05:05:5964_BANNED_OBJC_FUNCTIONS = (
65 (
66 'addTrackingRect:',
[email protected]23e6cbc2012-06-16 18:51:2067 (
68 'The use of -[NSView addTrackingRect:owner:userData:assumeInside:] is'
[email protected]127f18ec2012-06-16 05:05:5969 'prohibited. Please use CrTrackingArea instead.',
70 'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts',
71 ),
72 False,
73 ),
74 (
75 'NSTrackingArea',
[email protected]23e6cbc2012-06-16 18:51:2076 (
77 'The use of NSTrackingAreas is prohibited. Please use CrTrackingArea',
[email protected]127f18ec2012-06-16 05:05:5978 'instead.',
79 'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts',
80 ),
81 False,
82 ),
83 (
84 'convertPointFromBase:',
[email protected]23e6cbc2012-06-16 18:51:2085 (
86 'The use of -[NSView convertPointFromBase:] is almost certainly wrong.',
[email protected]127f18ec2012-06-16 05:05:5987 'Please use |convertPoint:(point) fromView:nil| instead.',
88 'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts',
89 ),
90 True,
91 ),
92 (
93 'convertPointToBase:',
[email protected]23e6cbc2012-06-16 18:51:2094 (
95 'The use of -[NSView convertPointToBase:] is almost certainly wrong.',
[email protected]127f18ec2012-06-16 05:05:5996 'Please use |convertPoint:(point) toView:nil| instead.',
97 'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts',
98 ),
99 True,
100 ),
101 (
102 'convertRectFromBase:',
[email protected]23e6cbc2012-06-16 18:51:20103 (
104 'The use of -[NSView convertRectFromBase:] is almost certainly wrong.',
[email protected]127f18ec2012-06-16 05:05:59105 'Please use |convertRect:(point) fromView:nil| instead.',
106 'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts',
107 ),
108 True,
109 ),
110 (
111 'convertRectToBase:',
[email protected]23e6cbc2012-06-16 18:51:20112 (
113 'The use of -[NSView convertRectToBase:] is almost certainly wrong.',
[email protected]127f18ec2012-06-16 05:05:59114 'Please use |convertRect:(point) toView:nil| instead.',
115 'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts',
116 ),
117 True,
118 ),
119 (
120 'convertSizeFromBase:',
[email protected]23e6cbc2012-06-16 18:51:20121 (
122 'The use of -[NSView convertSizeFromBase:] is almost certainly wrong.',
[email protected]127f18ec2012-06-16 05:05:59123 'Please use |convertSize:(point) fromView:nil| instead.',
124 'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts',
125 ),
126 True,
127 ),
128 (
129 'convertSizeToBase:',
[email protected]23e6cbc2012-06-16 18:51:20130 (
131 'The use of -[NSView convertSizeToBase:] is almost certainly wrong.',
[email protected]127f18ec2012-06-16 05:05:59132 'Please use |convertSize:(point) toView:nil| instead.',
133 'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts',
134 ),
135 True,
136 ),
137)
138
139
140_BANNED_CPP_FUNCTIONS = (
[email protected]23e6cbc2012-06-16 18:51:20141 # Make sure that gtest's FRIEND_TEST() macro is not used; the
142 # FRIEND_TEST_ALL_PREFIXES() macro from base/gtest_prod_util.h should be
[email protected]e00ccc92012-11-01 17:32:30143 # used instead since that allows for FLAKY_ and DISABLED_ prefixes.
[email protected]23e6cbc2012-06-16 18:51:20144 (
145 'FRIEND_TEST(',
146 (
[email protected]e3c945502012-06-26 20:01:49147 'Chromium code should not use gtest\'s FRIEND_TEST() macro. Include',
[email protected]23e6cbc2012-06-16 18:51:20148 'base/gtest_prod_util.h and use FRIEND_TEST_ALL_PREFIXES() instead.',
149 ),
150 False,
[email protected]7345da02012-11-27 14:31:49151 (),
[email protected]23e6cbc2012-06-16 18:51:20152 ),
153 (
154 'ScopedAllowIO',
155 (
[email protected]e3c945502012-06-26 20:01:49156 'New code should not use ScopedAllowIO. Post a task to the blocking',
157 'pool or the FILE thread instead.',
[email protected]23e6cbc2012-06-16 18:51:20158 ),
[email protected]e3c945502012-06-26 20:01:49159 True,
[email protected]7345da02012-11-27 14:31:49160 (
161 r"^content[\\\/]shell[\\\/]shell_browser_main\.cc$",
[email protected]398ad132013-04-02 15:11:01162 r"^net[\\\/]disk_cache[\\\/]cache_util\.cc$",
[email protected]7345da02012-11-27 14:31:49163 ),
[email protected]23e6cbc2012-06-16 18:51:20164 ),
[email protected]127f18ec2012-06-16 05:05:59165)
166
167
[email protected]b00342e7f2013-03-26 16:21:54168_VALID_OS_MACROS = (
169 # Please keep sorted.
170 'OS_ANDROID',
171 'OS_BSD',
172 'OS_CAT', # For testing.
173 'OS_CHROMEOS',
174 'OS_FREEBSD',
175 'OS_IOS',
176 'OS_LINUX',
177 'OS_MACOSX',
178 'OS_NACL',
179 'OS_OPENBSD',
180 'OS_POSIX',
181 'OS_SOLARIS',
182 'OS_SUN', # Not in build/build_config.h but in skia.
183 'OS_WIN',
184)
185
186
[email protected]55459852011-08-10 15:17:19187def _CheckNoProductionCodeUsingTestOnlyFunctions(input_api, output_api):
188 """Attempts to prevent use of functions intended only for testing in
189 non-testing code. For now this is just a best-effort implementation
190 that ignores header files and may have some false positives. A
191 better implementation would probably need a proper C++ parser.
192 """
193 # We only scan .cc files and the like, as the declaration of
194 # for-testing functions in header files are hard to distinguish from
195 # calls to such functions without a proper C++ parser.
[email protected]06e6d0ff2012-12-11 01:36:44196 file_inclusion_pattern = r'.+%s' % _IMPLEMENTATION_EXTENSIONS
[email protected]55459852011-08-10 15:17:19197
198 base_function_pattern = r'ForTest(ing)?|for_test(ing)?'
199 inclusion_pattern = input_api.re.compile(r'(%s)\s*\(' % base_function_pattern)
200 exclusion_pattern = input_api.re.compile(
201 r'::[A-Za-z0-9_]+(%s)|(%s)[^;]+\{' % (
202 base_function_pattern, base_function_pattern))
203
204 def FilterFile(affected_file):
[email protected]06e6d0ff2012-12-11 01:36:44205 black_list = (_EXCLUDED_PATHS +
206 _TEST_CODE_EXCLUDED_PATHS +
207 input_api.DEFAULT_BLACK_LIST)
[email protected]55459852011-08-10 15:17:19208 return input_api.FilterSourceFile(
209 affected_file,
210 white_list=(file_inclusion_pattern, ),
211 black_list=black_list)
212
213 problems = []
214 for f in input_api.AffectedSourceFiles(FilterFile):
215 local_path = f.LocalPath()
[email protected]2fdd1f362013-01-16 03:56:03216 lines = input_api.ReadFile(f).splitlines()
217 line_number = 0
218 for line in lines:
219 if (inclusion_pattern.search(line) and
220 not exclusion_pattern.search(line)):
[email protected]55459852011-08-10 15:17:19221 problems.append(
[email protected]2fdd1f362013-01-16 03:56:03222 '%s:%d\n %s' % (local_path, line_number, line.strip()))
223 line_number += 1
[email protected]55459852011-08-10 15:17:19224
225 if problems:
[email protected]2fdd1f362013-01-16 03:56:03226 if not input_api.is_committing:
227 return [output_api.PresubmitPromptWarning(_TEST_ONLY_WARNING, problems)]
228 else:
[email protected]eea609a2011-11-18 13:10:12229 # We don't warn on commit, to avoid stopping commits going through CQ.
230 return [output_api.PresubmitNotifyResult(_TEST_ONLY_WARNING, problems)]
[email protected]2fdd1f362013-01-16 03:56:03231 else:
232 return []
[email protected]55459852011-08-10 15:17:19233
234
[email protected]10689ca2011-09-02 02:31:54235def _CheckNoIOStreamInHeaders(input_api, output_api):
236 """Checks to make sure no .h files include <iostream>."""
237 files = []
238 pattern = input_api.re.compile(r'^#include\s*<iostream>',
239 input_api.re.MULTILINE)
240 for f in input_api.AffectedSourceFiles(input_api.FilterSourceFile):
241 if not f.LocalPath().endswith('.h'):
242 continue
243 contents = input_api.ReadFile(f)
244 if pattern.search(contents):
245 files.append(f)
246
247 if len(files):
248 return [ output_api.PresubmitError(
[email protected]6c063c62012-07-11 19:11:06249 'Do not #include <iostream> in header files, since it inserts static '
250 'initialization into every file including the header. Instead, '
[email protected]10689ca2011-09-02 02:31:54251 '#include <ostream>. See http://crbug.com/94794',
252 files) ]
253 return []
254
255
[email protected]72df4e782012-06-21 16:28:18256def _CheckNoUNIT_TESTInSourceFiles(input_api, output_api):
257 """Checks to make sure no source files use UNIT_TEST"""
258 problems = []
259 for f in input_api.AffectedFiles():
260 if (not f.LocalPath().endswith(('.cc', '.mm'))):
261 continue
262
263 for line_num, line in f.ChangedContents():
264 if 'UNIT_TEST' in line:
265 problems.append(' %s:%d' % (f.LocalPath(), line_num))
266
267 if not problems:
268 return []
269 return [output_api.PresubmitPromptWarning('UNIT_TEST is only for headers.\n' +
270 '\n'.join(problems))]
271
272
[email protected]8ea5d4b2011-09-13 21:49:22273def _CheckNoNewWStrings(input_api, output_api):
274 """Checks to make sure we don't introduce use of wstrings."""
[email protected]55463aa62011-10-12 00:48:27275 problems = []
[email protected]8ea5d4b2011-09-13 21:49:22276 for f in input_api.AffectedFiles():
[email protected]b5c24292011-11-28 14:38:20277 if (not f.LocalPath().endswith(('.cc', '.h')) or
278 f.LocalPath().endswith('test.cc')):
279 continue
[email protected]8ea5d4b2011-09-13 21:49:22280
[email protected]a11dbe9b2012-08-07 01:32:58281 allowWString = False
[email protected]b5c24292011-11-28 14:38:20282 for line_num, line in f.ChangedContents():
[email protected]a11dbe9b2012-08-07 01:32:58283 if 'presubmit: allow wstring' in line:
284 allowWString = True
285 elif not allowWString and 'wstring' in line:
[email protected]55463aa62011-10-12 00:48:27286 problems.append(' %s:%d' % (f.LocalPath(), line_num))
[email protected]a11dbe9b2012-08-07 01:32:58287 allowWString = False
288 else:
289 allowWString = False
[email protected]8ea5d4b2011-09-13 21:49:22290
[email protected]55463aa62011-10-12 00:48:27291 if not problems:
292 return []
293 return [output_api.PresubmitPromptWarning('New code should not use wstrings.'
[email protected]a11dbe9b2012-08-07 01:32:58294 ' If you are calling a cross-platform API that accepts a wstring, '
295 'fix the API.\n' +
[email protected]55463aa62011-10-12 00:48:27296 '\n'.join(problems))]
[email protected]8ea5d4b2011-09-13 21:49:22297
298
[email protected]2a8ac9c2011-10-19 17:20:44299def _CheckNoDEPSGIT(input_api, output_api):
300 """Make sure .DEPS.git is never modified manually."""
301 if any(f.LocalPath().endswith('.DEPS.git') for f in
302 input_api.AffectedFiles()):
303 return [output_api.PresubmitError(
304 'Never commit changes to .DEPS.git. This file is maintained by an\n'
305 'automated system based on what\'s in DEPS and your changes will be\n'
306 'overwritten.\n'
307 'See http://code.google.com/p/chromium/wiki/UsingNewGit#Rolling_DEPS\n'
308 'for more information')]
309 return []
310
311
[email protected]127f18ec2012-06-16 05:05:59312def _CheckNoBannedFunctions(input_api, output_api):
313 """Make sure that banned functions are not used."""
314 warnings = []
315 errors = []
316
317 file_filter = lambda f: f.LocalPath().endswith(('.mm', '.m', '.h'))
318 for f in input_api.AffectedFiles(file_filter=file_filter):
319 for line_num, line in f.ChangedContents():
320 for func_name, message, error in _BANNED_OBJC_FUNCTIONS:
321 if func_name in line:
322 problems = warnings;
323 if error:
324 problems = errors;
325 problems.append(' %s:%d:' % (f.LocalPath(), line_num))
326 for message_line in message:
327 problems.append(' %s' % message_line)
328
329 file_filter = lambda f: f.LocalPath().endswith(('.cc', '.mm', '.h'))
330 for f in input_api.AffectedFiles(file_filter=file_filter):
331 for line_num, line in f.ChangedContents():
[email protected]7345da02012-11-27 14:31:49332 for func_name, message, error, excluded_paths in _BANNED_CPP_FUNCTIONS:
333 def IsBlacklisted(affected_file, blacklist):
334 local_path = affected_file.LocalPath()
335 for item in blacklist:
336 if input_api.re.match(item, local_path):
337 return True
338 return False
339 if IsBlacklisted(f, excluded_paths):
340 continue
[email protected]127f18ec2012-06-16 05:05:59341 if func_name in line:
342 problems = warnings;
343 if error:
344 problems = errors;
345 problems.append(' %s:%d:' % (f.LocalPath(), line_num))
346 for message_line in message:
347 problems.append(' %s' % message_line)
348
349 result = []
350 if (warnings):
351 result.append(output_api.PresubmitPromptWarning(
352 'Banned functions were used.\n' + '\n'.join(warnings)))
353 if (errors):
354 result.append(output_api.PresubmitError(
355 'Banned functions were used.\n' + '\n'.join(errors)))
356 return result
357
358
[email protected]6c063c62012-07-11 19:11:06359def _CheckNoPragmaOnce(input_api, output_api):
360 """Make sure that banned functions are not used."""
361 files = []
362 pattern = input_api.re.compile(r'^#pragma\s+once',
363 input_api.re.MULTILINE)
364 for f in input_api.AffectedSourceFiles(input_api.FilterSourceFile):
365 if not f.LocalPath().endswith('.h'):
366 continue
367 contents = input_api.ReadFile(f)
368 if pattern.search(contents):
369 files.append(f)
370
371 if files:
372 return [output_api.PresubmitError(
373 'Do not use #pragma once in header files.\n'
374 'See http://www.chromium.org/developers/coding-style#TOC-File-headers',
375 files)]
376 return []
377
[email protected]127f18ec2012-06-16 05:05:59378
[email protected]e7479052012-09-19 00:26:12379def _CheckNoTrinaryTrueFalse(input_api, output_api):
380 """Checks to make sure we don't introduce use of foo ? true : false."""
381 problems = []
382 pattern = input_api.re.compile(r'\?\s*(true|false)\s*:\s*(true|false)')
383 for f in input_api.AffectedFiles():
384 if not f.LocalPath().endswith(('.cc', '.h', '.inl', '.m', '.mm')):
385 continue
386
387 for line_num, line in f.ChangedContents():
388 if pattern.match(line):
389 problems.append(' %s:%d' % (f.LocalPath(), line_num))
390
391 if not problems:
392 return []
393 return [output_api.PresubmitPromptWarning(
394 'Please consider avoiding the "? true : false" pattern if possible.\n' +
395 '\n'.join(problems))]
396
397
[email protected]55f9f382012-07-31 11:02:18398def _CheckUnwantedDependencies(input_api, output_api):
399 """Runs checkdeps on #include statements added in this
400 change. Breaking - rules is an error, breaking ! rules is a
401 warning.
402 """
403 # We need to wait until we have an input_api object and use this
404 # roundabout construct to import checkdeps because this file is
405 # eval-ed and thus doesn't have __file__.
406 original_sys_path = sys.path
407 try:
408 sys.path = sys.path + [input_api.os_path.join(
409 input_api.PresubmitLocalPath(), 'tools', 'checkdeps')]
410 import checkdeps
411 from cpp_checker import CppChecker
412 from rules import Rule
413 finally:
414 # Restore sys.path to what it was before.
415 sys.path = original_sys_path
416
417 added_includes = []
418 for f in input_api.AffectedFiles():
419 if not CppChecker.IsCppFile(f.LocalPath()):
420 continue
421
422 changed_lines = [line for line_num, line in f.ChangedContents()]
423 added_includes.append([f.LocalPath(), changed_lines])
424
425 deps_checker = checkdeps.DepsChecker()
426
427 error_descriptions = []
428 warning_descriptions = []
429 for path, rule_type, rule_description in deps_checker.CheckAddedCppIncludes(
430 added_includes):
431 description_with_path = '%s\n %s' % (path, rule_description)
432 if rule_type == Rule.DISALLOW:
433 error_descriptions.append(description_with_path)
434 else:
435 warning_descriptions.append(description_with_path)
436
437 results = []
438 if error_descriptions:
439 results.append(output_api.PresubmitError(
440 'You added one or more #includes that violate checkdeps rules.',
441 error_descriptions))
442 if warning_descriptions:
[email protected]2fdd1f362013-01-16 03:56:03443 if not input_api.is_committing:
444 warning_factory = output_api.PresubmitPromptWarning
445 else:
[email protected]779caa52012-08-21 17:05:59446 # We don't want to block use of the CQ when there is a warning
447 # of this kind, so we only show a message when committing.
448 warning_factory = output_api.PresubmitNotifyResult
449 results.append(warning_factory(
[email protected]55f9f382012-07-31 11:02:18450 'You added one or more #includes of files that are temporarily\n'
451 'allowed but being removed. Can you avoid introducing the\n'
452 '#include? See relevant DEPS file(s) for details and contacts.',
453 warning_descriptions))
454 return results
455
456
[email protected]fbcafe5a2012-08-08 15:31:22457def _CheckFilePermissions(input_api, output_api):
458 """Check that all files have their permissions properly set."""
459 args = [sys.executable, 'tools/checkperms/checkperms.py', '--root',
460 input_api.change.RepositoryRoot()]
461 for f in input_api.AffectedFiles():
462 args += ['--file', f.LocalPath()]
463 errors = []
464 (errors, stderrdata) = subprocess.Popen(args).communicate()
465
466 results = []
467 if errors:
[email protected]c8278b32012-10-30 20:35:49468 results.append(output_api.PresubmitError('checkperms.py failed.',
[email protected]fbcafe5a2012-08-08 15:31:22469 errors))
470 return results
471
472
[email protected]c8278b32012-10-30 20:35:49473def _CheckNoAuraWindowPropertyHInHeaders(input_api, output_api):
474 """Makes sure we don't include ui/aura/window_property.h
475 in header files.
476 """
477 pattern = input_api.re.compile(r'^#include\s*"ui/aura/window_property.h"')
478 errors = []
479 for f in input_api.AffectedFiles():
480 if not f.LocalPath().endswith('.h'):
481 continue
482 for line_num, line in f.ChangedContents():
483 if pattern.match(line):
484 errors.append(' %s:%d' % (f.LocalPath(), line_num))
485
486 results = []
487 if errors:
488 results.append(output_api.PresubmitError(
489 'Header files should not include ui/aura/window_property.h', errors))
490 return results
491
492
[email protected]cf9b78f2012-11-14 11:40:28493def _CheckIncludeOrderForScope(scope, input_api, file_path, changed_linenums):
494 """Checks that the lines in scope occur in the right order.
495
496 1. C system files in alphabetical order
497 2. C++ system files in alphabetical order
498 3. Project's .h files
499 """
500
501 c_system_include_pattern = input_api.re.compile(r'\s*#include <.*\.h>')
502 cpp_system_include_pattern = input_api.re.compile(r'\s*#include <.*>')
503 custom_include_pattern = input_api.re.compile(r'\s*#include ".*')
504
505 C_SYSTEM_INCLUDES, CPP_SYSTEM_INCLUDES, CUSTOM_INCLUDES = range(3)
506
507 state = C_SYSTEM_INCLUDES
508
509 previous_line = ''
[email protected]728b9bb2012-11-14 20:38:57510 previous_line_num = 0
[email protected]cf9b78f2012-11-14 11:40:28511 problem_linenums = []
512 for line_num, line in scope:
513 if c_system_include_pattern.match(line):
514 if state != C_SYSTEM_INCLUDES:
[email protected]728b9bb2012-11-14 20:38:57515 problem_linenums.append((line_num, previous_line_num))
[email protected]cf9b78f2012-11-14 11:40:28516 elif previous_line and previous_line > line:
[email protected]728b9bb2012-11-14 20:38:57517 problem_linenums.append((line_num, previous_line_num))
[email protected]cf9b78f2012-11-14 11:40:28518 elif cpp_system_include_pattern.match(line):
519 if state == C_SYSTEM_INCLUDES:
520 state = CPP_SYSTEM_INCLUDES
521 elif state == CUSTOM_INCLUDES:
[email protected]728b9bb2012-11-14 20:38:57522 problem_linenums.append((line_num, previous_line_num))
[email protected]cf9b78f2012-11-14 11:40:28523 elif previous_line and previous_line > line:
[email protected]728b9bb2012-11-14 20:38:57524 problem_linenums.append((line_num, previous_line_num))
[email protected]cf9b78f2012-11-14 11:40:28525 elif custom_include_pattern.match(line):
526 if state != CUSTOM_INCLUDES:
527 state = CUSTOM_INCLUDES
528 elif previous_line and previous_line > line:
[email protected]728b9bb2012-11-14 20:38:57529 problem_linenums.append((line_num, previous_line_num))
[email protected]cf9b78f2012-11-14 11:40:28530 else:
531 problem_linenums.append(line_num)
532 previous_line = line
[email protected]728b9bb2012-11-14 20:38:57533 previous_line_num = line_num
[email protected]cf9b78f2012-11-14 11:40:28534
535 warnings = []
[email protected]728b9bb2012-11-14 20:38:57536 for (line_num, previous_line_num) in problem_linenums:
537 if line_num in changed_linenums or previous_line_num in changed_linenums:
[email protected]cf9b78f2012-11-14 11:40:28538 warnings.append(' %s:%d' % (file_path, line_num))
539 return warnings
540
541
[email protected]ac294a12012-12-06 16:38:43542def _CheckIncludeOrderInFile(input_api, f, changed_linenums):
[email protected]cf9b78f2012-11-14 11:40:28543 """Checks the #include order for the given file f."""
544
[email protected]2299dcf2012-11-15 19:56:24545 system_include_pattern = input_api.re.compile(r'\s*#include \<.*')
[email protected]962f117e2012-11-22 18:11:56546 # Exclude #include <.../...> includes from the check; e.g., <sys/...> includes
547 # often need to appear in a specific order.
548 excluded_include_pattern = input_api.re.compile(r'\s*#include \<.*/.*')
[email protected]2299dcf2012-11-15 19:56:24549 custom_include_pattern = input_api.re.compile(r'\s*#include "(?P<FILE>.*)"')
[email protected]0e5c1852012-12-18 20:17:11550 if_pattern = input_api.re.compile(
551 r'\s*#\s*(if|elif|else|endif|define|undef).*')
552 # Some files need specialized order of includes; exclude such files from this
553 # check.
554 uncheckable_includes_pattern = input_api.re.compile(
555 r'\s*#include '
556 '("ipc/.*macros\.h"|<windows\.h>|".*gl.*autogen.h")\s*')
[email protected]cf9b78f2012-11-14 11:40:28557
558 contents = f.NewContents()
559 warnings = []
560 line_num = 0
561
[email protected]ac294a12012-12-06 16:38:43562 # Handle the special first include. If the first include file is
563 # some/path/file.h, the corresponding including file can be some/path/file.cc,
564 # some/other/path/file.cc, some/path/file_platform.cc, some/path/file-suffix.h
565 # etc. It's also possible that no special first include exists.
566 for line in contents:
567 line_num += 1
568 if system_include_pattern.match(line):
569 # No special first include -> process the line again along with normal
570 # includes.
571 line_num -= 1
572 break
573 match = custom_include_pattern.match(line)
574 if match:
575 match_dict = match.groupdict()
576 header_basename = input_api.os_path.basename(
577 match_dict['FILE']).replace('.h', '')
578 if header_basename not in input_api.os_path.basename(f.LocalPath()):
[email protected]2299dcf2012-11-15 19:56:24579 # No special first include -> process the line again along with normal
580 # includes.
581 line_num -= 1
[email protected]ac294a12012-12-06 16:38:43582 break
[email protected]cf9b78f2012-11-14 11:40:28583
584 # Split into scopes: Each region between #if and #endif is its own scope.
585 scopes = []
586 current_scope = []
587 for line in contents[line_num:]:
588 line_num += 1
[email protected]0e5c1852012-12-18 20:17:11589 if uncheckable_includes_pattern.match(line):
590 return []
[email protected]2309b0fa02012-11-16 12:18:27591 if if_pattern.match(line):
[email protected]cf9b78f2012-11-14 11:40:28592 scopes.append(current_scope)
593 current_scope = []
[email protected]962f117e2012-11-22 18:11:56594 elif ((system_include_pattern.match(line) or
595 custom_include_pattern.match(line)) and
596 not excluded_include_pattern.match(line)):
[email protected]cf9b78f2012-11-14 11:40:28597 current_scope.append((line_num, line))
598 scopes.append(current_scope)
599
600 for scope in scopes:
601 warnings.extend(_CheckIncludeOrderForScope(scope, input_api, f.LocalPath(),
602 changed_linenums))
603 return warnings
604
605
606def _CheckIncludeOrder(input_api, output_api):
607 """Checks that the #include order is correct.
608
609 1. The corresponding header for source files.
610 2. C system files in alphabetical order
611 3. C++ system files in alphabetical order
612 4. Project's .h files in alphabetical order
613
[email protected]ac294a12012-12-06 16:38:43614 Each region separated by #if, #elif, #else, #endif, #define and #undef follows
615 these rules separately.
[email protected]cf9b78f2012-11-14 11:40:28616 """
617
618 warnings = []
619 for f in input_api.AffectedFiles():
[email protected]ac294a12012-12-06 16:38:43620 if f.LocalPath().endswith(('.cc', '.h')):
621 changed_linenums = set(line_num for line_num, _ in f.ChangedContents())
622 warnings.extend(_CheckIncludeOrderInFile(input_api, f, changed_linenums))
[email protected]cf9b78f2012-11-14 11:40:28623
624 results = []
625 if warnings:
[email protected]2fdd1f362013-01-16 03:56:03626 if not input_api.is_committing:
627 results.append(output_api.PresubmitPromptWarning(_INCLUDE_ORDER_WARNING,
628 warnings))
629 else:
[email protected]120cf540d2012-12-10 17:55:53630 # We don't warn on commit, to avoid stopping commits going through CQ.
631 results.append(output_api.PresubmitNotifyResult(_INCLUDE_ORDER_WARNING,
632 warnings))
[email protected]cf9b78f2012-11-14 11:40:28633 return results
634
635
[email protected]70ca77752012-11-20 03:45:03636def _CheckForVersionControlConflictsInFile(input_api, f):
637 pattern = input_api.re.compile('^(?:<<<<<<<|>>>>>>>) |^=======$')
638 errors = []
639 for line_num, line in f.ChangedContents():
640 if pattern.match(line):
641 errors.append(' %s:%d %s' % (f.LocalPath(), line_num, line))
642 return errors
643
644
645def _CheckForVersionControlConflicts(input_api, output_api):
646 """Usually this is not intentional and will cause a compile failure."""
647 errors = []
648 for f in input_api.AffectedFiles():
649 errors.extend(_CheckForVersionControlConflictsInFile(input_api, f))
650
651 results = []
652 if errors:
653 results.append(output_api.PresubmitError(
654 'Version control conflict markers found, please resolve.', errors))
655 return results
656
657
[email protected]06e6d0ff2012-12-11 01:36:44658def _CheckHardcodedGoogleHostsInLowerLayers(input_api, output_api):
659 def FilterFile(affected_file):
660 """Filter function for use with input_api.AffectedSourceFiles,
661 below. This filters out everything except non-test files from
662 top-level directories that generally speaking should not hard-code
663 service URLs (e.g. src/android_webview/, src/content/ and others).
664 """
665 return input_api.FilterSourceFile(
666 affected_file,
[email protected]78bb39d62012-12-11 15:11:56667 white_list=(r'^(android_webview|base|content|net)[\\\/].*', ),
[email protected]06e6d0ff2012-12-11 01:36:44668 black_list=(_EXCLUDED_PATHS +
669 _TEST_CODE_EXCLUDED_PATHS +
670 input_api.DEFAULT_BLACK_LIST))
671
672 pattern = input_api.re.compile('"[^"]*google\.com[^"]*"')
673 problems = [] # items are (filename, line_number, line)
674 for f in input_api.AffectedSourceFiles(FilterFile):
675 for line_num, line in f.ChangedContents():
676 if pattern.search(line):
677 problems.append((f.LocalPath(), line_num, line))
678
679 if problems:
[email protected]2fdd1f362013-01-16 03:56:03680 if not input_api.is_committing:
681 warning_factory = output_api.PresubmitPromptWarning
682 else:
[email protected]06e6d0ff2012-12-11 01:36:44683 # We don't want to block use of the CQ when there is a warning
684 # of this kind, so we only show a message when committing.
685 warning_factory = output_api.PresubmitNotifyResult
686 return [warning_factory(
687 'Most layers below src/chrome/ should not hardcode service URLs.\n'
688 'Are you sure this is correct? (Contact: [email protected])',
689 [' %s:%d: %s' % (
690 problem[0], problem[1], problem[2]) for problem in problems])]
[email protected]2fdd1f362013-01-16 03:56:03691 else:
692 return []
[email protected]06e6d0ff2012-12-11 01:36:44693
694
[email protected]d2530012013-01-25 16:39:27695def _CheckNoAbbreviationInPngFileName(input_api, output_api):
696 """Makes sure there are no abbreviations in the name of PNG files.
697 """
[email protected]4053a48e2013-01-25 21:43:04698 pattern = input_api.re.compile(r'.*_[a-z]_.*\.png$|.*_[a-z]\.png$')
[email protected]d2530012013-01-25 16:39:27699 errors = []
700 for f in input_api.AffectedFiles(include_deletes=False):
701 if pattern.match(f.LocalPath()):
702 errors.append(' %s' % f.LocalPath())
703
704 results = []
705 if errors:
706 results.append(output_api.PresubmitError(
707 'The name of PNG files should not have abbreviations. \n'
708 'Use _hover.png, _center.png, instead of _h.png, _c.png.\n'
709 'Contact [email protected] if you have questions.', errors))
710 return results
711
712
[email protected]22c9bd72011-03-27 16:47:39713def _CommonChecks(input_api, output_api):
714 """Checks common to both upload and commit."""
715 results = []
716 results.extend(input_api.canned_checks.PanProjectChecks(
717 input_api, output_api, excluded_paths=_EXCLUDED_PATHS))
[email protected]66daa702011-05-28 14:41:46718 results.extend(_CheckAuthorizedAuthor(input_api, output_api))
[email protected]55459852011-08-10 15:17:19719 results.extend(
720 _CheckNoProductionCodeUsingTestOnlyFunctions(input_api, output_api))
[email protected]10689ca2011-09-02 02:31:54721 results.extend(_CheckNoIOStreamInHeaders(input_api, output_api))
[email protected]72df4e782012-06-21 16:28:18722 results.extend(_CheckNoUNIT_TESTInSourceFiles(input_api, output_api))
[email protected]8ea5d4b2011-09-13 21:49:22723 results.extend(_CheckNoNewWStrings(input_api, output_api))
[email protected]2a8ac9c2011-10-19 17:20:44724 results.extend(_CheckNoDEPSGIT(input_api, output_api))
[email protected]127f18ec2012-06-16 05:05:59725 results.extend(_CheckNoBannedFunctions(input_api, output_api))
[email protected]6c063c62012-07-11 19:11:06726 results.extend(_CheckNoPragmaOnce(input_api, output_api))
[email protected]e7479052012-09-19 00:26:12727 results.extend(_CheckNoTrinaryTrueFalse(input_api, output_api))
[email protected]55f9f382012-07-31 11:02:18728 results.extend(_CheckUnwantedDependencies(input_api, output_api))
[email protected]fbcafe5a2012-08-08 15:31:22729 results.extend(_CheckFilePermissions(input_api, output_api))
[email protected]c8278b32012-10-30 20:35:49730 results.extend(_CheckNoAuraWindowPropertyHInHeaders(input_api, output_api))
[email protected]2309b0fa02012-11-16 12:18:27731 results.extend(_CheckIncludeOrder(input_api, output_api))
[email protected]70ca77752012-11-20 03:45:03732 results.extend(_CheckForVersionControlConflicts(input_api, output_api))
[email protected]b8079ae4a2012-12-05 19:56:49733 results.extend(_CheckPatchFiles(input_api, output_api))
[email protected]06e6d0ff2012-12-11 01:36:44734 results.extend(_CheckHardcodedGoogleHostsInLowerLayers(input_api, output_api))
[email protected]d2530012013-01-25 16:39:27735 results.extend(_CheckNoAbbreviationInPngFileName(input_api, output_api))
[email protected]b00342e7f2013-03-26 16:21:54736 results.extend(_CheckForInvalidOSMacros(input_api, output_api))
[email protected]2299dcf2012-11-15 19:56:24737
738 if any('PRESUBMIT.py' == f.LocalPath() for f in input_api.AffectedFiles()):
739 results.extend(input_api.canned_checks.RunUnitTestsInDirectory(
740 input_api, output_api,
741 input_api.PresubmitLocalPath(),
[email protected]6be63382013-01-21 15:42:38742 whitelist=[r'^PRESUBMIT_test\.py$']))
[email protected]22c9bd72011-03-27 16:47:39743 return results
[email protected]1f7b4172010-01-28 01:17:34744
[email protected]b337cb5b2011-01-23 21:24:05745
746def _CheckSubversionConfig(input_api, output_api):
747 """Verifies the subversion config file is correctly setup.
748
749 Checks that autoprops are enabled, returns an error otherwise.
750 """
751 join = input_api.os_path.join
752 if input_api.platform == 'win32':
753 appdata = input_api.environ.get('APPDATA', '')
754 if not appdata:
755 return [output_api.PresubmitError('%APPDATA% is not configured.')]
756 path = join(appdata, 'Subversion', 'config')
757 else:
758 home = input_api.environ.get('HOME', '')
759 if not home:
760 return [output_api.PresubmitError('$HOME is not configured.')]
761 path = join(home, '.subversion', 'config')
762
763 error_msg = (
764 'Please look at http://dev.chromium.org/developers/coding-style to\n'
765 'configure your subversion configuration file. This enables automatic\n'
[email protected]c6a3c10b2011-01-24 16:14:20766 'properties to simplify the project maintenance.\n'
767 'Pro-tip: just download and install\n'
768 'http://src.chromium.org/viewvc/chrome/trunk/tools/build/slave/config\n')
[email protected]b337cb5b2011-01-23 21:24:05769
770 try:
771 lines = open(path, 'r').read().splitlines()
772 # Make sure auto-props is enabled and check for 2 Chromium standard
773 # auto-prop.
774 if (not '*.cc = svn:eol-style=LF' in lines or
775 not '*.pdf = svn:mime-type=application/pdf' in lines or
776 not 'enable-auto-props = yes' in lines):
777 return [
[email protected]79ed7e62011-02-21 21:08:53778 output_api.PresubmitNotifyResult(
[email protected]b337cb5b2011-01-23 21:24:05779 'It looks like you have not configured your subversion config '
[email protected]b5359c02011-02-01 20:29:56780 'file or it is not up-to-date.\n' + error_msg)
[email protected]b337cb5b2011-01-23 21:24:05781 ]
782 except (OSError, IOError):
783 return [
[email protected]79ed7e62011-02-21 21:08:53784 output_api.PresubmitNotifyResult(
[email protected]b337cb5b2011-01-23 21:24:05785 'Can\'t find your subversion config file.\n' + error_msg)
786 ]
787 return []
788
789
[email protected]66daa702011-05-28 14:41:46790def _CheckAuthorizedAuthor(input_api, output_api):
791 """For non-googler/chromites committers, verify the author's email address is
792 in AUTHORS.
793 """
[email protected]9bb9cb82011-06-13 20:43:01794 # TODO(maruel): Add it to input_api?
795 import fnmatch
796
[email protected]66daa702011-05-28 14:41:46797 author = input_api.change.author_email
[email protected]9bb9cb82011-06-13 20:43:01798 if not author:
799 input_api.logging.info('No author, skipping AUTHOR check')
[email protected]66daa702011-05-28 14:41:46800 return []
[email protected]c99663292011-05-31 19:46:08801 authors_path = input_api.os_path.join(
[email protected]66daa702011-05-28 14:41:46802 input_api.PresubmitLocalPath(), 'AUTHORS')
803 valid_authors = (
804 input_api.re.match(r'[^#]+\s+\<(.+?)\>\s*$', line)
805 for line in open(authors_path))
[email protected]ac54b132011-06-06 18:11:18806 valid_authors = [item.group(1).lower() for item in valid_authors if item]
[email protected]d8b50be2011-06-15 14:19:44807 if not any(fnmatch.fnmatch(author.lower(), valid) for valid in valid_authors):
[email protected]5861efb2013-01-07 18:33:23808 input_api.logging.info('Valid authors are %s', ', '.join(valid_authors))
[email protected]66daa702011-05-28 14:41:46809 return [output_api.PresubmitPromptWarning(
810 ('%s is not in AUTHORS file. If you are a new contributor, please visit'
811 '\n'
812 'http://www.chromium.org/developers/contributing-code and read the '
813 '"Legal" section\n'
814 'If you are a chromite, verify the contributor signed the CLA.') %
815 author)]
816 return []
817
818
[email protected]b8079ae4a2012-12-05 19:56:49819def _CheckPatchFiles(input_api, output_api):
820 problems = [f.LocalPath() for f in input_api.AffectedFiles()
821 if f.LocalPath().endswith(('.orig', '.rej'))]
822 if problems:
823 return [output_api.PresubmitError(
824 "Don't commit .rej and .orig files.", problems)]
[email protected]2fdd1f362013-01-16 03:56:03825 else:
826 return []
[email protected]b8079ae4a2012-12-05 19:56:49827
828
[email protected]b00342e7f2013-03-26 16:21:54829def _DidYouMeanOSMacro(bad_macro):
830 try:
831 return {'A': 'OS_ANDROID',
832 'B': 'OS_BSD',
833 'C': 'OS_CHROMEOS',
834 'F': 'OS_FREEBSD',
835 'L': 'OS_LINUX',
836 'M': 'OS_MACOSX',
837 'N': 'OS_NACL',
838 'O': 'OS_OPENBSD',
839 'P': 'OS_POSIX',
840 'S': 'OS_SOLARIS',
841 'W': 'OS_WIN'}[bad_macro[3].upper()]
842 except KeyError:
843 return ''
844
845
846def _CheckForInvalidOSMacrosInFile(input_api, f):
847 """Check for sensible looking, totally invalid OS macros."""
848 preprocessor_statement = input_api.re.compile(r'^\s*#')
849 os_macro = input_api.re.compile(r'defined\((OS_[^)]+)\)')
850 results = []
851 for lnum, line in f.ChangedContents():
852 if preprocessor_statement.search(line):
853 for match in os_macro.finditer(line):
854 if not match.group(1) in _VALID_OS_MACROS:
855 good = _DidYouMeanOSMacro(match.group(1))
856 did_you_mean = ' (did you mean %s?)' % good if good else ''
857 results.append(' %s:%d %s%s' % (f.LocalPath(),
858 lnum,
859 match.group(1),
860 did_you_mean))
861 return results
862
863
864def _CheckForInvalidOSMacros(input_api, output_api):
865 """Check all affected files for invalid OS macros."""
866 bad_macros = []
867 for f in input_api.AffectedFiles():
868 if not f.LocalPath().endswith(('.py', '.js', '.html', '.css')):
869 bad_macros.extend(_CheckForInvalidOSMacrosInFile(input_api, f))
870
871 if not bad_macros:
872 return []
873
874 return [output_api.PresubmitError(
875 'Possibly invalid OS macro[s] found. Please fix your code\n'
876 'or add your macro to src/PRESUBMIT.py.', bad_macros)]
877
878
[email protected]1f7b4172010-01-28 01:17:34879def CheckChangeOnUpload(input_api, output_api):
880 results = []
881 results.extend(_CommonChecks(input_api, output_api))
[email protected]fe5f57c52009-06-05 14:25:54882 return results
[email protected]ca8d19842009-02-19 16:33:12883
884
885def CheckChangeOnCommit(input_api, output_api):
[email protected]fe5f57c52009-06-05 14:25:54886 results = []
[email protected]1f7b4172010-01-28 01:17:34887 results.extend(_CommonChecks(input_api, output_api))
[email protected]dd805fe2009-10-01 08:11:51888 # TODO(thestig) temporarily disabled, doesn't work in third_party/
889 #results.extend(input_api.canned_checks.CheckSvnModifiedDirectories(
890 # input_api, output_api, sources))
[email protected]fe5f57c52009-06-05 14:25:54891 # Make sure the tree is 'open'.
[email protected]806e98e2010-03-19 17:49:27892 results.extend(input_api.canned_checks.CheckTreeIsOpen(
[email protected]7f238152009-08-12 19:00:34893 input_api,
894 output_api,
[email protected]2fdd1f362013-01-16 03:56:03895 json_url='http://chromium-status.appspot.com/current?format=json'))
[email protected]806e98e2010-03-19 17:49:27896 results.extend(input_api.canned_checks.CheckRietveldTryJobExecution(input_api,
[email protected]2fdd1f362013-01-16 03:56:03897 output_api, 'http://codereview.chromium.org',
[email protected]c1ba4c52012-03-09 14:23:28898 ('win_rel', 'linux_rel', 'mac_rel, win:compile'),
899 '[email protected]'))
[email protected]806e98e2010-03-19 17:49:27900
[email protected]3e4eb112011-01-18 03:29:54901 results.extend(input_api.canned_checks.CheckChangeHasBugField(
902 input_api, output_api))
[email protected]c4b47562011-12-05 23:39:41903 results.extend(input_api.canned_checks.CheckChangeHasDescription(
904 input_api, output_api))
[email protected]b337cb5b2011-01-23 21:24:05905 results.extend(_CheckSubversionConfig(input_api, output_api))
[email protected]fe5f57c52009-06-05 14:25:54906 return results
[email protected]ca8d19842009-02-19 16:33:12907
908
[email protected]5efb2a822011-09-27 23:06:13909def GetPreferredTrySlaves(project, change):
[email protected]4ce995ea2012-06-27 02:13:10910 files = change.LocalPaths()
911
[email protected]751b05f2013-01-10 23:12:17912 if not files or all(re.search(r'[\\/]OWNERS$', f) for f in files):
[email protected]3019c902012-06-29 00:09:03913 return []
914
[email protected]d668899a2012-09-06 18:16:59915 if all(re.search('\.(m|mm)$|(^|[/_])mac[/_.]', f) for f in files):
[email protected]7fab6202013-02-21 17:54:35916 return ['mac_rel', 'mac_asan', 'mac:compile']
[email protected]d668899a2012-09-06 18:16:59917 if all(re.search('(^|[/_])win[/_.]', f) for f in files):
[email protected]7fab6202013-02-21 17:54:35918 return ['win_rel', 'win7_aura', 'win:compile']
[email protected]d668899a2012-09-06 18:16:59919 if all(re.search('(^|[/_])android[/_.]', f) for f in files):
[email protected]3e2f0402012-11-02 16:28:01920 return ['android_dbg', 'android_clang_dbg']
[email protected]356aa542012-09-19 23:31:29921 if all(re.search('^native_client_sdk', f) for f in files):
922 return ['linux_nacl_sdk', 'win_nacl_sdk', 'mac_nacl_sdk']
[email protected]de142152012-10-03 23:02:45923 if all(re.search('[/_]ios[/_.]', f) for f in files):
924 return ['ios_rel_device', 'ios_dbg_simulator']
[email protected]4ce995ea2012-06-27 02:13:10925
[email protected]3e2f0402012-11-02 16:28:01926 trybots = [
927 'android_clang_dbg',
928 'android_dbg',
929 'ios_dbg_simulator',
930 'ios_rel_device',
931 'linux_asan',
[email protected]95c989162012-11-29 05:58:25932 'linux_aura',
[email protected]3e2f0402012-11-02 16:28:01933 'linux_chromeos',
934 'linux_clang:compile',
935 'linux_rel',
936 'mac_asan',
937 'mac_rel',
[email protected]7fab6202013-02-21 17:54:35938 'mac:compile',
[email protected]aa85c8b2013-01-11 04:20:28939 'win7_aura',
[email protected]3e2f0402012-11-02 16:28:01940 'win_rel',
[email protected]7fab6202013-02-21 17:54:35941 'win:compile',
[email protected]3e2f0402012-11-02 16:28:01942 ]
[email protected]911753b2012-08-02 12:11:54943
944 # Match things like path/aura/file.cc and path/file_aura.cc.
[email protected]95c989162012-11-29 05:58:25945 # Same for chromeos.
946 if any(re.search('[/_](aura|chromeos)', f) for f in files):
[email protected]3e2f0402012-11-02 16:28:01947 trybots += ['linux_chromeos_clang:compile', 'linux_chromeos_asan']
[email protected]4ce995ea2012-06-27 02:13:10948
[email protected]4ce995ea2012-06-27 02:13:10949 return trybots