blob: 9bb1471cbed6ae9c37ed36022b878fe58fc95d21 [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]e07b6ac72013-08-20 00:30:4228 r"^gpu[\\\/]config[\\\/].*_list_json\.cc$",
[email protected]4306417642009-06-11 00:33:4029)
[email protected]ca8d19842009-02-19 16:33:1230
[email protected]3de922f2013-12-20 13:27:3831# TestRunner library is temporarily excluded from pan-project checks until
32# it's transitioned to chromium coding style.
33_TESTRUNNER_PATHS = (
34 r"^content[\\\/]shell[\\\/]renderer[\\\/]test_runner[\\\/].*",
35 r"^content[\\\/]shell[\\\/]common[\\\/]test_runner[\\\/].*",
36)
37
[email protected]06e6d0ff2012-12-11 01:36:4438# Fragment of a regular expression that matches C++ and Objective-C++
39# implementation files.
40_IMPLEMENTATION_EXTENSIONS = r'\.(cc|cpp|cxx|mm)$'
41
42# Regular expression that matches code only used for test binaries
43# (best effort).
44_TEST_CODE_EXCLUDED_PATHS = (
45 r'.*[/\\](fake_|test_|mock_).+%s' % _IMPLEMENTATION_EXTENSIONS,
46 r'.+_test_(base|support|util)%s' % _IMPLEMENTATION_EXTENSIONS,
[email protected]11e06082013-04-26 19:09:0347 r'.+_(api|browser|perf|pixel|unit|ui)?test(_[a-z]+)?%s' %
[email protected]e2d7e6f2013-04-23 12:57:1248 _IMPLEMENTATION_EXTENSIONS,
[email protected]06e6d0ff2012-12-11 01:36:4449 r'.+profile_sync_service_harness%s' % _IMPLEMENTATION_EXTENSIONS,
50 r'.*[/\\](test|tool(s)?)[/\\].*',
[email protected]ef070cc2013-05-03 11:53:0551 # content_shell is used for running layout tests.
52 r'content[/\\]shell[/\\].*',
[email protected]06e6d0ff2012-12-11 01:36:4453 # At request of folks maintaining this folder.
54 r'chrome[/\\]browser[/\\]automation[/\\].*',
[email protected]7b054982013-11-27 00:44:4755 # Non-production example code.
56 r'mojo[/\\]examples[/\\].*',
[email protected]06e6d0ff2012-12-11 01:36:4457)
[email protected]ca8d19842009-02-19 16:33:1258
[email protected]eea609a2011-11-18 13:10:1259_TEST_ONLY_WARNING = (
60 'You might be calling functions intended only for testing from\n'
61 'production code. It is OK to ignore this warning if you know what\n'
62 'you are doing, as the heuristics used to detect the situation are\n'
63 'not perfect. The commit queue will not block on this warning.\n'
64 'Email [email protected] if you have questions.')
65
66
[email protected]cf9b78f2012-11-14 11:40:2867_INCLUDE_ORDER_WARNING = (
68 'Your #include order seems to be broken. Send mail to\n'
69 '[email protected] if this is not the case.')
70
71
[email protected]127f18ec2012-06-16 05:05:5972_BANNED_OBJC_FUNCTIONS = (
73 (
74 'addTrackingRect:',
[email protected]23e6cbc2012-06-16 18:51:2075 (
76 'The use of -[NSView addTrackingRect:owner:userData:assumeInside:] is'
[email protected]127f18ec2012-06-16 05:05:5977 'prohibited. Please use CrTrackingArea instead.',
78 'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts',
79 ),
80 False,
81 ),
82 (
83 'NSTrackingArea',
[email protected]23e6cbc2012-06-16 18:51:2084 (
85 'The use of NSTrackingAreas is prohibited. Please use CrTrackingArea',
[email protected]127f18ec2012-06-16 05:05:5986 'instead.',
87 'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts',
88 ),
89 False,
90 ),
91 (
92 'convertPointFromBase:',
[email protected]23e6cbc2012-06-16 18:51:2093 (
94 'The use of -[NSView convertPointFromBase:] is almost certainly wrong.',
[email protected]127f18ec2012-06-16 05:05:5995 'Please use |convertPoint:(point) fromView:nil| instead.',
96 'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts',
97 ),
98 True,
99 ),
100 (
101 'convertPointToBase:',
[email protected]23e6cbc2012-06-16 18:51:20102 (
103 'The use of -[NSView convertPointToBase:] is almost certainly wrong.',
[email protected]127f18ec2012-06-16 05:05:59104 'Please use |convertPoint:(point) toView:nil| instead.',
105 'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts',
106 ),
107 True,
108 ),
109 (
110 'convertRectFromBase:',
[email protected]23e6cbc2012-06-16 18:51:20111 (
112 'The use of -[NSView convertRectFromBase:] is almost certainly wrong.',
[email protected]127f18ec2012-06-16 05:05:59113 'Please use |convertRect:(point) fromView:nil| instead.',
114 'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts',
115 ),
116 True,
117 ),
118 (
119 'convertRectToBase:',
[email protected]23e6cbc2012-06-16 18:51:20120 (
121 'The use of -[NSView convertRectToBase:] is almost certainly wrong.',
[email protected]127f18ec2012-06-16 05:05:59122 'Please use |convertRect:(point) toView:nil| instead.',
123 'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts',
124 ),
125 True,
126 ),
127 (
128 'convertSizeFromBase:',
[email protected]23e6cbc2012-06-16 18:51:20129 (
130 'The use of -[NSView convertSizeFromBase:] is almost certainly wrong.',
[email protected]127f18ec2012-06-16 05:05:59131 'Please use |convertSize:(point) fromView:nil| instead.',
132 'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts',
133 ),
134 True,
135 ),
136 (
137 'convertSizeToBase:',
[email protected]23e6cbc2012-06-16 18:51:20138 (
139 'The use of -[NSView convertSizeToBase:] is almost certainly wrong.',
[email protected]127f18ec2012-06-16 05:05:59140 'Please use |convertSize:(point) toView:nil| instead.',
141 'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts',
142 ),
143 True,
144 ),
145)
146
147
148_BANNED_CPP_FUNCTIONS = (
[email protected]23e6cbc2012-06-16 18:51:20149 # Make sure that gtest's FRIEND_TEST() macro is not used; the
150 # FRIEND_TEST_ALL_PREFIXES() macro from base/gtest_prod_util.h should be
[email protected]e00ccc92012-11-01 17:32:30151 # used instead since that allows for FLAKY_ and DISABLED_ prefixes.
[email protected]23e6cbc2012-06-16 18:51:20152 (
153 'FRIEND_TEST(',
154 (
[email protected]e3c945502012-06-26 20:01:49155 'Chromium code should not use gtest\'s FRIEND_TEST() macro. Include',
[email protected]23e6cbc2012-06-16 18:51:20156 'base/gtest_prod_util.h and use FRIEND_TEST_ALL_PREFIXES() instead.',
157 ),
158 False,
[email protected]7345da02012-11-27 14:31:49159 (),
[email protected]23e6cbc2012-06-16 18:51:20160 ),
161 (
162 'ScopedAllowIO',
163 (
[email protected]e3c945502012-06-26 20:01:49164 'New code should not use ScopedAllowIO. Post a task to the blocking',
165 'pool or the FILE thread instead.',
[email protected]23e6cbc2012-06-16 18:51:20166 ),
[email protected]e3c945502012-06-26 20:01:49167 True,
[email protected]7345da02012-11-27 14:31:49168 (
[email protected]0b818f72013-10-22 00:11:03169 r"^components[\\\/]breakpad[\\\/]app[\\\/]breakpad_mac\.mm$",
[email protected]de7d61ff2013-08-20 11:30:41170 r"^content[\\\/]shell[\\\/]browser[\\\/]shell_browser_main\.cc$",
171 r"^content[\\\/]shell[\\\/]browser[\\\/]shell_message_filter\.cc$",
[email protected]398ad132013-04-02 15:11:01172 r"^net[\\\/]disk_cache[\\\/]cache_util\.cc$",
[email protected]7345da02012-11-27 14:31:49173 ),
[email protected]23e6cbc2012-06-16 18:51:20174 ),
[email protected]52657f62013-05-20 05:30:31175 (
176 'SkRefPtr',
177 (
178 'The use of SkRefPtr is prohibited. ',
179 'Please use skia::RefPtr instead.'
180 ),
181 True,
182 (),
183 ),
184 (
185 'SkAutoRef',
186 (
187 'The indirect use of SkRefPtr via SkAutoRef is prohibited. ',
188 'Please use skia::RefPtr instead.'
189 ),
190 True,
191 (),
192 ),
193 (
194 'SkAutoTUnref',
195 (
196 'The use of SkAutoTUnref is dangerous because it implicitly ',
197 'converts to a raw pointer. Please use skia::RefPtr instead.'
198 ),
199 True,
200 (),
201 ),
202 (
203 'SkAutoUnref',
204 (
205 'The indirect use of SkAutoTUnref through SkAutoUnref is dangerous ',
206 'because it implicitly converts to a raw pointer. ',
207 'Please use skia::RefPtr instead.'
208 ),
209 True,
210 (),
211 ),
[email protected]d89eec82013-12-03 14:10:59212 (
213 r'/HANDLE_EINTR\(.*close',
214 (
215 'HANDLE_EINTR(close) is invalid. If close fails with EINTR, the file',
216 'descriptor will be closed, and it is incorrect to retry the close.',
217 'Either call close directly and ignore its return value, or wrap close',
218 'in IGNORE_EINTR to use its return value. See http://crbug.com/269623'
219 ),
220 True,
221 (),
222 ),
223 (
224 r'/IGNORE_EINTR\((?!.*close)',
225 (
226 'IGNORE_EINTR is only valid when wrapping close. To wrap other system',
227 'calls, use HANDLE_EINTR. See http://crbug.com/269623',
228 ),
229 True,
230 (
231 # Files that #define IGNORE_EINTR.
232 r'^base[\\\/]posix[\\\/]eintr_wrapper\.h$',
233 r'^ppapi[\\\/]tests[\\\/]test_broker\.cc$',
234 ),
235 ),
[email protected]127f18ec2012-06-16 05:05:59236)
237
238
[email protected]b00342e7f2013-03-26 16:21:54239_VALID_OS_MACROS = (
240 # Please keep sorted.
241 'OS_ANDROID',
242 'OS_BSD',
243 'OS_CAT', # For testing.
244 'OS_CHROMEOS',
245 'OS_FREEBSD',
246 'OS_IOS',
247 'OS_LINUX',
248 'OS_MACOSX',
249 'OS_NACL',
250 'OS_OPENBSD',
251 'OS_POSIX',
252 'OS_SOLARIS',
[email protected]b00342e7f2013-03-26 16:21:54253 'OS_WIN',
254)
255
256
[email protected]55459852011-08-10 15:17:19257def _CheckNoProductionCodeUsingTestOnlyFunctions(input_api, output_api):
258 """Attempts to prevent use of functions intended only for testing in
259 non-testing code. For now this is just a best-effort implementation
260 that ignores header files and may have some false positives. A
261 better implementation would probably need a proper C++ parser.
262 """
263 # We only scan .cc files and the like, as the declaration of
264 # for-testing functions in header files are hard to distinguish from
265 # calls to such functions without a proper C++ parser.
[email protected]06e6d0ff2012-12-11 01:36:44266 file_inclusion_pattern = r'.+%s' % _IMPLEMENTATION_EXTENSIONS
[email protected]55459852011-08-10 15:17:19267
268 base_function_pattern = r'ForTest(ing)?|for_test(ing)?'
269 inclusion_pattern = input_api.re.compile(r'(%s)\s*\(' % base_function_pattern)
[email protected]de4f7d22013-05-23 14:27:46270 comment_pattern = input_api.re.compile(r'//.*%s' % base_function_pattern)
[email protected]55459852011-08-10 15:17:19271 exclusion_pattern = input_api.re.compile(
272 r'::[A-Za-z0-9_]+(%s)|(%s)[^;]+\{' % (
273 base_function_pattern, base_function_pattern))
274
275 def FilterFile(affected_file):
[email protected]06e6d0ff2012-12-11 01:36:44276 black_list = (_EXCLUDED_PATHS +
277 _TEST_CODE_EXCLUDED_PATHS +
278 input_api.DEFAULT_BLACK_LIST)
[email protected]55459852011-08-10 15:17:19279 return input_api.FilterSourceFile(
280 affected_file,
281 white_list=(file_inclusion_pattern, ),
282 black_list=black_list)
283
284 problems = []
285 for f in input_api.AffectedSourceFiles(FilterFile):
286 local_path = f.LocalPath()
[email protected]2fdd1f362013-01-16 03:56:03287 lines = input_api.ReadFile(f).splitlines()
288 line_number = 0
289 for line in lines:
290 if (inclusion_pattern.search(line) and
[email protected]de4f7d22013-05-23 14:27:46291 not comment_pattern.search(line) and
[email protected]2fdd1f362013-01-16 03:56:03292 not exclusion_pattern.search(line)):
[email protected]55459852011-08-10 15:17:19293 problems.append(
[email protected]2fdd1f362013-01-16 03:56:03294 '%s:%d\n %s' % (local_path, line_number, line.strip()))
295 line_number += 1
[email protected]55459852011-08-10 15:17:19296
297 if problems:
[email protected]f7051d52013-04-02 18:31:42298 return [output_api.PresubmitPromptOrNotify(_TEST_ONLY_WARNING, problems)]
[email protected]2fdd1f362013-01-16 03:56:03299 else:
300 return []
[email protected]55459852011-08-10 15:17:19301
302
[email protected]10689ca2011-09-02 02:31:54303def _CheckNoIOStreamInHeaders(input_api, output_api):
304 """Checks to make sure no .h files include <iostream>."""
305 files = []
306 pattern = input_api.re.compile(r'^#include\s*<iostream>',
307 input_api.re.MULTILINE)
308 for f in input_api.AffectedSourceFiles(input_api.FilterSourceFile):
309 if not f.LocalPath().endswith('.h'):
310 continue
311 contents = input_api.ReadFile(f)
312 if pattern.search(contents):
313 files.append(f)
314
315 if len(files):
316 return [ output_api.PresubmitError(
[email protected]6c063c62012-07-11 19:11:06317 'Do not #include <iostream> in header files, since it inserts static '
318 'initialization into every file including the header. Instead, '
[email protected]10689ca2011-09-02 02:31:54319 '#include <ostream>. See http://crbug.com/94794',
320 files) ]
321 return []
322
323
[email protected]72df4e782012-06-21 16:28:18324def _CheckNoUNIT_TESTInSourceFiles(input_api, output_api):
325 """Checks to make sure no source files use UNIT_TEST"""
326 problems = []
327 for f in input_api.AffectedFiles():
328 if (not f.LocalPath().endswith(('.cc', '.mm'))):
329 continue
330
331 for line_num, line in f.ChangedContents():
[email protected]549f86a2013-11-19 13:00:04332 if 'UNIT_TEST ' in line or line.endswith('UNIT_TEST'):
[email protected]72df4e782012-06-21 16:28:18333 problems.append(' %s:%d' % (f.LocalPath(), line_num))
334
335 if not problems:
336 return []
337 return [output_api.PresubmitPromptWarning('UNIT_TEST is only for headers.\n' +
338 '\n'.join(problems))]
339
340
[email protected]8ea5d4b2011-09-13 21:49:22341def _CheckNoNewWStrings(input_api, output_api):
342 """Checks to make sure we don't introduce use of wstrings."""
[email protected]55463aa62011-10-12 00:48:27343 problems = []
[email protected]8ea5d4b2011-09-13 21:49:22344 for f in input_api.AffectedFiles():
[email protected]b5c24292011-11-28 14:38:20345 if (not f.LocalPath().endswith(('.cc', '.h')) or
[email protected]24be83c2013-08-29 23:01:23346 f.LocalPath().endswith(('test.cc', '_win.cc', '_win.h'))):
[email protected]b5c24292011-11-28 14:38:20347 continue
[email protected]8ea5d4b2011-09-13 21:49:22348
[email protected]a11dbe9b2012-08-07 01:32:58349 allowWString = False
[email protected]b5c24292011-11-28 14:38:20350 for line_num, line in f.ChangedContents():
[email protected]a11dbe9b2012-08-07 01:32:58351 if 'presubmit: allow wstring' in line:
352 allowWString = True
353 elif not allowWString and 'wstring' in line:
[email protected]55463aa62011-10-12 00:48:27354 problems.append(' %s:%d' % (f.LocalPath(), line_num))
[email protected]a11dbe9b2012-08-07 01:32:58355 allowWString = False
356 else:
357 allowWString = False
[email protected]8ea5d4b2011-09-13 21:49:22358
[email protected]55463aa62011-10-12 00:48:27359 if not problems:
360 return []
361 return [output_api.PresubmitPromptWarning('New code should not use wstrings.'
[email protected]a11dbe9b2012-08-07 01:32:58362 ' If you are calling a cross-platform API that accepts a wstring, '
363 'fix the API.\n' +
[email protected]55463aa62011-10-12 00:48:27364 '\n'.join(problems))]
[email protected]8ea5d4b2011-09-13 21:49:22365
366
[email protected]2a8ac9c2011-10-19 17:20:44367def _CheckNoDEPSGIT(input_api, output_api):
368 """Make sure .DEPS.git is never modified manually."""
369 if any(f.LocalPath().endswith('.DEPS.git') for f in
370 input_api.AffectedFiles()):
371 return [output_api.PresubmitError(
372 'Never commit changes to .DEPS.git. This file is maintained by an\n'
373 'automated system based on what\'s in DEPS and your changes will be\n'
374 'overwritten.\n'
375 'See http://code.google.com/p/chromium/wiki/UsingNewGit#Rolling_DEPS\n'
376 'for more information')]
377 return []
378
379
[email protected]127f18ec2012-06-16 05:05:59380def _CheckNoBannedFunctions(input_api, output_api):
381 """Make sure that banned functions are not used."""
382 warnings = []
383 errors = []
384
385 file_filter = lambda f: f.LocalPath().endswith(('.mm', '.m', '.h'))
386 for f in input_api.AffectedFiles(file_filter=file_filter):
387 for line_num, line in f.ChangedContents():
388 for func_name, message, error in _BANNED_OBJC_FUNCTIONS:
389 if func_name in line:
390 problems = warnings;
391 if error:
392 problems = errors;
393 problems.append(' %s:%d:' % (f.LocalPath(), line_num))
394 for message_line in message:
395 problems.append(' %s' % message_line)
396
397 file_filter = lambda f: f.LocalPath().endswith(('.cc', '.mm', '.h'))
398 for f in input_api.AffectedFiles(file_filter=file_filter):
399 for line_num, line in f.ChangedContents():
[email protected]7345da02012-11-27 14:31:49400 for func_name, message, error, excluded_paths in _BANNED_CPP_FUNCTIONS:
401 def IsBlacklisted(affected_file, blacklist):
402 local_path = affected_file.LocalPath()
403 for item in blacklist:
404 if input_api.re.match(item, local_path):
405 return True
406 return False
407 if IsBlacklisted(f, excluded_paths):
408 continue
[email protected]d89eec82013-12-03 14:10:59409 matched = False
410 if func_name[0:1] == '/':
411 regex = func_name[1:]
412 if input_api.re.search(regex, line):
413 matched = True
414 elif func_name in line:
415 matched = True
416 if matched:
[email protected]127f18ec2012-06-16 05:05:59417 problems = warnings;
418 if error:
419 problems = errors;
420 problems.append(' %s:%d:' % (f.LocalPath(), line_num))
421 for message_line in message:
422 problems.append(' %s' % message_line)
423
424 result = []
425 if (warnings):
426 result.append(output_api.PresubmitPromptWarning(
427 'Banned functions were used.\n' + '\n'.join(warnings)))
428 if (errors):
429 result.append(output_api.PresubmitError(
430 'Banned functions were used.\n' + '\n'.join(errors)))
431 return result
432
433
[email protected]6c063c62012-07-11 19:11:06434def _CheckNoPragmaOnce(input_api, output_api):
435 """Make sure that banned functions are not used."""
436 files = []
437 pattern = input_api.re.compile(r'^#pragma\s+once',
438 input_api.re.MULTILINE)
439 for f in input_api.AffectedSourceFiles(input_api.FilterSourceFile):
440 if not f.LocalPath().endswith('.h'):
441 continue
442 contents = input_api.ReadFile(f)
443 if pattern.search(contents):
444 files.append(f)
445
446 if files:
447 return [output_api.PresubmitError(
448 'Do not use #pragma once in header files.\n'
449 'See http://www.chromium.org/developers/coding-style#TOC-File-headers',
450 files)]
451 return []
452
[email protected]127f18ec2012-06-16 05:05:59453
[email protected]e7479052012-09-19 00:26:12454def _CheckNoTrinaryTrueFalse(input_api, output_api):
455 """Checks to make sure we don't introduce use of foo ? true : false."""
456 problems = []
457 pattern = input_api.re.compile(r'\?\s*(true|false)\s*:\s*(true|false)')
458 for f in input_api.AffectedFiles():
459 if not f.LocalPath().endswith(('.cc', '.h', '.inl', '.m', '.mm')):
460 continue
461
462 for line_num, line in f.ChangedContents():
463 if pattern.match(line):
464 problems.append(' %s:%d' % (f.LocalPath(), line_num))
465
466 if not problems:
467 return []
468 return [output_api.PresubmitPromptWarning(
469 'Please consider avoiding the "? true : false" pattern if possible.\n' +
470 '\n'.join(problems))]
471
472
[email protected]55f9f382012-07-31 11:02:18473def _CheckUnwantedDependencies(input_api, output_api):
474 """Runs checkdeps on #include statements added in this
475 change. Breaking - rules is an error, breaking ! rules is a
476 warning.
477 """
478 # We need to wait until we have an input_api object and use this
479 # roundabout construct to import checkdeps because this file is
480 # eval-ed and thus doesn't have __file__.
481 original_sys_path = sys.path
482 try:
483 sys.path = sys.path + [input_api.os_path.join(
484 input_api.PresubmitLocalPath(), 'tools', 'checkdeps')]
485 import checkdeps
486 from cpp_checker import CppChecker
487 from rules import Rule
488 finally:
489 # Restore sys.path to what it was before.
490 sys.path = original_sys_path
491
492 added_includes = []
493 for f in input_api.AffectedFiles():
494 if not CppChecker.IsCppFile(f.LocalPath()):
495 continue
496
497 changed_lines = [line for line_num, line in f.ChangedContents()]
498 added_includes.append([f.LocalPath(), changed_lines])
499
[email protected]26385172013-05-09 23:11:35500 deps_checker = checkdeps.DepsChecker(input_api.PresubmitLocalPath())
[email protected]55f9f382012-07-31 11:02:18501
502 error_descriptions = []
503 warning_descriptions = []
504 for path, rule_type, rule_description in deps_checker.CheckAddedCppIncludes(
505 added_includes):
506 description_with_path = '%s\n %s' % (path, rule_description)
507 if rule_type == Rule.DISALLOW:
508 error_descriptions.append(description_with_path)
509 else:
510 warning_descriptions.append(description_with_path)
511
512 results = []
513 if error_descriptions:
514 results.append(output_api.PresubmitError(
515 'You added one or more #includes that violate checkdeps rules.',
516 error_descriptions))
517 if warning_descriptions:
[email protected]f7051d52013-04-02 18:31:42518 results.append(output_api.PresubmitPromptOrNotify(
[email protected]55f9f382012-07-31 11:02:18519 'You added one or more #includes of files that are temporarily\n'
520 'allowed but being removed. Can you avoid introducing the\n'
521 '#include? See relevant DEPS file(s) for details and contacts.',
522 warning_descriptions))
523 return results
524
525
[email protected]fbcafe5a2012-08-08 15:31:22526def _CheckFilePermissions(input_api, output_api):
527 """Check that all files have their permissions properly set."""
528 args = [sys.executable, 'tools/checkperms/checkperms.py', '--root',
529 input_api.change.RepositoryRoot()]
530 for f in input_api.AffectedFiles():
531 args += ['--file', f.LocalPath()]
532 errors = []
533 (errors, stderrdata) = subprocess.Popen(args).communicate()
534
535 results = []
536 if errors:
[email protected]c8278b32012-10-30 20:35:49537 results.append(output_api.PresubmitError('checkperms.py failed.',
[email protected]fbcafe5a2012-08-08 15:31:22538 errors))
539 return results
540
541
[email protected]c8278b32012-10-30 20:35:49542def _CheckNoAuraWindowPropertyHInHeaders(input_api, output_api):
543 """Makes sure we don't include ui/aura/window_property.h
544 in header files.
545 """
546 pattern = input_api.re.compile(r'^#include\s*"ui/aura/window_property.h"')
547 errors = []
548 for f in input_api.AffectedFiles():
549 if not f.LocalPath().endswith('.h'):
550 continue
551 for line_num, line in f.ChangedContents():
552 if pattern.match(line):
553 errors.append(' %s:%d' % (f.LocalPath(), line_num))
554
555 results = []
556 if errors:
557 results.append(output_api.PresubmitError(
558 'Header files should not include ui/aura/window_property.h', errors))
559 return results
560
561
[email protected]cf9b78f2012-11-14 11:40:28562def _CheckIncludeOrderForScope(scope, input_api, file_path, changed_linenums):
563 """Checks that the lines in scope occur in the right order.
564
565 1. C system files in alphabetical order
566 2. C++ system files in alphabetical order
567 3. Project's .h files
568 """
569
570 c_system_include_pattern = input_api.re.compile(r'\s*#include <.*\.h>')
571 cpp_system_include_pattern = input_api.re.compile(r'\s*#include <.*>')
572 custom_include_pattern = input_api.re.compile(r'\s*#include ".*')
573
574 C_SYSTEM_INCLUDES, CPP_SYSTEM_INCLUDES, CUSTOM_INCLUDES = range(3)
575
576 state = C_SYSTEM_INCLUDES
577
578 previous_line = ''
[email protected]728b9bb2012-11-14 20:38:57579 previous_line_num = 0
[email protected]cf9b78f2012-11-14 11:40:28580 problem_linenums = []
581 for line_num, line in scope:
582 if c_system_include_pattern.match(line):
583 if state != C_SYSTEM_INCLUDES:
[email protected]728b9bb2012-11-14 20:38:57584 problem_linenums.append((line_num, previous_line_num))
[email protected]cf9b78f2012-11-14 11:40:28585 elif previous_line and previous_line > line:
[email protected]728b9bb2012-11-14 20:38:57586 problem_linenums.append((line_num, previous_line_num))
[email protected]cf9b78f2012-11-14 11:40:28587 elif cpp_system_include_pattern.match(line):
588 if state == C_SYSTEM_INCLUDES:
589 state = CPP_SYSTEM_INCLUDES
590 elif state == CUSTOM_INCLUDES:
[email protected]728b9bb2012-11-14 20:38:57591 problem_linenums.append((line_num, previous_line_num))
[email protected]cf9b78f2012-11-14 11:40:28592 elif previous_line and previous_line > line:
[email protected]728b9bb2012-11-14 20:38:57593 problem_linenums.append((line_num, previous_line_num))
[email protected]cf9b78f2012-11-14 11:40:28594 elif custom_include_pattern.match(line):
595 if state != CUSTOM_INCLUDES:
596 state = CUSTOM_INCLUDES
597 elif previous_line and previous_line > line:
[email protected]728b9bb2012-11-14 20:38:57598 problem_linenums.append((line_num, previous_line_num))
[email protected]cf9b78f2012-11-14 11:40:28599 else:
600 problem_linenums.append(line_num)
601 previous_line = line
[email protected]728b9bb2012-11-14 20:38:57602 previous_line_num = line_num
[email protected]cf9b78f2012-11-14 11:40:28603
604 warnings = []
[email protected]728b9bb2012-11-14 20:38:57605 for (line_num, previous_line_num) in problem_linenums:
606 if line_num in changed_linenums or previous_line_num in changed_linenums:
[email protected]cf9b78f2012-11-14 11:40:28607 warnings.append(' %s:%d' % (file_path, line_num))
608 return warnings
609
610
[email protected]ac294a12012-12-06 16:38:43611def _CheckIncludeOrderInFile(input_api, f, changed_linenums):
[email protected]cf9b78f2012-11-14 11:40:28612 """Checks the #include order for the given file f."""
613
[email protected]2299dcf2012-11-15 19:56:24614 system_include_pattern = input_api.re.compile(r'\s*#include \<.*')
[email protected]23093b62013-09-20 12:16:30615 # Exclude the following includes from the check:
616 # 1) #include <.../...>, e.g., <sys/...> includes often need to appear in a
617 # specific order.
618 # 2) <atlbase.h>, "build/build_config.h"
619 excluded_include_pattern = input_api.re.compile(
620 r'\s*#include (\<.*/.*|\<atlbase\.h\>|"build/build_config.h")')
[email protected]2299dcf2012-11-15 19:56:24621 custom_include_pattern = input_api.re.compile(r'\s*#include "(?P<FILE>.*)"')
[email protected]3e83618c2013-10-09 22:32:33622 # Match the final or penultimate token if it is xxxtest so we can ignore it
623 # when considering the special first include.
624 test_file_tag_pattern = input_api.re.compile(
625 r'_[a-z]+test(?=(_[a-zA-Z0-9]+)?\.)')
[email protected]0e5c1852012-12-18 20:17:11626 if_pattern = input_api.re.compile(
627 r'\s*#\s*(if|elif|else|endif|define|undef).*')
628 # Some files need specialized order of includes; exclude such files from this
629 # check.
630 uncheckable_includes_pattern = input_api.re.compile(
631 r'\s*#include '
632 '("ipc/.*macros\.h"|<windows\.h>|".*gl.*autogen.h")\s*')
[email protected]cf9b78f2012-11-14 11:40:28633
634 contents = f.NewContents()
635 warnings = []
636 line_num = 0
637
[email protected]ac294a12012-12-06 16:38:43638 # Handle the special first include. If the first include file is
639 # some/path/file.h, the corresponding including file can be some/path/file.cc,
640 # some/other/path/file.cc, some/path/file_platform.cc, some/path/file-suffix.h
641 # etc. It's also possible that no special first include exists.
[email protected]3e83618c2013-10-09 22:32:33642 # If the included file is some/path/file_platform.h the including file could
643 # also be some/path/file_xxxtest_platform.h.
644 including_file_base_name = test_file_tag_pattern.sub(
645 '', input_api.os_path.basename(f.LocalPath()))
646
[email protected]ac294a12012-12-06 16:38:43647 for line in contents:
648 line_num += 1
649 if system_include_pattern.match(line):
650 # No special first include -> process the line again along with normal
651 # includes.
652 line_num -= 1
653 break
654 match = custom_include_pattern.match(line)
655 if match:
656 match_dict = match.groupdict()
[email protected]3e83618c2013-10-09 22:32:33657 header_basename = test_file_tag_pattern.sub(
658 '', input_api.os_path.basename(match_dict['FILE'])).replace('.h', '')
659
660 if header_basename not in including_file_base_name:
[email protected]2299dcf2012-11-15 19:56:24661 # No special first include -> process the line again along with normal
662 # includes.
663 line_num -= 1
[email protected]ac294a12012-12-06 16:38:43664 break
[email protected]cf9b78f2012-11-14 11:40:28665
666 # Split into scopes: Each region between #if and #endif is its own scope.
667 scopes = []
668 current_scope = []
669 for line in contents[line_num:]:
670 line_num += 1
[email protected]0e5c1852012-12-18 20:17:11671 if uncheckable_includes_pattern.match(line):
672 return []
[email protected]2309b0fa02012-11-16 12:18:27673 if if_pattern.match(line):
[email protected]cf9b78f2012-11-14 11:40:28674 scopes.append(current_scope)
675 current_scope = []
[email protected]962f117e2012-11-22 18:11:56676 elif ((system_include_pattern.match(line) or
677 custom_include_pattern.match(line)) and
678 not excluded_include_pattern.match(line)):
[email protected]cf9b78f2012-11-14 11:40:28679 current_scope.append((line_num, line))
680 scopes.append(current_scope)
681
682 for scope in scopes:
683 warnings.extend(_CheckIncludeOrderForScope(scope, input_api, f.LocalPath(),
684 changed_linenums))
685 return warnings
686
687
688def _CheckIncludeOrder(input_api, output_api):
689 """Checks that the #include order is correct.
690
691 1. The corresponding header for source files.
692 2. C system files in alphabetical order
693 3. C++ system files in alphabetical order
694 4. Project's .h files in alphabetical order
695
[email protected]ac294a12012-12-06 16:38:43696 Each region separated by #if, #elif, #else, #endif, #define and #undef follows
697 these rules separately.
[email protected]cf9b78f2012-11-14 11:40:28698 """
699
700 warnings = []
701 for f in input_api.AffectedFiles():
[email protected]ac294a12012-12-06 16:38:43702 if f.LocalPath().endswith(('.cc', '.h')):
703 changed_linenums = set(line_num for line_num, _ in f.ChangedContents())
704 warnings.extend(_CheckIncludeOrderInFile(input_api, f, changed_linenums))
[email protected]cf9b78f2012-11-14 11:40:28705
706 results = []
707 if warnings:
[email protected]f7051d52013-04-02 18:31:42708 results.append(output_api.PresubmitPromptOrNotify(_INCLUDE_ORDER_WARNING,
[email protected]120cf540d2012-12-10 17:55:53709 warnings))
[email protected]cf9b78f2012-11-14 11:40:28710 return results
711
712
[email protected]70ca77752012-11-20 03:45:03713def _CheckForVersionControlConflictsInFile(input_api, f):
714 pattern = input_api.re.compile('^(?:<<<<<<<|>>>>>>>) |^=======$')
715 errors = []
716 for line_num, line in f.ChangedContents():
717 if pattern.match(line):
718 errors.append(' %s:%d %s' % (f.LocalPath(), line_num, line))
719 return errors
720
721
722def _CheckForVersionControlConflicts(input_api, output_api):
723 """Usually this is not intentional and will cause a compile failure."""
724 errors = []
725 for f in input_api.AffectedFiles():
726 errors.extend(_CheckForVersionControlConflictsInFile(input_api, f))
727
728 results = []
729 if errors:
730 results.append(output_api.PresubmitError(
731 'Version control conflict markers found, please resolve.', errors))
732 return results
733
734
[email protected]06e6d0ff2012-12-11 01:36:44735def _CheckHardcodedGoogleHostsInLowerLayers(input_api, output_api):
736 def FilterFile(affected_file):
737 """Filter function for use with input_api.AffectedSourceFiles,
738 below. This filters out everything except non-test files from
739 top-level directories that generally speaking should not hard-code
740 service URLs (e.g. src/android_webview/, src/content/ and others).
741 """
742 return input_api.FilterSourceFile(
743 affected_file,
[email protected]78bb39d62012-12-11 15:11:56744 white_list=(r'^(android_webview|base|content|net)[\\\/].*', ),
[email protected]06e6d0ff2012-12-11 01:36:44745 black_list=(_EXCLUDED_PATHS +
746 _TEST_CODE_EXCLUDED_PATHS +
747 input_api.DEFAULT_BLACK_LIST))
748
[email protected]de4f7d22013-05-23 14:27:46749 base_pattern = '"[^"]*google\.com[^"]*"'
750 comment_pattern = input_api.re.compile('//.*%s' % base_pattern)
751 pattern = input_api.re.compile(base_pattern)
[email protected]06e6d0ff2012-12-11 01:36:44752 problems = [] # items are (filename, line_number, line)
753 for f in input_api.AffectedSourceFiles(FilterFile):
754 for line_num, line in f.ChangedContents():
[email protected]de4f7d22013-05-23 14:27:46755 if not comment_pattern.search(line) and pattern.search(line):
[email protected]06e6d0ff2012-12-11 01:36:44756 problems.append((f.LocalPath(), line_num, line))
757
758 if problems:
[email protected]f7051d52013-04-02 18:31:42759 return [output_api.PresubmitPromptOrNotify(
[email protected]06e6d0ff2012-12-11 01:36:44760 'Most layers below src/chrome/ should not hardcode service URLs.\n'
761 'Are you sure this is correct? (Contact: [email protected])',
762 [' %s:%d: %s' % (
763 problem[0], problem[1], problem[2]) for problem in problems])]
[email protected]2fdd1f362013-01-16 03:56:03764 else:
765 return []
[email protected]06e6d0ff2012-12-11 01:36:44766
767
[email protected]d2530012013-01-25 16:39:27768def _CheckNoAbbreviationInPngFileName(input_api, output_api):
769 """Makes sure there are no abbreviations in the name of PNG files.
770 """
[email protected]4053a48e2013-01-25 21:43:04771 pattern = input_api.re.compile(r'.*_[a-z]_.*\.png$|.*_[a-z]\.png$')
[email protected]d2530012013-01-25 16:39:27772 errors = []
773 for f in input_api.AffectedFiles(include_deletes=False):
774 if pattern.match(f.LocalPath()):
775 errors.append(' %s' % f.LocalPath())
776
777 results = []
778 if errors:
779 results.append(output_api.PresubmitError(
780 'The name of PNG files should not have abbreviations. \n'
781 'Use _hover.png, _center.png, instead of _h.png, _c.png.\n'
782 'Contact [email protected] if you have questions.', errors))
783 return results
784
785
[email protected]f32e2d1e2013-07-26 21:39:08786def _DepsFilesToCheck(re, changed_lines):
787 """Helper method for _CheckAddedDepsHaveTargetApprovals. Returns
788 a set of DEPS entries that we should look up."""
[email protected]2b438d62013-11-14 17:54:14789 # We ignore deps entries on auto-generated directories.
790 AUTO_GENERATED_DIRS = ['grit', 'jni']
[email protected]f32e2d1e2013-07-26 21:39:08791
792 # This pattern grabs the path without basename in the first
793 # parentheses, and the basename (if present) in the second. It
794 # relies on the simple heuristic that if there is a basename it will
795 # be a header file ending in ".h".
796 pattern = re.compile(
797 r"""['"]\+([^'"]+?)(/[a-zA-Z0-9_]+\.h)?['"].*""")
[email protected]2b438d62013-11-14 17:54:14798 results = set()
[email protected]f32e2d1e2013-07-26 21:39:08799 for changed_line in changed_lines:
800 m = pattern.match(changed_line)
801 if m:
802 path = m.group(1)
[email protected]2b438d62013-11-14 17:54:14803 if path.split('/')[0] not in AUTO_GENERATED_DIRS:
[email protected]f32e2d1e2013-07-26 21:39:08804 results.add('%s/DEPS' % m.group(1))
805 return results
806
807
[email protected]e871964c2013-05-13 14:14:55808def _CheckAddedDepsHaveTargetApprovals(input_api, output_api):
809 """When a dependency prefixed with + is added to a DEPS file, we
810 want to make sure that the change is reviewed by an OWNER of the
811 target file or directory, to avoid layering violations from being
812 introduced. This check verifies that this happens.
813 """
814 changed_lines = set()
815 for f in input_api.AffectedFiles():
816 filename = input_api.os_path.basename(f.LocalPath())
817 if filename == 'DEPS':
818 changed_lines |= set(line.strip()
819 for line_num, line
820 in f.ChangedContents())
821 if not changed_lines:
822 return []
823
[email protected]f32e2d1e2013-07-26 21:39:08824 virtual_depended_on_files = _DepsFilesToCheck(input_api.re, changed_lines)
[email protected]e871964c2013-05-13 14:14:55825 if not virtual_depended_on_files:
826 return []
827
828 if input_api.is_committing:
829 if input_api.tbr:
830 return [output_api.PresubmitNotifyResult(
831 '--tbr was specified, skipping OWNERS check for DEPS additions')]
832 if not input_api.change.issue:
833 return [output_api.PresubmitError(
834 "DEPS approval by OWNERS check failed: this change has "
835 "no Rietveld issue number, so we can't check it for approvals.")]
836 output = output_api.PresubmitError
837 else:
838 output = output_api.PresubmitNotifyResult
839
840 owners_db = input_api.owners_db
841 owner_email, reviewers = input_api.canned_checks._RietveldOwnerAndReviewers(
842 input_api,
843 owners_db.email_regexp,
844 approval_needed=input_api.is_committing)
845
846 owner_email = owner_email or input_api.change.author_email
847
[email protected]de4f7d22013-05-23 14:27:46848 reviewers_plus_owner = set(reviewers)
[email protected]e71c6082013-05-22 02:28:51849 if owner_email:
[email protected]de4f7d22013-05-23 14:27:46850 reviewers_plus_owner.add(owner_email)
[email protected]e871964c2013-05-13 14:14:55851 missing_files = owners_db.files_not_covered_by(virtual_depended_on_files,
852 reviewers_plus_owner)
853 unapproved_dependencies = ["'+%s'," % path[:-len('/DEPS')]
854 for path in missing_files]
855
856 if unapproved_dependencies:
857 output_list = [
858 output('Missing LGTM from OWNERS of directories added to DEPS:\n %s' %
859 '\n '.join(sorted(unapproved_dependencies)))]
860 if not input_api.is_committing:
861 suggested_owners = owners_db.reviewers_for(missing_files, owner_email)
862 output_list.append(output(
863 'Suggested missing target path OWNERS:\n %s' %
864 '\n '.join(suggested_owners or [])))
865 return output_list
866
867 return []
868
869
[email protected]85218562013-11-22 07:41:40870def _CheckSpamLogging(input_api, output_api):
871 file_inclusion_pattern = r'.+%s' % _IMPLEMENTATION_EXTENSIONS
872 black_list = (_EXCLUDED_PATHS +
873 _TEST_CODE_EXCLUDED_PATHS +
874 input_api.DEFAULT_BLACK_LIST +
[email protected]6f742dd02013-11-26 23:19:50875 (r"^base[\\\/]logging\.h$",
[email protected]8dc338c2013-12-09 16:28:48876 r"^chrome[\\\/]app[\\\/]chrome_main_delegate\.cc$",
[email protected]6e268db2013-12-04 01:41:46877 r"^chrome[\\\/]browser[\\\/]chrome_browser_main\.cc$",
[email protected]4de75262013-12-18 23:16:12878 r"^chrome[\\\/]browser[\\\/]ui[\\\/]startup[\\\/]"
879 r"startup_browser_creator\.cc$",
[email protected]fe0e6e12013-12-04 05:52:58880 r"^chrome[\\\/]installer[\\\/]setup[\\\/].*",
[email protected]95c6b3012013-12-02 14:30:31881 r"^chrome[\\\/]renderer[\\\/]extensions[\\\/]"
[email protected]6e268db2013-12-04 01:41:46882 r"logging_native_handler\.cc$",
[email protected]cdbdced2013-11-27 21:35:50883 r"^remoting[\\\/]base[\\\/]logging\.h$",
[email protected]67c96ab2013-12-17 02:05:36884 r"^remoting[\\\/]host[\\\/].*",
[email protected]8232f8fd2013-12-14 00:52:31885 r"^sandbox[\\\/]linux[\\\/].*",
886 r"^ui[\\\/]aura[\\\/]bench[\\\/]bench_main\.cc$",))
[email protected]85218562013-11-22 07:41:40887 source_file_filter = lambda x: input_api.FilterSourceFile(
888 x, white_list=(file_inclusion_pattern,), black_list=black_list)
889
890 log_info = []
891 printf = []
892
893 for f in input_api.AffectedSourceFiles(source_file_filter):
894 contents = input_api.ReadFile(f, 'rb')
895 if re.search(r"\bD?LOG\s*\(\s*INFO\s*\)", contents):
896 log_info.append(f.LocalPath())
[email protected]18b466b2013-12-02 22:01:37897 elif re.search(r"\bD?LOG_IF\s*\(\s*INFO\s*,", contents):
[email protected]85210652013-11-28 05:50:13898 log_info.append(f.LocalPath())
[email protected]18b466b2013-12-02 22:01:37899
900 if re.search(r"\bprintf\(", contents):
901 printf.append(f.LocalPath())
902 elif re.search(r"\bfprintf\((stdout|stderr)", contents):
[email protected]85218562013-11-22 07:41:40903 printf.append(f.LocalPath())
904
905 if log_info:
906 return [output_api.PresubmitError(
907 'These files spam the console log with LOG(INFO):',
908 items=log_info)]
909 if printf:
910 return [output_api.PresubmitError(
911 'These files spam the console log with printf/fprintf:',
912 items=printf)]
913 return []
914
915
[email protected]49aa76a2013-12-04 06:59:16916def _CheckForAnonymousVariables(input_api, output_api):
917 """These types are all expected to hold locks while in scope and
918 so should never be anonymous (which causes them to be immediately
919 destroyed)."""
920 they_who_must_be_named = [
921 'base::AutoLock',
922 'base::AutoReset',
923 'base::AutoUnlock',
924 'SkAutoAlphaRestore',
925 'SkAutoBitmapShaderInstall',
926 'SkAutoBlitterChoose',
927 'SkAutoBounderCommit',
928 'SkAutoCallProc',
929 'SkAutoCanvasRestore',
930 'SkAutoCommentBlock',
931 'SkAutoDescriptor',
932 'SkAutoDisableDirectionCheck',
933 'SkAutoDisableOvalCheck',
934 'SkAutoFree',
935 'SkAutoGlyphCache',
936 'SkAutoHDC',
937 'SkAutoLockColors',
938 'SkAutoLockPixels',
939 'SkAutoMalloc',
940 'SkAutoMaskFreeImage',
941 'SkAutoMutexAcquire',
942 'SkAutoPathBoundsUpdate',
943 'SkAutoPDFRelease',
944 'SkAutoRasterClipValidate',
945 'SkAutoRef',
946 'SkAutoTime',
947 'SkAutoTrace',
948 'SkAutoUnref',
949 ]
950 anonymous = r'(%s)\s*[({]' % '|'.join(they_who_must_be_named)
951 # bad: base::AutoLock(lock.get());
952 # not bad: base::AutoLock lock(lock.get());
953 bad_pattern = input_api.re.compile(anonymous)
954 # good: new base::AutoLock(lock.get())
955 good_pattern = input_api.re.compile(r'\bnew\s*' + anonymous)
956 errors = []
957
958 for f in input_api.AffectedFiles():
959 if not f.LocalPath().endswith(('.cc', '.h', '.inl', '.m', '.mm')):
960 continue
961 for linenum, line in f.ChangedContents():
962 if bad_pattern.search(line) and not good_pattern.search(line):
963 errors.append('%s:%d' % (f.LocalPath(), linenum))
964
965 if errors:
966 return [output_api.PresubmitError(
967 'These lines create anonymous variables that need to be named:',
968 items=errors)]
969 return []
970
971
[email protected]5fe0f8742013-11-29 01:04:59972def _CheckCygwinShell(input_api, output_api):
973 source_file_filter = lambda x: input_api.FilterSourceFile(
974 x, white_list=(r'.+\.(gyp|gypi)$',))
975 cygwin_shell = []
976
977 for f in input_api.AffectedSourceFiles(source_file_filter):
978 for linenum, line in f.ChangedContents():
979 if 'msvs_cygwin_shell' in line:
980 cygwin_shell.append(f.LocalPath())
981 break
982
983 if cygwin_shell:
984 return [output_api.PresubmitError(
985 'These files should not use msvs_cygwin_shell (the default is 0):',
986 items=cygwin_shell)]
987 return []
988
[email protected]85218562013-11-22 07:41:40989
[email protected]760deea2013-12-10 19:33:49990def _CheckJavaStyle(input_api, output_api):
991 """Runs checkstyle on changed java files and returns errors if any exist."""
992 original_sys_path = sys.path
993 try:
994 sys.path = sys.path + [input_api.os_path.join(
995 input_api.PresubmitLocalPath(), 'tools', 'android', 'checkstyle')]
996 import checkstyle
997 finally:
998 # Restore sys.path to what it was before.
999 sys.path = original_sys_path
1000
1001 return checkstyle.RunCheckstyle(
1002 input_api, output_api, 'tools/android/checkstyle/chromium-style-5.0.xml')
1003
1004
[email protected]22c9bd72011-03-27 16:47:391005def _CommonChecks(input_api, output_api):
1006 """Checks common to both upload and commit."""
1007 results = []
1008 results.extend(input_api.canned_checks.PanProjectChecks(
[email protected]3de922f2013-12-20 13:27:381009 input_api, output_api,
1010 excluded_paths=_EXCLUDED_PATHS + _TESTRUNNER_PATHS))
[email protected]66daa702011-05-28 14:41:461011 results.extend(_CheckAuthorizedAuthor(input_api, output_api))
[email protected]55459852011-08-10 15:17:191012 results.extend(
[email protected]760deea2013-12-10 19:33:491013 _CheckNoProductionCodeUsingTestOnlyFunctions(input_api, output_api))
[email protected]10689ca2011-09-02 02:31:541014 results.extend(_CheckNoIOStreamInHeaders(input_api, output_api))
[email protected]72df4e782012-06-21 16:28:181015 results.extend(_CheckNoUNIT_TESTInSourceFiles(input_api, output_api))
[email protected]8ea5d4b2011-09-13 21:49:221016 results.extend(_CheckNoNewWStrings(input_api, output_api))
[email protected]2a8ac9c2011-10-19 17:20:441017 results.extend(_CheckNoDEPSGIT(input_api, output_api))
[email protected]127f18ec2012-06-16 05:05:591018 results.extend(_CheckNoBannedFunctions(input_api, output_api))
[email protected]6c063c62012-07-11 19:11:061019 results.extend(_CheckNoPragmaOnce(input_api, output_api))
[email protected]e7479052012-09-19 00:26:121020 results.extend(_CheckNoTrinaryTrueFalse(input_api, output_api))
[email protected]55f9f382012-07-31 11:02:181021 results.extend(_CheckUnwantedDependencies(input_api, output_api))
[email protected]fbcafe5a2012-08-08 15:31:221022 results.extend(_CheckFilePermissions(input_api, output_api))
[email protected]c8278b32012-10-30 20:35:491023 results.extend(_CheckNoAuraWindowPropertyHInHeaders(input_api, output_api))
[email protected]2309b0fa02012-11-16 12:18:271024 results.extend(_CheckIncludeOrder(input_api, output_api))
[email protected]70ca77752012-11-20 03:45:031025 results.extend(_CheckForVersionControlConflicts(input_api, output_api))
[email protected]b8079ae4a2012-12-05 19:56:491026 results.extend(_CheckPatchFiles(input_api, output_api))
[email protected]06e6d0ff2012-12-11 01:36:441027 results.extend(_CheckHardcodedGoogleHostsInLowerLayers(input_api, output_api))
[email protected]d2530012013-01-25 16:39:271028 results.extend(_CheckNoAbbreviationInPngFileName(input_api, output_api))
[email protected]b00342e7f2013-03-26 16:21:541029 results.extend(_CheckForInvalidOSMacros(input_api, output_api))
[email protected]e871964c2013-05-13 14:14:551030 results.extend(_CheckAddedDepsHaveTargetApprovals(input_api, output_api))
[email protected]9f919cc2013-07-31 03:04:041031 results.extend(
1032 input_api.canned_checks.CheckChangeHasNoTabs(
1033 input_api,
1034 output_api,
1035 source_file_filter=lambda x: x.LocalPath().endswith('.grd')))
[email protected]85218562013-11-22 07:41:401036 results.extend(_CheckSpamLogging(input_api, output_api))
[email protected]49aa76a2013-12-04 06:59:161037 results.extend(_CheckForAnonymousVariables(input_api, output_api))
[email protected]5fe0f8742013-11-29 01:04:591038 results.extend(_CheckCygwinShell(input_api, output_api))
[email protected]760deea2013-12-10 19:33:491039 results.extend(_CheckJavaStyle(input_api, output_api))
[email protected]a817dd22013-12-18 04:35:411040 results.extend(_CheckForString16(input_api, output_api))
[email protected]2299dcf2012-11-15 19:56:241041
1042 if any('PRESUBMIT.py' == f.LocalPath() for f in input_api.AffectedFiles()):
1043 results.extend(input_api.canned_checks.RunUnitTestsInDirectory(
1044 input_api, output_api,
1045 input_api.PresubmitLocalPath(),
[email protected]6be63382013-01-21 15:42:381046 whitelist=[r'^PRESUBMIT_test\.py$']))
[email protected]22c9bd72011-03-27 16:47:391047 return results
[email protected]1f7b4172010-01-28 01:17:341048
[email protected]b337cb5b2011-01-23 21:24:051049
1050def _CheckSubversionConfig(input_api, output_api):
1051 """Verifies the subversion config file is correctly setup.
1052
1053 Checks that autoprops are enabled, returns an error otherwise.
1054 """
1055 join = input_api.os_path.join
1056 if input_api.platform == 'win32':
1057 appdata = input_api.environ.get('APPDATA', '')
1058 if not appdata:
1059 return [output_api.PresubmitError('%APPDATA% is not configured.')]
1060 path = join(appdata, 'Subversion', 'config')
1061 else:
1062 home = input_api.environ.get('HOME', '')
1063 if not home:
1064 return [output_api.PresubmitError('$HOME is not configured.')]
1065 path = join(home, '.subversion', 'config')
1066
1067 error_msg = (
1068 'Please look at http://dev.chromium.org/developers/coding-style to\n'
1069 'configure your subversion configuration file. This enables automatic\n'
[email protected]c6a3c10b2011-01-24 16:14:201070 'properties to simplify the project maintenance.\n'
1071 'Pro-tip: just download and install\n'
1072 'http://src.chromium.org/viewvc/chrome/trunk/tools/build/slave/config\n')
[email protected]b337cb5b2011-01-23 21:24:051073
1074 try:
1075 lines = open(path, 'r').read().splitlines()
1076 # Make sure auto-props is enabled and check for 2 Chromium standard
1077 # auto-prop.
1078 if (not '*.cc = svn:eol-style=LF' in lines or
1079 not '*.pdf = svn:mime-type=application/pdf' in lines or
1080 not 'enable-auto-props = yes' in lines):
1081 return [
[email protected]79ed7e62011-02-21 21:08:531082 output_api.PresubmitNotifyResult(
[email protected]b337cb5b2011-01-23 21:24:051083 'It looks like you have not configured your subversion config '
[email protected]b5359c02011-02-01 20:29:561084 'file or it is not up-to-date.\n' + error_msg)
[email protected]b337cb5b2011-01-23 21:24:051085 ]
1086 except (OSError, IOError):
1087 return [
[email protected]79ed7e62011-02-21 21:08:531088 output_api.PresubmitNotifyResult(
[email protected]b337cb5b2011-01-23 21:24:051089 'Can\'t find your subversion config file.\n' + error_msg)
1090 ]
1091 return []
1092
1093
[email protected]66daa702011-05-28 14:41:461094def _CheckAuthorizedAuthor(input_api, output_api):
1095 """For non-googler/chromites committers, verify the author's email address is
1096 in AUTHORS.
1097 """
[email protected]9bb9cb82011-06-13 20:43:011098 # TODO(maruel): Add it to input_api?
1099 import fnmatch
1100
[email protected]66daa702011-05-28 14:41:461101 author = input_api.change.author_email
[email protected]9bb9cb82011-06-13 20:43:011102 if not author:
1103 input_api.logging.info('No author, skipping AUTHOR check')
[email protected]66daa702011-05-28 14:41:461104 return []
[email protected]c99663292011-05-31 19:46:081105 authors_path = input_api.os_path.join(
[email protected]66daa702011-05-28 14:41:461106 input_api.PresubmitLocalPath(), 'AUTHORS')
1107 valid_authors = (
1108 input_api.re.match(r'[^#]+\s+\<(.+?)\>\s*$', line)
1109 for line in open(authors_path))
[email protected]ac54b132011-06-06 18:11:181110 valid_authors = [item.group(1).lower() for item in valid_authors if item]
[email protected]d8b50be2011-06-15 14:19:441111 if not any(fnmatch.fnmatch(author.lower(), valid) for valid in valid_authors):
[email protected]5861efb2013-01-07 18:33:231112 input_api.logging.info('Valid authors are %s', ', '.join(valid_authors))
[email protected]66daa702011-05-28 14:41:461113 return [output_api.PresubmitPromptWarning(
1114 ('%s is not in AUTHORS file. If you are a new contributor, please visit'
1115 '\n'
1116 'http://www.chromium.org/developers/contributing-code and read the '
1117 '"Legal" section\n'
1118 'If you are a chromite, verify the contributor signed the CLA.') %
1119 author)]
1120 return []
1121
1122
[email protected]b8079ae4a2012-12-05 19:56:491123def _CheckPatchFiles(input_api, output_api):
1124 problems = [f.LocalPath() for f in input_api.AffectedFiles()
1125 if f.LocalPath().endswith(('.orig', '.rej'))]
1126 if problems:
1127 return [output_api.PresubmitError(
1128 "Don't commit .rej and .orig files.", problems)]
[email protected]2fdd1f362013-01-16 03:56:031129 else:
1130 return []
[email protected]b8079ae4a2012-12-05 19:56:491131
1132
[email protected]b00342e7f2013-03-26 16:21:541133def _DidYouMeanOSMacro(bad_macro):
1134 try:
1135 return {'A': 'OS_ANDROID',
1136 'B': 'OS_BSD',
1137 'C': 'OS_CHROMEOS',
1138 'F': 'OS_FREEBSD',
1139 'L': 'OS_LINUX',
1140 'M': 'OS_MACOSX',
1141 'N': 'OS_NACL',
1142 'O': 'OS_OPENBSD',
1143 'P': 'OS_POSIX',
1144 'S': 'OS_SOLARIS',
1145 'W': 'OS_WIN'}[bad_macro[3].upper()]
1146 except KeyError:
1147 return ''
1148
1149
1150def _CheckForInvalidOSMacrosInFile(input_api, f):
1151 """Check for sensible looking, totally invalid OS macros."""
1152 preprocessor_statement = input_api.re.compile(r'^\s*#')
1153 os_macro = input_api.re.compile(r'defined\((OS_[^)]+)\)')
1154 results = []
1155 for lnum, line in f.ChangedContents():
1156 if preprocessor_statement.search(line):
1157 for match in os_macro.finditer(line):
1158 if not match.group(1) in _VALID_OS_MACROS:
1159 good = _DidYouMeanOSMacro(match.group(1))
1160 did_you_mean = ' (did you mean %s?)' % good if good else ''
1161 results.append(' %s:%d %s%s' % (f.LocalPath(),
1162 lnum,
1163 match.group(1),
1164 did_you_mean))
1165 return results
1166
1167
1168def _CheckForInvalidOSMacros(input_api, output_api):
1169 """Check all affected files for invalid OS macros."""
1170 bad_macros = []
1171 for f in input_api.AffectedFiles():
1172 if not f.LocalPath().endswith(('.py', '.js', '.html', '.css')):
1173 bad_macros.extend(_CheckForInvalidOSMacrosInFile(input_api, f))
1174
1175 if not bad_macros:
1176 return []
1177
1178 return [output_api.PresubmitError(
1179 'Possibly invalid OS macro[s] found. Please fix your code\n'
1180 'or add your macro to src/PRESUBMIT.py.', bad_macros)]
1181
1182
[email protected]a817dd22013-12-18 04:35:411183def _CheckForString16InFile(input_api, f):
1184 """Check for string16 without base:: in front."""
1185 reg = input_api.re.compile(r'\b(?<!base::)string16\b')
1186 use = 'using base::string16;'
1187 include = '#include "base/strings/string16.h"'
1188 results = []
1189 for lnum, line in f.ChangedContents():
1190 if reg.search(line) and not include in line and not use in f.NewContents():
1191 results.append(' %s:%d' % (f.LocalPath(), lnum))
1192 return results
1193
1194
1195def _CheckForString16(input_api, output_api):
1196 file_filter = lambda f: input_api.FilterSourceFile(f,
[email protected]d15af07b2013-12-19 19:19:361197 white_list=(
[email protected]a9066f42013-12-19 23:57:471198 r'^android_webview[\\\/]',
[email protected]d15af07b2013-12-19 19:19:361199 r'^apps[\\\/]',
1200 r'^ash[\\\/]',
[email protected]391c93a2013-12-20 09:13:191201 r'^chrome[\\\/]',
[email protected]a9066f42013-12-19 23:57:471202 r'^chromeos[\\\/]',
1203 r'^components[\\\/]',
[email protected]391c93a2013-12-20 09:13:191204 r'^content[\\\/]',
[email protected]a9066f42013-12-19 23:57:471205 r'^device[\\\/]',
1206 r'^ipc[\\\/]',
[email protected]d15af07b2013-12-19 19:19:361207 r'^net[\\\/]',
[email protected]a9066f42013-12-19 23:57:471208 r'^ppapi[\\\/]',
1209 r'^printing[\\\/]',
1210 r'^rlz[\\\/]',
[email protected]d15af07b2013-12-19 19:19:361211 r'^skia[\\\/]',
[email protected]a9066f42013-12-19 23:57:471212 r'^tools[\\\/]',
[email protected]d15af07b2013-12-19 19:19:361213 r'^ui[\\\/]',
1214 r'^webkit[\\\/]',
1215 ),
[email protected]a817dd22013-12-18 04:35:411216 black_list=(_EXCLUDED_PATHS + _TEST_CODE_EXCLUDED_PATHS +
1217 input_api.DEFAULT_BLACK_LIST))
1218
1219 unprefixed = []
1220 for f in input_api.AffectedFiles(file_filter=file_filter):
1221 unprefixed.extend(_CheckForString16InFile(input_api, f))
1222
1223 if not unprefixed:
1224 return []
1225
1226 return [output_api.PresubmitPromptWarning(
1227 'string16 should be prefixed with base:: namespace.', unprefixed)]
1228
1229
[email protected]1f7b4172010-01-28 01:17:341230def CheckChangeOnUpload(input_api, output_api):
1231 results = []
1232 results.extend(_CommonChecks(input_api, output_api))
[email protected]fe5f57c52009-06-05 14:25:541233 return results
[email protected]ca8d19842009-02-19 16:33:121234
1235
[email protected]38c6a512013-12-18 23:48:011236def GetDefaultTryConfigs(bots=None):
1237 """Returns a list of ('bot', set(['tests']), optionally filtered by [bots].
1238
1239 To add tests to this list, they MUST be in the the corresponding master's
1240 gatekeeper config. For example, anything on master.chromium would be closed by
1241 tools/build/masters/master.chromium/master_gatekeeper_cfg.py.
1242
1243 If 'bots' is specified, will only return configurations for bots in that list.
1244 """
1245
1246 standard_tests = [
1247 'base_unittests',
1248 'browser_tests',
1249 'cacheinvalidation_unittests',
1250 'check_deps',
1251 'check_deps2git',
1252 'content_browsertests',
1253 'content_unittests',
1254 'crypto_unittests',
1255 #'gfx_unittests',
1256 'gpu_unittests',
1257 'interactive_ui_tests',
1258 'ipc_tests',
1259 'jingle_unittests',
1260 'media_unittests',
1261 'net_unittests',
1262 'ppapi_unittests',
1263 'printing_unittests',
1264 'sql_unittests',
1265 'sync_unit_tests',
1266 'unit_tests',
1267 # Broken in release.
1268 #'url_unittests',
1269 #'webkit_unit_tests',
1270 ]
1271
1272 linux_aura_tests = [
1273 'app_list_unittests',
1274 'aura_unittests',
1275 'browser_tests',
1276 'compositor_unittests',
1277 'content_browsertests',
1278 'content_unittests',
1279 'events_unittests',
1280 'interactive_ui_tests',
1281 'unit_tests',
1282 ]
1283 builders_and_tests = {
1284 # TODO(maruel): Figure out a way to run 'sizes' where people can
1285 # effectively update the perf expectation correctly. This requires a
1286 # clobber=True build running 'sizes'. 'sizes' is not accurate with
1287 # incremental build. Reference:
1288 # http://chromium.org/developers/tree-sheriffs/perf-sheriffs.
1289 # TODO(maruel): An option would be to run 'sizes' but not count a failure
1290 # of this step as a try job failure.
1291 'android_aosp': ['compile'],
1292 'android_clang_dbg': ['slave_steps'],
1293 'android_dbg': ['slave_steps'],
1294 'cros_x86': ['defaulttests'],
1295 'ios_dbg_simulator': [
1296 'compile',
1297 'base_unittests',
1298 'content_unittests',
1299 'crypto_unittests',
1300 'url_unittests',
1301 'net_unittests',
1302 'sql_unittests',
1303 'ui_unittests',
1304 ],
1305 'ios_rel_device': ['compile'],
1306 'linux_asan': ['defaulttests'],
1307 #TODO(stip): Change the name of this builder to reflect that it's release.
1308 'linux_aura': linux_aura_tests,
1309 'linux_chromeos_asan': ['defaulttests'],
1310 'linux_chromeos_clang': ['compile'],
1311 # Note: It is a Release builder even if its name convey otherwise.
1312 'linux_chromeos': standard_tests + [
1313 'app_list_unittests',
1314 'aura_unittests',
1315 'ash_unittests',
1316 'chromeos_unittests',
1317 'components_unittests',
1318 'dbus_unittests',
1319 'device_unittests',
1320 'events_unittests',
1321 'google_apis_unittests',
1322 'sandbox_linux_unittests',
1323 ],
1324 'linux_clang': ['compile'],
1325 'linux_rel': standard_tests + [
1326 'cc_unittests',
1327 'chromedriver2_unittests',
1328 'components_unittests',
1329 'google_apis_unittests',
1330 'nacl_integration',
1331 'remoting_unittests',
1332 'sandbox_linux_unittests',
1333 'sync_integration_tests',
1334 ],
1335 'mac': ['compile'],
1336 'mac_rel': standard_tests + [
1337 'app_list_unittests',
1338 'cc_unittests',
1339 'chromedriver2_unittests',
1340 'components_unittests',
1341 'google_apis_unittests',
1342 'message_center_unittests',
1343 'nacl_integration',
1344 'remoting_unittests',
1345 'sync_integration_tests',
1346 'telemetry_unittests',
1347 ],
1348 'win': ['compile'],
1349 'win_rel': standard_tests + [
1350 'app_list_unittests',
1351 'ash_unittests',
1352 'aura_unittests',
1353 'cc_unittests',
1354 'chrome_elf_unittests',
1355 'chromedriver2_unittests',
1356 'components_unittests',
1357 'compositor_unittests',
1358 'events_unittests',
1359 'google_apis_unittests',
1360 'installer_util_unittests',
1361 'mini_installer_test',
1362 'nacl_integration',
1363 'remoting_unittests',
1364 'sync_integration_tests',
1365 'telemetry_unittests',
1366 'views_unittests',
1367 ],
1368 'win_x64_rel': [
1369 'base_unittests',
1370 ],
1371 }
1372
1373 swarm_enabled_builders = (
1374 'linux_rel',
1375 'mac_rel',
1376 'win_rel',
1377 )
1378
1379 swarm_enabled_tests = (
1380 'base_unittests',
1381 'browser_tests',
1382 'interactive_ui_tests',
1383 'net_unittests',
1384 'unit_tests',
1385 )
1386
1387 for bot in builders_and_tests:
1388 if bot in swarm_enabled_builders:
1389 builders_and_tests[bot] = [x + '_swarm' if x in swarm_enabled_tests else x
1390 for x in builders_and_tests[bot]]
1391
1392 if bots:
1393 return [(bot, set(builders_and_tests[bot])) for bot in bots]
1394 else:
1395 return [(bot, set(tests)) for bot, tests in builders_and_tests.iteritems()]
1396
1397
[email protected]ca8d19842009-02-19 16:33:121398def CheckChangeOnCommit(input_api, output_api):
[email protected]fe5f57c52009-06-05 14:25:541399 results = []
[email protected]1f7b4172010-01-28 01:17:341400 results.extend(_CommonChecks(input_api, output_api))
[email protected]dd805fe2009-10-01 08:11:511401 # TODO(thestig) temporarily disabled, doesn't work in third_party/
1402 #results.extend(input_api.canned_checks.CheckSvnModifiedDirectories(
1403 # input_api, output_api, sources))
[email protected]fe5f57c52009-06-05 14:25:541404 # Make sure the tree is 'open'.
[email protected]806e98e2010-03-19 17:49:271405 results.extend(input_api.canned_checks.CheckTreeIsOpen(
[email protected]7f238152009-08-12 19:00:341406 input_api,
1407 output_api,
[email protected]2fdd1f362013-01-16 03:56:031408 json_url='http://chromium-status.appspot.com/current?format=json'))
[email protected]806e98e2010-03-19 17:49:271409 results.extend(input_api.canned_checks.CheckRietveldTryJobExecution(input_api,
[email protected]2fdd1f362013-01-16 03:56:031410 output_api, 'http://codereview.chromium.org',
[email protected]c1ba4c52012-03-09 14:23:281411 ('win_rel', 'linux_rel', 'mac_rel, win:compile'),
1412 '[email protected]'))
[email protected]806e98e2010-03-19 17:49:271413
[email protected]3e4eb112011-01-18 03:29:541414 results.extend(input_api.canned_checks.CheckChangeHasBugField(
1415 input_api, output_api))
[email protected]c4b47562011-12-05 23:39:411416 results.extend(input_api.canned_checks.CheckChangeHasDescription(
1417 input_api, output_api))
[email protected]b337cb5b2011-01-23 21:24:051418 results.extend(_CheckSubversionConfig(input_api, output_api))
[email protected]fe5f57c52009-06-05 14:25:541419 return results
[email protected]ca8d19842009-02-19 16:33:121420
1421
[email protected]5efb2a822011-09-27 23:06:131422def GetPreferredTrySlaves(project, change):
[email protected]4ce995ea2012-06-27 02:13:101423 files = change.LocalPaths()
1424
[email protected]751b05f2013-01-10 23:12:171425 if not files or all(re.search(r'[\\/]OWNERS$', f) for f in files):
[email protected]3019c902012-06-29 00:09:031426 return []
1427
[email protected]d668899a2012-09-06 18:16:591428 if all(re.search('\.(m|mm)$|(^|[/_])mac[/_.]', f) for f in files):
[email protected]38c6a512013-12-18 23:48:011429 return GetDefaultTryConfigs(['mac', 'mac_rel'])
[email protected]d668899a2012-09-06 18:16:591430 if all(re.search('(^|[/_])win[/_.]', f) for f in files):
[email protected]3630be892013-12-19 05:34:281431 return GetDefaultTryConfigs(['win', 'win_rel'])
[email protected]d668899a2012-09-06 18:16:591432 if all(re.search('(^|[/_])android[/_.]', f) for f in files):
[email protected]38c6a512013-12-18 23:48:011433 return GetDefaultTryConfigs([
1434 'android_aosp',
1435 'android_clang_dbg',
1436 'android_dbg',
1437 ])
[email protected]356aa542012-09-19 23:31:291438 if all(re.search('^native_client_sdk', f) for f in files):
[email protected]38c6a512013-12-18 23:48:011439 return GetDefaultTryConfigs([
1440 'linux_nacl_sdk',
1441 'mac_nacl_sdk',
1442 'win_nacl_sdk',
1443 ])
[email protected]de142152012-10-03 23:02:451444 if all(re.search('[/_]ios[/_.]', f) for f in files):
[email protected]38c6a512013-12-18 23:48:011445 return GetDefaultTryConfigs(['ios_rel_device', 'ios_dbg_simulator'])
[email protected]4ce995ea2012-06-27 02:13:101446
[email protected]38c6a512013-12-18 23:48:011447 trybots = GetDefaultTryConfigs([
[email protected]3e2f0402012-11-02 16:28:011448 'android_clang_dbg',
1449 'android_dbg',
1450 'ios_dbg_simulator',
1451 'ios_rel_device',
[email protected]95c989162012-11-29 05:58:251452 'linux_aura',
[email protected]38c6a512013-12-18 23:48:011453 'linux_asan',
[email protected]3e2f0402012-11-02 16:28:011454 'linux_chromeos',
[email protected]38c6a512013-12-18 23:48:011455 'linux_clang',
[email protected]3e2f0402012-11-02 16:28:011456 'linux_rel',
[email protected]38c6a512013-12-18 23:48:011457 'mac',
[email protected]3e2f0402012-11-02 16:28:011458 'mac_rel',
[email protected]38c6a512013-12-18 23:48:011459 'win',
[email protected]3e2f0402012-11-02 16:28:011460 'win_rel',
[email protected]38c6a512013-12-18 23:48:011461 'win_x64_rel',
1462 ])
[email protected]911753b2012-08-02 12:11:541463
1464 # Match things like path/aura/file.cc and path/file_aura.cc.
[email protected]95c989162012-11-29 05:58:251465 # Same for chromeos.
1466 if any(re.search('[/_](aura|chromeos)', f) for f in files):
[email protected]38c6a512013-12-18 23:48:011467 trybots.extend(GetDefaultTryConfigs([
1468 'linux_chromeos_asan', 'linux_chromeos_clang']))
[email protected]4ce995ea2012-06-27 02:13:101469
[email protected]e8df48f2013-09-30 20:07:541470 # If there are gyp changes to base, build, or chromeos, run a full cros build
1471 # in addition to the shorter linux_chromeos build. Changes to high level gyp
1472 # files have a much higher chance of breaking the cros build, which is
1473 # differnt from the linux_chromeos build that most chrome developers test
1474 # with.
1475 if any(re.search('^(base|build|chromeos).*\.gypi?$', f) for f in files):
[email protected]38c6a512013-12-18 23:48:011476 trybots.extend(GetDefaultTryConfigs(['cros_x86']))
[email protected]e8df48f2013-09-30 20:07:541477
[email protected]d95948ef2013-07-02 10:51:001478 # The AOSP bot doesn't build the chrome/ layer, so ignore any changes to it
1479 # unless they're .gyp(i) files as changes to those files can break the gyp
1480 # step on that bot.
1481 if (not all(re.search('^chrome', f) for f in files) or
1482 any(re.search('\.gypi?$', f) for f in files)):
[email protected]38c6a512013-12-18 23:48:011483 trybots.extend(GetDefaultTryConfigs(['android_aosp']))
[email protected]d95948ef2013-07-02 10:51:001484
[email protected]4ce995ea2012-06-27 02:13:101485 return trybots