blob: bc16ad8f92e8f7d8a6941caced04aaeb57162ec7 [file] [log] [blame]
[email protected]a18130a2012-01-03 17:52:081# Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]ca8d1982009-02-19 16:33:122# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5"""Top-level presubmit script for Chromium.
6
[email protected]f1293792009-07-31 18:09:567See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts
[email protected]50d7d721e2009-11-15 17:56:188for more details about the presubmit API built into gcl.
[email protected]ca8d1982009-02-19 16:33:129"""
10
[email protected]eea609a2011-11-18 13:10:1211
[email protected]23c81d552014-01-07 13:45:4612import random
[email protected]9d16ad12011-12-14 20:49:4713import re
[email protected]fbcafe5a2012-08-08 15:31:2214import subprocess
[email protected]55f9f382012-07-31 11:02:1815import sys
[email protected]9d16ad12011-12-14 20:49:4716
17
[email protected]379e7dd2010-01-28 17:39:2118_EXCLUDED_PATHS = (
[email protected]3e4eb112011-01-18 03:29:5419 r"^breakpad[\\\/].*",
[email protected]40d1dbb2012-10-26 07:18:0020 r"^native_client_sdk[\\\/]src[\\\/]build_tools[\\\/]make_rules.py",
21 r"^native_client_sdk[\\\/]src[\\\/]build_tools[\\\/]make_simple.py",
[email protected]8886ffcb2013-02-12 04:56:2822 r"^native_client_sdk[\\\/]src[\\\/]tools[\\\/].*.mk",
[email protected]a18130a2012-01-03 17:52:0823 r"^net[\\\/]tools[\\\/]spdyshark[\\\/].*",
[email protected]3e4eb112011-01-18 03:29:5424 r"^skia[\\\/].*",
25 r"^v8[\\\/].*",
26 r".*MakeFile$",
[email protected]1084ccc2012-03-14 03:22:5327 r".+_autogen\.h$",
[email protected]ce145c02012-09-06 09:49:3428 r".+[\\\/]pnacl_shim\.c$",
[email protected]e07b6ac72013-08-20 00:30:4229 r"^gpu[\\\/]config[\\\/].*_list_json\.cc$",
[email protected]4306417642009-06-11 00:33:4030)
[email protected]ca8d1982009-02-19 16:33:1231
[email protected]3de922f2013-12-20 13:27:3832# TestRunner library is temporarily excluded from pan-project checks until
33# it's transitioned to chromium coding style.
34_TESTRUNNER_PATHS = (
35 r"^content[\\\/]shell[\\\/]renderer[\\\/]test_runner[\\\/].*",
36 r"^content[\\\/]shell[\\\/]common[\\\/]test_runner[\\\/].*",
37)
38
[email protected]06e6d0ff2012-12-11 01:36:4439# Fragment of a regular expression that matches C++ and Objective-C++
40# implementation files.
41_IMPLEMENTATION_EXTENSIONS = r'\.(cc|cpp|cxx|mm)$'
42
43# Regular expression that matches code only used for test binaries
44# (best effort).
45_TEST_CODE_EXCLUDED_PATHS = (
46 r'.*[/\\](fake_|test_|mock_).+%s' % _IMPLEMENTATION_EXTENSIONS,
47 r'.+_test_(base|support|util)%s' % _IMPLEMENTATION_EXTENSIONS,
[email protected]11e06082013-04-26 19:09:0348 r'.+_(api|browser|perf|pixel|unit|ui)?test(_[a-z]+)?%s' %
[email protected]e2d7e6f2013-04-23 12:57:1249 _IMPLEMENTATION_EXTENSIONS,
[email protected]06e6d0ff2012-12-11 01:36:4450 r'.+profile_sync_service_harness%s' % _IMPLEMENTATION_EXTENSIONS,
51 r'.*[/\\](test|tool(s)?)[/\\].*',
[email protected]ef070cc2013-05-03 11:53:0552 # content_shell is used for running layout tests.
53 r'content[/\\]shell[/\\].*',
[email protected]06e6d0ff2012-12-11 01:36:4454 # At request of folks maintaining this folder.
55 r'chrome[/\\]browser[/\\]automation[/\\].*',
[email protected]7b054982013-11-27 00:44:4756 # Non-production example code.
57 r'mojo[/\\]examples[/\\].*',
[email protected]06e6d0ff2012-12-11 01:36:4458)
[email protected]ca8d1982009-02-19 16:33:1259
[email protected]eea609a2011-11-18 13:10:1260_TEST_ONLY_WARNING = (
61 'You might be calling functions intended only for testing from\n'
62 'production code. It is OK to ignore this warning if you know what\n'
63 'you are doing, as the heuristics used to detect the situation are\n'
64 'not perfect. The commit queue will not block on this warning.\n'
65 'Email [email protected] if you have questions.')
66
67
[email protected]cf9b78f2012-11-14 11:40:2868_INCLUDE_ORDER_WARNING = (
69 'Your #include order seems to be broken. Send mail to\n'
70 '[email protected] if this is not the case.')
71
72
[email protected]127f18ec2012-06-16 05:05:5973_BANNED_OBJC_FUNCTIONS = (
74 (
75 'addTrackingRect:',
[email protected]23e6cbc2012-06-16 18:51:2076 (
77 'The use of -[NSView addTrackingRect:owner:userData:assumeInside:] is'
[email protected]127f18ec2012-06-16 05:05:5978 'prohibited. Please use CrTrackingArea instead.',
79 'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts',
80 ),
81 False,
82 ),
83 (
84 'NSTrackingArea',
[email protected]23e6cbc2012-06-16 18:51:2085 (
86 'The use of NSTrackingAreas is prohibited. Please use CrTrackingArea',
[email protected]127f18ec2012-06-16 05:05:5987 'instead.',
88 'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts',
89 ),
90 False,
91 ),
92 (
93 'convertPointFromBase:',
[email protected]23e6cbc2012-06-16 18:51:2094 (
95 'The use of -[NSView convertPointFromBase:] is almost certainly wrong.',
[email protected]127f18ec2012-06-16 05:05:5996 'Please use |convertPoint:(point) fromView:nil| instead.',
97 'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts',
98 ),
99 True,
100 ),
101 (
102 'convertPointToBase:',
[email protected]23e6cbc2012-06-16 18:51:20103 (
104 'The use of -[NSView convertPointToBase:] is almost certainly wrong.',
[email protected]127f18ec2012-06-16 05:05:59105 'Please use |convertPoint:(point) toView:nil| instead.',
106 'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts',
107 ),
108 True,
109 ),
110 (
111 'convertRectFromBase:',
[email protected]23e6cbc2012-06-16 18:51:20112 (
113 'The use of -[NSView convertRectFromBase:] is almost certainly wrong.',
[email protected]127f18ec2012-06-16 05:05:59114 'Please use |convertRect:(point) fromView:nil| instead.',
115 'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts',
116 ),
117 True,
118 ),
119 (
120 'convertRectToBase:',
[email protected]23e6cbc2012-06-16 18:51:20121 (
122 'The use of -[NSView convertRectToBase:] is almost certainly wrong.',
[email protected]127f18ec2012-06-16 05:05:59123 'Please use |convertRect:(point) toView:nil| instead.',
124 'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts',
125 ),
126 True,
127 ),
128 (
129 'convertSizeFromBase:',
[email protected]23e6cbc2012-06-16 18:51:20130 (
131 'The use of -[NSView convertSizeFromBase:] is almost certainly wrong.',
[email protected]127f18ec2012-06-16 05:05:59132 'Please use |convertSize:(point) fromView:nil| instead.',
133 'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts',
134 ),
135 True,
136 ),
137 (
138 'convertSizeToBase:',
[email protected]23e6cbc2012-06-16 18:51:20139 (
140 'The use of -[NSView convertSizeToBase:] is almost certainly wrong.',
[email protected]127f18ec2012-06-16 05:05:59141 'Please use |convertSize:(point) toView:nil| instead.',
142 'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts',
143 ),
144 True,
145 ),
146)
147
148
149_BANNED_CPP_FUNCTIONS = (
[email protected]23e6cbc2012-06-16 18:51:20150 # Make sure that gtest's FRIEND_TEST() macro is not used; the
151 # FRIEND_TEST_ALL_PREFIXES() macro from base/gtest_prod_util.h should be
[email protected]e00ccc92012-11-01 17:32:30152 # used instead since that allows for FLAKY_ and DISABLED_ prefixes.
[email protected]23e6cbc2012-06-16 18:51:20153 (
154 'FRIEND_TEST(',
155 (
[email protected]e3c945502012-06-26 20:01:49156 'Chromium code should not use gtest\'s FRIEND_TEST() macro. Include',
[email protected]23e6cbc2012-06-16 18:51:20157 'base/gtest_prod_util.h and use FRIEND_TEST_ALL_PREFIXES() instead.',
158 ),
159 False,
[email protected]7345da02012-11-27 14:31:49160 (),
[email protected]23e6cbc2012-06-16 18:51:20161 ),
162 (
163 'ScopedAllowIO',
164 (
[email protected]e3c945502012-06-26 20:01:49165 'New code should not use ScopedAllowIO. Post a task to the blocking',
166 'pool or the FILE thread instead.',
[email protected]23e6cbc2012-06-16 18:51:20167 ),
[email protected]e3c945502012-06-26 20:01:49168 True,
[email protected]7345da02012-11-27 14:31:49169 (
[email protected]0b818f72013-10-22 00:11:03170 r"^components[\\\/]breakpad[\\\/]app[\\\/]breakpad_mac\.mm$",
[email protected]de7d61ff2013-08-20 11:30:41171 r"^content[\\\/]shell[\\\/]browser[\\\/]shell_browser_main\.cc$",
172 r"^content[\\\/]shell[\\\/]browser[\\\/]shell_message_filter\.cc$",
[email protected]398ad132013-04-02 15:11:01173 r"^net[\\\/]disk_cache[\\\/]cache_util\.cc$",
[email protected]7345da02012-11-27 14:31:49174 ),
[email protected]23e6cbc2012-06-16 18:51:20175 ),
[email protected]52657f62013-05-20 05:30:31176 (
177 'SkRefPtr',
178 (
179 'The use of SkRefPtr is prohibited. ',
180 'Please use skia::RefPtr instead.'
181 ),
182 True,
183 (),
184 ),
185 (
186 'SkAutoRef',
187 (
188 'The indirect use of SkRefPtr via SkAutoRef is prohibited. ',
189 'Please use skia::RefPtr instead.'
190 ),
191 True,
192 (),
193 ),
194 (
195 'SkAutoTUnref',
196 (
197 'The use of SkAutoTUnref is dangerous because it implicitly ',
198 'converts to a raw pointer. Please use skia::RefPtr instead.'
199 ),
200 True,
201 (),
202 ),
203 (
204 'SkAutoUnref',
205 (
206 'The indirect use of SkAutoTUnref through SkAutoUnref is dangerous ',
207 'because it implicitly converts to a raw pointer. ',
208 'Please use skia::RefPtr instead.'
209 ),
210 True,
211 (),
212 ),
[email protected]d89eec82013-12-03 14:10:59213 (
214 r'/HANDLE_EINTR\(.*close',
215 (
216 'HANDLE_EINTR(close) is invalid. If close fails with EINTR, the file',
217 'descriptor will be closed, and it is incorrect to retry the close.',
218 'Either call close directly and ignore its return value, or wrap close',
219 'in IGNORE_EINTR to use its return value. See http://crbug.com/269623'
220 ),
221 True,
222 (),
223 ),
224 (
225 r'/IGNORE_EINTR\((?!.*close)',
226 (
227 'IGNORE_EINTR is only valid when wrapping close. To wrap other system',
228 'calls, use HANDLE_EINTR. See http://crbug.com/269623',
229 ),
230 True,
231 (
232 # Files that #define IGNORE_EINTR.
233 r'^base[\\\/]posix[\\\/]eintr_wrapper\.h$',
234 r'^ppapi[\\\/]tests[\\\/]test_broker\.cc$',
235 ),
236 ),
[email protected]127f18ec2012-06-16 05:05:59237)
238
239
[email protected]b00342e7f2013-03-26 16:21:54240_VALID_OS_MACROS = (
241 # Please keep sorted.
242 'OS_ANDROID',
243 'OS_BSD',
244 'OS_CAT', # For testing.
245 'OS_CHROMEOS',
246 'OS_FREEBSD',
247 'OS_IOS',
248 'OS_LINUX',
249 'OS_MACOSX',
250 'OS_NACL',
251 'OS_OPENBSD',
252 'OS_POSIX',
253 'OS_SOLARIS',
[email protected]b00342e7f2013-03-26 16:21:54254 'OS_WIN',
255)
256
257
[email protected]55459852011-08-10 15:17:19258def _CheckNoProductionCodeUsingTestOnlyFunctions(input_api, output_api):
259 """Attempts to prevent use of functions intended only for testing in
260 non-testing code. For now this is just a best-effort implementation
261 that ignores header files and may have some false positives. A
262 better implementation would probably need a proper C++ parser.
263 """
264 # We only scan .cc files and the like, as the declaration of
265 # for-testing functions in header files are hard to distinguish from
266 # calls to such functions without a proper C++ parser.
[email protected]06e6d0ff2012-12-11 01:36:44267 file_inclusion_pattern = r'.+%s' % _IMPLEMENTATION_EXTENSIONS
[email protected]55459852011-08-10 15:17:19268
269 base_function_pattern = r'ForTest(ing)?|for_test(ing)?'
270 inclusion_pattern = input_api.re.compile(r'(%s)\s*\(' % base_function_pattern)
[email protected]de4f7d22013-05-23 14:27:46271 comment_pattern = input_api.re.compile(r'//.*%s' % base_function_pattern)
[email protected]55459852011-08-10 15:17:19272 exclusion_pattern = input_api.re.compile(
273 r'::[A-Za-z0-9_]+(%s)|(%s)[^;]+\{' % (
274 base_function_pattern, base_function_pattern))
275
276 def FilterFile(affected_file):
[email protected]06e6d0ff2012-12-11 01:36:44277 black_list = (_EXCLUDED_PATHS +
278 _TEST_CODE_EXCLUDED_PATHS +
279 input_api.DEFAULT_BLACK_LIST)
[email protected]55459852011-08-10 15:17:19280 return input_api.FilterSourceFile(
281 affected_file,
282 white_list=(file_inclusion_pattern, ),
283 black_list=black_list)
284
285 problems = []
286 for f in input_api.AffectedSourceFiles(FilterFile):
287 local_path = f.LocalPath()
[email protected]825d27182014-01-02 21:24:24288 for line_number, line in f.ChangedContents():
[email protected]2fdd1f362013-01-16 03:56:03289 if (inclusion_pattern.search(line) and
[email protected]de4f7d22013-05-23 14:27:46290 not comment_pattern.search(line) and
[email protected]2fdd1f362013-01-16 03:56:03291 not exclusion_pattern.search(line)):
[email protected]55459852011-08-10 15:17:19292 problems.append(
[email protected]2fdd1f362013-01-16 03:56:03293 '%s:%d\n %s' % (local_path, line_number, line.strip()))
[email protected]55459852011-08-10 15:17:19294
295 if problems:
[email protected]f7051d52013-04-02 18:31:42296 return [output_api.PresubmitPromptOrNotify(_TEST_ONLY_WARNING, problems)]
[email protected]2fdd1f362013-01-16 03:56:03297 else:
298 return []
[email protected]55459852011-08-10 15:17:19299
300
[email protected]10689ca2011-09-02 02:31:54301def _CheckNoIOStreamInHeaders(input_api, output_api):
302 """Checks to make sure no .h files include <iostream>."""
303 files = []
304 pattern = input_api.re.compile(r'^#include\s*<iostream>',
305 input_api.re.MULTILINE)
306 for f in input_api.AffectedSourceFiles(input_api.FilterSourceFile):
307 if not f.LocalPath().endswith('.h'):
308 continue
309 contents = input_api.ReadFile(f)
310 if pattern.search(contents):
311 files.append(f)
312
313 if len(files):
314 return [ output_api.PresubmitError(
[email protected]6c063c62012-07-11 19:11:06315 'Do not #include <iostream> in header files, since it inserts static '
316 'initialization into every file including the header. Instead, '
[email protected]10689ca2011-09-02 02:31:54317 '#include <ostream>. See http://crbug.com/94794',
318 files) ]
319 return []
320
321
[email protected]72df4e782012-06-21 16:28:18322def _CheckNoUNIT_TESTInSourceFiles(input_api, output_api):
323 """Checks to make sure no source files use UNIT_TEST"""
324 problems = []
325 for f in input_api.AffectedFiles():
326 if (not f.LocalPath().endswith(('.cc', '.mm'))):
327 continue
328
329 for line_num, line in f.ChangedContents():
[email protected]549f86a2013-11-19 13:00:04330 if 'UNIT_TEST ' in line or line.endswith('UNIT_TEST'):
[email protected]72df4e782012-06-21 16:28:18331 problems.append(' %s:%d' % (f.LocalPath(), line_num))
332
333 if not problems:
334 return []
335 return [output_api.PresubmitPromptWarning('UNIT_TEST is only for headers.\n' +
336 '\n'.join(problems))]
337
338
[email protected]8ea5d4b2011-09-13 21:49:22339def _CheckNoNewWStrings(input_api, output_api):
340 """Checks to make sure we don't introduce use of wstrings."""
[email protected]55463aa62011-10-12 00:48:27341 problems = []
[email protected]8ea5d4b2011-09-13 21:49:22342 for f in input_api.AffectedFiles():
[email protected]b5c24292011-11-28 14:38:20343 if (not f.LocalPath().endswith(('.cc', '.h')) or
[email protected]24be83c2013-08-29 23:01:23344 f.LocalPath().endswith(('test.cc', '_win.cc', '_win.h'))):
[email protected]b5c24292011-11-28 14:38:20345 continue
[email protected]8ea5d4b2011-09-13 21:49:22346
[email protected]a11dbe9b2012-08-07 01:32:58347 allowWString = False
[email protected]b5c24292011-11-28 14:38:20348 for line_num, line in f.ChangedContents():
[email protected]a11dbe9b2012-08-07 01:32:58349 if 'presubmit: allow wstring' in line:
350 allowWString = True
351 elif not allowWString and 'wstring' in line:
[email protected]55463aa62011-10-12 00:48:27352 problems.append(' %s:%d' % (f.LocalPath(), line_num))
[email protected]a11dbe9b2012-08-07 01:32:58353 allowWString = False
354 else:
355 allowWString = False
[email protected]8ea5d4b2011-09-13 21:49:22356
[email protected]55463aa62011-10-12 00:48:27357 if not problems:
358 return []
359 return [output_api.PresubmitPromptWarning('New code should not use wstrings.'
[email protected]a11dbe9b2012-08-07 01:32:58360 ' If you are calling a cross-platform API that accepts a wstring, '
361 'fix the API.\n' +
[email protected]55463aa62011-10-12 00:48:27362 '\n'.join(problems))]
[email protected]8ea5d4b2011-09-13 21:49:22363
364
[email protected]2a8ac9c2011-10-19 17:20:44365def _CheckNoDEPSGIT(input_api, output_api):
366 """Make sure .DEPS.git is never modified manually."""
367 if any(f.LocalPath().endswith('.DEPS.git') for f in
368 input_api.AffectedFiles()):
369 return [output_api.PresubmitError(
370 'Never commit changes to .DEPS.git. This file is maintained by an\n'
371 'automated system based on what\'s in DEPS and your changes will be\n'
372 'overwritten.\n'
373 'See http://code.google.com/p/chromium/wiki/UsingNewGit#Rolling_DEPS\n'
374 'for more information')]
375 return []
376
377
[email protected]127f18ec2012-06-16 05:05:59378def _CheckNoBannedFunctions(input_api, output_api):
379 """Make sure that banned functions are not used."""
380 warnings = []
381 errors = []
382
383 file_filter = lambda f: f.LocalPath().endswith(('.mm', '.m', '.h'))
384 for f in input_api.AffectedFiles(file_filter=file_filter):
385 for line_num, line in f.ChangedContents():
386 for func_name, message, error in _BANNED_OBJC_FUNCTIONS:
387 if func_name in line:
388 problems = warnings;
389 if error:
390 problems = errors;
391 problems.append(' %s:%d:' % (f.LocalPath(), line_num))
392 for message_line in message:
393 problems.append(' %s' % message_line)
394
395 file_filter = lambda f: f.LocalPath().endswith(('.cc', '.mm', '.h'))
396 for f in input_api.AffectedFiles(file_filter=file_filter):
397 for line_num, line in f.ChangedContents():
[email protected]7345da02012-11-27 14:31:49398 for func_name, message, error, excluded_paths in _BANNED_CPP_FUNCTIONS:
399 def IsBlacklisted(affected_file, blacklist):
400 local_path = affected_file.LocalPath()
401 for item in blacklist:
402 if input_api.re.match(item, local_path):
403 return True
404 return False
405 if IsBlacklisted(f, excluded_paths):
406 continue
[email protected]d89eec82013-12-03 14:10:59407 matched = False
408 if func_name[0:1] == '/':
409 regex = func_name[1:]
410 if input_api.re.search(regex, line):
411 matched = True
412 elif func_name in line:
413 matched = True
414 if matched:
[email protected]127f18ec2012-06-16 05:05:59415 problems = warnings;
416 if error:
417 problems = errors;
418 problems.append(' %s:%d:' % (f.LocalPath(), line_num))
419 for message_line in message:
420 problems.append(' %s' % message_line)
421
422 result = []
423 if (warnings):
424 result.append(output_api.PresubmitPromptWarning(
425 'Banned functions were used.\n' + '\n'.join(warnings)))
426 if (errors):
427 result.append(output_api.PresubmitError(
428 'Banned functions were used.\n' + '\n'.join(errors)))
429 return result
430
431
[email protected]6c063c62012-07-11 19:11:06432def _CheckNoPragmaOnce(input_api, output_api):
433 """Make sure that banned functions are not used."""
434 files = []
435 pattern = input_api.re.compile(r'^#pragma\s+once',
436 input_api.re.MULTILINE)
437 for f in input_api.AffectedSourceFiles(input_api.FilterSourceFile):
438 if not f.LocalPath().endswith('.h'):
439 continue
440 contents = input_api.ReadFile(f)
441 if pattern.search(contents):
442 files.append(f)
443
444 if files:
445 return [output_api.PresubmitError(
446 'Do not use #pragma once in header files.\n'
447 'See http://www.chromium.org/developers/coding-style#TOC-File-headers',
448 files)]
449 return []
450
[email protected]127f18ec2012-06-16 05:05:59451
[email protected]e7479052012-09-19 00:26:12452def _CheckNoTrinaryTrueFalse(input_api, output_api):
453 """Checks to make sure we don't introduce use of foo ? true : false."""
454 problems = []
455 pattern = input_api.re.compile(r'\?\s*(true|false)\s*:\s*(true|false)')
456 for f in input_api.AffectedFiles():
457 if not f.LocalPath().endswith(('.cc', '.h', '.inl', '.m', '.mm')):
458 continue
459
460 for line_num, line in f.ChangedContents():
461 if pattern.match(line):
462 problems.append(' %s:%d' % (f.LocalPath(), line_num))
463
464 if not problems:
465 return []
466 return [output_api.PresubmitPromptWarning(
467 'Please consider avoiding the "? true : false" pattern if possible.\n' +
468 '\n'.join(problems))]
469
470
[email protected]55f9f382012-07-31 11:02:18471def _CheckUnwantedDependencies(input_api, output_api):
472 """Runs checkdeps on #include statements added in this
473 change. Breaking - rules is an error, breaking ! rules is a
474 warning.
475 """
476 # We need to wait until we have an input_api object and use this
477 # roundabout construct to import checkdeps because this file is
478 # eval-ed and thus doesn't have __file__.
479 original_sys_path = sys.path
480 try:
481 sys.path = sys.path + [input_api.os_path.join(
482 input_api.PresubmitLocalPath(), 'tools', 'checkdeps')]
483 import checkdeps
484 from cpp_checker import CppChecker
485 from rules import Rule
486 finally:
487 # Restore sys.path to what it was before.
488 sys.path = original_sys_path
489
490 added_includes = []
491 for f in input_api.AffectedFiles():
492 if not CppChecker.IsCppFile(f.LocalPath()):
493 continue
494
495 changed_lines = [line for line_num, line in f.ChangedContents()]
496 added_includes.append([f.LocalPath(), changed_lines])
497
[email protected]26385172013-05-09 23:11:35498 deps_checker = checkdeps.DepsChecker(input_api.PresubmitLocalPath())
[email protected]55f9f382012-07-31 11:02:18499
500 error_descriptions = []
501 warning_descriptions = []
502 for path, rule_type, rule_description in deps_checker.CheckAddedCppIncludes(
503 added_includes):
504 description_with_path = '%s\n %s' % (path, rule_description)
505 if rule_type == Rule.DISALLOW:
506 error_descriptions.append(description_with_path)
507 else:
508 warning_descriptions.append(description_with_path)
509
510 results = []
511 if error_descriptions:
512 results.append(output_api.PresubmitError(
513 'You added one or more #includes that violate checkdeps rules.',
514 error_descriptions))
515 if warning_descriptions:
[email protected]f7051d52013-04-02 18:31:42516 results.append(output_api.PresubmitPromptOrNotify(
[email protected]55f9f382012-07-31 11:02:18517 'You added one or more #includes of files that are temporarily\n'
518 'allowed but being removed. Can you avoid introducing the\n'
519 '#include? See relevant DEPS file(s) for details and contacts.',
520 warning_descriptions))
521 return results
522
523
[email protected]fbcafe5a2012-08-08 15:31:22524def _CheckFilePermissions(input_api, output_api):
525 """Check that all files have their permissions properly set."""
526 args = [sys.executable, 'tools/checkperms/checkperms.py', '--root',
527 input_api.change.RepositoryRoot()]
528 for f in input_api.AffectedFiles():
529 args += ['--file', f.LocalPath()]
530 errors = []
531 (errors, stderrdata) = subprocess.Popen(args).communicate()
532
533 results = []
534 if errors:
[email protected]c8278b32012-10-30 20:35:49535 results.append(output_api.PresubmitError('checkperms.py failed.',
[email protected]fbcafe5a2012-08-08 15:31:22536 errors))
537 return results
538
539
[email protected]c8278b32012-10-30 20:35:49540def _CheckNoAuraWindowPropertyHInHeaders(input_api, output_api):
541 """Makes sure we don't include ui/aura/window_property.h
542 in header files.
543 """
544 pattern = input_api.re.compile(r'^#include\s*"ui/aura/window_property.h"')
545 errors = []
546 for f in input_api.AffectedFiles():
547 if not f.LocalPath().endswith('.h'):
548 continue
549 for line_num, line in f.ChangedContents():
550 if pattern.match(line):
551 errors.append(' %s:%d' % (f.LocalPath(), line_num))
552
553 results = []
554 if errors:
555 results.append(output_api.PresubmitError(
556 'Header files should not include ui/aura/window_property.h', errors))
557 return results
558
559
[email protected]cf9b78f2012-11-14 11:40:28560def _CheckIncludeOrderForScope(scope, input_api, file_path, changed_linenums):
561 """Checks that the lines in scope occur in the right order.
562
563 1. C system files in alphabetical order
564 2. C++ system files in alphabetical order
565 3. Project's .h files
566 """
567
568 c_system_include_pattern = input_api.re.compile(r'\s*#include <.*\.h>')
569 cpp_system_include_pattern = input_api.re.compile(r'\s*#include <.*>')
570 custom_include_pattern = input_api.re.compile(r'\s*#include ".*')
571
572 C_SYSTEM_INCLUDES, CPP_SYSTEM_INCLUDES, CUSTOM_INCLUDES = range(3)
573
574 state = C_SYSTEM_INCLUDES
575
576 previous_line = ''
[email protected]728b9bb2012-11-14 20:38:57577 previous_line_num = 0
[email protected]cf9b78f2012-11-14 11:40:28578 problem_linenums = []
579 for line_num, line in scope:
580 if c_system_include_pattern.match(line):
581 if state != C_SYSTEM_INCLUDES:
[email protected]728b9bb2012-11-14 20:38:57582 problem_linenums.append((line_num, previous_line_num))
[email protected]cf9b78f2012-11-14 11:40:28583 elif previous_line and previous_line > line:
[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 cpp_system_include_pattern.match(line):
586 if state == C_SYSTEM_INCLUDES:
587 state = CPP_SYSTEM_INCLUDES
588 elif state == CUSTOM_INCLUDES:
[email protected]728b9bb2012-11-14 20:38:57589 problem_linenums.append((line_num, previous_line_num))
[email protected]cf9b78f2012-11-14 11:40:28590 elif previous_line and previous_line > line:
[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 custom_include_pattern.match(line):
593 if state != CUSTOM_INCLUDES:
594 state = CUSTOM_INCLUDES
595 elif previous_line and previous_line > line:
[email protected]728b9bb2012-11-14 20:38:57596 problem_linenums.append((line_num, previous_line_num))
[email protected]cf9b78f2012-11-14 11:40:28597 else:
598 problem_linenums.append(line_num)
599 previous_line = line
[email protected]728b9bb2012-11-14 20:38:57600 previous_line_num = line_num
[email protected]cf9b78f2012-11-14 11:40:28601
602 warnings = []
[email protected]728b9bb2012-11-14 20:38:57603 for (line_num, previous_line_num) in problem_linenums:
604 if line_num in changed_linenums or previous_line_num in changed_linenums:
[email protected]cf9b78f2012-11-14 11:40:28605 warnings.append(' %s:%d' % (file_path, line_num))
606 return warnings
607
608
[email protected]ac294a12012-12-06 16:38:43609def _CheckIncludeOrderInFile(input_api, f, changed_linenums):
[email protected]cf9b78f2012-11-14 11:40:28610 """Checks the #include order for the given file f."""
611
[email protected]2299dcf2012-11-15 19:56:24612 system_include_pattern = input_api.re.compile(r'\s*#include \<.*')
[email protected]23093b62013-09-20 12:16:30613 # Exclude the following includes from the check:
614 # 1) #include <.../...>, e.g., <sys/...> includes often need to appear in a
615 # specific order.
616 # 2) <atlbase.h>, "build/build_config.h"
617 excluded_include_pattern = input_api.re.compile(
618 r'\s*#include (\<.*/.*|\<atlbase\.h\>|"build/build_config.h")')
[email protected]2299dcf2012-11-15 19:56:24619 custom_include_pattern = input_api.re.compile(r'\s*#include "(?P<FILE>.*)"')
[email protected]3e83618c2013-10-09 22:32:33620 # Match the final or penultimate token if it is xxxtest so we can ignore it
621 # when considering the special first include.
622 test_file_tag_pattern = input_api.re.compile(
623 r'_[a-z]+test(?=(_[a-zA-Z0-9]+)?\.)')
[email protected]0e5c1852012-12-18 20:17:11624 if_pattern = input_api.re.compile(
625 r'\s*#\s*(if|elif|else|endif|define|undef).*')
626 # Some files need specialized order of includes; exclude such files from this
627 # check.
628 uncheckable_includes_pattern = input_api.re.compile(
629 r'\s*#include '
630 '("ipc/.*macros\.h"|<windows\.h>|".*gl.*autogen.h")\s*')
[email protected]cf9b78f2012-11-14 11:40:28631
632 contents = f.NewContents()
633 warnings = []
634 line_num = 0
635
[email protected]ac294a12012-12-06 16:38:43636 # Handle the special first include. If the first include file is
637 # some/path/file.h, the corresponding including file can be some/path/file.cc,
638 # some/other/path/file.cc, some/path/file_platform.cc, some/path/file-suffix.h
639 # etc. It's also possible that no special first include exists.
[email protected]3e83618c2013-10-09 22:32:33640 # If the included file is some/path/file_platform.h the including file could
641 # also be some/path/file_xxxtest_platform.h.
642 including_file_base_name = test_file_tag_pattern.sub(
643 '', input_api.os_path.basename(f.LocalPath()))
644
[email protected]ac294a12012-12-06 16:38:43645 for line in contents:
646 line_num += 1
647 if system_include_pattern.match(line):
648 # No special first include -> process the line again along with normal
649 # includes.
650 line_num -= 1
651 break
652 match = custom_include_pattern.match(line)
653 if match:
654 match_dict = match.groupdict()
[email protected]3e83618c2013-10-09 22:32:33655 header_basename = test_file_tag_pattern.sub(
656 '', input_api.os_path.basename(match_dict['FILE'])).replace('.h', '')
657
658 if header_basename not in including_file_base_name:
[email protected]2299dcf2012-11-15 19:56:24659 # No special first include -> process the line again along with normal
660 # includes.
661 line_num -= 1
[email protected]ac294a12012-12-06 16:38:43662 break
[email protected]cf9b78f2012-11-14 11:40:28663
664 # Split into scopes: Each region between #if and #endif is its own scope.
665 scopes = []
666 current_scope = []
667 for line in contents[line_num:]:
668 line_num += 1
[email protected]0e5c1852012-12-18 20:17:11669 if uncheckable_includes_pattern.match(line):
670 return []
[email protected]2309b0fa02012-11-16 12:18:27671 if if_pattern.match(line):
[email protected]cf9b78f2012-11-14 11:40:28672 scopes.append(current_scope)
673 current_scope = []
[email protected]962f117e2012-11-22 18:11:56674 elif ((system_include_pattern.match(line) or
675 custom_include_pattern.match(line)) and
676 not excluded_include_pattern.match(line)):
[email protected]cf9b78f2012-11-14 11:40:28677 current_scope.append((line_num, line))
678 scopes.append(current_scope)
679
680 for scope in scopes:
681 warnings.extend(_CheckIncludeOrderForScope(scope, input_api, f.LocalPath(),
682 changed_linenums))
683 return warnings
684
685
686def _CheckIncludeOrder(input_api, output_api):
687 """Checks that the #include order is correct.
688
689 1. The corresponding header for source files.
690 2. C system files in alphabetical order
691 3. C++ system files in alphabetical order
692 4. Project's .h files in alphabetical order
693
[email protected]ac294a12012-12-06 16:38:43694 Each region separated by #if, #elif, #else, #endif, #define and #undef follows
695 these rules separately.
[email protected]cf9b78f2012-11-14 11:40:28696 """
697
698 warnings = []
699 for f in input_api.AffectedFiles():
[email protected]ac294a12012-12-06 16:38:43700 if f.LocalPath().endswith(('.cc', '.h')):
701 changed_linenums = set(line_num for line_num, _ in f.ChangedContents())
702 warnings.extend(_CheckIncludeOrderInFile(input_api, f, changed_linenums))
[email protected]cf9b78f2012-11-14 11:40:28703
704 results = []
705 if warnings:
[email protected]f7051d52013-04-02 18:31:42706 results.append(output_api.PresubmitPromptOrNotify(_INCLUDE_ORDER_WARNING,
[email protected]120cf540d2012-12-10 17:55:53707 warnings))
[email protected]cf9b78f2012-11-14 11:40:28708 return results
709
710
[email protected]70ca77752012-11-20 03:45:03711def _CheckForVersionControlConflictsInFile(input_api, f):
712 pattern = input_api.re.compile('^(?:<<<<<<<|>>>>>>>) |^=======$')
713 errors = []
714 for line_num, line in f.ChangedContents():
715 if pattern.match(line):
716 errors.append(' %s:%d %s' % (f.LocalPath(), line_num, line))
717 return errors
718
719
720def _CheckForVersionControlConflicts(input_api, output_api):
721 """Usually this is not intentional and will cause a compile failure."""
722 errors = []
723 for f in input_api.AffectedFiles():
724 errors.extend(_CheckForVersionControlConflictsInFile(input_api, f))
725
726 results = []
727 if errors:
728 results.append(output_api.PresubmitError(
729 'Version control conflict markers found, please resolve.', errors))
730 return results
731
732
[email protected]06e6d0ff2012-12-11 01:36:44733def _CheckHardcodedGoogleHostsInLowerLayers(input_api, output_api):
734 def FilterFile(affected_file):
735 """Filter function for use with input_api.AffectedSourceFiles,
736 below. This filters out everything except non-test files from
737 top-level directories that generally speaking should not hard-code
738 service URLs (e.g. src/android_webview/, src/content/ and others).
739 """
740 return input_api.FilterSourceFile(
741 affected_file,
[email protected]78bb39d62012-12-11 15:11:56742 white_list=(r'^(android_webview|base|content|net)[\\\/].*', ),
[email protected]06e6d0ff2012-12-11 01:36:44743 black_list=(_EXCLUDED_PATHS +
744 _TEST_CODE_EXCLUDED_PATHS +
745 input_api.DEFAULT_BLACK_LIST))
746
[email protected]de4f7d22013-05-23 14:27:46747 base_pattern = '"[^"]*google\.com[^"]*"'
748 comment_pattern = input_api.re.compile('//.*%s' % base_pattern)
749 pattern = input_api.re.compile(base_pattern)
[email protected]06e6d0ff2012-12-11 01:36:44750 problems = [] # items are (filename, line_number, line)
751 for f in input_api.AffectedSourceFiles(FilterFile):
752 for line_num, line in f.ChangedContents():
[email protected]de4f7d22013-05-23 14:27:46753 if not comment_pattern.search(line) and pattern.search(line):
[email protected]06e6d0ff2012-12-11 01:36:44754 problems.append((f.LocalPath(), line_num, line))
755
756 if problems:
[email protected]f7051d52013-04-02 18:31:42757 return [output_api.PresubmitPromptOrNotify(
[email protected]06e6d0ff2012-12-11 01:36:44758 'Most layers below src/chrome/ should not hardcode service URLs.\n'
759 'Are you sure this is correct? (Contact: [email protected])',
760 [' %s:%d: %s' % (
761 problem[0], problem[1], problem[2]) for problem in problems])]
[email protected]2fdd1f362013-01-16 03:56:03762 else:
763 return []
[email protected]06e6d0ff2012-12-11 01:36:44764
765
[email protected]d2530012013-01-25 16:39:27766def _CheckNoAbbreviationInPngFileName(input_api, output_api):
767 """Makes sure there are no abbreviations in the name of PNG files.
768 """
[email protected]4053a48e2013-01-25 21:43:04769 pattern = input_api.re.compile(r'.*_[a-z]_.*\.png$|.*_[a-z]\.png$')
[email protected]d2530012013-01-25 16:39:27770 errors = []
771 for f in input_api.AffectedFiles(include_deletes=False):
772 if pattern.match(f.LocalPath()):
773 errors.append(' %s' % f.LocalPath())
774
775 results = []
776 if errors:
777 results.append(output_api.PresubmitError(
778 'The name of PNG files should not have abbreviations. \n'
779 'Use _hover.png, _center.png, instead of _h.png, _c.png.\n'
780 'Contact [email protected] if you have questions.', errors))
781 return results
782
783
[email protected]f32e2d1e2013-07-26 21:39:08784def _DepsFilesToCheck(re, changed_lines):
785 """Helper method for _CheckAddedDepsHaveTargetApprovals. Returns
786 a set of DEPS entries that we should look up."""
[email protected]2b438d62013-11-14 17:54:14787 # We ignore deps entries on auto-generated directories.
788 AUTO_GENERATED_DIRS = ['grit', 'jni']
[email protected]f32e2d1e2013-07-26 21:39:08789
790 # This pattern grabs the path without basename in the first
791 # parentheses, and the basename (if present) in the second. It
792 # relies on the simple heuristic that if there is a basename it will
793 # be a header file ending in ".h".
794 pattern = re.compile(
795 r"""['"]\+([^'"]+?)(/[a-zA-Z0-9_]+\.h)?['"].*""")
[email protected]2b438d62013-11-14 17:54:14796 results = set()
[email protected]f32e2d1e2013-07-26 21:39:08797 for changed_line in changed_lines:
798 m = pattern.match(changed_line)
799 if m:
800 path = m.group(1)
[email protected]2b438d62013-11-14 17:54:14801 if path.split('/')[0] not in AUTO_GENERATED_DIRS:
[email protected]f32e2d1e2013-07-26 21:39:08802 results.add('%s/DEPS' % m.group(1))
803 return results
804
805
[email protected]e871964c2013-05-13 14:14:55806def _CheckAddedDepsHaveTargetApprovals(input_api, output_api):
807 """When a dependency prefixed with + is added to a DEPS file, we
808 want to make sure that the change is reviewed by an OWNER of the
809 target file or directory, to avoid layering violations from being
810 introduced. This check verifies that this happens.
811 """
812 changed_lines = set()
813 for f in input_api.AffectedFiles():
814 filename = input_api.os_path.basename(f.LocalPath())
815 if filename == 'DEPS':
816 changed_lines |= set(line.strip()
817 for line_num, line
818 in f.ChangedContents())
819 if not changed_lines:
820 return []
821
[email protected]f32e2d1e2013-07-26 21:39:08822 virtual_depended_on_files = _DepsFilesToCheck(input_api.re, changed_lines)
[email protected]e871964c2013-05-13 14:14:55823 if not virtual_depended_on_files:
824 return []
825
826 if input_api.is_committing:
827 if input_api.tbr:
828 return [output_api.PresubmitNotifyResult(
829 '--tbr was specified, skipping OWNERS check for DEPS additions')]
830 if not input_api.change.issue:
831 return [output_api.PresubmitError(
832 "DEPS approval by OWNERS check failed: this change has "
833 "no Rietveld issue number, so we can't check it for approvals.")]
834 output = output_api.PresubmitError
835 else:
836 output = output_api.PresubmitNotifyResult
837
838 owners_db = input_api.owners_db
839 owner_email, reviewers = input_api.canned_checks._RietveldOwnerAndReviewers(
840 input_api,
841 owners_db.email_regexp,
842 approval_needed=input_api.is_committing)
843
844 owner_email = owner_email or input_api.change.author_email
845
[email protected]de4f7d22013-05-23 14:27:46846 reviewers_plus_owner = set(reviewers)
[email protected]e71c6082013-05-22 02:28:51847 if owner_email:
[email protected]de4f7d22013-05-23 14:27:46848 reviewers_plus_owner.add(owner_email)
[email protected]e871964c2013-05-13 14:14:55849 missing_files = owners_db.files_not_covered_by(virtual_depended_on_files,
850 reviewers_plus_owner)
851 unapproved_dependencies = ["'+%s'," % path[:-len('/DEPS')]
852 for path in missing_files]
853
854 if unapproved_dependencies:
855 output_list = [
856 output('Missing LGTM from OWNERS of directories added to DEPS:\n %s' %
857 '\n '.join(sorted(unapproved_dependencies)))]
858 if not input_api.is_committing:
859 suggested_owners = owners_db.reviewers_for(missing_files, owner_email)
860 output_list.append(output(
861 'Suggested missing target path OWNERS:\n %s' %
862 '\n '.join(suggested_owners or [])))
863 return output_list
864
865 return []
866
867
[email protected]85218562013-11-22 07:41:40868def _CheckSpamLogging(input_api, output_api):
869 file_inclusion_pattern = r'.+%s' % _IMPLEMENTATION_EXTENSIONS
870 black_list = (_EXCLUDED_PATHS +
871 _TEST_CODE_EXCLUDED_PATHS +
872 input_api.DEFAULT_BLACK_LIST +
[email protected]6f742dd02013-11-26 23:19:50873 (r"^base[\\\/]logging\.h$",
[email protected]8dc338c2013-12-09 16:28:48874 r"^chrome[\\\/]app[\\\/]chrome_main_delegate\.cc$",
[email protected]6e268db2013-12-04 01:41:46875 r"^chrome[\\\/]browser[\\\/]chrome_browser_main\.cc$",
[email protected]4de75262013-12-18 23:16:12876 r"^chrome[\\\/]browser[\\\/]ui[\\\/]startup[\\\/]"
877 r"startup_browser_creator\.cc$",
[email protected]fe0e6e12013-12-04 05:52:58878 r"^chrome[\\\/]installer[\\\/]setup[\\\/].*",
[email protected]95c6b3012013-12-02 14:30:31879 r"^chrome[\\\/]renderer[\\\/]extensions[\\\/]"
[email protected]6e268db2013-12-04 01:41:46880 r"logging_native_handler\.cc$",
[email protected]cdbdced2013-11-27 21:35:50881 r"^remoting[\\\/]base[\\\/]logging\.h$",
[email protected]67c96ab2013-12-17 02:05:36882 r"^remoting[\\\/]host[\\\/].*",
[email protected]8232f8fd2013-12-14 00:52:31883 r"^sandbox[\\\/]linux[\\\/].*",
884 r"^ui[\\\/]aura[\\\/]bench[\\\/]bench_main\.cc$",))
[email protected]85218562013-11-22 07:41:40885 source_file_filter = lambda x: input_api.FilterSourceFile(
886 x, white_list=(file_inclusion_pattern,), black_list=black_list)
887
888 log_info = []
889 printf = []
890
891 for f in input_api.AffectedSourceFiles(source_file_filter):
892 contents = input_api.ReadFile(f, 'rb')
893 if re.search(r"\bD?LOG\s*\(\s*INFO\s*\)", contents):
894 log_info.append(f.LocalPath())
[email protected]18b466b2013-12-02 22:01:37895 elif re.search(r"\bD?LOG_IF\s*\(\s*INFO\s*,", contents):
[email protected]85210652013-11-28 05:50:13896 log_info.append(f.LocalPath())
[email protected]18b466b2013-12-02 22:01:37897
898 if re.search(r"\bprintf\(", contents):
899 printf.append(f.LocalPath())
900 elif re.search(r"\bfprintf\((stdout|stderr)", contents):
[email protected]85218562013-11-22 07:41:40901 printf.append(f.LocalPath())
902
903 if log_info:
904 return [output_api.PresubmitError(
905 'These files spam the console log with LOG(INFO):',
906 items=log_info)]
907 if printf:
908 return [output_api.PresubmitError(
909 'These files spam the console log with printf/fprintf:',
910 items=printf)]
911 return []
912
913
[email protected]49aa76a2013-12-04 06:59:16914def _CheckForAnonymousVariables(input_api, output_api):
915 """These types are all expected to hold locks while in scope and
916 so should never be anonymous (which causes them to be immediately
917 destroyed)."""
918 they_who_must_be_named = [
919 'base::AutoLock',
920 'base::AutoReset',
921 'base::AutoUnlock',
922 'SkAutoAlphaRestore',
923 'SkAutoBitmapShaderInstall',
924 'SkAutoBlitterChoose',
925 'SkAutoBounderCommit',
926 'SkAutoCallProc',
927 'SkAutoCanvasRestore',
928 'SkAutoCommentBlock',
929 'SkAutoDescriptor',
930 'SkAutoDisableDirectionCheck',
931 'SkAutoDisableOvalCheck',
932 'SkAutoFree',
933 'SkAutoGlyphCache',
934 'SkAutoHDC',
935 'SkAutoLockColors',
936 'SkAutoLockPixels',
937 'SkAutoMalloc',
938 'SkAutoMaskFreeImage',
939 'SkAutoMutexAcquire',
940 'SkAutoPathBoundsUpdate',
941 'SkAutoPDFRelease',
942 'SkAutoRasterClipValidate',
943 'SkAutoRef',
944 'SkAutoTime',
945 'SkAutoTrace',
946 'SkAutoUnref',
947 ]
948 anonymous = r'(%s)\s*[({]' % '|'.join(they_who_must_be_named)
949 # bad: base::AutoLock(lock.get());
950 # not bad: base::AutoLock lock(lock.get());
951 bad_pattern = input_api.re.compile(anonymous)
952 # good: new base::AutoLock(lock.get())
953 good_pattern = input_api.re.compile(r'\bnew\s*' + anonymous)
954 errors = []
955
956 for f in input_api.AffectedFiles():
957 if not f.LocalPath().endswith(('.cc', '.h', '.inl', '.m', '.mm')):
958 continue
959 for linenum, line in f.ChangedContents():
960 if bad_pattern.search(line) and not good_pattern.search(line):
961 errors.append('%s:%d' % (f.LocalPath(), linenum))
962
963 if errors:
964 return [output_api.PresubmitError(
965 'These lines create anonymous variables that need to be named:',
966 items=errors)]
967 return []
968
969
[email protected]5fe0f8742013-11-29 01:04:59970def _CheckCygwinShell(input_api, output_api):
971 source_file_filter = lambda x: input_api.FilterSourceFile(
972 x, white_list=(r'.+\.(gyp|gypi)$',))
973 cygwin_shell = []
974
975 for f in input_api.AffectedSourceFiles(source_file_filter):
976 for linenum, line in f.ChangedContents():
977 if 'msvs_cygwin_shell' in line:
978 cygwin_shell.append(f.LocalPath())
979 break
980
981 if cygwin_shell:
982 return [output_api.PresubmitError(
983 'These files should not use msvs_cygwin_shell (the default is 0):',
984 items=cygwin_shell)]
985 return []
986
[email protected]85218562013-11-22 07:41:40987
[email protected]760deea2013-12-10 19:33:49988def _CheckJavaStyle(input_api, output_api):
989 """Runs checkstyle on changed java files and returns errors if any exist."""
990 original_sys_path = sys.path
991 try:
992 sys.path = sys.path + [input_api.os_path.join(
993 input_api.PresubmitLocalPath(), 'tools', 'android', 'checkstyle')]
994 import checkstyle
995 finally:
996 # Restore sys.path to what it was before.
997 sys.path = original_sys_path
998
999 return checkstyle.RunCheckstyle(
1000 input_api, output_api, 'tools/android/checkstyle/chromium-style-5.0.xml')
1001
1002
[email protected]22c9bd72011-03-27 16:47:391003def _CommonChecks(input_api, output_api):
1004 """Checks common to both upload and commit."""
1005 results = []
1006 results.extend(input_api.canned_checks.PanProjectChecks(
[email protected]3de922f2013-12-20 13:27:381007 input_api, output_api,
1008 excluded_paths=_EXCLUDED_PATHS + _TESTRUNNER_PATHS))
[email protected]66daa702011-05-28 14:41:461009 results.extend(_CheckAuthorizedAuthor(input_api, output_api))
[email protected]55459852011-08-10 15:17:191010 results.extend(
[email protected]760deea2013-12-10 19:33:491011 _CheckNoProductionCodeUsingTestOnlyFunctions(input_api, output_api))
[email protected]10689ca2011-09-02 02:31:541012 results.extend(_CheckNoIOStreamInHeaders(input_api, output_api))
[email protected]72df4e782012-06-21 16:28:181013 results.extend(_CheckNoUNIT_TESTInSourceFiles(input_api, output_api))
[email protected]8ea5d4b2011-09-13 21:49:221014 results.extend(_CheckNoNewWStrings(input_api, output_api))
[email protected]2a8ac9c2011-10-19 17:20:441015 results.extend(_CheckNoDEPSGIT(input_api, output_api))
[email protected]127f18ec2012-06-16 05:05:591016 results.extend(_CheckNoBannedFunctions(input_api, output_api))
[email protected]6c063c62012-07-11 19:11:061017 results.extend(_CheckNoPragmaOnce(input_api, output_api))
[email protected]e7479052012-09-19 00:26:121018 results.extend(_CheckNoTrinaryTrueFalse(input_api, output_api))
[email protected]55f9f382012-07-31 11:02:181019 results.extend(_CheckUnwantedDependencies(input_api, output_api))
[email protected]fbcafe5a2012-08-08 15:31:221020 results.extend(_CheckFilePermissions(input_api, output_api))
[email protected]c8278b32012-10-30 20:35:491021 results.extend(_CheckNoAuraWindowPropertyHInHeaders(input_api, output_api))
[email protected]2309b0fa02012-11-16 12:18:271022 results.extend(_CheckIncludeOrder(input_api, output_api))
[email protected]70ca77752012-11-20 03:45:031023 results.extend(_CheckForVersionControlConflicts(input_api, output_api))
[email protected]b8079ae4a2012-12-05 19:56:491024 results.extend(_CheckPatchFiles(input_api, output_api))
[email protected]06e6d0ff2012-12-11 01:36:441025 results.extend(_CheckHardcodedGoogleHostsInLowerLayers(input_api, output_api))
[email protected]d2530012013-01-25 16:39:271026 results.extend(_CheckNoAbbreviationInPngFileName(input_api, output_api))
[email protected]b00342e7f2013-03-26 16:21:541027 results.extend(_CheckForInvalidOSMacros(input_api, output_api))
[email protected]e871964c2013-05-13 14:14:551028 results.extend(_CheckAddedDepsHaveTargetApprovals(input_api, output_api))
[email protected]9f919cc2013-07-31 03:04:041029 results.extend(
1030 input_api.canned_checks.CheckChangeHasNoTabs(
1031 input_api,
1032 output_api,
1033 source_file_filter=lambda x: x.LocalPath().endswith('.grd')))
[email protected]85218562013-11-22 07:41:401034 results.extend(_CheckSpamLogging(input_api, output_api))
[email protected]49aa76a2013-12-04 06:59:161035 results.extend(_CheckForAnonymousVariables(input_api, output_api))
[email protected]5fe0f8742013-11-29 01:04:591036 results.extend(_CheckCygwinShell(input_api, output_api))
[email protected]760deea2013-12-10 19:33:491037 results.extend(_CheckJavaStyle(input_api, output_api))
[email protected]2299dcf2012-11-15 19:56:241038
1039 if any('PRESUBMIT.py' == f.LocalPath() for f in input_api.AffectedFiles()):
1040 results.extend(input_api.canned_checks.RunUnitTestsInDirectory(
1041 input_api, output_api,
1042 input_api.PresubmitLocalPath(),
[email protected]6be63382013-01-21 15:42:381043 whitelist=[r'^PRESUBMIT_test\.py$']))
[email protected]22c9bd72011-03-27 16:47:391044 return results
[email protected]1f7b4172010-01-28 01:17:341045
[email protected]b337cb5b2011-01-23 21:24:051046
1047def _CheckSubversionConfig(input_api, output_api):
1048 """Verifies the subversion config file is correctly setup.
1049
1050 Checks that autoprops are enabled, returns an error otherwise.
1051 """
1052 join = input_api.os_path.join
1053 if input_api.platform == 'win32':
1054 appdata = input_api.environ.get('APPDATA', '')
1055 if not appdata:
1056 return [output_api.PresubmitError('%APPDATA% is not configured.')]
1057 path = join(appdata, 'Subversion', 'config')
1058 else:
1059 home = input_api.environ.get('HOME', '')
1060 if not home:
1061 return [output_api.PresubmitError('$HOME is not configured.')]
1062 path = join(home, '.subversion', 'config')
1063
1064 error_msg = (
1065 'Please look at http://dev.chromium.org/developers/coding-style to\n'
1066 'configure your subversion configuration file. This enables automatic\n'
[email protected]c6a3c10b2011-01-24 16:14:201067 'properties to simplify the project maintenance.\n'
1068 'Pro-tip: just download and install\n'
1069 'http://src.chromium.org/viewvc/chrome/trunk/tools/build/slave/config\n')
[email protected]b337cb5b2011-01-23 21:24:051070
1071 try:
1072 lines = open(path, 'r').read().splitlines()
1073 # Make sure auto-props is enabled and check for 2 Chromium standard
1074 # auto-prop.
1075 if (not '*.cc = svn:eol-style=LF' in lines or
1076 not '*.pdf = svn:mime-type=application/pdf' in lines or
1077 not 'enable-auto-props = yes' in lines):
1078 return [
[email protected]79ed7e62011-02-21 21:08:531079 output_api.PresubmitNotifyResult(
[email protected]b337cb5b2011-01-23 21:24:051080 'It looks like you have not configured your subversion config '
[email protected]b5359c02011-02-01 20:29:561081 'file or it is not up-to-date.\n' + error_msg)
[email protected]b337cb5b2011-01-23 21:24:051082 ]
1083 except (OSError, IOError):
1084 return [
[email protected]79ed7e62011-02-21 21:08:531085 output_api.PresubmitNotifyResult(
[email protected]b337cb5b2011-01-23 21:24:051086 'Can\'t find your subversion config file.\n' + error_msg)
1087 ]
1088 return []
1089
1090
[email protected]66daa702011-05-28 14:41:461091def _CheckAuthorizedAuthor(input_api, output_api):
1092 """For non-googler/chromites committers, verify the author's email address is
1093 in AUTHORS.
1094 """
[email protected]9bb9cb82011-06-13 20:43:011095 # TODO(maruel): Add it to input_api?
1096 import fnmatch
1097
[email protected]66daa702011-05-28 14:41:461098 author = input_api.change.author_email
[email protected]9bb9cb82011-06-13 20:43:011099 if not author:
1100 input_api.logging.info('No author, skipping AUTHOR check')
[email protected]66daa702011-05-28 14:41:461101 return []
[email protected]c99663292011-05-31 19:46:081102 authors_path = input_api.os_path.join(
[email protected]66daa702011-05-28 14:41:461103 input_api.PresubmitLocalPath(), 'AUTHORS')
1104 valid_authors = (
1105 input_api.re.match(r'[^#]+\s+\<(.+?)\>\s*$', line)
1106 for line in open(authors_path))
[email protected]ac54b132011-06-06 18:11:181107 valid_authors = [item.group(1).lower() for item in valid_authors if item]
[email protected]d8b50be2011-06-15 14:19:441108 if not any(fnmatch.fnmatch(author.lower(), valid) for valid in valid_authors):
[email protected]5861efb2013-01-07 18:33:231109 input_api.logging.info('Valid authors are %s', ', '.join(valid_authors))
[email protected]66daa702011-05-28 14:41:461110 return [output_api.PresubmitPromptWarning(
1111 ('%s is not in AUTHORS file. If you are a new contributor, please visit'
1112 '\n'
1113 'http://www.chromium.org/developers/contributing-code and read the '
1114 '"Legal" section\n'
1115 'If you are a chromite, verify the contributor signed the CLA.') %
1116 author)]
1117 return []
1118
1119
[email protected]b8079ae4a2012-12-05 19:56:491120def _CheckPatchFiles(input_api, output_api):
1121 problems = [f.LocalPath() for f in input_api.AffectedFiles()
1122 if f.LocalPath().endswith(('.orig', '.rej'))]
1123 if problems:
1124 return [output_api.PresubmitError(
1125 "Don't commit .rej and .orig files.", problems)]
[email protected]2fdd1f362013-01-16 03:56:031126 else:
1127 return []
[email protected]b8079ae4a2012-12-05 19:56:491128
1129
[email protected]b00342e7f2013-03-26 16:21:541130def _DidYouMeanOSMacro(bad_macro):
1131 try:
1132 return {'A': 'OS_ANDROID',
1133 'B': 'OS_BSD',
1134 'C': 'OS_CHROMEOS',
1135 'F': 'OS_FREEBSD',
1136 'L': 'OS_LINUX',
1137 'M': 'OS_MACOSX',
1138 'N': 'OS_NACL',
1139 'O': 'OS_OPENBSD',
1140 'P': 'OS_POSIX',
1141 'S': 'OS_SOLARIS',
1142 'W': 'OS_WIN'}[bad_macro[3].upper()]
1143 except KeyError:
1144 return ''
1145
1146
1147def _CheckForInvalidOSMacrosInFile(input_api, f):
1148 """Check for sensible looking, totally invalid OS macros."""
1149 preprocessor_statement = input_api.re.compile(r'^\s*#')
1150 os_macro = input_api.re.compile(r'defined\((OS_[^)]+)\)')
1151 results = []
1152 for lnum, line in f.ChangedContents():
1153 if preprocessor_statement.search(line):
1154 for match in os_macro.finditer(line):
1155 if not match.group(1) in _VALID_OS_MACROS:
1156 good = _DidYouMeanOSMacro(match.group(1))
1157 did_you_mean = ' (did you mean %s?)' % good if good else ''
1158 results.append(' %s:%d %s%s' % (f.LocalPath(),
1159 lnum,
1160 match.group(1),
1161 did_you_mean))
1162 return results
1163
1164
1165def _CheckForInvalidOSMacros(input_api, output_api):
1166 """Check all affected files for invalid OS macros."""
1167 bad_macros = []
1168 for f in input_api.AffectedFiles():
1169 if not f.LocalPath().endswith(('.py', '.js', '.html', '.css')):
1170 bad_macros.extend(_CheckForInvalidOSMacrosInFile(input_api, f))
1171
1172 if not bad_macros:
1173 return []
1174
1175 return [output_api.PresubmitError(
1176 'Possibly invalid OS macro[s] found. Please fix your code\n'
1177 'or add your macro to src/PRESUBMIT.py.', bad_macros)]
1178
1179
[email protected]1f7b4172010-01-28 01:17:341180def CheckChangeOnUpload(input_api, output_api):
1181 results = []
1182 results.extend(_CommonChecks(input_api, output_api))
[email protected]fe5f57c52009-06-05 14:25:541183 return results
[email protected]ca8d1982009-02-19 16:33:121184
1185
[email protected]38c6a512013-12-18 23:48:011186def GetDefaultTryConfigs(bots=None):
1187 """Returns a list of ('bot', set(['tests']), optionally filtered by [bots].
1188
1189 To add tests to this list, they MUST be in the the corresponding master's
1190 gatekeeper config. For example, anything on master.chromium would be closed by
1191 tools/build/masters/master.chromium/master_gatekeeper_cfg.py.
1192
1193 If 'bots' is specified, will only return configurations for bots in that list.
1194 """
1195
1196 standard_tests = [
1197 'base_unittests',
1198 'browser_tests',
1199 'cacheinvalidation_unittests',
1200 'check_deps',
1201 'check_deps2git',
1202 'content_browsertests',
1203 'content_unittests',
1204 'crypto_unittests',
1205 #'gfx_unittests',
1206 'gpu_unittests',
1207 'interactive_ui_tests',
1208 'ipc_tests',
1209 'jingle_unittests',
1210 'media_unittests',
1211 'net_unittests',
1212 'ppapi_unittests',
1213 'printing_unittests',
1214 'sql_unittests',
1215 'sync_unit_tests',
1216 'unit_tests',
1217 # Broken in release.
1218 #'url_unittests',
1219 #'webkit_unit_tests',
1220 ]
1221
1222 linux_aura_tests = [
1223 'app_list_unittests',
1224 'aura_unittests',
1225 'browser_tests',
1226 'compositor_unittests',
1227 'content_browsertests',
1228 'content_unittests',
1229 'events_unittests',
1230 'interactive_ui_tests',
1231 'unit_tests',
1232 ]
1233 builders_and_tests = {
1234 # TODO(maruel): Figure out a way to run 'sizes' where people can
1235 # effectively update the perf expectation correctly. This requires a
1236 # clobber=True build running 'sizes'. 'sizes' is not accurate with
1237 # incremental build. Reference:
1238 # http://chromium.org/developers/tree-sheriffs/perf-sheriffs.
1239 # TODO(maruel): An option would be to run 'sizes' but not count a failure
1240 # of this step as a try job failure.
1241 'android_aosp': ['compile'],
1242 'android_clang_dbg': ['slave_steps'],
1243 'android_dbg': ['slave_steps'],
1244 'cros_x86': ['defaulttests'],
1245 'ios_dbg_simulator': [
1246 'compile',
1247 'base_unittests',
1248 'content_unittests',
1249 'crypto_unittests',
1250 'url_unittests',
1251 'net_unittests',
1252 'sql_unittests',
1253 'ui_unittests',
1254 ],
1255 'ios_rel_device': ['compile'],
1256 'linux_asan': ['defaulttests'],
1257 #TODO(stip): Change the name of this builder to reflect that it's release.
1258 'linux_aura': linux_aura_tests,
1259 'linux_chromeos_asan': ['defaulttests'],
1260 'linux_chromeos_clang': ['compile'],
1261 # Note: It is a Release builder even if its name convey otherwise.
1262 'linux_chromeos': standard_tests + [
1263 'app_list_unittests',
1264 'aura_unittests',
1265 'ash_unittests',
1266 'chromeos_unittests',
1267 'components_unittests',
1268 'dbus_unittests',
1269 'device_unittests',
1270 'events_unittests',
1271 'google_apis_unittests',
1272 'sandbox_linux_unittests',
1273 ],
[email protected]23c81d552014-01-07 13:45:461274 'linux_chromium_dbg': ['defaulttests'],
1275 'linux_chromium_rel': ['defaulttests'],
[email protected]38c6a512013-12-18 23:48:011276 'linux_clang': ['compile'],
1277 'linux_rel': standard_tests + [
1278 'cc_unittests',
[email protected]5d0413fc2014-01-03 18:24:301279 'chromedriver_unittests',
[email protected]38c6a512013-12-18 23:48:011280 'components_unittests',
1281 'google_apis_unittests',
1282 'nacl_integration',
1283 'remoting_unittests',
1284 'sandbox_linux_unittests',
1285 'sync_integration_tests',
1286 ],
1287 'mac': ['compile'],
[email protected]23c81d552014-01-07 13:45:461288 'mac_chromium_dbg': ['defaulttests'],
1289 'mac_chromium_rel': ['defaulttests'],
[email protected]38c6a512013-12-18 23:48:011290 'mac_rel': standard_tests + [
1291 'app_list_unittests',
1292 'cc_unittests',
[email protected]5d0413fc2014-01-03 18:24:301293 'chromedriver_unittests',
[email protected]38c6a512013-12-18 23:48:011294 'components_unittests',
1295 'google_apis_unittests',
1296 'message_center_unittests',
1297 'nacl_integration',
1298 'remoting_unittests',
1299 'sync_integration_tests',
1300 'telemetry_unittests',
1301 ],
1302 'win': ['compile'],
1303 'win_rel': standard_tests + [
1304 'app_list_unittests',
1305 'ash_unittests',
1306 'aura_unittests',
1307 'cc_unittests',
1308 'chrome_elf_unittests',
[email protected]5d0413fc2014-01-03 18:24:301309 'chromedriver_unittests',
[email protected]38c6a512013-12-18 23:48:011310 'components_unittests',
1311 'compositor_unittests',
1312 'events_unittests',
1313 'google_apis_unittests',
1314 'installer_util_unittests',
1315 'mini_installer_test',
1316 'nacl_integration',
1317 'remoting_unittests',
1318 'sync_integration_tests',
1319 'telemetry_unittests',
1320 'views_unittests',
1321 ],
1322 'win_x64_rel': [
1323 'base_unittests',
1324 ],
1325 }
1326
1327 swarm_enabled_builders = (
1328 'linux_rel',
1329 'mac_rel',
1330 'win_rel',
1331 )
1332
1333 swarm_enabled_tests = (
1334 'base_unittests',
1335 'browser_tests',
1336 'interactive_ui_tests',
1337 'net_unittests',
1338 'unit_tests',
1339 )
1340
1341 for bot in builders_and_tests:
1342 if bot in swarm_enabled_builders:
1343 builders_and_tests[bot] = [x + '_swarm' if x in swarm_enabled_tests else x
1344 for x in builders_and_tests[bot]]
1345
1346 if bots:
1347 return [(bot, set(builders_and_tests[bot])) for bot in bots]
1348 else:
1349 return [(bot, set(tests)) for bot, tests in builders_and_tests.iteritems()]
1350
1351
[email protected]ca8d1982009-02-19 16:33:121352def CheckChangeOnCommit(input_api, output_api):
[email protected]fe5f57c52009-06-05 14:25:541353 results = []
[email protected]1f7b4172010-01-28 01:17:341354 results.extend(_CommonChecks(input_api, output_api))
[email protected]dd805fe2009-10-01 08:11:511355 # TODO(thestig) temporarily disabled, doesn't work in third_party/
1356 #results.extend(input_api.canned_checks.CheckSvnModifiedDirectories(
1357 # input_api, output_api, sources))
[email protected]fe5f57c52009-06-05 14:25:541358 # Make sure the tree is 'open'.
[email protected]806e98e2010-03-19 17:49:271359 results.extend(input_api.canned_checks.CheckTreeIsOpen(
[email protected]7f238152009-08-12 19:00:341360 input_api,
1361 output_api,
[email protected]2fdd1f362013-01-16 03:56:031362 json_url='http://chromium-status.appspot.com/current?format=json'))
[email protected]806e98e2010-03-19 17:49:271363 results.extend(input_api.canned_checks.CheckRietveldTryJobExecution(input_api,
[email protected]2fdd1f362013-01-16 03:56:031364 output_api, 'http://codereview.chromium.org',
[email protected]c1ba4c52012-03-09 14:23:281365 ('win_rel', 'linux_rel', 'mac_rel, win:compile'),
1366 '[email protected]'))
[email protected]806e98e2010-03-19 17:49:271367
[email protected]3e4eb112011-01-18 03:29:541368 results.extend(input_api.canned_checks.CheckChangeHasBugField(
1369 input_api, output_api))
[email protected]c4b47562011-12-05 23:39:411370 results.extend(input_api.canned_checks.CheckChangeHasDescription(
1371 input_api, output_api))
[email protected]b337cb5b2011-01-23 21:24:051372 results.extend(_CheckSubversionConfig(input_api, output_api))
[email protected]fe5f57c52009-06-05 14:25:541373 return results
[email protected]ca8d1982009-02-19 16:33:121374
1375
[email protected]5efb2a822011-09-27 23:06:131376def GetPreferredTrySlaves(project, change):
[email protected]4ce995ea2012-06-27 02:13:101377 files = change.LocalPaths()
1378
[email protected]751b05f2013-01-10 23:12:171379 if not files or all(re.search(r'[\\/]OWNERS$', f) for f in files):
[email protected]3019c902012-06-29 00:09:031380 return []
1381
[email protected]d668899a2012-09-06 18:16:591382 if all(re.search('\.(m|mm)$|(^|[/_])mac[/_.]', f) for f in files):
[email protected]38c6a512013-12-18 23:48:011383 return GetDefaultTryConfigs(['mac', 'mac_rel'])
[email protected]d668899a2012-09-06 18:16:591384 if all(re.search('(^|[/_])win[/_.]', f) for f in files):
[email protected]3630be892013-12-19 05:34:281385 return GetDefaultTryConfigs(['win', 'win_rel'])
[email protected]d668899a2012-09-06 18:16:591386 if all(re.search('(^|[/_])android[/_.]', f) for f in files):
[email protected]38c6a512013-12-18 23:48:011387 return GetDefaultTryConfigs([
1388 'android_aosp',
1389 'android_clang_dbg',
1390 'android_dbg',
1391 ])
[email protected]356aa542012-09-19 23:31:291392 if all(re.search('^native_client_sdk', f) for f in files):
[email protected]38c6a512013-12-18 23:48:011393 return GetDefaultTryConfigs([
1394 'linux_nacl_sdk',
1395 'mac_nacl_sdk',
1396 'win_nacl_sdk',
1397 ])
[email protected]de142152012-10-03 23:02:451398 if all(re.search('[/_]ios[/_.]', f) for f in files):
[email protected]38c6a512013-12-18 23:48:011399 return GetDefaultTryConfigs(['ios_rel_device', 'ios_dbg_simulator'])
[email protected]4ce995ea2012-06-27 02:13:101400
[email protected]38c6a512013-12-18 23:48:011401 trybots = GetDefaultTryConfigs([
[email protected]3e2f0402012-11-02 16:28:011402 'android_clang_dbg',
1403 'android_dbg',
1404 'ios_dbg_simulator',
1405 'ios_rel_device',
[email protected]95c989162012-11-29 05:58:251406 'linux_aura',
[email protected]38c6a512013-12-18 23:48:011407 'linux_asan',
[email protected]3e2f0402012-11-02 16:28:011408 'linux_chromeos',
[email protected]38c6a512013-12-18 23:48:011409 'linux_clang',
[email protected]3e2f0402012-11-02 16:28:011410 'linux_rel',
[email protected]38c6a512013-12-18 23:48:011411 'mac',
[email protected]3e2f0402012-11-02 16:28:011412 'mac_rel',
[email protected]38c6a512013-12-18 23:48:011413 'win',
[email protected]3e2f0402012-11-02 16:28:011414 'win_rel',
[email protected]38c6a512013-12-18 23:48:011415 'win_x64_rel',
1416 ])
[email protected]911753b2012-08-02 12:11:541417
1418 # Match things like path/aura/file.cc and path/file_aura.cc.
[email protected]95c989162012-11-29 05:58:251419 # Same for chromeos.
1420 if any(re.search('[/_](aura|chromeos)', f) for f in files):
[email protected]38c6a512013-12-18 23:48:011421 trybots.extend(GetDefaultTryConfigs([
1422 'linux_chromeos_asan', 'linux_chromeos_clang']))
[email protected]4ce995ea2012-06-27 02:13:101423
[email protected]e8df48f2013-09-30 20:07:541424 # If there are gyp changes to base, build, or chromeos, run a full cros build
1425 # in addition to the shorter linux_chromeos build. Changes to high level gyp
1426 # files have a much higher chance of breaking the cros build, which is
1427 # differnt from the linux_chromeos build that most chrome developers test
1428 # with.
1429 if any(re.search('^(base|build|chromeos).*\.gypi?$', f) for f in files):
[email protected]38c6a512013-12-18 23:48:011430 trybots.extend(GetDefaultTryConfigs(['cros_x86']))
[email protected]e8df48f2013-09-30 20:07:541431
[email protected]d95948ef2013-07-02 10:51:001432 # The AOSP bot doesn't build the chrome/ layer, so ignore any changes to it
1433 # unless they're .gyp(i) files as changes to those files can break the gyp
1434 # step on that bot.
1435 if (not all(re.search('^chrome', f) for f in files) or
1436 any(re.search('\.gypi?$', f) for f in files)):
[email protected]38c6a512013-12-18 23:48:011437 trybots.extend(GetDefaultTryConfigs(['android_aosp']))
[email protected]d95948ef2013-07-02 10:51:001438
[email protected]23c81d552014-01-07 13:45:461439 # Experimental recipe-based Chromium trybots. To avoid possible capacity
1440 # problems, only enable for a small percentage of try runs.
1441 if random.random() < 0.01:
1442 trybots.extend(GetDefaultTryConfigs([
1443 'linux_chromium_dbg',
1444 'linux_chromium_rel',
1445 'mac_chromium_dbg',
1446 'mac_chromium_rel',
1447 ]))
1448
[email protected]4ce995ea2012-06-27 02:13:101449 return trybots