blob: 306dc8e91c6917802522868262de46d4f17d81c4 [file] [log] [blame]
[email protected]a18130a2012-01-03 17:52:081# Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]ca8d19842009-02-19 16:33:122# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5"""Top-level presubmit script for Chromium.
6
[email protected]f1293792009-07-31 18:09:567See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts
[email protected]50d7d721e2009-11-15 17:56:188for more details about the presubmit API built into gcl.
[email protected]ca8d19842009-02-19 16:33:129"""
10
[email protected]eea609a2011-11-18 13:10:1211
[email protected]9d16ad12011-12-14 20:49:4712import re
[email protected]55f9f382012-07-31 11:02:1813import sys
[email protected]9d16ad12011-12-14 20:49:4714
15
[email protected]379e7dd2010-01-28 17:39:2116_EXCLUDED_PATHS = (
[email protected]3e4eb112011-01-18 03:29:5417 r"^breakpad[\\\/].*",
[email protected]40d1dbb2012-10-26 07:18:0018 r"^native_client_sdk[\\\/]src[\\\/]build_tools[\\\/]make_rules.py",
19 r"^native_client_sdk[\\\/]src[\\\/]build_tools[\\\/]make_simple.py",
[email protected]8886ffcb2013-02-12 04:56:2820 r"^native_client_sdk[\\\/]src[\\\/]tools[\\\/].*.mk",
[email protected]a18130a2012-01-03 17:52:0821 r"^net[\\\/]tools[\\\/]spdyshark[\\\/].*",
[email protected]3e4eb112011-01-18 03:29:5422 r"^skia[\\\/].*",
23 r"^v8[\\\/].*",
24 r".*MakeFile$",
[email protected]1084ccc2012-03-14 03:22:5325 r".+_autogen\.h$",
[email protected]ce145c02012-09-06 09:49:3426 r".+[\\\/]pnacl_shim\.c$",
[email protected]e07b6ac72013-08-20 00:30:4227 r"^gpu[\\\/]config[\\\/].*_list_json\.cc$",
[email protected]d2600602014-02-19 00:09:1928 r"^chrome[\\\/]browser[\\\/]resources[\\\/]pdf[\\\/]index.js"
[email protected]4306417642009-06-11 00:33:4029)
[email protected]ca8d19842009-02-19 16:33:1230
[email protected]de28fed2e2014-02-01 14:36:3231# TestRunner and NetscapePlugIn library is temporarily excluded from pan-project
32# checks until it's transitioned to chromium coding style.
[email protected]3de922f2013-12-20 13:27:3833_TESTRUNNER_PATHS = (
34 r"^content[\\\/]shell[\\\/]renderer[\\\/]test_runner[\\\/].*",
[email protected]de28fed2e2014-02-01 14:36:3235 r"^content[\\\/]shell[\\\/]tools[\\\/]plugin[\\\/].*",
[email protected]3de922f2013-12-20 13:27:3836)
37
[email protected]06e6d0ff2012-12-11 01:36:4438# Fragment of a regular expression that matches C++ and Objective-C++
39# implementation files.
40_IMPLEMENTATION_EXTENSIONS = r'\.(cc|cpp|cxx|mm)$'
41
42# Regular expression that matches code only used for test binaries
43# (best effort).
44_TEST_CODE_EXCLUDED_PATHS = (
45 r'.*[/\\](fake_|test_|mock_).+%s' % _IMPLEMENTATION_EXTENSIONS,
46 r'.+_test_(base|support|util)%s' % _IMPLEMENTATION_EXTENSIONS,
[email protected]6e04f8c2014-01-29 18:08:3247 r'.+_(api|browser|kif|perf|pixel|unit|ui)?test(_[a-z]+)?%s' %
[email protected]e2d7e6f2013-04-23 12:57:1248 _IMPLEMENTATION_EXTENSIONS,
[email protected]06e6d0ff2012-12-11 01:36:4449 r'.+profile_sync_service_harness%s' % _IMPLEMENTATION_EXTENSIONS,
50 r'.*[/\\](test|tool(s)?)[/\\].*',
[email protected]ef070cc2013-05-03 11:53:0551 # content_shell is used for running layout tests.
52 r'content[/\\]shell[/\\].*',
[email protected]06e6d0ff2012-12-11 01:36:4453 # At request of folks maintaining this folder.
54 r'chrome[/\\]browser[/\\]automation[/\\].*',
[email protected]7b054982013-11-27 00:44:4755 # Non-production example code.
56 r'mojo[/\\]examples[/\\].*',
[email protected]06e6d0ff2012-12-11 01:36:4457)
[email protected]ca8d19842009-02-19 16:33:1258
[email protected]eea609a2011-11-18 13:10:1259_TEST_ONLY_WARNING = (
60 'You might be calling functions intended only for testing from\n'
61 'production code. It is OK to ignore this warning if you know what\n'
62 'you are doing, as the heuristics used to detect the situation are\n'
[email protected]b0149772014-03-27 16:47:5863 'not perfect. The commit queue will not block on this warning.')
[email protected]eea609a2011-11-18 13:10:1264
65
[email protected]cf9b78f2012-11-14 11:40:2866_INCLUDE_ORDER_WARNING = (
67 'Your #include order seems to be broken. Send mail to\n'
68 '[email protected] if this is not the case.')
69
70
[email protected]127f18ec2012-06-16 05:05:5971_BANNED_OBJC_FUNCTIONS = (
72 (
73 'addTrackingRect:',
[email protected]23e6cbc2012-06-16 18:51:2074 (
75 'The use of -[NSView addTrackingRect:owner:userData:assumeInside:] is'
[email protected]127f18ec2012-06-16 05:05:5976 'prohibited. Please use CrTrackingArea instead.',
77 'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts',
78 ),
79 False,
80 ),
81 (
[email protected]eaae1972014-04-16 04:17:2682 r'/NSTrackingArea\W',
[email protected]23e6cbc2012-06-16 18:51:2083 (
84 'The use of NSTrackingAreas is prohibited. Please use CrTrackingArea',
[email protected]127f18ec2012-06-16 05:05:5985 'instead.',
86 'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts',
87 ),
88 False,
89 ),
90 (
91 'convertPointFromBase:',
[email protected]23e6cbc2012-06-16 18:51:2092 (
93 'The use of -[NSView convertPointFromBase:] is almost certainly wrong.',
[email protected]127f18ec2012-06-16 05:05:5994 'Please use |convertPoint:(point) fromView:nil| instead.',
95 'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts',
96 ),
97 True,
98 ),
99 (
100 'convertPointToBase:',
[email protected]23e6cbc2012-06-16 18:51:20101 (
102 'The use of -[NSView convertPointToBase:] is almost certainly wrong.',
[email protected]127f18ec2012-06-16 05:05:59103 'Please use |convertPoint:(point) toView:nil| instead.',
104 'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts',
105 ),
106 True,
107 ),
108 (
109 'convertRectFromBase:',
[email protected]23e6cbc2012-06-16 18:51:20110 (
111 'The use of -[NSView convertRectFromBase:] is almost certainly wrong.',
[email protected]127f18ec2012-06-16 05:05:59112 'Please use |convertRect:(point) fromView:nil| instead.',
113 'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts',
114 ),
115 True,
116 ),
117 (
118 'convertRectToBase:',
[email protected]23e6cbc2012-06-16 18:51:20119 (
120 'The use of -[NSView convertRectToBase:] is almost certainly wrong.',
[email protected]127f18ec2012-06-16 05:05:59121 'Please use |convertRect:(point) toView:nil| instead.',
122 'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts',
123 ),
124 True,
125 ),
126 (
127 'convertSizeFromBase:',
[email protected]23e6cbc2012-06-16 18:51:20128 (
129 'The use of -[NSView convertSizeFromBase:] is almost certainly wrong.',
[email protected]127f18ec2012-06-16 05:05:59130 'Please use |convertSize:(point) fromView:nil| instead.',
131 'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts',
132 ),
133 True,
134 ),
135 (
136 'convertSizeToBase:',
[email protected]23e6cbc2012-06-16 18:51:20137 (
138 'The use of -[NSView convertSizeToBase:] is almost certainly wrong.',
[email protected]127f18ec2012-06-16 05:05:59139 'Please use |convertSize:(point) toView:nil| instead.',
140 'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts',
141 ),
142 True,
143 ),
144)
145
146
147_BANNED_CPP_FUNCTIONS = (
[email protected]23e6cbc2012-06-16 18:51:20148 # Make sure that gtest's FRIEND_TEST() macro is not used; the
149 # FRIEND_TEST_ALL_PREFIXES() macro from base/gtest_prod_util.h should be
[email protected]e00ccc92012-11-01 17:32:30150 # used instead since that allows for FLAKY_ and DISABLED_ prefixes.
[email protected]23e6cbc2012-06-16 18:51:20151 (
152 'FRIEND_TEST(',
153 (
[email protected]e3c945502012-06-26 20:01:49154 'Chromium code should not use gtest\'s FRIEND_TEST() macro. Include',
[email protected]23e6cbc2012-06-16 18:51:20155 'base/gtest_prod_util.h and use FRIEND_TEST_ALL_PREFIXES() instead.',
156 ),
157 False,
[email protected]7345da02012-11-27 14:31:49158 (),
[email protected]23e6cbc2012-06-16 18:51:20159 ),
160 (
161 'ScopedAllowIO',
162 (
[email protected]e3c945502012-06-26 20:01:49163 'New code should not use ScopedAllowIO. Post a task to the blocking',
164 'pool or the FILE thread instead.',
[email protected]23e6cbc2012-06-16 18:51:20165 ),
[email protected]e3c945502012-06-26 20:01:49166 True,
[email protected]7345da02012-11-27 14:31:49167 (
[email protected]0b818f72013-10-22 00:11:03168 r"^components[\\\/]breakpad[\\\/]app[\\\/]breakpad_mac\.mm$",
[email protected]de7d61ff2013-08-20 11:30:41169 r"^content[\\\/]shell[\\\/]browser[\\\/]shell_browser_main\.cc$",
170 r"^content[\\\/]shell[\\\/]browser[\\\/]shell_message_filter\.cc$",
[email protected]ac1df702014-03-21 20:45:27171 r"^mojo[\\\/]system[\\\/]raw_shared_buffer_posix\.cc$",
[email protected]398ad132013-04-02 15:11:01172 r"^net[\\\/]disk_cache[\\\/]cache_util\.cc$",
[email protected]1f52a572014-05-12 23:21:54173 r"^net[\\\/]url_request[\\\/]test_url_fetcher_factory\.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]ec5b3f02014-04-04 18:43:43237 (
238 r'/v8::Extension\(',
239 (
240 'Do not introduce new v8::Extensions into the code base, use',
241 'gin::Wrappable instead. See http://crbug.com/334679',
242 ),
243 True,
[email protected]f55c90ee62014-04-12 00:50:03244 (
245 r'extensions[/\\]renderer[/\\]safe_builtins\.*',
246 ),
[email protected]ec5b3f02014-04-04 18:43:43247 ),
[email protected]127f18ec2012-06-16 05:05:59248)
249
250
[email protected]b00342e7f2013-03-26 16:21:54251_VALID_OS_MACROS = (
252 # Please keep sorted.
253 'OS_ANDROID',
[email protected]f4440b42014-03-19 05:47:01254 'OS_ANDROID_HOST',
[email protected]b00342e7f2013-03-26 16:21:54255 'OS_BSD',
256 'OS_CAT', # For testing.
257 'OS_CHROMEOS',
258 'OS_FREEBSD',
259 'OS_IOS',
260 'OS_LINUX',
261 'OS_MACOSX',
262 'OS_NACL',
263 'OS_OPENBSD',
264 'OS_POSIX',
[email protected]eda7afa12014-02-06 12:27:37265 'OS_QNX',
[email protected]b00342e7f2013-03-26 16:21:54266 'OS_SOLARIS',
[email protected]b00342e7f2013-03-26 16:21:54267 'OS_WIN',
268)
269
270
[email protected]55459852011-08-10 15:17:19271def _CheckNoProductionCodeUsingTestOnlyFunctions(input_api, output_api):
272 """Attempts to prevent use of functions intended only for testing in
273 non-testing code. For now this is just a best-effort implementation
274 that ignores header files and may have some false positives. A
275 better implementation would probably need a proper C++ parser.
276 """
277 # We only scan .cc files and the like, as the declaration of
278 # for-testing functions in header files are hard to distinguish from
279 # calls to such functions without a proper C++ parser.
[email protected]06e6d0ff2012-12-11 01:36:44280 file_inclusion_pattern = r'.+%s' % _IMPLEMENTATION_EXTENSIONS
[email protected]55459852011-08-10 15:17:19281
[email protected]23501822014-05-14 02:06:09282 base_function_pattern = r'[ :]test::[^\s]+|ForTest(ing)?|for_test(ing)?'
[email protected]55459852011-08-10 15:17:19283 inclusion_pattern = input_api.re.compile(r'(%s)\s*\(' % base_function_pattern)
[email protected]23501822014-05-14 02:06:09284 comment_pattern = input_api.re.compile(r'//.*(%s)' % base_function_pattern)
[email protected]55459852011-08-10 15:17:19285 exclusion_pattern = input_api.re.compile(
286 r'::[A-Za-z0-9_]+(%s)|(%s)[^;]+\{' % (
287 base_function_pattern, base_function_pattern))
288
289 def FilterFile(affected_file):
[email protected]06e6d0ff2012-12-11 01:36:44290 black_list = (_EXCLUDED_PATHS +
291 _TEST_CODE_EXCLUDED_PATHS +
292 input_api.DEFAULT_BLACK_LIST)
[email protected]55459852011-08-10 15:17:19293 return input_api.FilterSourceFile(
294 affected_file,
295 white_list=(file_inclusion_pattern, ),
296 black_list=black_list)
297
298 problems = []
299 for f in input_api.AffectedSourceFiles(FilterFile):
300 local_path = f.LocalPath()
[email protected]825d27182014-01-02 21:24:24301 for line_number, line in f.ChangedContents():
[email protected]2fdd1f362013-01-16 03:56:03302 if (inclusion_pattern.search(line) and
[email protected]de4f7d22013-05-23 14:27:46303 not comment_pattern.search(line) and
[email protected]2fdd1f362013-01-16 03:56:03304 not exclusion_pattern.search(line)):
[email protected]55459852011-08-10 15:17:19305 problems.append(
[email protected]2fdd1f362013-01-16 03:56:03306 '%s:%d\n %s' % (local_path, line_number, line.strip()))
[email protected]55459852011-08-10 15:17:19307
308 if problems:
[email protected]f7051d52013-04-02 18:31:42309 return [output_api.PresubmitPromptOrNotify(_TEST_ONLY_WARNING, problems)]
[email protected]2fdd1f362013-01-16 03:56:03310 else:
311 return []
[email protected]55459852011-08-10 15:17:19312
313
[email protected]10689ca2011-09-02 02:31:54314def _CheckNoIOStreamInHeaders(input_api, output_api):
315 """Checks to make sure no .h files include <iostream>."""
316 files = []
317 pattern = input_api.re.compile(r'^#include\s*<iostream>',
318 input_api.re.MULTILINE)
319 for f in input_api.AffectedSourceFiles(input_api.FilterSourceFile):
320 if not f.LocalPath().endswith('.h'):
321 continue
322 contents = input_api.ReadFile(f)
323 if pattern.search(contents):
324 files.append(f)
325
326 if len(files):
327 return [ output_api.PresubmitError(
[email protected]6c063c62012-07-11 19:11:06328 'Do not #include <iostream> in header files, since it inserts static '
329 'initialization into every file including the header. Instead, '
[email protected]10689ca2011-09-02 02:31:54330 '#include <ostream>. See http://crbug.com/94794',
331 files) ]
332 return []
333
334
[email protected]72df4e782012-06-21 16:28:18335def _CheckNoUNIT_TESTInSourceFiles(input_api, output_api):
336 """Checks to make sure no source files use UNIT_TEST"""
337 problems = []
338 for f in input_api.AffectedFiles():
339 if (not f.LocalPath().endswith(('.cc', '.mm'))):
340 continue
341
342 for line_num, line in f.ChangedContents():
[email protected]549f86a2013-11-19 13:00:04343 if 'UNIT_TEST ' in line or line.endswith('UNIT_TEST'):
[email protected]72df4e782012-06-21 16:28:18344 problems.append(' %s:%d' % (f.LocalPath(), line_num))
345
346 if not problems:
347 return []
348 return [output_api.PresubmitPromptWarning('UNIT_TEST is only for headers.\n' +
349 '\n'.join(problems))]
350
351
[email protected]8ea5d4b2011-09-13 21:49:22352def _CheckNoNewWStrings(input_api, output_api):
353 """Checks to make sure we don't introduce use of wstrings."""
[email protected]55463aa62011-10-12 00:48:27354 problems = []
[email protected]8ea5d4b2011-09-13 21:49:22355 for f in input_api.AffectedFiles():
[email protected]b5c24292011-11-28 14:38:20356 if (not f.LocalPath().endswith(('.cc', '.h')) or
[email protected]24be83c2013-08-29 23:01:23357 f.LocalPath().endswith(('test.cc', '_win.cc', '_win.h'))):
[email protected]b5c24292011-11-28 14:38:20358 continue
[email protected]8ea5d4b2011-09-13 21:49:22359
[email protected]a11dbe9b2012-08-07 01:32:58360 allowWString = False
[email protected]b5c24292011-11-28 14:38:20361 for line_num, line in f.ChangedContents():
[email protected]a11dbe9b2012-08-07 01:32:58362 if 'presubmit: allow wstring' in line:
363 allowWString = True
364 elif not allowWString and 'wstring' in line:
[email protected]55463aa62011-10-12 00:48:27365 problems.append(' %s:%d' % (f.LocalPath(), line_num))
[email protected]a11dbe9b2012-08-07 01:32:58366 allowWString = False
367 else:
368 allowWString = False
[email protected]8ea5d4b2011-09-13 21:49:22369
[email protected]55463aa62011-10-12 00:48:27370 if not problems:
371 return []
372 return [output_api.PresubmitPromptWarning('New code should not use wstrings.'
[email protected]a11dbe9b2012-08-07 01:32:58373 ' If you are calling a cross-platform API that accepts a wstring, '
374 'fix the API.\n' +
[email protected]55463aa62011-10-12 00:48:27375 '\n'.join(problems))]
[email protected]8ea5d4b2011-09-13 21:49:22376
377
[email protected]2a8ac9c2011-10-19 17:20:44378def _CheckNoDEPSGIT(input_api, output_api):
379 """Make sure .DEPS.git is never modified manually."""
380 if any(f.LocalPath().endswith('.DEPS.git') for f in
381 input_api.AffectedFiles()):
382 return [output_api.PresubmitError(
383 'Never commit changes to .DEPS.git. This file is maintained by an\n'
384 'automated system based on what\'s in DEPS and your changes will be\n'
385 'overwritten.\n'
386 'See http://code.google.com/p/chromium/wiki/UsingNewGit#Rolling_DEPS\n'
387 'for more information')]
388 return []
389
390
[email protected]127f18ec2012-06-16 05:05:59391def _CheckNoBannedFunctions(input_api, output_api):
392 """Make sure that banned functions are not used."""
393 warnings = []
394 errors = []
395
396 file_filter = lambda f: f.LocalPath().endswith(('.mm', '.m', '.h'))
397 for f in input_api.AffectedFiles(file_filter=file_filter):
398 for line_num, line in f.ChangedContents():
399 for func_name, message, error in _BANNED_OBJC_FUNCTIONS:
[email protected]eaae1972014-04-16 04:17:26400 matched = False
401 if func_name[0:1] == '/':
402 regex = func_name[1:]
403 if input_api.re.search(regex, line):
404 matched = True
405 elif func_name in line:
406 matched = True
407 if matched:
[email protected]127f18ec2012-06-16 05:05:59408 problems = warnings;
409 if error:
410 problems = errors;
411 problems.append(' %s:%d:' % (f.LocalPath(), line_num))
412 for message_line in message:
413 problems.append(' %s' % message_line)
414
415 file_filter = lambda f: f.LocalPath().endswith(('.cc', '.mm', '.h'))
416 for f in input_api.AffectedFiles(file_filter=file_filter):
417 for line_num, line in f.ChangedContents():
[email protected]7345da02012-11-27 14:31:49418 for func_name, message, error, excluded_paths in _BANNED_CPP_FUNCTIONS:
419 def IsBlacklisted(affected_file, blacklist):
420 local_path = affected_file.LocalPath()
421 for item in blacklist:
422 if input_api.re.match(item, local_path):
423 return True
424 return False
425 if IsBlacklisted(f, excluded_paths):
426 continue
[email protected]d89eec82013-12-03 14:10:59427 matched = False
428 if func_name[0:1] == '/':
429 regex = func_name[1:]
430 if input_api.re.search(regex, line):
431 matched = True
432 elif func_name in line:
433 matched = True
434 if matched:
[email protected]127f18ec2012-06-16 05:05:59435 problems = warnings;
436 if error:
437 problems = errors;
438 problems.append(' %s:%d:' % (f.LocalPath(), line_num))
439 for message_line in message:
440 problems.append(' %s' % message_line)
441
442 result = []
443 if (warnings):
444 result.append(output_api.PresubmitPromptWarning(
445 'Banned functions were used.\n' + '\n'.join(warnings)))
446 if (errors):
447 result.append(output_api.PresubmitError(
448 'Banned functions were used.\n' + '\n'.join(errors)))
449 return result
450
451
[email protected]6c063c62012-07-11 19:11:06452def _CheckNoPragmaOnce(input_api, output_api):
453 """Make sure that banned functions are not used."""
454 files = []
455 pattern = input_api.re.compile(r'^#pragma\s+once',
456 input_api.re.MULTILINE)
457 for f in input_api.AffectedSourceFiles(input_api.FilterSourceFile):
458 if not f.LocalPath().endswith('.h'):
459 continue
460 contents = input_api.ReadFile(f)
461 if pattern.search(contents):
462 files.append(f)
463
464 if files:
465 return [output_api.PresubmitError(
466 'Do not use #pragma once in header files.\n'
467 'See http://www.chromium.org/developers/coding-style#TOC-File-headers',
468 files)]
469 return []
470
[email protected]127f18ec2012-06-16 05:05:59471
[email protected]e7479052012-09-19 00:26:12472def _CheckNoTrinaryTrueFalse(input_api, output_api):
473 """Checks to make sure we don't introduce use of foo ? true : false."""
474 problems = []
475 pattern = input_api.re.compile(r'\?\s*(true|false)\s*:\s*(true|false)')
476 for f in input_api.AffectedFiles():
477 if not f.LocalPath().endswith(('.cc', '.h', '.inl', '.m', '.mm')):
478 continue
479
480 for line_num, line in f.ChangedContents():
481 if pattern.match(line):
482 problems.append(' %s:%d' % (f.LocalPath(), line_num))
483
484 if not problems:
485 return []
486 return [output_api.PresubmitPromptWarning(
487 'Please consider avoiding the "? true : false" pattern if possible.\n' +
488 '\n'.join(problems))]
489
490
[email protected]55f9f382012-07-31 11:02:18491def _CheckUnwantedDependencies(input_api, output_api):
492 """Runs checkdeps on #include statements added in this
493 change. Breaking - rules is an error, breaking ! rules is a
494 warning.
495 """
496 # We need to wait until we have an input_api object and use this
497 # roundabout construct to import checkdeps because this file is
498 # eval-ed and thus doesn't have __file__.
499 original_sys_path = sys.path
500 try:
501 sys.path = sys.path + [input_api.os_path.join(
[email protected]5298cc982014-05-29 20:53:47502 input_api.PresubmitLocalPath(), 'buildtools', 'checkdeps')]
[email protected]55f9f382012-07-31 11:02:18503 import checkdeps
504 from cpp_checker import CppChecker
505 from rules import Rule
506 finally:
507 # Restore sys.path to what it was before.
508 sys.path = original_sys_path
509
510 added_includes = []
511 for f in input_api.AffectedFiles():
512 if not CppChecker.IsCppFile(f.LocalPath()):
513 continue
514
515 changed_lines = [line for line_num, line in f.ChangedContents()]
516 added_includes.append([f.LocalPath(), changed_lines])
517
[email protected]26385172013-05-09 23:11:35518 deps_checker = checkdeps.DepsChecker(input_api.PresubmitLocalPath())
[email protected]55f9f382012-07-31 11:02:18519
520 error_descriptions = []
521 warning_descriptions = []
522 for path, rule_type, rule_description in deps_checker.CheckAddedCppIncludes(
523 added_includes):
524 description_with_path = '%s\n %s' % (path, rule_description)
525 if rule_type == Rule.DISALLOW:
526 error_descriptions.append(description_with_path)
527 else:
528 warning_descriptions.append(description_with_path)
529
530 results = []
531 if error_descriptions:
532 results.append(output_api.PresubmitError(
533 'You added one or more #includes that violate checkdeps rules.',
534 error_descriptions))
535 if warning_descriptions:
[email protected]f7051d52013-04-02 18:31:42536 results.append(output_api.PresubmitPromptOrNotify(
[email protected]55f9f382012-07-31 11:02:18537 'You added one or more #includes of files that are temporarily\n'
538 'allowed but being removed. Can you avoid introducing the\n'
539 '#include? See relevant DEPS file(s) for details and contacts.',
540 warning_descriptions))
541 return results
542
543
[email protected]fbcafe5a2012-08-08 15:31:22544def _CheckFilePermissions(input_api, output_api):
545 """Check that all files have their permissions properly set."""
[email protected]791507202014-02-03 23:19:15546 if input_api.platform == 'win32':
547 return []
[email protected]fbcafe5a2012-08-08 15:31:22548 args = [sys.executable, 'tools/checkperms/checkperms.py', '--root',
549 input_api.change.RepositoryRoot()]
550 for f in input_api.AffectedFiles():
551 args += ['--file', f.LocalPath()]
[email protected]f0d330f2014-01-30 01:44:34552 checkperms = input_api.subprocess.Popen(args,
553 stdout=input_api.subprocess.PIPE)
554 errors = checkperms.communicate()[0].strip()
[email protected]fbcafe5a2012-08-08 15:31:22555 if errors:
[email protected]f0d330f2014-01-30 01:44:34556 return [output_api.PresubmitError('checkperms.py failed.',
557 errors.splitlines())]
558 return []
[email protected]fbcafe5a2012-08-08 15:31:22559
560
[email protected]c8278b32012-10-30 20:35:49561def _CheckNoAuraWindowPropertyHInHeaders(input_api, output_api):
562 """Makes sure we don't include ui/aura/window_property.h
563 in header files.
564 """
565 pattern = input_api.re.compile(r'^#include\s*"ui/aura/window_property.h"')
566 errors = []
567 for f in input_api.AffectedFiles():
568 if not f.LocalPath().endswith('.h'):
569 continue
570 for line_num, line in f.ChangedContents():
571 if pattern.match(line):
572 errors.append(' %s:%d' % (f.LocalPath(), line_num))
573
574 results = []
575 if errors:
576 results.append(output_api.PresubmitError(
577 'Header files should not include ui/aura/window_property.h', errors))
578 return results
579
580
[email protected]cf9b78f2012-11-14 11:40:28581def _CheckIncludeOrderForScope(scope, input_api, file_path, changed_linenums):
582 """Checks that the lines in scope occur in the right order.
583
584 1. C system files in alphabetical order
585 2. C++ system files in alphabetical order
586 3. Project's .h files
587 """
588
589 c_system_include_pattern = input_api.re.compile(r'\s*#include <.*\.h>')
590 cpp_system_include_pattern = input_api.re.compile(r'\s*#include <.*>')
591 custom_include_pattern = input_api.re.compile(r'\s*#include ".*')
592
593 C_SYSTEM_INCLUDES, CPP_SYSTEM_INCLUDES, CUSTOM_INCLUDES = range(3)
594
595 state = C_SYSTEM_INCLUDES
596
597 previous_line = ''
[email protected]728b9bb2012-11-14 20:38:57598 previous_line_num = 0
[email protected]cf9b78f2012-11-14 11:40:28599 problem_linenums = []
600 for line_num, line in scope:
601 if c_system_include_pattern.match(line):
602 if state != C_SYSTEM_INCLUDES:
[email protected]728b9bb2012-11-14 20:38:57603 problem_linenums.append((line_num, previous_line_num))
[email protected]cf9b78f2012-11-14 11:40:28604 elif previous_line and previous_line > line:
[email protected]728b9bb2012-11-14 20:38:57605 problem_linenums.append((line_num, previous_line_num))
[email protected]cf9b78f2012-11-14 11:40:28606 elif cpp_system_include_pattern.match(line):
607 if state == C_SYSTEM_INCLUDES:
608 state = CPP_SYSTEM_INCLUDES
609 elif state == CUSTOM_INCLUDES:
[email protected]728b9bb2012-11-14 20:38:57610 problem_linenums.append((line_num, previous_line_num))
[email protected]cf9b78f2012-11-14 11:40:28611 elif previous_line and previous_line > line:
[email protected]728b9bb2012-11-14 20:38:57612 problem_linenums.append((line_num, previous_line_num))
[email protected]cf9b78f2012-11-14 11:40:28613 elif custom_include_pattern.match(line):
614 if state != CUSTOM_INCLUDES:
615 state = CUSTOM_INCLUDES
616 elif previous_line and previous_line > line:
[email protected]728b9bb2012-11-14 20:38:57617 problem_linenums.append((line_num, previous_line_num))
[email protected]cf9b78f2012-11-14 11:40:28618 else:
619 problem_linenums.append(line_num)
620 previous_line = line
[email protected]728b9bb2012-11-14 20:38:57621 previous_line_num = line_num
[email protected]cf9b78f2012-11-14 11:40:28622
623 warnings = []
[email protected]728b9bb2012-11-14 20:38:57624 for (line_num, previous_line_num) in problem_linenums:
625 if line_num in changed_linenums or previous_line_num in changed_linenums:
[email protected]cf9b78f2012-11-14 11:40:28626 warnings.append(' %s:%d' % (file_path, line_num))
627 return warnings
628
629
[email protected]ac294a12012-12-06 16:38:43630def _CheckIncludeOrderInFile(input_api, f, changed_linenums):
[email protected]cf9b78f2012-11-14 11:40:28631 """Checks the #include order for the given file f."""
632
[email protected]2299dcf2012-11-15 19:56:24633 system_include_pattern = input_api.re.compile(r'\s*#include \<.*')
[email protected]23093b62013-09-20 12:16:30634 # Exclude the following includes from the check:
635 # 1) #include <.../...>, e.g., <sys/...> includes often need to appear in a
636 # specific order.
637 # 2) <atlbase.h>, "build/build_config.h"
638 excluded_include_pattern = input_api.re.compile(
639 r'\s*#include (\<.*/.*|\<atlbase\.h\>|"build/build_config.h")')
[email protected]2299dcf2012-11-15 19:56:24640 custom_include_pattern = input_api.re.compile(r'\s*#include "(?P<FILE>.*)"')
[email protected]3e83618c2013-10-09 22:32:33641 # Match the final or penultimate token if it is xxxtest so we can ignore it
642 # when considering the special first include.
643 test_file_tag_pattern = input_api.re.compile(
644 r'_[a-z]+test(?=(_[a-zA-Z0-9]+)?\.)')
[email protected]0e5c1852012-12-18 20:17:11645 if_pattern = input_api.re.compile(
646 r'\s*#\s*(if|elif|else|endif|define|undef).*')
647 # Some files need specialized order of includes; exclude such files from this
648 # check.
649 uncheckable_includes_pattern = input_api.re.compile(
650 r'\s*#include '
651 '("ipc/.*macros\.h"|<windows\.h>|".*gl.*autogen.h")\s*')
[email protected]cf9b78f2012-11-14 11:40:28652
653 contents = f.NewContents()
654 warnings = []
655 line_num = 0
656
[email protected]ac294a12012-12-06 16:38:43657 # Handle the special first include. If the first include file is
658 # some/path/file.h, the corresponding including file can be some/path/file.cc,
659 # some/other/path/file.cc, some/path/file_platform.cc, some/path/file-suffix.h
660 # etc. It's also possible that no special first include exists.
[email protected]3e83618c2013-10-09 22:32:33661 # If the included file is some/path/file_platform.h the including file could
662 # also be some/path/file_xxxtest_platform.h.
663 including_file_base_name = test_file_tag_pattern.sub(
664 '', input_api.os_path.basename(f.LocalPath()))
665
[email protected]ac294a12012-12-06 16:38:43666 for line in contents:
667 line_num += 1
668 if system_include_pattern.match(line):
669 # No special first include -> process the line again along with normal
670 # includes.
671 line_num -= 1
672 break
673 match = custom_include_pattern.match(line)
674 if match:
675 match_dict = match.groupdict()
[email protected]3e83618c2013-10-09 22:32:33676 header_basename = test_file_tag_pattern.sub(
677 '', input_api.os_path.basename(match_dict['FILE'])).replace('.h', '')
678
679 if header_basename not in including_file_base_name:
[email protected]2299dcf2012-11-15 19:56:24680 # No special first include -> process the line again along with normal
681 # includes.
682 line_num -= 1
[email protected]ac294a12012-12-06 16:38:43683 break
[email protected]cf9b78f2012-11-14 11:40:28684
685 # Split into scopes: Each region between #if and #endif is its own scope.
686 scopes = []
687 current_scope = []
688 for line in contents[line_num:]:
689 line_num += 1
[email protected]0e5c1852012-12-18 20:17:11690 if uncheckable_includes_pattern.match(line):
[email protected]4436c9e2014-01-07 23:19:54691 continue
[email protected]2309b0fa02012-11-16 12:18:27692 if if_pattern.match(line):
[email protected]cf9b78f2012-11-14 11:40:28693 scopes.append(current_scope)
694 current_scope = []
[email protected]962f117e2012-11-22 18:11:56695 elif ((system_include_pattern.match(line) or
696 custom_include_pattern.match(line)) and
697 not excluded_include_pattern.match(line)):
[email protected]cf9b78f2012-11-14 11:40:28698 current_scope.append((line_num, line))
699 scopes.append(current_scope)
700
701 for scope in scopes:
702 warnings.extend(_CheckIncludeOrderForScope(scope, input_api, f.LocalPath(),
703 changed_linenums))
704 return warnings
705
706
707def _CheckIncludeOrder(input_api, output_api):
708 """Checks that the #include order is correct.
709
710 1. The corresponding header for source files.
711 2. C system files in alphabetical order
712 3. C++ system files in alphabetical order
713 4. Project's .h files in alphabetical order
714
[email protected]ac294a12012-12-06 16:38:43715 Each region separated by #if, #elif, #else, #endif, #define and #undef follows
716 these rules separately.
[email protected]cf9b78f2012-11-14 11:40:28717 """
718
719 warnings = []
720 for f in input_api.AffectedFiles():
[email protected]ac294a12012-12-06 16:38:43721 if f.LocalPath().endswith(('.cc', '.h')):
722 changed_linenums = set(line_num for line_num, _ in f.ChangedContents())
723 warnings.extend(_CheckIncludeOrderInFile(input_api, f, changed_linenums))
[email protected]cf9b78f2012-11-14 11:40:28724
725 results = []
726 if warnings:
[email protected]f7051d52013-04-02 18:31:42727 results.append(output_api.PresubmitPromptOrNotify(_INCLUDE_ORDER_WARNING,
[email protected]120cf540d2012-12-10 17:55:53728 warnings))
[email protected]cf9b78f2012-11-14 11:40:28729 return results
730
731
[email protected]70ca77752012-11-20 03:45:03732def _CheckForVersionControlConflictsInFile(input_api, f):
733 pattern = input_api.re.compile('^(?:<<<<<<<|>>>>>>>) |^=======$')
734 errors = []
735 for line_num, line in f.ChangedContents():
736 if pattern.match(line):
737 errors.append(' %s:%d %s' % (f.LocalPath(), line_num, line))
738 return errors
739
740
741def _CheckForVersionControlConflicts(input_api, output_api):
742 """Usually this is not intentional and will cause a compile failure."""
743 errors = []
744 for f in input_api.AffectedFiles():
745 errors.extend(_CheckForVersionControlConflictsInFile(input_api, f))
746
747 results = []
748 if errors:
749 results.append(output_api.PresubmitError(
750 'Version control conflict markers found, please resolve.', errors))
751 return results
752
753
[email protected]06e6d0ff2012-12-11 01:36:44754def _CheckHardcodedGoogleHostsInLowerLayers(input_api, output_api):
755 def FilterFile(affected_file):
756 """Filter function for use with input_api.AffectedSourceFiles,
757 below. This filters out everything except non-test files from
758 top-level directories that generally speaking should not hard-code
759 service URLs (e.g. src/android_webview/, src/content/ and others).
760 """
761 return input_api.FilterSourceFile(
762 affected_file,
[email protected]78bb39d62012-12-11 15:11:56763 white_list=(r'^(android_webview|base|content|net)[\\\/].*', ),
[email protected]06e6d0ff2012-12-11 01:36:44764 black_list=(_EXCLUDED_PATHS +
765 _TEST_CODE_EXCLUDED_PATHS +
766 input_api.DEFAULT_BLACK_LIST))
767
[email protected]de4f7d22013-05-23 14:27:46768 base_pattern = '"[^"]*google\.com[^"]*"'
769 comment_pattern = input_api.re.compile('//.*%s' % base_pattern)
770 pattern = input_api.re.compile(base_pattern)
[email protected]06e6d0ff2012-12-11 01:36:44771 problems = [] # items are (filename, line_number, line)
772 for f in input_api.AffectedSourceFiles(FilterFile):
773 for line_num, line in f.ChangedContents():
[email protected]de4f7d22013-05-23 14:27:46774 if not comment_pattern.search(line) and pattern.search(line):
[email protected]06e6d0ff2012-12-11 01:36:44775 problems.append((f.LocalPath(), line_num, line))
776
777 if problems:
[email protected]f7051d52013-04-02 18:31:42778 return [output_api.PresubmitPromptOrNotify(
[email protected]06e6d0ff2012-12-11 01:36:44779 'Most layers below src/chrome/ should not hardcode service URLs.\n'
[email protected]b0149772014-03-27 16:47:58780 'Are you sure this is correct?',
[email protected]06e6d0ff2012-12-11 01:36:44781 [' %s:%d: %s' % (
782 problem[0], problem[1], problem[2]) for problem in problems])]
[email protected]2fdd1f362013-01-16 03:56:03783 else:
784 return []
[email protected]06e6d0ff2012-12-11 01:36:44785
786
[email protected]d2530012013-01-25 16:39:27787def _CheckNoAbbreviationInPngFileName(input_api, output_api):
788 """Makes sure there are no abbreviations in the name of PNG files.
789 """
[email protected]4053a48e2013-01-25 21:43:04790 pattern = input_api.re.compile(r'.*_[a-z]_.*\.png$|.*_[a-z]\.png$')
[email protected]d2530012013-01-25 16:39:27791 errors = []
792 for f in input_api.AffectedFiles(include_deletes=False):
793 if pattern.match(f.LocalPath()):
794 errors.append(' %s' % f.LocalPath())
795
796 results = []
797 if errors:
798 results.append(output_api.PresubmitError(
799 'The name of PNG files should not have abbreviations. \n'
800 'Use _hover.png, _center.png, instead of _h.png, _c.png.\n'
801 'Contact [email protected] if you have questions.', errors))
802 return results
803
804
[email protected]14a6131c2014-01-08 01:15:41805def _FilesToCheckForIncomingDeps(re, changed_lines):
[email protected]f32e2d1e2013-07-26 21:39:08806 """Helper method for _CheckAddedDepsHaveTargetApprovals. Returns
[email protected]14a6131c2014-01-08 01:15:41807 a set of DEPS entries that we should look up.
808
809 For a directory (rather than a specific filename) we fake a path to
810 a specific filename by adding /DEPS. This is chosen as a file that
811 will seldom or never be subject to per-file include_rules.
812 """
[email protected]2b438d62013-11-14 17:54:14813 # We ignore deps entries on auto-generated directories.
814 AUTO_GENERATED_DIRS = ['grit', 'jni']
[email protected]f32e2d1e2013-07-26 21:39:08815
816 # This pattern grabs the path without basename in the first
817 # parentheses, and the basename (if present) in the second. It
818 # relies on the simple heuristic that if there is a basename it will
819 # be a header file ending in ".h".
820 pattern = re.compile(
821 r"""['"]\+([^'"]+?)(/[a-zA-Z0-9_]+\.h)?['"].*""")
[email protected]2b438d62013-11-14 17:54:14822 results = set()
[email protected]f32e2d1e2013-07-26 21:39:08823 for changed_line in changed_lines:
824 m = pattern.match(changed_line)
825 if m:
826 path = m.group(1)
[email protected]2b438d62013-11-14 17:54:14827 if path.split('/')[0] not in AUTO_GENERATED_DIRS:
[email protected]14a6131c2014-01-08 01:15:41828 if m.group(2):
829 results.add('%s%s' % (path, m.group(2)))
830 else:
831 results.add('%s/DEPS' % path)
[email protected]f32e2d1e2013-07-26 21:39:08832 return results
833
834
[email protected]e871964c2013-05-13 14:14:55835def _CheckAddedDepsHaveTargetApprovals(input_api, output_api):
836 """When a dependency prefixed with + is added to a DEPS file, we
837 want to make sure that the change is reviewed by an OWNER of the
838 target file or directory, to avoid layering violations from being
839 introduced. This check verifies that this happens.
840 """
841 changed_lines = set()
842 for f in input_api.AffectedFiles():
843 filename = input_api.os_path.basename(f.LocalPath())
844 if filename == 'DEPS':
845 changed_lines |= set(line.strip()
846 for line_num, line
847 in f.ChangedContents())
848 if not changed_lines:
849 return []
850
[email protected]14a6131c2014-01-08 01:15:41851 virtual_depended_on_files = _FilesToCheckForIncomingDeps(input_api.re,
852 changed_lines)
[email protected]e871964c2013-05-13 14:14:55853 if not virtual_depended_on_files:
854 return []
855
856 if input_api.is_committing:
857 if input_api.tbr:
858 return [output_api.PresubmitNotifyResult(
859 '--tbr was specified, skipping OWNERS check for DEPS additions')]
860 if not input_api.change.issue:
861 return [output_api.PresubmitError(
862 "DEPS approval by OWNERS check failed: this change has "
863 "no Rietveld issue number, so we can't check it for approvals.")]
864 output = output_api.PresubmitError
865 else:
866 output = output_api.PresubmitNotifyResult
867
868 owners_db = input_api.owners_db
869 owner_email, reviewers = input_api.canned_checks._RietveldOwnerAndReviewers(
870 input_api,
871 owners_db.email_regexp,
872 approval_needed=input_api.is_committing)
873
874 owner_email = owner_email or input_api.change.author_email
875
[email protected]de4f7d22013-05-23 14:27:46876 reviewers_plus_owner = set(reviewers)
[email protected]e71c6082013-05-22 02:28:51877 if owner_email:
[email protected]de4f7d22013-05-23 14:27:46878 reviewers_plus_owner.add(owner_email)
[email protected]e871964c2013-05-13 14:14:55879 missing_files = owners_db.files_not_covered_by(virtual_depended_on_files,
880 reviewers_plus_owner)
[email protected]14a6131c2014-01-08 01:15:41881
882 # We strip the /DEPS part that was added by
883 # _FilesToCheckForIncomingDeps to fake a path to a file in a
884 # directory.
885 def StripDeps(path):
886 start_deps = path.rfind('/DEPS')
887 if start_deps != -1:
888 return path[:start_deps]
889 else:
890 return path
891 unapproved_dependencies = ["'+%s'," % StripDeps(path)
[email protected]e871964c2013-05-13 14:14:55892 for path in missing_files]
893
894 if unapproved_dependencies:
895 output_list = [
[email protected]14a6131c2014-01-08 01:15:41896 output('Missing LGTM from OWNERS of dependencies added to DEPS:\n %s' %
[email protected]e871964c2013-05-13 14:14:55897 '\n '.join(sorted(unapproved_dependencies)))]
898 if not input_api.is_committing:
899 suggested_owners = owners_db.reviewers_for(missing_files, owner_email)
900 output_list.append(output(
901 'Suggested missing target path OWNERS:\n %s' %
902 '\n '.join(suggested_owners or [])))
903 return output_list
904
905 return []
906
907
[email protected]85218562013-11-22 07:41:40908def _CheckSpamLogging(input_api, output_api):
909 file_inclusion_pattern = r'.+%s' % _IMPLEMENTATION_EXTENSIONS
910 black_list = (_EXCLUDED_PATHS +
911 _TEST_CODE_EXCLUDED_PATHS +
912 input_api.DEFAULT_BLACK_LIST +
[email protected]6f742dd02013-11-26 23:19:50913 (r"^base[\\\/]logging\.h$",
[email protected]80f360a2014-01-23 01:36:19914 r"^base[\\\/]logging\.cc$",
[email protected]b3643872014-02-11 23:29:39915 r"^cloud_print[\\\/]",
[email protected]c80b35022014-03-03 17:01:41916 r"^chrome_elf[\\\/]dll_hash[\\\/]dll_hash_main\.cc$",
[email protected]8dc338c2013-12-09 16:28:48917 r"^chrome[\\\/]app[\\\/]chrome_main_delegate\.cc$",
[email protected]6e268db2013-12-04 01:41:46918 r"^chrome[\\\/]browser[\\\/]chrome_browser_main\.cc$",
[email protected]4de75262013-12-18 23:16:12919 r"^chrome[\\\/]browser[\\\/]ui[\\\/]startup[\\\/]"
920 r"startup_browser_creator\.cc$",
[email protected]fe0e6e12013-12-04 05:52:58921 r"^chrome[\\\/]installer[\\\/]setup[\\\/].*",
[email protected]701a94e2014-04-17 04:37:37922 r"^extensions[\\\/]renderer[\\\/]logging_native_handler\.cc$",
[email protected]9056e732014-01-08 06:25:25923 r"^content[\\\/]common[\\\/]gpu[\\\/]client[\\\/]"
924 r"gl_helper_benchmark\.cc$",
[email protected]9c36d922014-03-24 16:47:52925 r"^native_client_sdk[\\\/]",
[email protected]cdbdced2013-11-27 21:35:50926 r"^remoting[\\\/]base[\\\/]logging\.h$",
[email protected]67c96ab2013-12-17 02:05:36927 r"^remoting[\\\/]host[\\\/].*",
[email protected]8232f8fd2013-12-14 00:52:31928 r"^sandbox[\\\/]linux[\\\/].*",
[email protected]0b7a21e2014-02-11 18:38:13929 r"^tools[\\\/]",
[email protected]8232f8fd2013-12-14 00:52:31930 r"^ui[\\\/]aura[\\\/]bench[\\\/]bench_main\.cc$",))
[email protected]85218562013-11-22 07:41:40931 source_file_filter = lambda x: input_api.FilterSourceFile(
932 x, white_list=(file_inclusion_pattern,), black_list=black_list)
933
934 log_info = []
935 printf = []
936
937 for f in input_api.AffectedSourceFiles(source_file_filter):
938 contents = input_api.ReadFile(f, 'rb')
939 if re.search(r"\bD?LOG\s*\(\s*INFO\s*\)", contents):
940 log_info.append(f.LocalPath())
[email protected]18b466b2013-12-02 22:01:37941 elif re.search(r"\bD?LOG_IF\s*\(\s*INFO\s*,", contents):
[email protected]85210652013-11-28 05:50:13942 log_info.append(f.LocalPath())
[email protected]18b466b2013-12-02 22:01:37943
944 if re.search(r"\bprintf\(", contents):
945 printf.append(f.LocalPath())
946 elif re.search(r"\bfprintf\((stdout|stderr)", contents):
[email protected]85218562013-11-22 07:41:40947 printf.append(f.LocalPath())
948
949 if log_info:
950 return [output_api.PresubmitError(
951 'These files spam the console log with LOG(INFO):',
952 items=log_info)]
953 if printf:
954 return [output_api.PresubmitError(
955 'These files spam the console log with printf/fprintf:',
956 items=printf)]
957 return []
958
959
[email protected]49aa76a2013-12-04 06:59:16960def _CheckForAnonymousVariables(input_api, output_api):
961 """These types are all expected to hold locks while in scope and
962 so should never be anonymous (which causes them to be immediately
963 destroyed)."""
964 they_who_must_be_named = [
965 'base::AutoLock',
966 'base::AutoReset',
967 'base::AutoUnlock',
968 'SkAutoAlphaRestore',
969 'SkAutoBitmapShaderInstall',
970 'SkAutoBlitterChoose',
971 'SkAutoBounderCommit',
972 'SkAutoCallProc',
973 'SkAutoCanvasRestore',
974 'SkAutoCommentBlock',
975 'SkAutoDescriptor',
976 'SkAutoDisableDirectionCheck',
977 'SkAutoDisableOvalCheck',
978 'SkAutoFree',
979 'SkAutoGlyphCache',
980 'SkAutoHDC',
981 'SkAutoLockColors',
982 'SkAutoLockPixels',
983 'SkAutoMalloc',
984 'SkAutoMaskFreeImage',
985 'SkAutoMutexAcquire',
986 'SkAutoPathBoundsUpdate',
987 'SkAutoPDFRelease',
988 'SkAutoRasterClipValidate',
989 'SkAutoRef',
990 'SkAutoTime',
991 'SkAutoTrace',
992 'SkAutoUnref',
993 ]
994 anonymous = r'(%s)\s*[({]' % '|'.join(they_who_must_be_named)
995 # bad: base::AutoLock(lock.get());
996 # not bad: base::AutoLock lock(lock.get());
997 bad_pattern = input_api.re.compile(anonymous)
998 # good: new base::AutoLock(lock.get())
999 good_pattern = input_api.re.compile(r'\bnew\s*' + anonymous)
1000 errors = []
1001
1002 for f in input_api.AffectedFiles():
1003 if not f.LocalPath().endswith(('.cc', '.h', '.inl', '.m', '.mm')):
1004 continue
1005 for linenum, line in f.ChangedContents():
1006 if bad_pattern.search(line) and not good_pattern.search(line):
1007 errors.append('%s:%d' % (f.LocalPath(), linenum))
1008
1009 if errors:
1010 return [output_api.PresubmitError(
1011 'These lines create anonymous variables that need to be named:',
1012 items=errors)]
1013 return []
1014
1015
[email protected]5fe0f8742013-11-29 01:04:591016def _CheckCygwinShell(input_api, output_api):
1017 source_file_filter = lambda x: input_api.FilterSourceFile(
1018 x, white_list=(r'.+\.(gyp|gypi)$',))
1019 cygwin_shell = []
1020
1021 for f in input_api.AffectedSourceFiles(source_file_filter):
1022 for linenum, line in f.ChangedContents():
1023 if 'msvs_cygwin_shell' in line:
1024 cygwin_shell.append(f.LocalPath())
1025 break
1026
1027 if cygwin_shell:
1028 return [output_api.PresubmitError(
1029 'These files should not use msvs_cygwin_shell (the default is 0):',
1030 items=cygwin_shell)]
1031 return []
1032
[email protected]85218562013-11-22 07:41:401033
[email protected]999261d2014-03-03 20:08:081034def _CheckUserActionUpdate(input_api, output_api):
1035 """Checks if any new user action has been added."""
[email protected]2f92dec2014-03-07 19:21:521036 if any('actions.xml' == input_api.os_path.basename(f) for f in
[email protected]999261d2014-03-03 20:08:081037 input_api.LocalPaths()):
[email protected]2f92dec2014-03-07 19:21:521038 # If actions.xml is already included in the changelist, the PRESUBMIT
1039 # for actions.xml will do a more complete presubmit check.
[email protected]999261d2014-03-03 20:08:081040 return []
1041
[email protected]999261d2014-03-03 20:08:081042 file_filter = lambda f: f.LocalPath().endswith(('.cc', '.mm'))
1043 action_re = r'[^a-zA-Z]UserMetricsAction\("([^"]*)'
[email protected]2f92dec2014-03-07 19:21:521044 current_actions = None
[email protected]999261d2014-03-03 20:08:081045 for f in input_api.AffectedFiles(file_filter=file_filter):
1046 for line_num, line in f.ChangedContents():
1047 match = input_api.re.search(action_re, line)
1048 if match:
[email protected]2f92dec2014-03-07 19:21:521049 # Loads contents in tools/metrics/actions/actions.xml to memory. It's
1050 # loaded only once.
1051 if not current_actions:
1052 with open('tools/metrics/actions/actions.xml') as actions_f:
1053 current_actions = actions_f.read()
1054 # Search for the matched user action name in |current_actions|.
[email protected]999261d2014-03-03 20:08:081055 for action_name in match.groups():
[email protected]2f92dec2014-03-07 19:21:521056 action = 'name="{0}"'.format(action_name)
1057 if action not in current_actions:
[email protected]999261d2014-03-03 20:08:081058 return [output_api.PresubmitPromptWarning(
1059 'File %s line %d: %s is missing in '
[email protected]2f92dec2014-03-07 19:21:521060 'tools/metrics/actions/actions.xml. Please run '
1061 'tools/metrics/actions/extract_actions.py to update.'
[email protected]999261d2014-03-03 20:08:081062 % (f.LocalPath(), line_num, action_name))]
1063 return []
1064
1065
[email protected]760deea2013-12-10 19:33:491066def _CheckJavaStyle(input_api, output_api):
1067 """Runs checkstyle on changed java files and returns errors if any exist."""
1068 original_sys_path = sys.path
1069 try:
1070 sys.path = sys.path + [input_api.os_path.join(
1071 input_api.PresubmitLocalPath(), 'tools', 'android', 'checkstyle')]
1072 import checkstyle
1073 finally:
1074 # Restore sys.path to what it was before.
1075 sys.path = original_sys_path
1076
1077 return checkstyle.RunCheckstyle(
1078 input_api, output_api, 'tools/android/checkstyle/chromium-style-5.0.xml')
1079
1080
[email protected]fd20b902014-05-09 02:14:531081_DEPRECATED_CSS = [
1082 # Values
1083 ( "-webkit-box", "flex" ),
1084 ( "-webkit-inline-box", "inline-flex" ),
1085 ( "-webkit-flex", "flex" ),
1086 ( "-webkit-inline-flex", "inline-flex" ),
1087 ( "-webkit-min-content", "min-content" ),
1088 ( "-webkit-max-content", "max-content" ),
1089
1090 # Properties
1091 ( "-webkit-background-clip", "background-clip" ),
1092 ( "-webkit-background-origin", "background-origin" ),
1093 ( "-webkit-background-size", "background-size" ),
1094 ( "-webkit-box-shadow", "box-shadow" ),
1095
1096 # Functions
1097 ( "-webkit-gradient", "gradient" ),
1098 ( "-webkit-repeating-gradient", "repeating-gradient" ),
1099 ( "-webkit-linear-gradient", "linear-gradient" ),
1100 ( "-webkit-repeating-linear-gradient", "repeating-linear-gradient" ),
1101 ( "-webkit-radial-gradient", "radial-gradient" ),
1102 ( "-webkit-repeating-radial-gradient", "repeating-radial-gradient" ),
1103]
1104
1105def _CheckNoDeprecatedCSS(input_api, output_api):
1106 """ Make sure that we don't use deprecated CSS
[email protected]9a48e3f82014-05-22 00:06:251107 properties, functions or values. Our external
1108 documentation is ignored by the hooks as it
1109 needs to be consumed by WebKit. """
[email protected]fd20b902014-05-09 02:14:531110 results = []
[email protected]9a48e3f82014-05-22 00:06:251111 file_inclusion_pattern = (r".+\.css$")
1112 black_list = (_EXCLUDED_PATHS +
1113 _TEST_CODE_EXCLUDED_PATHS +
1114 input_api.DEFAULT_BLACK_LIST +
1115 (r"^chrome/common/extensions/docs",
1116 r"^chrome/docs",
1117 r"^native_client_sdk"))
1118 file_filter = lambda f: input_api.FilterSourceFile(
1119 f, white_list=file_inclusion_pattern, black_list=black_list)
[email protected]fd20b902014-05-09 02:14:531120 for fpath in input_api.AffectedFiles(file_filter=file_filter):
1121 for line_num, line in fpath.ChangedContents():
1122 for (deprecated_value, value) in _DEPRECATED_CSS:
1123 if input_api.re.search(deprecated_value, line):
1124 results.append(output_api.PresubmitError(
1125 "%s:%d: Use of deprecated CSS %s, use %s instead" %
1126 (fpath.LocalPath(), line_num, deprecated_value, value)))
1127 return results
1128
[email protected]22c9bd72011-03-27 16:47:391129def _CommonChecks(input_api, output_api):
1130 """Checks common to both upload and commit."""
1131 results = []
1132 results.extend(input_api.canned_checks.PanProjectChecks(
[email protected]3de922f2013-12-20 13:27:381133 input_api, output_api,
1134 excluded_paths=_EXCLUDED_PATHS + _TESTRUNNER_PATHS))
[email protected]66daa702011-05-28 14:41:461135 results.extend(_CheckAuthorizedAuthor(input_api, output_api))
[email protected]55459852011-08-10 15:17:191136 results.extend(
[email protected]760deea2013-12-10 19:33:491137 _CheckNoProductionCodeUsingTestOnlyFunctions(input_api, output_api))
[email protected]10689ca2011-09-02 02:31:541138 results.extend(_CheckNoIOStreamInHeaders(input_api, output_api))
[email protected]72df4e782012-06-21 16:28:181139 results.extend(_CheckNoUNIT_TESTInSourceFiles(input_api, output_api))
[email protected]8ea5d4b2011-09-13 21:49:221140 results.extend(_CheckNoNewWStrings(input_api, output_api))
[email protected]2a8ac9c2011-10-19 17:20:441141 results.extend(_CheckNoDEPSGIT(input_api, output_api))
[email protected]127f18ec2012-06-16 05:05:591142 results.extend(_CheckNoBannedFunctions(input_api, output_api))
[email protected]6c063c62012-07-11 19:11:061143 results.extend(_CheckNoPragmaOnce(input_api, output_api))
[email protected]e7479052012-09-19 00:26:121144 results.extend(_CheckNoTrinaryTrueFalse(input_api, output_api))
[email protected]55f9f382012-07-31 11:02:181145 results.extend(_CheckUnwantedDependencies(input_api, output_api))
[email protected]fbcafe5a2012-08-08 15:31:221146 results.extend(_CheckFilePermissions(input_api, output_api))
[email protected]c8278b32012-10-30 20:35:491147 results.extend(_CheckNoAuraWindowPropertyHInHeaders(input_api, output_api))
[email protected]2309b0fa02012-11-16 12:18:271148 results.extend(_CheckIncludeOrder(input_api, output_api))
[email protected]70ca77752012-11-20 03:45:031149 results.extend(_CheckForVersionControlConflicts(input_api, output_api))
[email protected]b8079ae4a2012-12-05 19:56:491150 results.extend(_CheckPatchFiles(input_api, output_api))
[email protected]06e6d0ff2012-12-11 01:36:441151 results.extend(_CheckHardcodedGoogleHostsInLowerLayers(input_api, output_api))
[email protected]d2530012013-01-25 16:39:271152 results.extend(_CheckNoAbbreviationInPngFileName(input_api, output_api))
[email protected]b00342e7f2013-03-26 16:21:541153 results.extend(_CheckForInvalidOSMacros(input_api, output_api))
[email protected]e871964c2013-05-13 14:14:551154 results.extend(_CheckAddedDepsHaveTargetApprovals(input_api, output_api))
[email protected]9f919cc2013-07-31 03:04:041155 results.extend(
1156 input_api.canned_checks.CheckChangeHasNoTabs(
1157 input_api,
1158 output_api,
1159 source_file_filter=lambda x: x.LocalPath().endswith('.grd')))
[email protected]85218562013-11-22 07:41:401160 results.extend(_CheckSpamLogging(input_api, output_api))
[email protected]49aa76a2013-12-04 06:59:161161 results.extend(_CheckForAnonymousVariables(input_api, output_api))
[email protected]5fe0f8742013-11-29 01:04:591162 results.extend(_CheckCygwinShell(input_api, output_api))
[email protected]999261d2014-03-03 20:08:081163 results.extend(_CheckUserActionUpdate(input_api, output_api))
[email protected]fd20b902014-05-09 02:14:531164 results.extend(_CheckNoDeprecatedCSS(input_api, output_api))
[email protected]2299dcf2012-11-15 19:56:241165
1166 if any('PRESUBMIT.py' == f.LocalPath() for f in input_api.AffectedFiles()):
1167 results.extend(input_api.canned_checks.RunUnitTestsInDirectory(
1168 input_api, output_api,
1169 input_api.PresubmitLocalPath(),
[email protected]6be63382013-01-21 15:42:381170 whitelist=[r'^PRESUBMIT_test\.py$']))
[email protected]22c9bd72011-03-27 16:47:391171 return results
[email protected]1f7b4172010-01-28 01:17:341172
[email protected]b337cb5b2011-01-23 21:24:051173
1174def _CheckSubversionConfig(input_api, output_api):
1175 """Verifies the subversion config file is correctly setup.
1176
1177 Checks that autoprops are enabled, returns an error otherwise.
1178 """
1179 join = input_api.os_path.join
1180 if input_api.platform == 'win32':
1181 appdata = input_api.environ.get('APPDATA', '')
1182 if not appdata:
1183 return [output_api.PresubmitError('%APPDATA% is not configured.')]
1184 path = join(appdata, 'Subversion', 'config')
1185 else:
1186 home = input_api.environ.get('HOME', '')
1187 if not home:
1188 return [output_api.PresubmitError('$HOME is not configured.')]
1189 path = join(home, '.subversion', 'config')
1190
1191 error_msg = (
1192 'Please look at http://dev.chromium.org/developers/coding-style to\n'
1193 'configure your subversion configuration file. This enables automatic\n'
[email protected]c6a3c10b2011-01-24 16:14:201194 'properties to simplify the project maintenance.\n'
1195 'Pro-tip: just download and install\n'
1196 'http://src.chromium.org/viewvc/chrome/trunk/tools/build/slave/config\n')
[email protected]b337cb5b2011-01-23 21:24:051197
1198 try:
1199 lines = open(path, 'r').read().splitlines()
1200 # Make sure auto-props is enabled and check for 2 Chromium standard
1201 # auto-prop.
1202 if (not '*.cc = svn:eol-style=LF' in lines or
1203 not '*.pdf = svn:mime-type=application/pdf' in lines or
1204 not 'enable-auto-props = yes' in lines):
1205 return [
[email protected]79ed7e62011-02-21 21:08:531206 output_api.PresubmitNotifyResult(
[email protected]b337cb5b2011-01-23 21:24:051207 'It looks like you have not configured your subversion config '
[email protected]b5359c02011-02-01 20:29:561208 'file or it is not up-to-date.\n' + error_msg)
[email protected]b337cb5b2011-01-23 21:24:051209 ]
1210 except (OSError, IOError):
1211 return [
[email protected]79ed7e62011-02-21 21:08:531212 output_api.PresubmitNotifyResult(
[email protected]b337cb5b2011-01-23 21:24:051213 'Can\'t find your subversion config file.\n' + error_msg)
1214 ]
1215 return []
1216
1217
[email protected]66daa702011-05-28 14:41:461218def _CheckAuthorizedAuthor(input_api, output_api):
1219 """For non-googler/chromites committers, verify the author's email address is
1220 in AUTHORS.
1221 """
[email protected]9bb9cb82011-06-13 20:43:011222 # TODO(maruel): Add it to input_api?
1223 import fnmatch
1224
[email protected]66daa702011-05-28 14:41:461225 author = input_api.change.author_email
[email protected]9bb9cb82011-06-13 20:43:011226 if not author:
1227 input_api.logging.info('No author, skipping AUTHOR check')
[email protected]66daa702011-05-28 14:41:461228 return []
[email protected]c99663292011-05-31 19:46:081229 authors_path = input_api.os_path.join(
[email protected]66daa702011-05-28 14:41:461230 input_api.PresubmitLocalPath(), 'AUTHORS')
1231 valid_authors = (
1232 input_api.re.match(r'[^#]+\s+\<(.+?)\>\s*$', line)
1233 for line in open(authors_path))
[email protected]ac54b132011-06-06 18:11:181234 valid_authors = [item.group(1).lower() for item in valid_authors if item]
[email protected]d8b50be2011-06-15 14:19:441235 if not any(fnmatch.fnmatch(author.lower(), valid) for valid in valid_authors):
[email protected]5861efb2013-01-07 18:33:231236 input_api.logging.info('Valid authors are %s', ', '.join(valid_authors))
[email protected]66daa702011-05-28 14:41:461237 return [output_api.PresubmitPromptWarning(
1238 ('%s is not in AUTHORS file. If you are a new contributor, please visit'
1239 '\n'
1240 'http://www.chromium.org/developers/contributing-code and read the '
1241 '"Legal" section\n'
1242 'If you are a chromite, verify the contributor signed the CLA.') %
1243 author)]
1244 return []
1245
1246
[email protected]b8079ae4a2012-12-05 19:56:491247def _CheckPatchFiles(input_api, output_api):
1248 problems = [f.LocalPath() for f in input_api.AffectedFiles()
1249 if f.LocalPath().endswith(('.orig', '.rej'))]
1250 if problems:
1251 return [output_api.PresubmitError(
1252 "Don't commit .rej and .orig files.", problems)]
[email protected]2fdd1f362013-01-16 03:56:031253 else:
1254 return []
[email protected]b8079ae4a2012-12-05 19:56:491255
1256
[email protected]b00342e7f2013-03-26 16:21:541257def _DidYouMeanOSMacro(bad_macro):
1258 try:
1259 return {'A': 'OS_ANDROID',
1260 'B': 'OS_BSD',
1261 'C': 'OS_CHROMEOS',
1262 'F': 'OS_FREEBSD',
1263 'L': 'OS_LINUX',
1264 'M': 'OS_MACOSX',
1265 'N': 'OS_NACL',
1266 'O': 'OS_OPENBSD',
1267 'P': 'OS_POSIX',
1268 'S': 'OS_SOLARIS',
1269 'W': 'OS_WIN'}[bad_macro[3].upper()]
1270 except KeyError:
1271 return ''
1272
1273
1274def _CheckForInvalidOSMacrosInFile(input_api, f):
1275 """Check for sensible looking, totally invalid OS macros."""
1276 preprocessor_statement = input_api.re.compile(r'^\s*#')
1277 os_macro = input_api.re.compile(r'defined\((OS_[^)]+)\)')
1278 results = []
1279 for lnum, line in f.ChangedContents():
1280 if preprocessor_statement.search(line):
1281 for match in os_macro.finditer(line):
1282 if not match.group(1) in _VALID_OS_MACROS:
1283 good = _DidYouMeanOSMacro(match.group(1))
1284 did_you_mean = ' (did you mean %s?)' % good if good else ''
1285 results.append(' %s:%d %s%s' % (f.LocalPath(),
1286 lnum,
1287 match.group(1),
1288 did_you_mean))
1289 return results
1290
1291
1292def _CheckForInvalidOSMacros(input_api, output_api):
1293 """Check all affected files for invalid OS macros."""
1294 bad_macros = []
1295 for f in input_api.AffectedFiles():
1296 if not f.LocalPath().endswith(('.py', '.js', '.html', '.css')):
1297 bad_macros.extend(_CheckForInvalidOSMacrosInFile(input_api, f))
1298
1299 if not bad_macros:
1300 return []
1301
1302 return [output_api.PresubmitError(
1303 'Possibly invalid OS macro[s] found. Please fix your code\n'
1304 'or add your macro to src/PRESUBMIT.py.', bad_macros)]
1305
1306
[email protected]1f7b4172010-01-28 01:17:341307def CheckChangeOnUpload(input_api, output_api):
1308 results = []
1309 results.extend(_CommonChecks(input_api, output_api))
[email protected]ae69ae72014-02-20 13:09:361310 results.extend(_CheckJavaStyle(input_api, output_api))
[email protected]fe5f57c52009-06-05 14:25:541311 return results
[email protected]ca8d19842009-02-19 16:33:121312
1313
[email protected]1bfb8322014-04-23 01:02:411314def GetTryServerMasterForBot(bot):
1315 """Returns the Try Server master for the given bot.
1316
1317 Assumes that most Try Servers are on the tryserver.chromium master."""
1318 non_default_master_map = {
1319 'linux_gpu': 'tryserver.chromium.gpu',
[email protected]5c5f13042014-05-09 21:28:301320 'mac_gpu': 'tryserver.chromium.gpu',
[email protected]d263d5b2014-04-30 01:15:551321 'win_gpu': 'tryserver.chromium.gpu',
[email protected]1bfb8322014-04-23 01:02:411322 }
1323 return non_default_master_map.get(bot, 'tryserver.chromium')
1324
1325
[email protected]38c6a512013-12-18 23:48:011326def GetDefaultTryConfigs(bots=None):
1327 """Returns a list of ('bot', set(['tests']), optionally filtered by [bots].
1328
1329 To add tests to this list, they MUST be in the the corresponding master's
1330 gatekeeper config. For example, anything on master.chromium would be closed by
1331 tools/build/masters/master.chromium/master_gatekeeper_cfg.py.
1332
1333 If 'bots' is specified, will only return configurations for bots in that list.
1334 """
1335
1336 standard_tests = [
1337 'base_unittests',
1338 'browser_tests',
1339 'cacheinvalidation_unittests',
1340 'check_deps',
1341 'check_deps2git',
1342 'content_browsertests',
1343 'content_unittests',
1344 'crypto_unittests',
[email protected]38c6a512013-12-18 23:48:011345 'gpu_unittests',
1346 'interactive_ui_tests',
1347 'ipc_tests',
1348 'jingle_unittests',
1349 'media_unittests',
1350 'net_unittests',
1351 'ppapi_unittests',
1352 'printing_unittests',
1353 'sql_unittests',
1354 'sync_unit_tests',
1355 'unit_tests',
1356 # Broken in release.
1357 #'url_unittests',
1358 #'webkit_unit_tests',
1359 ]
1360
[email protected]38c6a512013-12-18 23:48:011361 builders_and_tests = {
1362 # TODO(maruel): Figure out a way to run 'sizes' where people can
1363 # effectively update the perf expectation correctly. This requires a
1364 # clobber=True build running 'sizes'. 'sizes' is not accurate with
1365 # incremental build. Reference:
1366 # http://chromium.org/developers/tree-sheriffs/perf-sheriffs.
1367 # TODO(maruel): An option would be to run 'sizes' but not count a failure
1368 # of this step as a try job failure.
1369 'android_aosp': ['compile'],
[email protected]5a65d3042014-05-07 14:26:011370 'android_chromium_gn_compile_rel': ['compile'],
[email protected]38c6a512013-12-18 23:48:011371 'android_clang_dbg': ['slave_steps'],
1372 'android_dbg': ['slave_steps'],
1373 'cros_x86': ['defaulttests'],
1374 'ios_dbg_simulator': [
1375 'compile',
1376 'base_unittests',
1377 'content_unittests',
1378 'crypto_unittests',
1379 'url_unittests',
1380 'net_unittests',
1381 'sql_unittests',
1382 'ui_unittests',
1383 ],
1384 'ios_rel_device': ['compile'],
[email protected]971b08ce2014-03-19 22:03:561385 'linux_asan': ['compile'],
1386 'mac_asan': ['compile'],
[email protected]38c6a512013-12-18 23:48:011387 #TODO(stip): Change the name of this builder to reflect that it's release.
[email protected]71afb4ec2014-02-07 02:45:131388 'linux_gtk': standard_tests,
[email protected]971b08ce2014-03-19 22:03:561389 'linux_chromeos_asan': ['compile'],
[email protected]d910b6082014-02-27 18:15:431390 'linux_chromium_chromeos_clang_dbg': ['defaulttests'],
1391 'linux_chromium_chromeos_rel': ['defaulttests'],
1392 'linux_chromium_compile_dbg': ['defaulttests'],
[email protected]5a65d3042014-05-07 14:26:011393 'linux_chromium_gn_rel': ['defaulttests'],
[email protected]23c81d552014-01-07 13:45:461394 'linux_chromium_rel': ['defaulttests'],
[email protected]d910b6082014-02-27 18:15:431395 'linux_chromium_clang_dbg': ['defaulttests'],
[email protected]1bfb8322014-04-23 01:02:411396 'linux_gpu': ['defaulttests'],
[email protected]9780bac2014-01-11 00:12:021397 'linux_nacl_sdk_build': ['compile'],
[email protected]d910b6082014-02-27 18:15:431398 'linux_rel': [
[email protected]9021a5f72014-01-24 19:02:381399 'telemetry_perf_unittests',
1400 'telemetry_unittests',
[email protected]38c6a512013-12-18 23:48:011401 ],
[email protected]d910b6082014-02-27 18:15:431402 'mac_chromium_compile_dbg': ['defaulttests'],
[email protected]23c81d552014-01-07 13:45:461403 'mac_chromium_rel': ['defaulttests'],
[email protected]5c5f13042014-05-09 21:28:301404 'mac_gpu': ['defaulttests'],
[email protected]9780bac2014-01-11 00:12:021405 'mac_nacl_sdk_build': ['compile'],
[email protected]d910b6082014-02-27 18:15:431406 'mac_rel': [
[email protected]9021a5f72014-01-24 19:02:381407 'telemetry_perf_unittests',
[email protected]38c6a512013-12-18 23:48:011408 'telemetry_unittests',
1409 ],
1410 'win': ['compile'],
[email protected]0094fa12014-03-13 03:18:281411 'win_chromium_compile_dbg': ['defaulttests'],
[email protected]c17144e42014-04-15 09:32:431412 'win_chromium_dbg': ['defaulttests'],
1413 'win_chromium_rel': ['defaulttests'],
[email protected]2a207162014-04-15 17:05:301414 'win_chromium_x64_rel': ['defaulttests'],
[email protected]d263d5b2014-04-30 01:15:551415 'win_gpu': ['defaulttests'],
[email protected]9780bac2014-01-11 00:12:021416 'win_nacl_sdk_build': ['compile'],
[email protected]38c6a512013-12-18 23:48:011417 'win_rel': standard_tests + [
1418 'app_list_unittests',
1419 'ash_unittests',
1420 'aura_unittests',
1421 'cc_unittests',
1422 'chrome_elf_unittests',
[email protected]5d0413fc2014-01-03 18:24:301423 'chromedriver_unittests',
[email protected]38c6a512013-12-18 23:48:011424 'components_unittests',
1425 'compositor_unittests',
1426 'events_unittests',
[email protected]0df555e2014-02-27 14:53:111427 'gfx_unittests',
[email protected]38c6a512013-12-18 23:48:011428 'google_apis_unittests',
1429 'installer_util_unittests',
1430 'mini_installer_test',
1431 'nacl_integration',
1432 'remoting_unittests',
1433 'sync_integration_tests',
[email protected]9021a5f72014-01-24 19:02:381434 'telemetry_perf_unittests',
[email protected]38c6a512013-12-18 23:48:011435 'telemetry_unittests',
1436 'views_unittests',
1437 ],
1438 'win_x64_rel': [
1439 'base_unittests',
1440 ],
1441 }
1442
1443 swarm_enabled_builders = (
[email protected]9714f3b2014-03-20 19:50:111444 # http://crbug.com/354263
1445 # 'linux_rel',
1446 # 'mac_rel',
1447 # 'win_rel',
[email protected]38c6a512013-12-18 23:48:011448 )
1449
1450 swarm_enabled_tests = (
1451 'base_unittests',
1452 'browser_tests',
1453 'interactive_ui_tests',
1454 'net_unittests',
1455 'unit_tests',
1456 )
1457
1458 for bot in builders_and_tests:
1459 if bot in swarm_enabled_builders:
1460 builders_and_tests[bot] = [x + '_swarm' if x in swarm_enabled_tests else x
1461 for x in builders_and_tests[bot]]
1462
1463 if bots:
[email protected]1bfb8322014-04-23 01:02:411464 filtered_builders_and_tests = dict((bot, set(builders_and_tests[bot]))
1465 for bot in bots)
[email protected]38c6a512013-12-18 23:48:011466 else:
[email protected]1bfb8322014-04-23 01:02:411467 filtered_builders_and_tests = dict(
1468 (bot, set(tests))
1469 for bot, tests in builders_and_tests.iteritems())
1470
1471 # Build up the mapping from tryserver master to bot/test.
1472 out = dict()
1473 for bot, tests in filtered_builders_and_tests.iteritems():
1474 out.setdefault(GetTryServerMasterForBot(bot), {})[bot] = tests
1475 return out
[email protected]38c6a512013-12-18 23:48:011476
1477
[email protected]ca8d19842009-02-19 16:33:121478def CheckChangeOnCommit(input_api, output_api):
[email protected]fe5f57c52009-06-05 14:25:541479 results = []
[email protected]1f7b4172010-01-28 01:17:341480 results.extend(_CommonChecks(input_api, output_api))
[email protected]dd805fe2009-10-01 08:11:511481 # TODO(thestig) temporarily disabled, doesn't work in third_party/
1482 #results.extend(input_api.canned_checks.CheckSvnModifiedDirectories(
1483 # input_api, output_api, sources))
[email protected]fe5f57c52009-06-05 14:25:541484 # Make sure the tree is 'open'.
[email protected]806e98e2010-03-19 17:49:271485 results.extend(input_api.canned_checks.CheckTreeIsOpen(
[email protected]7f238152009-08-12 19:00:341486 input_api,
1487 output_api,
[email protected]2fdd1f362013-01-16 03:56:031488 json_url='http://chromium-status.appspot.com/current?format=json'))
[email protected]806e98e2010-03-19 17:49:271489
[email protected]3e4eb112011-01-18 03:29:541490 results.extend(input_api.canned_checks.CheckChangeHasBugField(
1491 input_api, output_api))
[email protected]c4b47562011-12-05 23:39:411492 results.extend(input_api.canned_checks.CheckChangeHasDescription(
1493 input_api, output_api))
[email protected]b337cb5b2011-01-23 21:24:051494 results.extend(_CheckSubversionConfig(input_api, output_api))
[email protected]fe5f57c52009-06-05 14:25:541495 return results
[email protected]ca8d19842009-02-19 16:33:121496
1497
[email protected]7468ac522014-03-12 23:35:571498def GetPreferredTryMasters(project, change):
[email protected]4ce995ea2012-06-27 02:13:101499 files = change.LocalPaths()
1500
[email protected]751b05f2013-01-10 23:12:171501 if not files or all(re.search(r'[\\/]OWNERS$', f) for f in files):
[email protected]7468ac522014-03-12 23:35:571502 return {}
[email protected]3019c902012-06-29 00:09:031503
[email protected]d668899a2012-09-06 18:16:591504 if all(re.search('\.(m|mm)$|(^|[/_])mac[/_.]', f) for f in files):
[email protected]d96b1f42014-02-27 19:17:521505 return GetDefaultTryConfigs([
1506 'mac_chromium_compile_dbg',
1507 'mac_chromium_rel',
[email protected]d96b1f42014-02-27 19:17:521508 ])
[email protected]d668899a2012-09-06 18:16:591509 if all(re.search('(^|[/_])win[/_.]', f) for f in files):
[email protected]c17144e42014-04-15 09:32:431510 return GetDefaultTryConfigs(['win_chromium_dbg', 'win_chromium_rel'])
[email protected]d668899a2012-09-06 18:16:591511 if all(re.search('(^|[/_])android[/_.]', f) for f in files):
[email protected]38c6a512013-12-18 23:48:011512 return GetDefaultTryConfigs([
1513 'android_aosp',
1514 'android_clang_dbg',
1515 'android_dbg',
1516 ])
[email protected]de142152012-10-03 23:02:451517 if all(re.search('[/_]ios[/_.]', f) for f in files):
[email protected]38c6a512013-12-18 23:48:011518 return GetDefaultTryConfigs(['ios_rel_device', 'ios_dbg_simulator'])
[email protected]4ce995ea2012-06-27 02:13:101519
[email protected]7468ac522014-03-12 23:35:571520 builders = [
[email protected]5a65d3042014-05-07 14:26:011521 'android_chromium_gn_compile_rel',
[email protected]3e2f0402012-11-02 16:28:011522 'android_clang_dbg',
1523 'android_dbg',
1524 'ios_dbg_simulator',
1525 'ios_rel_device',
[email protected]d96b1f42014-02-27 19:17:521526 'linux_chromium_chromeos_rel',
1527 'linux_chromium_clang_dbg',
[email protected]5a65d3042014-05-07 14:26:011528 'linux_chromium_gn_rel',
[email protected]d96b1f42014-02-27 19:17:521529 'linux_chromium_rel',
[email protected]1bfb8322014-04-23 01:02:411530 'linux_gpu',
[email protected]d96b1f42014-02-27 19:17:521531 'mac_chromium_compile_dbg',
[email protected]d96b1f42014-02-27 19:17:521532 'mac_chromium_rel',
[email protected]5c5f13042014-05-09 21:28:301533 'mac_gpu',
[email protected]0094fa12014-03-13 03:18:281534 'win_chromium_compile_dbg',
[email protected]c17144e42014-04-15 09:32:431535 'win_chromium_rel',
[email protected]2a207162014-04-15 17:05:301536 'win_chromium_x64_rel',
[email protected]d263d5b2014-04-30 01:15:551537 'win_gpu',
[email protected]7468ac522014-03-12 23:35:571538 ]
[email protected]911753b2012-08-02 12:11:541539
1540 # Match things like path/aura/file.cc and path/file_aura.cc.
[email protected]95c989162012-11-29 05:58:251541 # Same for chromeos.
1542 if any(re.search('[/_](aura|chromeos)', f) for f in files):
[email protected]7468ac522014-03-12 23:35:571543 builders.extend([
1544 'linux_chromeos_asan',
1545 'linux_chromium_chromeos_clang_dbg'
1546 ])
[email protected]4ce995ea2012-06-27 02:13:101547
[email protected]e8df48f2013-09-30 20:07:541548 # If there are gyp changes to base, build, or chromeos, run a full cros build
1549 # in addition to the shorter linux_chromeos build. Changes to high level gyp
1550 # files have a much higher chance of breaking the cros build, which is
1551 # differnt from the linux_chromeos build that most chrome developers test
1552 # with.
1553 if any(re.search('^(base|build|chromeos).*\.gypi?$', f) for f in files):
[email protected]7468ac522014-03-12 23:35:571554 builders.extend(['cros_x86'])
[email protected]e8df48f2013-09-30 20:07:541555
[email protected]d95948ef2013-07-02 10:51:001556 # The AOSP bot doesn't build the chrome/ layer, so ignore any changes to it
1557 # unless they're .gyp(i) files as changes to those files can break the gyp
1558 # step on that bot.
1559 if (not all(re.search('^chrome', f) for f in files) or
1560 any(re.search('\.gypi?$', f) for f in files)):
[email protected]7468ac522014-03-12 23:35:571561 builders.extend(['android_aosp'])
[email protected]d95948ef2013-07-02 10:51:001562
[email protected]7468ac522014-03-12 23:35:571563 return GetDefaultTryConfigs(builders)