blob: 773d70087e26ba4f01a43622d0760d25f5ed28b6 [file] [log] [blame]
[email protected]a18130a2012-01-03 17:52:081# Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]ca8d19842009-02-19 16:33:122# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5"""Top-level presubmit script for Chromium.
6
[email protected]f1293792009-07-31 18:09:567See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts
[email protected]50d7d721e2009-11-15 17:56:188for more details about the presubmit API built into gcl.
[email protected]ca8d19842009-02-19 16:33:129"""
10
[email protected]eea609a2011-11-18 13:10:1211
[email protected]9d16ad12011-12-14 20:49:4712import re
[email protected]fbcafe5a2012-08-08 15:31:2213import subprocess
[email protected]55f9f382012-07-31 11:02:1814import sys
[email protected]9d16ad12011-12-14 20:49:4715
16
[email protected]379e7dd2010-01-28 17:39:2117_EXCLUDED_PATHS = (
[email protected]3e4eb112011-01-18 03:29:5418 r"^breakpad[\\\/].*",
[email protected]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]ce145c02012-09-06 09:49:3426 r".+[\\\/]pnacl_shim\.c$",
[email protected]4306417642009-06-11 00:33:4027)
[email protected]ca8d19842009-02-19 16:33:1228
[email protected]ca8d19842009-02-19 16:33:1229
[email protected]eea609a2011-11-18 13:10:1230_TEST_ONLY_WARNING = (
31 'You might be calling functions intended only for testing from\n'
32 'production code. It is OK to ignore this warning if you know what\n'
33 'you are doing, as the heuristics used to detect the situation are\n'
34 'not perfect. The commit queue will not block on this warning.\n'
35 'Email [email protected] if you have questions.')
36
37
[email protected]127f18ec2012-06-16 05:05:5938_BANNED_OBJC_FUNCTIONS = (
39 (
40 'addTrackingRect:',
[email protected]23e6cbc2012-06-16 18:51:2041 (
42 'The use of -[NSView addTrackingRect:owner:userData:assumeInside:] is'
[email protected]127f18ec2012-06-16 05:05:5943 'prohibited. Please use CrTrackingArea instead.',
44 'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts',
45 ),
46 False,
47 ),
48 (
49 'NSTrackingArea',
[email protected]23e6cbc2012-06-16 18:51:2050 (
51 'The use of NSTrackingAreas is prohibited. Please use CrTrackingArea',
[email protected]127f18ec2012-06-16 05:05:5952 'instead.',
53 'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts',
54 ),
55 False,
56 ),
57 (
58 'convertPointFromBase:',
[email protected]23e6cbc2012-06-16 18:51:2059 (
60 'The use of -[NSView convertPointFromBase:] is almost certainly wrong.',
[email protected]127f18ec2012-06-16 05:05:5961 'Please use |convertPoint:(point) fromView:nil| instead.',
62 'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts',
63 ),
64 True,
65 ),
66 (
67 'convertPointToBase:',
[email protected]23e6cbc2012-06-16 18:51:2068 (
69 'The use of -[NSView convertPointToBase:] is almost certainly wrong.',
[email protected]127f18ec2012-06-16 05:05:5970 'Please use |convertPoint:(point) toView:nil| instead.',
71 'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts',
72 ),
73 True,
74 ),
75 (
76 'convertRectFromBase:',
[email protected]23e6cbc2012-06-16 18:51:2077 (
78 'The use of -[NSView convertRectFromBase:] is almost certainly wrong.',
[email protected]127f18ec2012-06-16 05:05:5979 'Please use |convertRect:(point) fromView:nil| instead.',
80 'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts',
81 ),
82 True,
83 ),
84 (
85 'convertRectToBase:',
[email protected]23e6cbc2012-06-16 18:51:2086 (
87 'The use of -[NSView convertRectToBase:] is almost certainly wrong.',
[email protected]127f18ec2012-06-16 05:05:5988 'Please use |convertRect:(point) toView:nil| instead.',
89 'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts',
90 ),
91 True,
92 ),
93 (
94 'convertSizeFromBase:',
[email protected]23e6cbc2012-06-16 18:51:2095 (
96 'The use of -[NSView convertSizeFromBase:] is almost certainly wrong.',
[email protected]127f18ec2012-06-16 05:05:5997 'Please use |convertSize:(point) fromView:nil| instead.',
98 'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts',
99 ),
100 True,
101 ),
102 (
103 'convertSizeToBase:',
[email protected]23e6cbc2012-06-16 18:51:20104 (
105 'The use of -[NSView convertSizeToBase:] is almost certainly wrong.',
[email protected]127f18ec2012-06-16 05:05:59106 'Please use |convertSize:(point) toView:nil| instead.',
107 'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts',
108 ),
109 True,
110 ),
111)
112
113
114_BANNED_CPP_FUNCTIONS = (
[email protected]23e6cbc2012-06-16 18:51:20115 # Make sure that gtest's FRIEND_TEST() macro is not used; the
116 # FRIEND_TEST_ALL_PREFIXES() macro from base/gtest_prod_util.h should be
117 # used instead since that allows for FLAKY_, FAILS_ and DISABLED_ prefixes.
118 (
119 'FRIEND_TEST(',
120 (
[email protected]e3c945502012-06-26 20:01:49121 'Chromium code should not use gtest\'s FRIEND_TEST() macro. Include',
[email protected]23e6cbc2012-06-16 18:51:20122 'base/gtest_prod_util.h and use FRIEND_TEST_ALL_PREFIXES() instead.',
123 ),
124 False,
125 ),
126 (
127 'ScopedAllowIO',
128 (
[email protected]e3c945502012-06-26 20:01:49129 'New code should not use ScopedAllowIO. Post a task to the blocking',
130 'pool or the FILE thread instead.',
[email protected]23e6cbc2012-06-16 18:51:20131 ),
[email protected]e3c945502012-06-26 20:01:49132 True,
[email protected]23e6cbc2012-06-16 18:51:20133 ),
134 (
135 'FilePathWatcher::Delegate',
136 (
[email protected]e3c945502012-06-26 20:01:49137 'New code should not use FilePathWatcher::Delegate. Use the callback',
[email protected]23e6cbc2012-06-16 18:51:20138 'interface instead.',
139 ),
140 False,
141 ),
[email protected]e3c945502012-06-26 20:01:49142 (
143 'browser::FindLastActiveWithProfile',
144 (
145 'This function is deprecated and we\'re working on removing it. Pass',
146 'more context to get a Browser*, like a WebContents, window, or session',
147 'id. Talk to ben@ or jam@ for more information.',
148 ),
149 True,
150 ),
151 (
[email protected]e3c945502012-06-26 20:01:49152 'browser::FindAnyBrowser',
153 (
154 'This function is deprecated and we\'re working on removing it. Pass',
155 'more context to get a Browser*, like a WebContents, window, or session',
156 'id. Talk to ben@ or jam@ for more information.',
157 ),
158 True,
159 ),
160 (
161 'browser::FindOrCreateTabbedBrowser',
162 (
163 'This function is deprecated and we\'re working on removing it. Pass',
164 'more context to get a Browser*, like a WebContents, window, or session',
165 'id. Talk to ben@ or jam@ for more information.',
166 ),
167 True,
168 ),
169 (
170 'browser::FindTabbedBrowser',
171 (
172 'This function is deprecated and we\'re working on removing it. Pass',
173 'more context to get a Browser*, like a WebContents, window, or session',
174 'id. Talk to ben@ or jam@ for more information.',
175 ),
176 True,
177 ),
[email protected]127f18ec2012-06-16 05:05:59178)
179
180
[email protected]eea609a2011-11-18 13:10:12181
[email protected]55459852011-08-10 15:17:19182def _CheckNoProductionCodeUsingTestOnlyFunctions(input_api, output_api):
183 """Attempts to prevent use of functions intended only for testing in
184 non-testing code. For now this is just a best-effort implementation
185 that ignores header files and may have some false positives. A
186 better implementation would probably need a proper C++ parser.
187 """
188 # We only scan .cc files and the like, as the declaration of
189 # for-testing functions in header files are hard to distinguish from
190 # calls to such functions without a proper C++ parser.
[email protected]403bfbc92012-06-11 23:30:09191 platform_specifiers = r'(_(android|chromeos|gtk|mac|posix|win))?'
[email protected]55459852011-08-10 15:17:19192 source_extensions = r'\.(cc|cpp|cxx|mm)$'
193 file_inclusion_pattern = r'.+%s' % source_extensions
[email protected]19e77fd2011-10-20 05:24:05194 file_exclusion_patterns = (
[email protected]e21ce382012-01-04 18:48:25195 r'.*[/\\](test_|mock_).+%s' % source_extensions,
[email protected]c762d252012-02-28 02:07:24196 r'.+_test_(base|support|util)%s' % source_extensions,
[email protected]403bfbc92012-06-11 23:30:09197 r'.+_(api|browser|perf|unit|ui)?test%s%s' % (platform_specifiers,
198 source_extensions),
[email protected]19e77fd2011-10-20 05:24:05199 r'.+profile_sync_service_harness%s' % source_extensions,
200 )
201 path_exclusion_patterns = (
202 r'.*[/\\](test|tool(s)?)[/\\].*',
203 # At request of folks maintaining this folder.
204 r'chrome[/\\]browser[/\\]automation[/\\].*',
205 )
[email protected]55459852011-08-10 15:17:19206
207 base_function_pattern = r'ForTest(ing)?|for_test(ing)?'
208 inclusion_pattern = input_api.re.compile(r'(%s)\s*\(' % base_function_pattern)
209 exclusion_pattern = input_api.re.compile(
210 r'::[A-Za-z0-9_]+(%s)|(%s)[^;]+\{' % (
211 base_function_pattern, base_function_pattern))
212
213 def FilterFile(affected_file):
[email protected]19e77fd2011-10-20 05:24:05214 black_list = (file_exclusion_patterns + path_exclusion_patterns +
[email protected]3afb12a42011-08-15 13:48:33215 _EXCLUDED_PATHS + input_api.DEFAULT_BLACK_LIST)
[email protected]55459852011-08-10 15:17:19216 return input_api.FilterSourceFile(
217 affected_file,
218 white_list=(file_inclusion_pattern, ),
219 black_list=black_list)
220
221 problems = []
222 for f in input_api.AffectedSourceFiles(FilterFile):
223 local_path = f.LocalPath()
224 lines = input_api.ReadFile(f).splitlines()
225 line_number = 0
226 for line in lines:
227 if (inclusion_pattern.search(line) and
228 not exclusion_pattern.search(line)):
229 problems.append(
230 '%s:%d\n %s' % (local_path, line_number, line.strip()))
231 line_number += 1
232
233 if problems:
[email protected]eea609a2011-11-18 13:10:12234 if not input_api.is_committing:
235 return [output_api.PresubmitPromptWarning(_TEST_ONLY_WARNING, problems)]
236 else:
237 # We don't warn on commit, to avoid stopping commits going through CQ.
238 return [output_api.PresubmitNotifyResult(_TEST_ONLY_WARNING, problems)]
[email protected]55459852011-08-10 15:17:19239 else:
240 return []
241
242
[email protected]10689ca2011-09-02 02:31:54243def _CheckNoIOStreamInHeaders(input_api, output_api):
244 """Checks to make sure no .h files include <iostream>."""
245 files = []
246 pattern = input_api.re.compile(r'^#include\s*<iostream>',
247 input_api.re.MULTILINE)
248 for f in input_api.AffectedSourceFiles(input_api.FilterSourceFile):
249 if not f.LocalPath().endswith('.h'):
250 continue
251 contents = input_api.ReadFile(f)
252 if pattern.search(contents):
253 files.append(f)
254
255 if len(files):
256 return [ output_api.PresubmitError(
[email protected]6c063c62012-07-11 19:11:06257 'Do not #include <iostream> in header files, since it inserts static '
258 'initialization into every file including the header. Instead, '
[email protected]10689ca2011-09-02 02:31:54259 '#include <ostream>. See http://crbug.com/94794',
260 files) ]
261 return []
262
263
[email protected]72df4e782012-06-21 16:28:18264def _CheckNoUNIT_TESTInSourceFiles(input_api, output_api):
265 """Checks to make sure no source files use UNIT_TEST"""
266 problems = []
267 for f in input_api.AffectedFiles():
268 if (not f.LocalPath().endswith(('.cc', '.mm'))):
269 continue
270
271 for line_num, line in f.ChangedContents():
272 if 'UNIT_TEST' in line:
273 problems.append(' %s:%d' % (f.LocalPath(), line_num))
274
275 if not problems:
276 return []
277 return [output_api.PresubmitPromptWarning('UNIT_TEST is only for headers.\n' +
278 '\n'.join(problems))]
279
280
[email protected]8ea5d4b2011-09-13 21:49:22281def _CheckNoNewWStrings(input_api, output_api):
282 """Checks to make sure we don't introduce use of wstrings."""
[email protected]55463aa62011-10-12 00:48:27283 problems = []
[email protected]8ea5d4b2011-09-13 21:49:22284 for f in input_api.AffectedFiles():
[email protected]b5c24292011-11-28 14:38:20285 if (not f.LocalPath().endswith(('.cc', '.h')) or
286 f.LocalPath().endswith('test.cc')):
287 continue
[email protected]8ea5d4b2011-09-13 21:49:22288
[email protected]a11dbe9b2012-08-07 01:32:58289 allowWString = False
[email protected]b5c24292011-11-28 14:38:20290 for line_num, line in f.ChangedContents():
[email protected]a11dbe9b2012-08-07 01:32:58291 if 'presubmit: allow wstring' in line:
292 allowWString = True
293 elif not allowWString and 'wstring' in line:
[email protected]55463aa62011-10-12 00:48:27294 problems.append(' %s:%d' % (f.LocalPath(), line_num))
[email protected]a11dbe9b2012-08-07 01:32:58295 allowWString = False
296 else:
297 allowWString = False
[email protected]8ea5d4b2011-09-13 21:49:22298
[email protected]55463aa62011-10-12 00:48:27299 if not problems:
300 return []
301 return [output_api.PresubmitPromptWarning('New code should not use wstrings.'
[email protected]a11dbe9b2012-08-07 01:32:58302 ' If you are calling a cross-platform API that accepts a wstring, '
303 'fix the API.\n' +
[email protected]55463aa62011-10-12 00:48:27304 '\n'.join(problems))]
[email protected]8ea5d4b2011-09-13 21:49:22305
306
[email protected]2a8ac9c2011-10-19 17:20:44307def _CheckNoDEPSGIT(input_api, output_api):
308 """Make sure .DEPS.git is never modified manually."""
309 if any(f.LocalPath().endswith('.DEPS.git') for f in
310 input_api.AffectedFiles()):
311 return [output_api.PresubmitError(
312 'Never commit changes to .DEPS.git. This file is maintained by an\n'
313 'automated system based on what\'s in DEPS and your changes will be\n'
314 'overwritten.\n'
315 'See http://code.google.com/p/chromium/wiki/UsingNewGit#Rolling_DEPS\n'
316 'for more information')]
317 return []
318
319
[email protected]127f18ec2012-06-16 05:05:59320def _CheckNoBannedFunctions(input_api, output_api):
321 """Make sure that banned functions are not used."""
322 warnings = []
323 errors = []
324
325 file_filter = lambda f: f.LocalPath().endswith(('.mm', '.m', '.h'))
326 for f in input_api.AffectedFiles(file_filter=file_filter):
327 for line_num, line in f.ChangedContents():
328 for func_name, message, error in _BANNED_OBJC_FUNCTIONS:
329 if func_name in line:
330 problems = warnings;
331 if error:
332 problems = errors;
333 problems.append(' %s:%d:' % (f.LocalPath(), line_num))
334 for message_line in message:
335 problems.append(' %s' % message_line)
336
337 file_filter = lambda f: f.LocalPath().endswith(('.cc', '.mm', '.h'))
338 for f in input_api.AffectedFiles(file_filter=file_filter):
339 for line_num, line in f.ChangedContents():
340 for func_name, message, error in _BANNED_CPP_FUNCTIONS:
341 if func_name in line:
342 problems = warnings;
343 if error:
344 problems = errors;
345 problems.append(' %s:%d:' % (f.LocalPath(), line_num))
346 for message_line in message:
347 problems.append(' %s' % message_line)
348
349 result = []
350 if (warnings):
351 result.append(output_api.PresubmitPromptWarning(
352 'Banned functions were used.\n' + '\n'.join(warnings)))
353 if (errors):
354 result.append(output_api.PresubmitError(
355 'Banned functions were used.\n' + '\n'.join(errors)))
356 return result
357
358
[email protected]6c063c62012-07-11 19:11:06359def _CheckNoPragmaOnce(input_api, output_api):
360 """Make sure that banned functions are not used."""
361 files = []
362 pattern = input_api.re.compile(r'^#pragma\s+once',
363 input_api.re.MULTILINE)
364 for f in input_api.AffectedSourceFiles(input_api.FilterSourceFile):
365 if not f.LocalPath().endswith('.h'):
366 continue
367 contents = input_api.ReadFile(f)
368 if pattern.search(contents):
369 files.append(f)
370
371 if files:
372 return [output_api.PresubmitError(
373 'Do not use #pragma once in header files.\n'
374 'See http://www.chromium.org/developers/coding-style#TOC-File-headers',
375 files)]
376 return []
377
[email protected]127f18ec2012-06-16 05:05:59378
[email protected]55f9f382012-07-31 11:02:18379def _CheckUnwantedDependencies(input_api, output_api):
380 """Runs checkdeps on #include statements added in this
381 change. Breaking - rules is an error, breaking ! rules is a
382 warning.
383 """
384 # We need to wait until we have an input_api object and use this
385 # roundabout construct to import checkdeps because this file is
386 # eval-ed and thus doesn't have __file__.
387 original_sys_path = sys.path
388 try:
389 sys.path = sys.path + [input_api.os_path.join(
390 input_api.PresubmitLocalPath(), 'tools', 'checkdeps')]
391 import checkdeps
392 from cpp_checker import CppChecker
393 from rules import Rule
394 finally:
395 # Restore sys.path to what it was before.
396 sys.path = original_sys_path
397
398 added_includes = []
399 for f in input_api.AffectedFiles():
400 if not CppChecker.IsCppFile(f.LocalPath()):
401 continue
402
403 changed_lines = [line for line_num, line in f.ChangedContents()]
404 added_includes.append([f.LocalPath(), changed_lines])
405
406 deps_checker = checkdeps.DepsChecker()
407
408 error_descriptions = []
409 warning_descriptions = []
410 for path, rule_type, rule_description in deps_checker.CheckAddedCppIncludes(
411 added_includes):
412 description_with_path = '%s\n %s' % (path, rule_description)
413 if rule_type == Rule.DISALLOW:
414 error_descriptions.append(description_with_path)
415 else:
416 warning_descriptions.append(description_with_path)
417
418 results = []
419 if error_descriptions:
420 results.append(output_api.PresubmitError(
421 'You added one or more #includes that violate checkdeps rules.',
422 error_descriptions))
423 if warning_descriptions:
[email protected]779caa52012-08-21 17:05:59424 if not input_api.is_committing:
425 warning_factory = output_api.PresubmitPromptWarning
426 else:
427 # We don't want to block use of the CQ when there is a warning
428 # of this kind, so we only show a message when committing.
429 warning_factory = output_api.PresubmitNotifyResult
430 results.append(warning_factory(
[email protected]55f9f382012-07-31 11:02:18431 'You added one or more #includes of files that are temporarily\n'
432 'allowed but being removed. Can you avoid introducing the\n'
433 '#include? See relevant DEPS file(s) for details and contacts.',
434 warning_descriptions))
435 return results
436
437
[email protected]fbcafe5a2012-08-08 15:31:22438def _CheckFilePermissions(input_api, output_api):
439 """Check that all files have their permissions properly set."""
440 args = [sys.executable, 'tools/checkperms/checkperms.py', '--root',
441 input_api.change.RepositoryRoot()]
442 for f in input_api.AffectedFiles():
443 args += ['--file', f.LocalPath()]
444 errors = []
445 (errors, stderrdata) = subprocess.Popen(args).communicate()
446
447 results = []
448 if errors:
449 results.append(output_api.PreSubmitError('checkperms.py failed.',
450 errors))
451 return results
452
453
[email protected]22c9bd72011-03-27 16:47:39454def _CommonChecks(input_api, output_api):
455 """Checks common to both upload and commit."""
456 results = []
457 results.extend(input_api.canned_checks.PanProjectChecks(
458 input_api, output_api, excluded_paths=_EXCLUDED_PATHS))
[email protected]66daa702011-05-28 14:41:46459 results.extend(_CheckAuthorizedAuthor(input_api, output_api))
[email protected]55459852011-08-10 15:17:19460 results.extend(
461 _CheckNoProductionCodeUsingTestOnlyFunctions(input_api, output_api))
[email protected]10689ca2011-09-02 02:31:54462 results.extend(_CheckNoIOStreamInHeaders(input_api, output_api))
[email protected]72df4e782012-06-21 16:28:18463 results.extend(_CheckNoUNIT_TESTInSourceFiles(input_api, output_api))
[email protected]8ea5d4b2011-09-13 21:49:22464 results.extend(_CheckNoNewWStrings(input_api, output_api))
[email protected]2a8ac9c2011-10-19 17:20:44465 results.extend(_CheckNoDEPSGIT(input_api, output_api))
[email protected]127f18ec2012-06-16 05:05:59466 results.extend(_CheckNoBannedFunctions(input_api, output_api))
[email protected]6c063c62012-07-11 19:11:06467 results.extend(_CheckNoPragmaOnce(input_api, output_api))
[email protected]55f9f382012-07-31 11:02:18468 results.extend(_CheckUnwantedDependencies(input_api, output_api))
[email protected]fbcafe5a2012-08-08 15:31:22469 results.extend(_CheckFilePermissions(input_api, output_api))
[email protected]22c9bd72011-03-27 16:47:39470 return results
[email protected]1f7b4172010-01-28 01:17:34471
[email protected]b337cb5b2011-01-23 21:24:05472
473def _CheckSubversionConfig(input_api, output_api):
474 """Verifies the subversion config file is correctly setup.
475
476 Checks that autoprops are enabled, returns an error otherwise.
477 """
478 join = input_api.os_path.join
479 if input_api.platform == 'win32':
480 appdata = input_api.environ.get('APPDATA', '')
481 if not appdata:
482 return [output_api.PresubmitError('%APPDATA% is not configured.')]
483 path = join(appdata, 'Subversion', 'config')
484 else:
485 home = input_api.environ.get('HOME', '')
486 if not home:
487 return [output_api.PresubmitError('$HOME is not configured.')]
488 path = join(home, '.subversion', 'config')
489
490 error_msg = (
491 'Please look at http://dev.chromium.org/developers/coding-style to\n'
492 'configure your subversion configuration file. This enables automatic\n'
[email protected]c6a3c10b2011-01-24 16:14:20493 'properties to simplify the project maintenance.\n'
494 'Pro-tip: just download and install\n'
495 'http://src.chromium.org/viewvc/chrome/trunk/tools/build/slave/config\n')
[email protected]b337cb5b2011-01-23 21:24:05496
497 try:
498 lines = open(path, 'r').read().splitlines()
499 # Make sure auto-props is enabled and check for 2 Chromium standard
500 # auto-prop.
501 if (not '*.cc = svn:eol-style=LF' in lines or
502 not '*.pdf = svn:mime-type=application/pdf' in lines or
503 not 'enable-auto-props = yes' in lines):
504 return [
[email protected]79ed7e62011-02-21 21:08:53505 output_api.PresubmitNotifyResult(
[email protected]b337cb5b2011-01-23 21:24:05506 'It looks like you have not configured your subversion config '
[email protected]b5359c02011-02-01 20:29:56507 'file or it is not up-to-date.\n' + error_msg)
[email protected]b337cb5b2011-01-23 21:24:05508 ]
509 except (OSError, IOError):
510 return [
[email protected]79ed7e62011-02-21 21:08:53511 output_api.PresubmitNotifyResult(
[email protected]b337cb5b2011-01-23 21:24:05512 'Can\'t find your subversion config file.\n' + error_msg)
513 ]
514 return []
515
516
[email protected]66daa702011-05-28 14:41:46517def _CheckAuthorizedAuthor(input_api, output_api):
518 """For non-googler/chromites committers, verify the author's email address is
519 in AUTHORS.
520 """
[email protected]9bb9cb82011-06-13 20:43:01521 # TODO(maruel): Add it to input_api?
522 import fnmatch
523
[email protected]66daa702011-05-28 14:41:46524 author = input_api.change.author_email
[email protected]9bb9cb82011-06-13 20:43:01525 if not author:
526 input_api.logging.info('No author, skipping AUTHOR check')
[email protected]66daa702011-05-28 14:41:46527 return []
[email protected]c99663292011-05-31 19:46:08528 authors_path = input_api.os_path.join(
[email protected]66daa702011-05-28 14:41:46529 input_api.PresubmitLocalPath(), 'AUTHORS')
530 valid_authors = (
531 input_api.re.match(r'[^#]+\s+\<(.+?)\>\s*$', line)
532 for line in open(authors_path))
[email protected]ac54b132011-06-06 18:11:18533 valid_authors = [item.group(1).lower() for item in valid_authors if item]
[email protected]9bb9cb82011-06-13 20:43:01534 if input_api.verbose:
535 print 'Valid authors are %s' % ', '.join(valid_authors)
[email protected]d8b50be2011-06-15 14:19:44536 if not any(fnmatch.fnmatch(author.lower(), valid) for valid in valid_authors):
[email protected]66daa702011-05-28 14:41:46537 return [output_api.PresubmitPromptWarning(
538 ('%s is not in AUTHORS file. If you are a new contributor, please visit'
539 '\n'
540 'http://www.chromium.org/developers/contributing-code and read the '
541 '"Legal" section\n'
542 'If you are a chromite, verify the contributor signed the CLA.') %
543 author)]
544 return []
545
546
[email protected]1f7b4172010-01-28 01:17:34547def CheckChangeOnUpload(input_api, output_api):
548 results = []
549 results.extend(_CommonChecks(input_api, output_api))
[email protected]fe5f57c52009-06-05 14:25:54550 return results
[email protected]ca8d19842009-02-19 16:33:12551
552
553def CheckChangeOnCommit(input_api, output_api):
[email protected]fe5f57c52009-06-05 14:25:54554 results = []
[email protected]1f7b4172010-01-28 01:17:34555 results.extend(_CommonChecks(input_api, output_api))
[email protected]dd805fe2009-10-01 08:11:51556 # TODO(thestig) temporarily disabled, doesn't work in third_party/
557 #results.extend(input_api.canned_checks.CheckSvnModifiedDirectories(
558 # input_api, output_api, sources))
[email protected]fe5f57c52009-06-05 14:25:54559 # Make sure the tree is 'open'.
[email protected]806e98e2010-03-19 17:49:27560 results.extend(input_api.canned_checks.CheckTreeIsOpen(
[email protected]7f238152009-08-12 19:00:34561 input_api,
562 output_api,
[email protected]4efa42142010-08-26 01:29:26563 json_url='http://chromium-status.appspot.com/current?format=json'))
[email protected]806e98e2010-03-19 17:49:27564 results.extend(input_api.canned_checks.CheckRietveldTryJobExecution(input_api,
[email protected]4ddc5df2011-12-12 03:05:04565 output_api, 'http://codereview.chromium.org',
[email protected]c1ba4c52012-03-09 14:23:28566 ('win_rel', 'linux_rel', 'mac_rel, win:compile'),
567 '[email protected]'))
[email protected]806e98e2010-03-19 17:49:27568
[email protected]3e4eb112011-01-18 03:29:54569 results.extend(input_api.canned_checks.CheckChangeHasBugField(
570 input_api, output_api))
[email protected]c4b47562011-12-05 23:39:41571 results.extend(input_api.canned_checks.CheckChangeHasDescription(
572 input_api, output_api))
[email protected]b337cb5b2011-01-23 21:24:05573 results.extend(_CheckSubversionConfig(input_api, output_api))
[email protected]fe5f57c52009-06-05 14:25:54574 return results
[email protected]ca8d19842009-02-19 16:33:12575
576
[email protected]5efb2a822011-09-27 23:06:13577def GetPreferredTrySlaves(project, change):
[email protected]4ce995ea2012-06-27 02:13:10578 files = change.LocalPaths()
579
[email protected]3019c902012-06-29 00:09:03580 if not files:
581 return []
582
[email protected]d668899a2012-09-06 18:16:59583 if all(re.search('\.(m|mm)$|(^|[/_])mac[/_.]', f) for f in files):
[email protected]641f2e3e2012-09-03 11:16:24584 return ['mac_rel', 'mac_asan']
[email protected]d668899a2012-09-06 18:16:59585 if all(re.search('(^|[/_])win[/_.]', f) for f in files):
[email protected]4ce995ea2012-06-27 02:13:10586 return ['win_rel']
[email protected]d668899a2012-09-06 18:16:59587 if all(re.search('(^|[/_])android[/_.]', f) for f in files):
[email protected]4ce995ea2012-06-27 02:13:10588 return ['android']
589
[email protected]d602b902012-07-19 16:30:31590 trybots = ['win_rel', 'linux_rel', 'mac_rel', 'linux_clang:compile',
[email protected]ddbdc192012-09-05 11:08:52591 'linux_chromeos', 'android', 'mac_asan']
[email protected]911753b2012-08-02 12:11:54592
593 # Match things like path/aura/file.cc and path/file_aura.cc.
[email protected]0be9553a2012-08-10 00:14:45594 # Same for ash and chromeos.
595 if any(re.search('[/_](ash|aura)', f) for f in files):
[email protected]641f2e3e2012-09-03 11:16:24596 trybots += ['linux_chromeos', 'linux_chromeos_clang:compile', 'win_aura',
597 'linux_chromeos_asan']
[email protected]0be9553a2012-08-10 00:14:45598 else:
599 if any(re.search('[/_]chromeos', f) for f in files):
[email protected]641f2e3e2012-09-03 11:16:24600 trybots += ['linux_chromeos', 'linux_chromeos_clang:compile',
601 'linux_chromeos_asan']
[email protected]4ce995ea2012-06-27 02:13:10602
[email protected]4ce995ea2012-06-27 02:13:10603 return trybots