blob: 22ff1a53b058e2784564ae665a5a76eca700cb93 [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]9d16ad12011-12-14 20:49:4712import re
[email protected]fbcafe5a2012-08-08 15:31:2213import subprocess
[email protected]55f9f382012-07-31 11:02:1814import sys
[email protected]9d16ad12011-12-14 20:49:4715
16
[email protected]379e7dd2010-01-28 17:39:2117_EXCLUDED_PATHS = (
[email protected]3e4eb112011-01-18 03:29:5418 r"^breakpad[\\\/].*",
[email protected]a18130a2012-01-03 17:52:0819 r"^native_client_sdk[\\\/].*",
20 r"^net[\\\/]tools[\\\/]spdyshark[\\\/].*",
[email protected]3e4eb112011-01-18 03:29:5421 r"^skia[\\\/].*",
22 r"^v8[\\\/].*",
23 r".*MakeFile$",
[email protected]1084ccc2012-03-14 03:22:5324 r".+_autogen\.h$",
[email protected]94f206c12012-08-25 00:09:1425 r"^cc[\\\/].*",
[email protected]4306417642009-06-11 00:33:4026)
[email protected]ca8d1982009-02-19 16:33:1227
[email protected]ca8d1982009-02-19 16:33:1228
[email protected]eea609a2011-11-18 13:10:1229_TEST_ONLY_WARNING = (
30 'You might be calling functions intended only for testing from\n'
31 'production code. It is OK to ignore this warning if you know what\n'
32 'you are doing, as the heuristics used to detect the situation are\n'
33 'not perfect. The commit queue will not block on this warning.\n'
34 'Email [email protected] if you have questions.')
35
36
[email protected]127f18ec2012-06-16 05:05:5937_BANNED_OBJC_FUNCTIONS = (
38 (
39 'addTrackingRect:',
[email protected]23e6cbc2012-06-16 18:51:2040 (
41 'The use of -[NSView addTrackingRect:owner:userData:assumeInside:] is'
[email protected]127f18ec2012-06-16 05:05:5942 'prohibited. Please use CrTrackingArea instead.',
43 'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts',
44 ),
45 False,
46 ),
47 (
48 'NSTrackingArea',
[email protected]23e6cbc2012-06-16 18:51:2049 (
50 'The use of NSTrackingAreas is prohibited. Please use CrTrackingArea',
[email protected]127f18ec2012-06-16 05:05:5951 'instead.',
52 'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts',
53 ),
54 False,
55 ),
56 (
57 'convertPointFromBase:',
[email protected]23e6cbc2012-06-16 18:51:2058 (
59 'The use of -[NSView convertPointFromBase:] is almost certainly wrong.',
[email protected]127f18ec2012-06-16 05:05:5960 'Please use |convertPoint:(point) fromView:nil| instead.',
61 'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts',
62 ),
63 True,
64 ),
65 (
66 'convertPointToBase:',
[email protected]23e6cbc2012-06-16 18:51:2067 (
68 'The use of -[NSView convertPointToBase:] is almost certainly wrong.',
[email protected]127f18ec2012-06-16 05:05:5969 'Please use |convertPoint:(point) toView:nil| instead.',
70 'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts',
71 ),
72 True,
73 ),
74 (
75 'convertRectFromBase:',
[email protected]23e6cbc2012-06-16 18:51:2076 (
77 'The use of -[NSView convertRectFromBase:] is almost certainly wrong.',
[email protected]127f18ec2012-06-16 05:05:5978 'Please use |convertRect:(point) fromView:nil| instead.',
79 'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts',
80 ),
81 True,
82 ),
83 (
84 'convertRectToBase:',
[email protected]23e6cbc2012-06-16 18:51:2085 (
86 'The use of -[NSView convertRectToBase:] is almost certainly wrong.',
[email protected]127f18ec2012-06-16 05:05:5987 'Please use |convertRect:(point) toView:nil| instead.',
88 'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts',
89 ),
90 True,
91 ),
92 (
93 'convertSizeFromBase:',
[email protected]23e6cbc2012-06-16 18:51:2094 (
95 'The use of -[NSView convertSizeFromBase:] is almost certainly wrong.',
[email protected]127f18ec2012-06-16 05:05:5996 'Please use |convertSize:(point) fromView:nil| instead.',
97 'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts',
98 ),
99 True,
100 ),
101 (
102 'convertSizeToBase:',
[email protected]23e6cbc2012-06-16 18:51:20103 (
104 'The use of -[NSView convertSizeToBase:] is almost certainly wrong.',
[email protected]127f18ec2012-06-16 05:05:59105 'Please use |convertSize:(point) toView:nil| instead.',
106 'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts',
107 ),
108 True,
109 ),
110)
111
112
113_BANNED_CPP_FUNCTIONS = (
[email protected]23e6cbc2012-06-16 18:51:20114 # Make sure that gtest's FRIEND_TEST() macro is not used; the
115 # FRIEND_TEST_ALL_PREFIXES() macro from base/gtest_prod_util.h should be
116 # used instead since that allows for FLAKY_, FAILS_ and DISABLED_ prefixes.
117 (
118 'FRIEND_TEST(',
119 (
[email protected]e3c945502012-06-26 20:01:49120 'Chromium code should not use gtest\'s FRIEND_TEST() macro. Include',
[email protected]23e6cbc2012-06-16 18:51:20121 'base/gtest_prod_util.h and use FRIEND_TEST_ALL_PREFIXES() instead.',
122 ),
123 False,
124 ),
125 (
126 'ScopedAllowIO',
127 (
[email protected]e3c945502012-06-26 20:01:49128 'New code should not use ScopedAllowIO. Post a task to the blocking',
129 'pool or the FILE thread instead.',
[email protected]23e6cbc2012-06-16 18:51:20130 ),
[email protected]e3c945502012-06-26 20:01:49131 True,
[email protected]23e6cbc2012-06-16 18:51:20132 ),
133 (
134 'FilePathWatcher::Delegate',
135 (
[email protected]e3c945502012-06-26 20:01:49136 'New code should not use FilePathWatcher::Delegate. Use the callback',
[email protected]23e6cbc2012-06-16 18:51:20137 'interface instead.',
138 ),
139 False,
140 ),
[email protected]e3c945502012-06-26 20:01:49141 (
142 'browser::FindLastActiveWithProfile',
143 (
144 'This function is deprecated and we\'re working on removing it. Pass',
145 'more context to get a Browser*, like a WebContents, window, or session',
146 'id. Talk to ben@ or jam@ for more information.',
147 ),
148 True,
149 ),
150 (
[email protected]e3c945502012-06-26 20:01:49151 'browser::FindAnyBrowser',
152 (
153 'This function is deprecated and we\'re working on removing it. Pass',
154 'more context to get a Browser*, like a WebContents, window, or session',
155 'id. Talk to ben@ or jam@ for more information.',
156 ),
157 True,
158 ),
159 (
160 'browser::FindOrCreateTabbedBrowser',
161 (
162 'This function is deprecated and we\'re working on removing it. Pass',
163 'more context to get a Browser*, like a WebContents, window, or session',
164 'id. Talk to ben@ or jam@ for more information.',
165 ),
166 True,
167 ),
168 (
169 'browser::FindTabbedBrowser',
170 (
171 'This function is deprecated and we\'re working on removing it. Pass',
172 'more context to get a Browser*, like a WebContents, window, or session',
173 'id. Talk to ben@ or jam@ for more information.',
174 ),
175 True,
176 ),
[email protected]127f18ec2012-06-16 05:05:59177)
178
179
[email protected]eea609a2011-11-18 13:10:12180
[email protected]55459852011-08-10 15:17:19181def _CheckNoProductionCodeUsingTestOnlyFunctions(input_api, output_api):
182 """Attempts to prevent use of functions intended only for testing in
183 non-testing code. For now this is just a best-effort implementation
184 that ignores header files and may have some false positives. A
185 better implementation would probably need a proper C++ parser.
186 """
187 # We only scan .cc files and the like, as the declaration of
188 # for-testing functions in header files are hard to distinguish from
189 # calls to such functions without a proper C++ parser.
[email protected]403bfbc92012-06-11 23:30:09190 platform_specifiers = r'(_(android|chromeos|gtk|mac|posix|win))?'
[email protected]55459852011-08-10 15:17:19191 source_extensions = r'\.(cc|cpp|cxx|mm)$'
192 file_inclusion_pattern = r'.+%s' % source_extensions
[email protected]19e77fd2011-10-20 05:24:05193 file_exclusion_patterns = (
[email protected]e21ce382012-01-04 18:48:25194 r'.*[/\\](test_|mock_).+%s' % source_extensions,
[email protected]c762d252012-02-28 02:07:24195 r'.+_test_(base|support|util)%s' % source_extensions,
[email protected]403bfbc92012-06-11 23:30:09196 r'.+_(api|browser|perf|unit|ui)?test%s%s' % (platform_specifiers,
197 source_extensions),
[email protected]19e77fd2011-10-20 05:24:05198 r'.+profile_sync_service_harness%s' % source_extensions,
199 )
200 path_exclusion_patterns = (
201 r'.*[/\\](test|tool(s)?)[/\\].*',
202 # At request of folks maintaining this folder.
203 r'chrome[/\\]browser[/\\]automation[/\\].*',
204 )
[email protected]55459852011-08-10 15:17:19205
206 base_function_pattern = r'ForTest(ing)?|for_test(ing)?'
207 inclusion_pattern = input_api.re.compile(r'(%s)\s*\(' % base_function_pattern)
208 exclusion_pattern = input_api.re.compile(
209 r'::[A-Za-z0-9_]+(%s)|(%s)[^;]+\{' % (
210 base_function_pattern, base_function_pattern))
211
212 def FilterFile(affected_file):
[email protected]19e77fd2011-10-20 05:24:05213 black_list = (file_exclusion_patterns + path_exclusion_patterns +
[email protected]3afb12a42011-08-15 13:48:33214 _EXCLUDED_PATHS + input_api.DEFAULT_BLACK_LIST)
[email protected]55459852011-08-10 15:17:19215 return input_api.FilterSourceFile(
216 affected_file,
217 white_list=(file_inclusion_pattern, ),
218 black_list=black_list)
219
220 problems = []
221 for f in input_api.AffectedSourceFiles(FilterFile):
222 local_path = f.LocalPath()
223 lines = input_api.ReadFile(f).splitlines()
224 line_number = 0
225 for line in lines:
226 if (inclusion_pattern.search(line) and
227 not exclusion_pattern.search(line)):
228 problems.append(
229 '%s:%d\n %s' % (local_path, line_number, line.strip()))
230 line_number += 1
231
232 if problems:
[email protected]eea609a2011-11-18 13:10:12233 if not input_api.is_committing:
234 return [output_api.PresubmitPromptWarning(_TEST_ONLY_WARNING, problems)]
235 else:
236 # We don't warn on commit, to avoid stopping commits going through CQ.
237 return [output_api.PresubmitNotifyResult(_TEST_ONLY_WARNING, problems)]
[email protected]55459852011-08-10 15:17:19238 else:
239 return []
240
241
[email protected]10689ca2011-09-02 02:31:54242def _CheckNoIOStreamInHeaders(input_api, output_api):
243 """Checks to make sure no .h files include <iostream>."""
244 files = []
245 pattern = input_api.re.compile(r'^#include\s*<iostream>',
246 input_api.re.MULTILINE)
247 for f in input_api.AffectedSourceFiles(input_api.FilterSourceFile):
248 if not f.LocalPath().endswith('.h'):
249 continue
250 contents = input_api.ReadFile(f)
251 if pattern.search(contents):
252 files.append(f)
253
254 if len(files):
255 return [ output_api.PresubmitError(
[email protected]6c063c62012-07-11 19:11:06256 'Do not #include <iostream> in header files, since it inserts static '
257 'initialization into every file including the header. Instead, '
[email protected]10689ca2011-09-02 02:31:54258 '#include <ostream>. See http://crbug.com/94794',
259 files) ]
260 return []
261
262
[email protected]72df4e782012-06-21 16:28:18263def _CheckNoUNIT_TESTInSourceFiles(input_api, output_api):
264 """Checks to make sure no source files use UNIT_TEST"""
265 problems = []
266 for f in input_api.AffectedFiles():
267 if (not f.LocalPath().endswith(('.cc', '.mm'))):
268 continue
269
270 for line_num, line in f.ChangedContents():
271 if 'UNIT_TEST' in line:
272 problems.append(' %s:%d' % (f.LocalPath(), line_num))
273
274 if not problems:
275 return []
276 return [output_api.PresubmitPromptWarning('UNIT_TEST is only for headers.\n' +
277 '\n'.join(problems))]
278
279
[email protected]8ea5d4b2011-09-13 21:49:22280def _CheckNoNewWStrings(input_api, output_api):
281 """Checks to make sure we don't introduce use of wstrings."""
[email protected]55463aa62011-10-12 00:48:27282 problems = []
[email protected]8ea5d4b2011-09-13 21:49:22283 for f in input_api.AffectedFiles():
[email protected]b5c24292011-11-28 14:38:20284 if (not f.LocalPath().endswith(('.cc', '.h')) or
285 f.LocalPath().endswith('test.cc')):
286 continue
[email protected]8ea5d4b2011-09-13 21:49:22287
[email protected]a11dbe9b2012-08-07 01:32:58288 allowWString = False
[email protected]b5c24292011-11-28 14:38:20289 for line_num, line in f.ChangedContents():
[email protected]a11dbe9b2012-08-07 01:32:58290 if 'presubmit: allow wstring' in line:
291 allowWString = True
292 elif not allowWString and 'wstring' in line:
[email protected]55463aa62011-10-12 00:48:27293 problems.append(' %s:%d' % (f.LocalPath(), line_num))
[email protected]a11dbe9b2012-08-07 01:32:58294 allowWString = False
295 else:
296 allowWString = False
[email protected]8ea5d4b2011-09-13 21:49:22297
[email protected]55463aa62011-10-12 00:48:27298 if not problems:
299 return []
300 return [output_api.PresubmitPromptWarning('New code should not use wstrings.'
[email protected]a11dbe9b2012-08-07 01:32:58301 ' If you are calling a cross-platform API that accepts a wstring, '
302 'fix the API.\n' +
[email protected]55463aa62011-10-12 00:48:27303 '\n'.join(problems))]
[email protected]8ea5d4b2011-09-13 21:49:22304
305
[email protected]2a8ac9c2011-10-19 17:20:44306def _CheckNoDEPSGIT(input_api, output_api):
307 """Make sure .DEPS.git is never modified manually."""
308 if any(f.LocalPath().endswith('.DEPS.git') for f in
309 input_api.AffectedFiles()):
310 return [output_api.PresubmitError(
311 'Never commit changes to .DEPS.git. This file is maintained by an\n'
312 'automated system based on what\'s in DEPS and your changes will be\n'
313 'overwritten.\n'
314 'See http://code.google.com/p/chromium/wiki/UsingNewGit#Rolling_DEPS\n'
315 'for more information')]
316 return []
317
318
[email protected]127f18ec2012-06-16 05:05:59319def _CheckNoBannedFunctions(input_api, output_api):
320 """Make sure that banned functions are not used."""
321 warnings = []
322 errors = []
323
324 file_filter = lambda f: f.LocalPath().endswith(('.mm', '.m', '.h'))
325 for f in input_api.AffectedFiles(file_filter=file_filter):
326 for line_num, line in f.ChangedContents():
327 for func_name, message, error in _BANNED_OBJC_FUNCTIONS:
328 if func_name in line:
329 problems = warnings;
330 if error:
331 problems = errors;
332 problems.append(' %s:%d:' % (f.LocalPath(), line_num))
333 for message_line in message:
334 problems.append(' %s' % message_line)
335
336 file_filter = lambda f: f.LocalPath().endswith(('.cc', '.mm', '.h'))
337 for f in input_api.AffectedFiles(file_filter=file_filter):
338 for line_num, line in f.ChangedContents():
339 for func_name, message, error in _BANNED_CPP_FUNCTIONS:
340 if func_name in line:
341 problems = warnings;
342 if error:
343 problems = errors;
344 problems.append(' %s:%d:' % (f.LocalPath(), line_num))
345 for message_line in message:
346 problems.append(' %s' % message_line)
347
348 result = []
349 if (warnings):
350 result.append(output_api.PresubmitPromptWarning(
351 'Banned functions were used.\n' + '\n'.join(warnings)))
352 if (errors):
353 result.append(output_api.PresubmitError(
354 'Banned functions were used.\n' + '\n'.join(errors)))
355 return result
356
357
[email protected]6c063c62012-07-11 19:11:06358def _CheckNoPragmaOnce(input_api, output_api):
359 """Make sure that banned functions are not used."""
360 files = []
361 pattern = input_api.re.compile(r'^#pragma\s+once',
362 input_api.re.MULTILINE)
363 for f in input_api.AffectedSourceFiles(input_api.FilterSourceFile):
364 if not f.LocalPath().endswith('.h'):
365 continue
366 contents = input_api.ReadFile(f)
367 if pattern.search(contents):
368 files.append(f)
369
370 if files:
371 return [output_api.PresubmitError(
372 'Do not use #pragma once in header files.\n'
373 'See http://www.chromium.org/developers/coding-style#TOC-File-headers',
374 files)]
375 return []
376
[email protected]127f18ec2012-06-16 05:05:59377
[email protected]55f9f382012-07-31 11:02:18378def _CheckUnwantedDependencies(input_api, output_api):
379 """Runs checkdeps on #include statements added in this
380 change. Breaking - rules is an error, breaking ! rules is a
381 warning.
382 """
383 # We need to wait until we have an input_api object and use this
384 # roundabout construct to import checkdeps because this file is
385 # eval-ed and thus doesn't have __file__.
386 original_sys_path = sys.path
387 try:
388 sys.path = sys.path + [input_api.os_path.join(
389 input_api.PresubmitLocalPath(), 'tools', 'checkdeps')]
390 import checkdeps
391 from cpp_checker import CppChecker
392 from rules import Rule
393 finally:
394 # Restore sys.path to what it was before.
395 sys.path = original_sys_path
396
397 added_includes = []
398 for f in input_api.AffectedFiles():
399 if not CppChecker.IsCppFile(f.LocalPath()):
400 continue
401
402 changed_lines = [line for line_num, line in f.ChangedContents()]
403 added_includes.append([f.LocalPath(), changed_lines])
404
405 deps_checker = checkdeps.DepsChecker()
406
407 error_descriptions = []
408 warning_descriptions = []
409 for path, rule_type, rule_description in deps_checker.CheckAddedCppIncludes(
410 added_includes):
411 description_with_path = '%s\n %s' % (path, rule_description)
412 if rule_type == Rule.DISALLOW:
413 error_descriptions.append(description_with_path)
414 else:
415 warning_descriptions.append(description_with_path)
416
417 results = []
418 if error_descriptions:
419 results.append(output_api.PresubmitError(
420 'You added one or more #includes that violate checkdeps rules.',
421 error_descriptions))
422 if warning_descriptions:
[email protected]779caa52012-08-21 17:05:59423 if not input_api.is_committing:
424 warning_factory = output_api.PresubmitPromptWarning
425 else:
426 # We don't want to block use of the CQ when there is a warning
427 # of this kind, so we only show a message when committing.
428 warning_factory = output_api.PresubmitNotifyResult
429 results.append(warning_factory(
[email protected]55f9f382012-07-31 11:02:18430 'You added one or more #includes of files that are temporarily\n'
431 'allowed but being removed. Can you avoid introducing the\n'
432 '#include? See relevant DEPS file(s) for details and contacts.',
433 warning_descriptions))
434 return results
435
436
[email protected]fbcafe5a2012-08-08 15:31:22437def _CheckFilePermissions(input_api, output_api):
438 """Check that all files have their permissions properly set."""
439 args = [sys.executable, 'tools/checkperms/checkperms.py', '--root',
440 input_api.change.RepositoryRoot()]
441 for f in input_api.AffectedFiles():
442 args += ['--file', f.LocalPath()]
443 errors = []
444 (errors, stderrdata) = subprocess.Popen(args).communicate()
445
446 results = []
447 if errors:
448 results.append(output_api.PreSubmitError('checkperms.py failed.',
449 errors))
450 return results
451
452
[email protected]22c9bd72011-03-27 16:47:39453def _CommonChecks(input_api, output_api):
454 """Checks common to both upload and commit."""
455 results = []
456 results.extend(input_api.canned_checks.PanProjectChecks(
457 input_api, output_api, excluded_paths=_EXCLUDED_PATHS))
[email protected]66daa702011-05-28 14:41:46458 results.extend(_CheckAuthorizedAuthor(input_api, output_api))
[email protected]55459852011-08-10 15:17:19459 results.extend(
460 _CheckNoProductionCodeUsingTestOnlyFunctions(input_api, output_api))
[email protected]10689ca2011-09-02 02:31:54461 results.extend(_CheckNoIOStreamInHeaders(input_api, output_api))
[email protected]72df4e782012-06-21 16:28:18462 results.extend(_CheckNoUNIT_TESTInSourceFiles(input_api, output_api))
[email protected]8ea5d4b2011-09-13 21:49:22463 results.extend(_CheckNoNewWStrings(input_api, output_api))
[email protected]2a8ac9c2011-10-19 17:20:44464 results.extend(_CheckNoDEPSGIT(input_api, output_api))
[email protected]127f18ec2012-06-16 05:05:59465 results.extend(_CheckNoBannedFunctions(input_api, output_api))
[email protected]6c063c62012-07-11 19:11:06466 results.extend(_CheckNoPragmaOnce(input_api, output_api))
[email protected]55f9f382012-07-31 11:02:18467 results.extend(_CheckUnwantedDependencies(input_api, output_api))
[email protected]fbcafe5a2012-08-08 15:31:22468 results.extend(_CheckFilePermissions(input_api, output_api))
[email protected]22c9bd72011-03-27 16:47:39469 return results
[email protected]1f7b4172010-01-28 01:17:34470
[email protected]b337cb5b2011-01-23 21:24:05471
472def _CheckSubversionConfig(input_api, output_api):
473 """Verifies the subversion config file is correctly setup.
474
475 Checks that autoprops are enabled, returns an error otherwise.
476 """
477 join = input_api.os_path.join
478 if input_api.platform == 'win32':
479 appdata = input_api.environ.get('APPDATA', '')
480 if not appdata:
481 return [output_api.PresubmitError('%APPDATA% is not configured.')]
482 path = join(appdata, 'Subversion', 'config')
483 else:
484 home = input_api.environ.get('HOME', '')
485 if not home:
486 return [output_api.PresubmitError('$HOME is not configured.')]
487 path = join(home, '.subversion', 'config')
488
489 error_msg = (
490 'Please look at http://dev.chromium.org/developers/coding-style to\n'
491 'configure your subversion configuration file. This enables automatic\n'
[email protected]c6a3c10b2011-01-24 16:14:20492 'properties to simplify the project maintenance.\n'
493 'Pro-tip: just download and install\n'
494 'http://src.chromium.org/viewvc/chrome/trunk/tools/build/slave/config\n')
[email protected]b337cb5b2011-01-23 21:24:05495
496 try:
497 lines = open(path, 'r').read().splitlines()
498 # Make sure auto-props is enabled and check for 2 Chromium standard
499 # auto-prop.
500 if (not '*.cc = svn:eol-style=LF' in lines or
501 not '*.pdf = svn:mime-type=application/pdf' in lines or
502 not 'enable-auto-props = yes' in lines):
503 return [
[email protected]79ed7e62011-02-21 21:08:53504 output_api.PresubmitNotifyResult(
[email protected]b337cb5b2011-01-23 21:24:05505 'It looks like you have not configured your subversion config '
[email protected]b5359c02011-02-01 20:29:56506 'file or it is not up-to-date.\n' + error_msg)
[email protected]b337cb5b2011-01-23 21:24:05507 ]
508 except (OSError, IOError):
509 return [
[email protected]79ed7e62011-02-21 21:08:53510 output_api.PresubmitNotifyResult(
[email protected]b337cb5b2011-01-23 21:24:05511 'Can\'t find your subversion config file.\n' + error_msg)
512 ]
513 return []
514
515
[email protected]66daa702011-05-28 14:41:46516def _CheckAuthorizedAuthor(input_api, output_api):
517 """For non-googler/chromites committers, verify the author's email address is
518 in AUTHORS.
519 """
[email protected]9bb9cb82011-06-13 20:43:01520 # TODO(maruel): Add it to input_api?
521 import fnmatch
522
[email protected]66daa702011-05-28 14:41:46523 author = input_api.change.author_email
[email protected]9bb9cb82011-06-13 20:43:01524 if not author:
525 input_api.logging.info('No author, skipping AUTHOR check')
[email protected]66daa702011-05-28 14:41:46526 return []
[email protected]c99663292011-05-31 19:46:08527 authors_path = input_api.os_path.join(
[email protected]66daa702011-05-28 14:41:46528 input_api.PresubmitLocalPath(), 'AUTHORS')
529 valid_authors = (
530 input_api.re.match(r'[^#]+\s+\<(.+?)\>\s*$', line)
531 for line in open(authors_path))
[email protected]ac54b132011-06-06 18:11:18532 valid_authors = [item.group(1).lower() for item in valid_authors if item]
[email protected]9bb9cb82011-06-13 20:43:01533 if input_api.verbose:
534 print 'Valid authors are %s' % ', '.join(valid_authors)
[email protected]d8b50be2011-06-15 14:19:44535 if not any(fnmatch.fnmatch(author.lower(), valid) for valid in valid_authors):
[email protected]66daa702011-05-28 14:41:46536 return [output_api.PresubmitPromptWarning(
537 ('%s is not in AUTHORS file. If you are a new contributor, please visit'
538 '\n'
539 'http://www.chromium.org/developers/contributing-code and read the '
540 '"Legal" section\n'
541 'If you are a chromite, verify the contributor signed the CLA.') %
542 author)]
543 return []
544
545
[email protected]1f7b4172010-01-28 01:17:34546def CheckChangeOnUpload(input_api, output_api):
547 results = []
548 results.extend(_CommonChecks(input_api, output_api))
[email protected]fe5f57c52009-06-05 14:25:54549 return results
[email protected]ca8d1982009-02-19 16:33:12550
551
552def CheckChangeOnCommit(input_api, output_api):
[email protected]fe5f57c52009-06-05 14:25:54553 results = []
[email protected]1f7b4172010-01-28 01:17:34554 results.extend(_CommonChecks(input_api, output_api))
[email protected]dd805fe2009-10-01 08:11:51555 # TODO(thestig) temporarily disabled, doesn't work in third_party/
556 #results.extend(input_api.canned_checks.CheckSvnModifiedDirectories(
557 # input_api, output_api, sources))
[email protected]fe5f57c52009-06-05 14:25:54558 # Make sure the tree is 'open'.
[email protected]806e98e2010-03-19 17:49:27559 results.extend(input_api.canned_checks.CheckTreeIsOpen(
[email protected]7f238152009-08-12 19:00:34560 input_api,
561 output_api,
[email protected]4efa42142010-08-26 01:29:26562 json_url='http://chromium-status.appspot.com/current?format=json'))
[email protected]806e98e2010-03-19 17:49:27563 results.extend(input_api.canned_checks.CheckRietveldTryJobExecution(input_api,
[email protected]4ddc5df2011-12-12 03:05:04564 output_api, 'http://codereview.chromium.org',
[email protected]c1ba4c52012-03-09 14:23:28565 ('win_rel', 'linux_rel', 'mac_rel, win:compile'),
566 '[email protected]'))
[email protected]806e98e2010-03-19 17:49:27567
[email protected]3e4eb112011-01-18 03:29:54568 results.extend(input_api.canned_checks.CheckChangeHasBugField(
569 input_api, output_api))
[email protected]c4b47562011-12-05 23:39:41570 results.extend(input_api.canned_checks.CheckChangeHasDescription(
571 input_api, output_api))
[email protected]b337cb5b2011-01-23 21:24:05572 results.extend(_CheckSubversionConfig(input_api, output_api))
[email protected]fe5f57c52009-06-05 14:25:54573 return results
[email protected]ca8d1982009-02-19 16:33:12574
575
[email protected]5efb2a822011-09-27 23:06:13576def GetPreferredTrySlaves(project, change):
[email protected]4ce995ea2012-06-27 02:13:10577 files = change.LocalPaths()
578
[email protected]3019c902012-06-29 00:09:03579 if not files:
580 return []
581
[email protected]4ce995ea2012-06-27 02:13:10582 if all(re.search('\.(m|mm)$|[/_]mac[/_.]', f) for f in files):
[email protected]641f2e3e2012-09-03 11:16:24583 return ['mac_rel', 'mac_asan']
[email protected]4ce995ea2012-06-27 02:13:10584 if all(re.search('[/_]win[/_.]', f) for f in files):
585 return ['win_rel']
586 if all(re.search('[/_]android[/_.]', f) for f in files):
587 return ['android']
588
[email protected]d602b902012-07-19 16:30:31589 trybots = ['win_rel', 'linux_rel', 'mac_rel', 'linux_clang:compile',
[email protected]641f2e3e2012-09-03 11:16:24590 'linux_chromeos', 'android', 'linux_asan', 'mac_asan']
[email protected]911753b2012-08-02 12:11:54591
592 # Match things like path/aura/file.cc and path/file_aura.cc.
[email protected]0be9553a2012-08-10 00:14:45593 # Same for ash and chromeos.
594 if any(re.search('[/_](ash|aura)', f) for f in files):
[email protected]641f2e3e2012-09-03 11:16:24595 trybots += ['linux_chromeos', 'linux_chromeos_clang:compile', 'win_aura',
596 'linux_chromeos_asan']
[email protected]0be9553a2012-08-10 00:14:45597 else:
598 if any(re.search('[/_]chromeos', f) for f in files):
[email protected]641f2e3e2012-09-03 11:16:24599 trybots += ['linux_chromeos', 'linux_chromeos_clang:compile',
600 'linux_chromeos_asan']
[email protected]4ce995ea2012-06-27 02:13:10601
[email protected]4ce995ea2012-06-27 02:13:10602 return trybots