blob: 0cd69c99ecbc5e9dae012c0f4450ec5815f45593 [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):
[email protected]4436c9e2014-01-07 23:19:54670 continue
[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]14a6131c2014-01-08 01:15:41784def _FilesToCheckForIncomingDeps(re, changed_lines):
[email protected]f32e2d1e2013-07-26 21:39:08785 """Helper method for _CheckAddedDepsHaveTargetApprovals. Returns
[email protected]14a6131c2014-01-08 01:15:41786 a set of DEPS entries that we should look up.
787
788 For a directory (rather than a specific filename) we fake a path to
789 a specific filename by adding /DEPS. This is chosen as a file that
790 will seldom or never be subject to per-file include_rules.
791 """
[email protected]2b438d62013-11-14 17:54:14792 # We ignore deps entries on auto-generated directories.
793 AUTO_GENERATED_DIRS = ['grit', 'jni']
[email protected]f32e2d1e2013-07-26 21:39:08794
795 # This pattern grabs the path without basename in the first
796 # parentheses, and the basename (if present) in the second. It
797 # relies on the simple heuristic that if there is a basename it will
798 # be a header file ending in ".h".
799 pattern = re.compile(
800 r"""['"]\+([^'"]+?)(/[a-zA-Z0-9_]+\.h)?['"].*""")
[email protected]2b438d62013-11-14 17:54:14801 results = set()
[email protected]f32e2d1e2013-07-26 21:39:08802 for changed_line in changed_lines:
803 m = pattern.match(changed_line)
804 if m:
805 path = m.group(1)
[email protected]2b438d62013-11-14 17:54:14806 if path.split('/')[0] not in AUTO_GENERATED_DIRS:
[email protected]14a6131c2014-01-08 01:15:41807 if m.group(2):
808 results.add('%s%s' % (path, m.group(2)))
809 else:
810 results.add('%s/DEPS' % path)
[email protected]f32e2d1e2013-07-26 21:39:08811 return results
812
813
[email protected]e871964c2013-05-13 14:14:55814def _CheckAddedDepsHaveTargetApprovals(input_api, output_api):
815 """When a dependency prefixed with + is added to a DEPS file, we
816 want to make sure that the change is reviewed by an OWNER of the
817 target file or directory, to avoid layering violations from being
818 introduced. This check verifies that this happens.
819 """
820 changed_lines = set()
821 for f in input_api.AffectedFiles():
822 filename = input_api.os_path.basename(f.LocalPath())
823 if filename == 'DEPS':
824 changed_lines |= set(line.strip()
825 for line_num, line
826 in f.ChangedContents())
827 if not changed_lines:
828 return []
829
[email protected]14a6131c2014-01-08 01:15:41830 virtual_depended_on_files = _FilesToCheckForIncomingDeps(input_api.re,
831 changed_lines)
[email protected]e871964c2013-05-13 14:14:55832 if not virtual_depended_on_files:
833 return []
834
835 if input_api.is_committing:
836 if input_api.tbr:
837 return [output_api.PresubmitNotifyResult(
838 '--tbr was specified, skipping OWNERS check for DEPS additions')]
839 if not input_api.change.issue:
840 return [output_api.PresubmitError(
841 "DEPS approval by OWNERS check failed: this change has "
842 "no Rietveld issue number, so we can't check it for approvals.")]
843 output = output_api.PresubmitError
844 else:
845 output = output_api.PresubmitNotifyResult
846
847 owners_db = input_api.owners_db
848 owner_email, reviewers = input_api.canned_checks._RietveldOwnerAndReviewers(
849 input_api,
850 owners_db.email_regexp,
851 approval_needed=input_api.is_committing)
852
853 owner_email = owner_email or input_api.change.author_email
854
[email protected]de4f7d22013-05-23 14:27:46855 reviewers_plus_owner = set(reviewers)
[email protected]e71c6082013-05-22 02:28:51856 if owner_email:
[email protected]de4f7d22013-05-23 14:27:46857 reviewers_plus_owner.add(owner_email)
[email protected]e871964c2013-05-13 14:14:55858 missing_files = owners_db.files_not_covered_by(virtual_depended_on_files,
859 reviewers_plus_owner)
[email protected]14a6131c2014-01-08 01:15:41860
861 # We strip the /DEPS part that was added by
862 # _FilesToCheckForIncomingDeps to fake a path to a file in a
863 # directory.
864 def StripDeps(path):
865 start_deps = path.rfind('/DEPS')
866 if start_deps != -1:
867 return path[:start_deps]
868 else:
869 return path
870 unapproved_dependencies = ["'+%s'," % StripDeps(path)
[email protected]e871964c2013-05-13 14:14:55871 for path in missing_files]
872
873 if unapproved_dependencies:
874 output_list = [
[email protected]14a6131c2014-01-08 01:15:41875 output('Missing LGTM from OWNERS of dependencies added to DEPS:\n %s' %
[email protected]e871964c2013-05-13 14:14:55876 '\n '.join(sorted(unapproved_dependencies)))]
877 if not input_api.is_committing:
878 suggested_owners = owners_db.reviewers_for(missing_files, owner_email)
879 output_list.append(output(
880 'Suggested missing target path OWNERS:\n %s' %
881 '\n '.join(suggested_owners or [])))
882 return output_list
883
884 return []
885
886
[email protected]85218562013-11-22 07:41:40887def _CheckSpamLogging(input_api, output_api):
888 file_inclusion_pattern = r'.+%s' % _IMPLEMENTATION_EXTENSIONS
889 black_list = (_EXCLUDED_PATHS +
890 _TEST_CODE_EXCLUDED_PATHS +
891 input_api.DEFAULT_BLACK_LIST +
[email protected]6f742dd02013-11-26 23:19:50892 (r"^base[\\\/]logging\.h$",
[email protected]8dc338c2013-12-09 16:28:48893 r"^chrome[\\\/]app[\\\/]chrome_main_delegate\.cc$",
[email protected]6e268db2013-12-04 01:41:46894 r"^chrome[\\\/]browser[\\\/]chrome_browser_main\.cc$",
[email protected]4de75262013-12-18 23:16:12895 r"^chrome[\\\/]browser[\\\/]ui[\\\/]startup[\\\/]"
896 r"startup_browser_creator\.cc$",
[email protected]fe0e6e12013-12-04 05:52:58897 r"^chrome[\\\/]installer[\\\/]setup[\\\/].*",
[email protected]95c6b3012013-12-02 14:30:31898 r"^chrome[\\\/]renderer[\\\/]extensions[\\\/]"
[email protected]6e268db2013-12-04 01:41:46899 r"logging_native_handler\.cc$",
[email protected]cdbdced2013-11-27 21:35:50900 r"^remoting[\\\/]base[\\\/]logging\.h$",
[email protected]67c96ab2013-12-17 02:05:36901 r"^remoting[\\\/]host[\\\/].*",
[email protected]8232f8fd2013-12-14 00:52:31902 r"^sandbox[\\\/]linux[\\\/].*",
903 r"^ui[\\\/]aura[\\\/]bench[\\\/]bench_main\.cc$",))
[email protected]85218562013-11-22 07:41:40904 source_file_filter = lambda x: input_api.FilterSourceFile(
905 x, white_list=(file_inclusion_pattern,), black_list=black_list)
906
907 log_info = []
908 printf = []
909
910 for f in input_api.AffectedSourceFiles(source_file_filter):
911 contents = input_api.ReadFile(f, 'rb')
912 if re.search(r"\bD?LOG\s*\(\s*INFO\s*\)", contents):
913 log_info.append(f.LocalPath())
[email protected]18b466b2013-12-02 22:01:37914 elif re.search(r"\bD?LOG_IF\s*\(\s*INFO\s*,", contents):
[email protected]85210652013-11-28 05:50:13915 log_info.append(f.LocalPath())
[email protected]18b466b2013-12-02 22:01:37916
917 if re.search(r"\bprintf\(", contents):
918 printf.append(f.LocalPath())
919 elif re.search(r"\bfprintf\((stdout|stderr)", contents):
[email protected]85218562013-11-22 07:41:40920 printf.append(f.LocalPath())
921
922 if log_info:
923 return [output_api.PresubmitError(
924 'These files spam the console log with LOG(INFO):',
925 items=log_info)]
926 if printf:
927 return [output_api.PresubmitError(
928 'These files spam the console log with printf/fprintf:',
929 items=printf)]
930 return []
931
932
[email protected]49aa76a2013-12-04 06:59:16933def _CheckForAnonymousVariables(input_api, output_api):
934 """These types are all expected to hold locks while in scope and
935 so should never be anonymous (which causes them to be immediately
936 destroyed)."""
937 they_who_must_be_named = [
938 'base::AutoLock',
939 'base::AutoReset',
940 'base::AutoUnlock',
941 'SkAutoAlphaRestore',
942 'SkAutoBitmapShaderInstall',
943 'SkAutoBlitterChoose',
944 'SkAutoBounderCommit',
945 'SkAutoCallProc',
946 'SkAutoCanvasRestore',
947 'SkAutoCommentBlock',
948 'SkAutoDescriptor',
949 'SkAutoDisableDirectionCheck',
950 'SkAutoDisableOvalCheck',
951 'SkAutoFree',
952 'SkAutoGlyphCache',
953 'SkAutoHDC',
954 'SkAutoLockColors',
955 'SkAutoLockPixels',
956 'SkAutoMalloc',
957 'SkAutoMaskFreeImage',
958 'SkAutoMutexAcquire',
959 'SkAutoPathBoundsUpdate',
960 'SkAutoPDFRelease',
961 'SkAutoRasterClipValidate',
962 'SkAutoRef',
963 'SkAutoTime',
964 'SkAutoTrace',
965 'SkAutoUnref',
966 ]
967 anonymous = r'(%s)\s*[({]' % '|'.join(they_who_must_be_named)
968 # bad: base::AutoLock(lock.get());
969 # not bad: base::AutoLock lock(lock.get());
970 bad_pattern = input_api.re.compile(anonymous)
971 # good: new base::AutoLock(lock.get())
972 good_pattern = input_api.re.compile(r'\bnew\s*' + anonymous)
973 errors = []
974
975 for f in input_api.AffectedFiles():
976 if not f.LocalPath().endswith(('.cc', '.h', '.inl', '.m', '.mm')):
977 continue
978 for linenum, line in f.ChangedContents():
979 if bad_pattern.search(line) and not good_pattern.search(line):
980 errors.append('%s:%d' % (f.LocalPath(), linenum))
981
982 if errors:
983 return [output_api.PresubmitError(
984 'These lines create anonymous variables that need to be named:',
985 items=errors)]
986 return []
987
988
[email protected]5fe0f8742013-11-29 01:04:59989def _CheckCygwinShell(input_api, output_api):
990 source_file_filter = lambda x: input_api.FilterSourceFile(
991 x, white_list=(r'.+\.(gyp|gypi)$',))
992 cygwin_shell = []
993
994 for f in input_api.AffectedSourceFiles(source_file_filter):
995 for linenum, line in f.ChangedContents():
996 if 'msvs_cygwin_shell' in line:
997 cygwin_shell.append(f.LocalPath())
998 break
999
1000 if cygwin_shell:
1001 return [output_api.PresubmitError(
1002 'These files should not use msvs_cygwin_shell (the default is 0):',
1003 items=cygwin_shell)]
1004 return []
1005
[email protected]85218562013-11-22 07:41:401006
[email protected]760deea2013-12-10 19:33:491007def _CheckJavaStyle(input_api, output_api):
1008 """Runs checkstyle on changed java files and returns errors if any exist."""
1009 original_sys_path = sys.path
1010 try:
1011 sys.path = sys.path + [input_api.os_path.join(
1012 input_api.PresubmitLocalPath(), 'tools', 'android', 'checkstyle')]
1013 import checkstyle
1014 finally:
1015 # Restore sys.path to what it was before.
1016 sys.path = original_sys_path
1017
1018 return checkstyle.RunCheckstyle(
1019 input_api, output_api, 'tools/android/checkstyle/chromium-style-5.0.xml')
1020
1021
[email protected]22c9bd72011-03-27 16:47:391022def _CommonChecks(input_api, output_api):
1023 """Checks common to both upload and commit."""
1024 results = []
1025 results.extend(input_api.canned_checks.PanProjectChecks(
[email protected]3de922f2013-12-20 13:27:381026 input_api, output_api,
1027 excluded_paths=_EXCLUDED_PATHS + _TESTRUNNER_PATHS))
[email protected]66daa702011-05-28 14:41:461028 results.extend(_CheckAuthorizedAuthor(input_api, output_api))
[email protected]55459852011-08-10 15:17:191029 results.extend(
[email protected]760deea2013-12-10 19:33:491030 _CheckNoProductionCodeUsingTestOnlyFunctions(input_api, output_api))
[email protected]10689ca2011-09-02 02:31:541031 results.extend(_CheckNoIOStreamInHeaders(input_api, output_api))
[email protected]72df4e782012-06-21 16:28:181032 results.extend(_CheckNoUNIT_TESTInSourceFiles(input_api, output_api))
[email protected]8ea5d4b2011-09-13 21:49:221033 results.extend(_CheckNoNewWStrings(input_api, output_api))
[email protected]2a8ac9c2011-10-19 17:20:441034 results.extend(_CheckNoDEPSGIT(input_api, output_api))
[email protected]127f18ec2012-06-16 05:05:591035 results.extend(_CheckNoBannedFunctions(input_api, output_api))
[email protected]6c063c62012-07-11 19:11:061036 results.extend(_CheckNoPragmaOnce(input_api, output_api))
[email protected]e7479052012-09-19 00:26:121037 results.extend(_CheckNoTrinaryTrueFalse(input_api, output_api))
[email protected]55f9f382012-07-31 11:02:181038 results.extend(_CheckUnwantedDependencies(input_api, output_api))
[email protected]fbcafe5a2012-08-08 15:31:221039 results.extend(_CheckFilePermissions(input_api, output_api))
[email protected]c8278b32012-10-30 20:35:491040 results.extend(_CheckNoAuraWindowPropertyHInHeaders(input_api, output_api))
[email protected]2309b0fa02012-11-16 12:18:271041 results.extend(_CheckIncludeOrder(input_api, output_api))
[email protected]70ca77752012-11-20 03:45:031042 results.extend(_CheckForVersionControlConflicts(input_api, output_api))
[email protected]b8079ae4a2012-12-05 19:56:491043 results.extend(_CheckPatchFiles(input_api, output_api))
[email protected]06e6d0ff2012-12-11 01:36:441044 results.extend(_CheckHardcodedGoogleHostsInLowerLayers(input_api, output_api))
[email protected]d2530012013-01-25 16:39:271045 results.extend(_CheckNoAbbreviationInPngFileName(input_api, output_api))
[email protected]b00342e7f2013-03-26 16:21:541046 results.extend(_CheckForInvalidOSMacros(input_api, output_api))
[email protected]e871964c2013-05-13 14:14:551047 results.extend(_CheckAddedDepsHaveTargetApprovals(input_api, output_api))
[email protected]9f919cc2013-07-31 03:04:041048 results.extend(
1049 input_api.canned_checks.CheckChangeHasNoTabs(
1050 input_api,
1051 output_api,
1052 source_file_filter=lambda x: x.LocalPath().endswith('.grd')))
[email protected]85218562013-11-22 07:41:401053 results.extend(_CheckSpamLogging(input_api, output_api))
[email protected]49aa76a2013-12-04 06:59:161054 results.extend(_CheckForAnonymousVariables(input_api, output_api))
[email protected]5fe0f8742013-11-29 01:04:591055 results.extend(_CheckCygwinShell(input_api, output_api))
[email protected]760deea2013-12-10 19:33:491056 results.extend(_CheckJavaStyle(input_api, output_api))
[email protected]2299dcf2012-11-15 19:56:241057
1058 if any('PRESUBMIT.py' == f.LocalPath() for f in input_api.AffectedFiles()):
1059 results.extend(input_api.canned_checks.RunUnitTestsInDirectory(
1060 input_api, output_api,
1061 input_api.PresubmitLocalPath(),
[email protected]6be63382013-01-21 15:42:381062 whitelist=[r'^PRESUBMIT_test\.py$']))
[email protected]22c9bd72011-03-27 16:47:391063 return results
[email protected]1f7b4172010-01-28 01:17:341064
[email protected]b337cb5b2011-01-23 21:24:051065
1066def _CheckSubversionConfig(input_api, output_api):
1067 """Verifies the subversion config file is correctly setup.
1068
1069 Checks that autoprops are enabled, returns an error otherwise.
1070 """
1071 join = input_api.os_path.join
1072 if input_api.platform == 'win32':
1073 appdata = input_api.environ.get('APPDATA', '')
1074 if not appdata:
1075 return [output_api.PresubmitError('%APPDATA% is not configured.')]
1076 path = join(appdata, 'Subversion', 'config')
1077 else:
1078 home = input_api.environ.get('HOME', '')
1079 if not home:
1080 return [output_api.PresubmitError('$HOME is not configured.')]
1081 path = join(home, '.subversion', 'config')
1082
1083 error_msg = (
1084 'Please look at http://dev.chromium.org/developers/coding-style to\n'
1085 'configure your subversion configuration file. This enables automatic\n'
[email protected]c6a3c10b2011-01-24 16:14:201086 'properties to simplify the project maintenance.\n'
1087 'Pro-tip: just download and install\n'
1088 'http://src.chromium.org/viewvc/chrome/trunk/tools/build/slave/config\n')
[email protected]b337cb5b2011-01-23 21:24:051089
1090 try:
1091 lines = open(path, 'r').read().splitlines()
1092 # Make sure auto-props is enabled and check for 2 Chromium standard
1093 # auto-prop.
1094 if (not '*.cc = svn:eol-style=LF' in lines or
1095 not '*.pdf = svn:mime-type=application/pdf' in lines or
1096 not 'enable-auto-props = yes' in lines):
1097 return [
[email protected]79ed7e62011-02-21 21:08:531098 output_api.PresubmitNotifyResult(
[email protected]b337cb5b2011-01-23 21:24:051099 'It looks like you have not configured your subversion config '
[email protected]b5359c02011-02-01 20:29:561100 'file or it is not up-to-date.\n' + error_msg)
[email protected]b337cb5b2011-01-23 21:24:051101 ]
1102 except (OSError, IOError):
1103 return [
[email protected]79ed7e62011-02-21 21:08:531104 output_api.PresubmitNotifyResult(
[email protected]b337cb5b2011-01-23 21:24:051105 'Can\'t find your subversion config file.\n' + error_msg)
1106 ]
1107 return []
1108
1109
[email protected]66daa702011-05-28 14:41:461110def _CheckAuthorizedAuthor(input_api, output_api):
1111 """For non-googler/chromites committers, verify the author's email address is
1112 in AUTHORS.
1113 """
[email protected]9bb9cb82011-06-13 20:43:011114 # TODO(maruel): Add it to input_api?
1115 import fnmatch
1116
[email protected]66daa702011-05-28 14:41:461117 author = input_api.change.author_email
[email protected]9bb9cb82011-06-13 20:43:011118 if not author:
1119 input_api.logging.info('No author, skipping AUTHOR check')
[email protected]66daa702011-05-28 14:41:461120 return []
[email protected]c99663292011-05-31 19:46:081121 authors_path = input_api.os_path.join(
[email protected]66daa702011-05-28 14:41:461122 input_api.PresubmitLocalPath(), 'AUTHORS')
1123 valid_authors = (
1124 input_api.re.match(r'[^#]+\s+\<(.+?)\>\s*$', line)
1125 for line in open(authors_path))
[email protected]ac54b132011-06-06 18:11:181126 valid_authors = [item.group(1).lower() for item in valid_authors if item]
[email protected]d8b50be2011-06-15 14:19:441127 if not any(fnmatch.fnmatch(author.lower(), valid) for valid in valid_authors):
[email protected]5861efb2013-01-07 18:33:231128 input_api.logging.info('Valid authors are %s', ', '.join(valid_authors))
[email protected]66daa702011-05-28 14:41:461129 return [output_api.PresubmitPromptWarning(
1130 ('%s is not in AUTHORS file. If you are a new contributor, please visit'
1131 '\n'
1132 'http://www.chromium.org/developers/contributing-code and read the '
1133 '"Legal" section\n'
1134 'If you are a chromite, verify the contributor signed the CLA.') %
1135 author)]
1136 return []
1137
1138
[email protected]b8079ae4a2012-12-05 19:56:491139def _CheckPatchFiles(input_api, output_api):
1140 problems = [f.LocalPath() for f in input_api.AffectedFiles()
1141 if f.LocalPath().endswith(('.orig', '.rej'))]
1142 if problems:
1143 return [output_api.PresubmitError(
1144 "Don't commit .rej and .orig files.", problems)]
[email protected]2fdd1f362013-01-16 03:56:031145 else:
1146 return []
[email protected]b8079ae4a2012-12-05 19:56:491147
1148
[email protected]b00342e7f2013-03-26 16:21:541149def _DidYouMeanOSMacro(bad_macro):
1150 try:
1151 return {'A': 'OS_ANDROID',
1152 'B': 'OS_BSD',
1153 'C': 'OS_CHROMEOS',
1154 'F': 'OS_FREEBSD',
1155 'L': 'OS_LINUX',
1156 'M': 'OS_MACOSX',
1157 'N': 'OS_NACL',
1158 'O': 'OS_OPENBSD',
1159 'P': 'OS_POSIX',
1160 'S': 'OS_SOLARIS',
1161 'W': 'OS_WIN'}[bad_macro[3].upper()]
1162 except KeyError:
1163 return ''
1164
1165
1166def _CheckForInvalidOSMacrosInFile(input_api, f):
1167 """Check for sensible looking, totally invalid OS macros."""
1168 preprocessor_statement = input_api.re.compile(r'^\s*#')
1169 os_macro = input_api.re.compile(r'defined\((OS_[^)]+)\)')
1170 results = []
1171 for lnum, line in f.ChangedContents():
1172 if preprocessor_statement.search(line):
1173 for match in os_macro.finditer(line):
1174 if not match.group(1) in _VALID_OS_MACROS:
1175 good = _DidYouMeanOSMacro(match.group(1))
1176 did_you_mean = ' (did you mean %s?)' % good if good else ''
1177 results.append(' %s:%d %s%s' % (f.LocalPath(),
1178 lnum,
1179 match.group(1),
1180 did_you_mean))
1181 return results
1182
1183
1184def _CheckForInvalidOSMacros(input_api, output_api):
1185 """Check all affected files for invalid OS macros."""
1186 bad_macros = []
1187 for f in input_api.AffectedFiles():
1188 if not f.LocalPath().endswith(('.py', '.js', '.html', '.css')):
1189 bad_macros.extend(_CheckForInvalidOSMacrosInFile(input_api, f))
1190
1191 if not bad_macros:
1192 return []
1193
1194 return [output_api.PresubmitError(
1195 'Possibly invalid OS macro[s] found. Please fix your code\n'
1196 'or add your macro to src/PRESUBMIT.py.', bad_macros)]
1197
1198
[email protected]1f7b4172010-01-28 01:17:341199def CheckChangeOnUpload(input_api, output_api):
1200 results = []
1201 results.extend(_CommonChecks(input_api, output_api))
[email protected]fe5f57c52009-06-05 14:25:541202 return results
[email protected]ca8d1982009-02-19 16:33:121203
1204
[email protected]38c6a512013-12-18 23:48:011205def GetDefaultTryConfigs(bots=None):
1206 """Returns a list of ('bot', set(['tests']), optionally filtered by [bots].
1207
1208 To add tests to this list, they MUST be in the the corresponding master's
1209 gatekeeper config. For example, anything on master.chromium would be closed by
1210 tools/build/masters/master.chromium/master_gatekeeper_cfg.py.
1211
1212 If 'bots' is specified, will only return configurations for bots in that list.
1213 """
1214
1215 standard_tests = [
1216 'base_unittests',
1217 'browser_tests',
1218 'cacheinvalidation_unittests',
1219 'check_deps',
1220 'check_deps2git',
1221 'content_browsertests',
1222 'content_unittests',
1223 'crypto_unittests',
1224 #'gfx_unittests',
1225 'gpu_unittests',
1226 'interactive_ui_tests',
1227 'ipc_tests',
1228 'jingle_unittests',
1229 'media_unittests',
1230 'net_unittests',
1231 'ppapi_unittests',
1232 'printing_unittests',
1233 'sql_unittests',
1234 'sync_unit_tests',
1235 'unit_tests',
1236 # Broken in release.
1237 #'url_unittests',
1238 #'webkit_unit_tests',
1239 ]
1240
1241 linux_aura_tests = [
1242 'app_list_unittests',
1243 'aura_unittests',
1244 'browser_tests',
1245 'compositor_unittests',
1246 'content_browsertests',
1247 'content_unittests',
1248 'events_unittests',
1249 'interactive_ui_tests',
1250 'unit_tests',
1251 ]
1252 builders_and_tests = {
1253 # TODO(maruel): Figure out a way to run 'sizes' where people can
1254 # effectively update the perf expectation correctly. This requires a
1255 # clobber=True build running 'sizes'. 'sizes' is not accurate with
1256 # incremental build. Reference:
1257 # http://chromium.org/developers/tree-sheriffs/perf-sheriffs.
1258 # TODO(maruel): An option would be to run 'sizes' but not count a failure
1259 # of this step as a try job failure.
1260 'android_aosp': ['compile'],
1261 'android_clang_dbg': ['slave_steps'],
1262 'android_dbg': ['slave_steps'],
1263 'cros_x86': ['defaulttests'],
1264 'ios_dbg_simulator': [
1265 'compile',
1266 'base_unittests',
1267 'content_unittests',
1268 'crypto_unittests',
1269 'url_unittests',
1270 'net_unittests',
1271 'sql_unittests',
1272 'ui_unittests',
1273 ],
1274 'ios_rel_device': ['compile'],
1275 'linux_asan': ['defaulttests'],
1276 #TODO(stip): Change the name of this builder to reflect that it's release.
1277 'linux_aura': linux_aura_tests,
1278 'linux_chromeos_asan': ['defaulttests'],
1279 'linux_chromeos_clang': ['compile'],
1280 # Note: It is a Release builder even if its name convey otherwise.
1281 'linux_chromeos': standard_tests + [
1282 'app_list_unittests',
1283 'aura_unittests',
1284 'ash_unittests',
1285 'chromeos_unittests',
1286 'components_unittests',
1287 'dbus_unittests',
1288 'device_unittests',
1289 'events_unittests',
1290 'google_apis_unittests',
1291 'sandbox_linux_unittests',
1292 ],
[email protected]23c81d552014-01-07 13:45:461293 'linux_chromium_dbg': ['defaulttests'],
1294 'linux_chromium_rel': ['defaulttests'],
[email protected]38c6a512013-12-18 23:48:011295 'linux_clang': ['compile'],
1296 'linux_rel': standard_tests + [
1297 'cc_unittests',
[email protected]5d0413fc2014-01-03 18:24:301298 'chromedriver_unittests',
[email protected]38c6a512013-12-18 23:48:011299 'components_unittests',
1300 'google_apis_unittests',
1301 'nacl_integration',
1302 'remoting_unittests',
1303 'sandbox_linux_unittests',
1304 'sync_integration_tests',
1305 ],
1306 'mac': ['compile'],
[email protected]23c81d552014-01-07 13:45:461307 'mac_chromium_dbg': ['defaulttests'],
1308 'mac_chromium_rel': ['defaulttests'],
[email protected]38c6a512013-12-18 23:48:011309 'mac_rel': standard_tests + [
1310 'app_list_unittests',
1311 'cc_unittests',
[email protected]5d0413fc2014-01-03 18:24:301312 'chromedriver_unittests',
[email protected]38c6a512013-12-18 23:48:011313 'components_unittests',
1314 'google_apis_unittests',
1315 'message_center_unittests',
1316 'nacl_integration',
1317 'remoting_unittests',
1318 'sync_integration_tests',
1319 'telemetry_unittests',
1320 ],
1321 'win': ['compile'],
1322 'win_rel': standard_tests + [
1323 'app_list_unittests',
1324 'ash_unittests',
1325 'aura_unittests',
1326 'cc_unittests',
1327 'chrome_elf_unittests',
[email protected]5d0413fc2014-01-03 18:24:301328 'chromedriver_unittests',
[email protected]38c6a512013-12-18 23:48:011329 'components_unittests',
1330 'compositor_unittests',
1331 'events_unittests',
1332 'google_apis_unittests',
1333 'installer_util_unittests',
1334 'mini_installer_test',
1335 'nacl_integration',
1336 'remoting_unittests',
1337 'sync_integration_tests',
1338 'telemetry_unittests',
1339 'views_unittests',
1340 ],
1341 'win_x64_rel': [
1342 'base_unittests',
1343 ],
1344 }
1345
1346 swarm_enabled_builders = (
1347 'linux_rel',
1348 'mac_rel',
1349 'win_rel',
1350 )
1351
1352 swarm_enabled_tests = (
1353 'base_unittests',
1354 'browser_tests',
1355 'interactive_ui_tests',
1356 'net_unittests',
1357 'unit_tests',
1358 )
1359
1360 for bot in builders_and_tests:
1361 if bot in swarm_enabled_builders:
1362 builders_and_tests[bot] = [x + '_swarm' if x in swarm_enabled_tests else x
1363 for x in builders_and_tests[bot]]
1364
1365 if bots:
1366 return [(bot, set(builders_and_tests[bot])) for bot in bots]
1367 else:
1368 return [(bot, set(tests)) for bot, tests in builders_and_tests.iteritems()]
1369
1370
[email protected]ca8d1982009-02-19 16:33:121371def CheckChangeOnCommit(input_api, output_api):
[email protected]fe5f57c52009-06-05 14:25:541372 results = []
[email protected]1f7b4172010-01-28 01:17:341373 results.extend(_CommonChecks(input_api, output_api))
[email protected]dd805fe2009-10-01 08:11:511374 # TODO(thestig) temporarily disabled, doesn't work in third_party/
1375 #results.extend(input_api.canned_checks.CheckSvnModifiedDirectories(
1376 # input_api, output_api, sources))
[email protected]fe5f57c52009-06-05 14:25:541377 # Make sure the tree is 'open'.
[email protected]806e98e2010-03-19 17:49:271378 results.extend(input_api.canned_checks.CheckTreeIsOpen(
[email protected]7f238152009-08-12 19:00:341379 input_api,
1380 output_api,
[email protected]2fdd1f362013-01-16 03:56:031381 json_url='http://chromium-status.appspot.com/current?format=json'))
[email protected]806e98e2010-03-19 17:49:271382 results.extend(input_api.canned_checks.CheckRietveldTryJobExecution(input_api,
[email protected]2fdd1f362013-01-16 03:56:031383 output_api, 'http://codereview.chromium.org',
[email protected]c1ba4c52012-03-09 14:23:281384 ('win_rel', 'linux_rel', 'mac_rel, win:compile'),
1385 '[email protected]'))
[email protected]806e98e2010-03-19 17:49:271386
[email protected]3e4eb112011-01-18 03:29:541387 results.extend(input_api.canned_checks.CheckChangeHasBugField(
1388 input_api, output_api))
[email protected]c4b47562011-12-05 23:39:411389 results.extend(input_api.canned_checks.CheckChangeHasDescription(
1390 input_api, output_api))
[email protected]b337cb5b2011-01-23 21:24:051391 results.extend(_CheckSubversionConfig(input_api, output_api))
[email protected]fe5f57c52009-06-05 14:25:541392 return results
[email protected]ca8d1982009-02-19 16:33:121393
1394
[email protected]5efb2a822011-09-27 23:06:131395def GetPreferredTrySlaves(project, change):
[email protected]4ce995ea2012-06-27 02:13:101396 files = change.LocalPaths()
1397
[email protected]751b05f2013-01-10 23:12:171398 if not files or all(re.search(r'[\\/]OWNERS$', f) for f in files):
[email protected]3019c902012-06-29 00:09:031399 return []
1400
[email protected]d668899a2012-09-06 18:16:591401 if all(re.search('\.(m|mm)$|(^|[/_])mac[/_.]', f) for f in files):
[email protected]38c6a512013-12-18 23:48:011402 return GetDefaultTryConfigs(['mac', 'mac_rel'])
[email protected]d668899a2012-09-06 18:16:591403 if all(re.search('(^|[/_])win[/_.]', f) for f in files):
[email protected]3630be892013-12-19 05:34:281404 return GetDefaultTryConfigs(['win', 'win_rel'])
[email protected]d668899a2012-09-06 18:16:591405 if all(re.search('(^|[/_])android[/_.]', f) for f in files):
[email protected]38c6a512013-12-18 23:48:011406 return GetDefaultTryConfigs([
1407 'android_aosp',
1408 'android_clang_dbg',
1409 'android_dbg',
1410 ])
[email protected]de142152012-10-03 23:02:451411 if all(re.search('[/_]ios[/_.]', f) for f in files):
[email protected]38c6a512013-12-18 23:48:011412 return GetDefaultTryConfigs(['ios_rel_device', 'ios_dbg_simulator'])
[email protected]4ce995ea2012-06-27 02:13:101413
[email protected]38c6a512013-12-18 23:48:011414 trybots = GetDefaultTryConfigs([
[email protected]3e2f0402012-11-02 16:28:011415 'android_clang_dbg',
1416 'android_dbg',
1417 'ios_dbg_simulator',
1418 'ios_rel_device',
[email protected]95c989162012-11-29 05:58:251419 'linux_aura',
[email protected]38c6a512013-12-18 23:48:011420 'linux_asan',
[email protected]3e2f0402012-11-02 16:28:011421 'linux_chromeos',
[email protected]38c6a512013-12-18 23:48:011422 'linux_clang',
[email protected]3e2f0402012-11-02 16:28:011423 'linux_rel',
[email protected]38c6a512013-12-18 23:48:011424 'mac',
[email protected]3e2f0402012-11-02 16:28:011425 'mac_rel',
[email protected]38c6a512013-12-18 23:48:011426 'win',
[email protected]3e2f0402012-11-02 16:28:011427 'win_rel',
[email protected]38c6a512013-12-18 23:48:011428 'win_x64_rel',
1429 ])
[email protected]911753b2012-08-02 12:11:541430
1431 # Match things like path/aura/file.cc and path/file_aura.cc.
[email protected]95c989162012-11-29 05:58:251432 # Same for chromeos.
1433 if any(re.search('[/_](aura|chromeos)', f) for f in files):
[email protected]38c6a512013-12-18 23:48:011434 trybots.extend(GetDefaultTryConfigs([
1435 'linux_chromeos_asan', 'linux_chromeos_clang']))
[email protected]4ce995ea2012-06-27 02:13:101436
[email protected]e8df48f2013-09-30 20:07:541437 # If there are gyp changes to base, build, or chromeos, run a full cros build
1438 # in addition to the shorter linux_chromeos build. Changes to high level gyp
1439 # files have a much higher chance of breaking the cros build, which is
1440 # differnt from the linux_chromeos build that most chrome developers test
1441 # with.
1442 if any(re.search('^(base|build|chromeos).*\.gypi?$', f) for f in files):
[email protected]38c6a512013-12-18 23:48:011443 trybots.extend(GetDefaultTryConfigs(['cros_x86']))
[email protected]e8df48f2013-09-30 20:07:541444
[email protected]d95948ef2013-07-02 10:51:001445 # The AOSP bot doesn't build the chrome/ layer, so ignore any changes to it
1446 # unless they're .gyp(i) files as changes to those files can break the gyp
1447 # step on that bot.
1448 if (not all(re.search('^chrome', f) for f in files) or
1449 any(re.search('\.gypi?$', f) for f in files)):
[email protected]38c6a512013-12-18 23:48:011450 trybots.extend(GetDefaultTryConfigs(['android_aosp']))
[email protected]d95948ef2013-07-02 10:51:001451
[email protected]23c81d552014-01-07 13:45:461452 # Experimental recipe-based Chromium trybots. To avoid possible capacity
1453 # problems, only enable for a small percentage of try runs.
1454 if random.random() < 0.01:
1455 trybots.extend(GetDefaultTryConfigs([
1456 'linux_chromium_dbg',
1457 'linux_chromium_rel',
1458 'mac_chromium_dbg',
1459 'mac_chromium_rel',
1460 ]))
1461
[email protected]4ce995ea2012-06-27 02:13:101462 return trybots