blob: 0eefbff4fe0a5ba8fde53071c7961338c184c19e [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]4306417642009-06-11 00:33:4025)
[email protected]ca8d1982009-02-19 16:33:1226
[email protected]ca8d1982009-02-19 16:33:1227
[email protected]eea609a2011-11-18 13:10:1228_TEST_ONLY_WARNING = (
29 'You might be calling functions intended only for testing from\n'
30 'production code. It is OK to ignore this warning if you know what\n'
31 'you are doing, as the heuristics used to detect the situation are\n'
32 'not perfect. The commit queue will not block on this warning.\n'
33 'Email [email protected] if you have questions.')
34
35
[email protected]127f18ec2012-06-16 05:05:5936_BANNED_OBJC_FUNCTIONS = (
37 (
38 'addTrackingRect:',
[email protected]23e6cbc2012-06-16 18:51:2039 (
40 'The use of -[NSView addTrackingRect:owner:userData:assumeInside:] is'
[email protected]127f18ec2012-06-16 05:05:5941 'prohibited. Please use CrTrackingArea instead.',
42 'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts',
43 ),
44 False,
45 ),
46 (
47 'NSTrackingArea',
[email protected]23e6cbc2012-06-16 18:51:2048 (
49 'The use of NSTrackingAreas is prohibited. Please use CrTrackingArea',
[email protected]127f18ec2012-06-16 05:05:5950 'instead.',
51 'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts',
52 ),
53 False,
54 ),
55 (
56 'convertPointFromBase:',
[email protected]23e6cbc2012-06-16 18:51:2057 (
58 'The use of -[NSView convertPointFromBase:] is almost certainly wrong.',
[email protected]127f18ec2012-06-16 05:05:5959 'Please use |convertPoint:(point) fromView:nil| instead.',
60 'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts',
61 ),
62 True,
63 ),
64 (
65 'convertPointToBase:',
[email protected]23e6cbc2012-06-16 18:51:2066 (
67 'The use of -[NSView convertPointToBase:] is almost certainly wrong.',
[email protected]127f18ec2012-06-16 05:05:5968 'Please use |convertPoint:(point) toView:nil| instead.',
69 'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts',
70 ),
71 True,
72 ),
73 (
74 'convertRectFromBase:',
[email protected]23e6cbc2012-06-16 18:51:2075 (
76 'The use of -[NSView convertRectFromBase:] is almost certainly wrong.',
[email protected]127f18ec2012-06-16 05:05:5977 'Please use |convertRect:(point) fromView:nil| instead.',
78 'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts',
79 ),
80 True,
81 ),
82 (
83 'convertRectToBase:',
[email protected]23e6cbc2012-06-16 18:51:2084 (
85 'The use of -[NSView convertRectToBase:] is almost certainly wrong.',
[email protected]127f18ec2012-06-16 05:05:5986 'Please use |convertRect:(point) toView:nil| instead.',
87 'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts',
88 ),
89 True,
90 ),
91 (
92 'convertSizeFromBase:',
[email protected]23e6cbc2012-06-16 18:51:2093 (
94 'The use of -[NSView convertSizeFromBase:] is almost certainly wrong.',
[email protected]127f18ec2012-06-16 05:05:5995 'Please use |convertSize:(point) fromView:nil| instead.',
96 'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts',
97 ),
98 True,
99 ),
100 (
101 'convertSizeToBase:',
[email protected]23e6cbc2012-06-16 18:51:20102 (
103 'The use of -[NSView convertSizeToBase:] is almost certainly wrong.',
[email protected]127f18ec2012-06-16 05:05:59104 'Please use |convertSize:(point) toView:nil| instead.',
105 'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts',
106 ),
107 True,
108 ),
109)
110
111
112_BANNED_CPP_FUNCTIONS = (
[email protected]23e6cbc2012-06-16 18:51:20113 # Make sure that gtest's FRIEND_TEST() macro is not used; the
114 # FRIEND_TEST_ALL_PREFIXES() macro from base/gtest_prod_util.h should be
115 # used instead since that allows for FLAKY_, FAILS_ and DISABLED_ prefixes.
116 (
117 'FRIEND_TEST(',
118 (
[email protected]e3c945502012-06-26 20:01:49119 'Chromium code should not use gtest\'s FRIEND_TEST() macro. Include',
[email protected]23e6cbc2012-06-16 18:51:20120 'base/gtest_prod_util.h and use FRIEND_TEST_ALL_PREFIXES() instead.',
121 ),
122 False,
123 ),
124 (
125 'ScopedAllowIO',
126 (
[email protected]e3c945502012-06-26 20:01:49127 'New code should not use ScopedAllowIO. Post a task to the blocking',
128 'pool or the FILE thread instead.',
[email protected]23e6cbc2012-06-16 18:51:20129 ),
[email protected]e3c945502012-06-26 20:01:49130 True,
[email protected]23e6cbc2012-06-16 18:51:20131 ),
132 (
133 'FilePathWatcher::Delegate',
134 (
[email protected]e3c945502012-06-26 20:01:49135 'New code should not use FilePathWatcher::Delegate. Use the callback',
[email protected]23e6cbc2012-06-16 18:51:20136 'interface instead.',
137 ),
138 False,
139 ),
[email protected]e3c945502012-06-26 20:01:49140 (
141 'browser::FindLastActiveWithProfile',
142 (
143 'This function is deprecated and we\'re working on removing it. Pass',
144 'more context to get a Browser*, like a WebContents, window, or session',
145 'id. Talk to ben@ or jam@ for more information.',
146 ),
147 True,
148 ),
149 (
150 'browser::FindBrowserWithProfile',
151 (
152 'This function is deprecated and we\'re working on removing it. Pass',
153 'more context to get a Browser*, like a WebContents, window, or session',
154 'id. Talk to ben@ or jam@ for more information.',
155 ),
156 True,
157 ),
158 (
159 'browser::FindAnyBrowser',
160 (
161 'This function is deprecated and we\'re working on removing it. Pass',
162 'more context to get a Browser*, like a WebContents, window, or session',
163 'id. Talk to ben@ or jam@ for more information.',
164 ),
165 True,
166 ),
167 (
168 'browser::FindOrCreateTabbedBrowser',
169 (
170 'This function is deprecated and we\'re working on removing it. Pass',
171 'more context to get a Browser*, like a WebContents, window, or session',
172 'id. Talk to ben@ or jam@ for more information.',
173 ),
174 True,
175 ),
176 (
177 'browser::FindTabbedBrowser',
178 (
179 'This function is deprecated and we\'re working on removing it. Pass',
180 'more context to get a Browser*, like a WebContents, window, or session',
181 'id. Talk to ben@ or jam@ for more information.',
182 ),
183 True,
184 ),
[email protected]127f18ec2012-06-16 05:05:59185)
186
187
[email protected]eea609a2011-11-18 13:10:12188
[email protected]55459852011-08-10 15:17:19189def _CheckNoProductionCodeUsingTestOnlyFunctions(input_api, output_api):
190 """Attempts to prevent use of functions intended only for testing in
191 non-testing code. For now this is just a best-effort implementation
192 that ignores header files and may have some false positives. A
193 better implementation would probably need a proper C++ parser.
194 """
195 # We only scan .cc files and the like, as the declaration of
196 # for-testing functions in header files are hard to distinguish from
197 # calls to such functions without a proper C++ parser.
[email protected]403bfbc92012-06-11 23:30:09198 platform_specifiers = r'(_(android|chromeos|gtk|mac|posix|win))?'
[email protected]55459852011-08-10 15:17:19199 source_extensions = r'\.(cc|cpp|cxx|mm)$'
200 file_inclusion_pattern = r'.+%s' % source_extensions
[email protected]19e77fd2011-10-20 05:24:05201 file_exclusion_patterns = (
[email protected]e21ce382012-01-04 18:48:25202 r'.*[/\\](test_|mock_).+%s' % source_extensions,
[email protected]c762d252012-02-28 02:07:24203 r'.+_test_(base|support|util)%s' % source_extensions,
[email protected]403bfbc92012-06-11 23:30:09204 r'.+_(api|browser|perf|unit|ui)?test%s%s' % (platform_specifiers,
205 source_extensions),
[email protected]19e77fd2011-10-20 05:24:05206 r'.+profile_sync_service_harness%s' % source_extensions,
207 )
208 path_exclusion_patterns = (
209 r'.*[/\\](test|tool(s)?)[/\\].*',
210 # At request of folks maintaining this folder.
211 r'chrome[/\\]browser[/\\]automation[/\\].*',
212 )
[email protected]55459852011-08-10 15:17:19213
214 base_function_pattern = r'ForTest(ing)?|for_test(ing)?'
215 inclusion_pattern = input_api.re.compile(r'(%s)\s*\(' % base_function_pattern)
216 exclusion_pattern = input_api.re.compile(
217 r'::[A-Za-z0-9_]+(%s)|(%s)[^;]+\{' % (
218 base_function_pattern, base_function_pattern))
219
220 def FilterFile(affected_file):
[email protected]19e77fd2011-10-20 05:24:05221 black_list = (file_exclusion_patterns + path_exclusion_patterns +
[email protected]3afb12a42011-08-15 13:48:33222 _EXCLUDED_PATHS + input_api.DEFAULT_BLACK_LIST)
[email protected]55459852011-08-10 15:17:19223 return input_api.FilterSourceFile(
224 affected_file,
225 white_list=(file_inclusion_pattern, ),
226 black_list=black_list)
227
228 problems = []
229 for f in input_api.AffectedSourceFiles(FilterFile):
230 local_path = f.LocalPath()
231 lines = input_api.ReadFile(f).splitlines()
232 line_number = 0
233 for line in lines:
234 if (inclusion_pattern.search(line) and
235 not exclusion_pattern.search(line)):
236 problems.append(
237 '%s:%d\n %s' % (local_path, line_number, line.strip()))
238 line_number += 1
239
240 if problems:
[email protected]eea609a2011-11-18 13:10:12241 if not input_api.is_committing:
242 return [output_api.PresubmitPromptWarning(_TEST_ONLY_WARNING, problems)]
243 else:
244 # We don't warn on commit, to avoid stopping commits going through CQ.
245 return [output_api.PresubmitNotifyResult(_TEST_ONLY_WARNING, problems)]
[email protected]55459852011-08-10 15:17:19246 else:
247 return []
248
249
[email protected]10689ca2011-09-02 02:31:54250def _CheckNoIOStreamInHeaders(input_api, output_api):
251 """Checks to make sure no .h files include <iostream>."""
252 files = []
253 pattern = input_api.re.compile(r'^#include\s*<iostream>',
254 input_api.re.MULTILINE)
255 for f in input_api.AffectedSourceFiles(input_api.FilterSourceFile):
256 if not f.LocalPath().endswith('.h'):
257 continue
258 contents = input_api.ReadFile(f)
259 if pattern.search(contents):
260 files.append(f)
261
262 if len(files):
263 return [ output_api.PresubmitError(
[email protected]6c063c62012-07-11 19:11:06264 'Do not #include <iostream> in header files, since it inserts static '
265 'initialization into every file including the header. Instead, '
[email protected]10689ca2011-09-02 02:31:54266 '#include <ostream>. See http://crbug.com/94794',
267 files) ]
268 return []
269
270
[email protected]72df4e782012-06-21 16:28:18271def _CheckNoUNIT_TESTInSourceFiles(input_api, output_api):
272 """Checks to make sure no source files use UNIT_TEST"""
273 problems = []
274 for f in input_api.AffectedFiles():
275 if (not f.LocalPath().endswith(('.cc', '.mm'))):
276 continue
277
278 for line_num, line in f.ChangedContents():
279 if 'UNIT_TEST' in line:
280 problems.append(' %s:%d' % (f.LocalPath(), line_num))
281
282 if not problems:
283 return []
284 return [output_api.PresubmitPromptWarning('UNIT_TEST is only for headers.\n' +
285 '\n'.join(problems))]
286
287
[email protected]8ea5d4b2011-09-13 21:49:22288def _CheckNoNewWStrings(input_api, output_api):
289 """Checks to make sure we don't introduce use of wstrings."""
[email protected]55463aa62011-10-12 00:48:27290 problems = []
[email protected]8ea5d4b2011-09-13 21:49:22291 for f in input_api.AffectedFiles():
[email protected]b5c24292011-11-28 14:38:20292 if (not f.LocalPath().endswith(('.cc', '.h')) or
293 f.LocalPath().endswith('test.cc')):
294 continue
[email protected]8ea5d4b2011-09-13 21:49:22295
[email protected]a11dbe9b2012-08-07 01:32:58296 allowWString = False
[email protected]b5c24292011-11-28 14:38:20297 for line_num, line in f.ChangedContents():
[email protected]a11dbe9b2012-08-07 01:32:58298 if 'presubmit: allow wstring' in line:
299 allowWString = True
300 elif not allowWString and 'wstring' in line:
[email protected]55463aa62011-10-12 00:48:27301 problems.append(' %s:%d' % (f.LocalPath(), line_num))
[email protected]a11dbe9b2012-08-07 01:32:58302 allowWString = False
303 else:
304 allowWString = False
[email protected]8ea5d4b2011-09-13 21:49:22305
[email protected]55463aa62011-10-12 00:48:27306 if not problems:
307 return []
308 return [output_api.PresubmitPromptWarning('New code should not use wstrings.'
[email protected]a11dbe9b2012-08-07 01:32:58309 ' If you are calling a cross-platform API that accepts a wstring, '
310 'fix the API.\n' +
[email protected]55463aa62011-10-12 00:48:27311 '\n'.join(problems))]
[email protected]8ea5d4b2011-09-13 21:49:22312
313
[email protected]2a8ac9c2011-10-19 17:20:44314def _CheckNoDEPSGIT(input_api, output_api):
315 """Make sure .DEPS.git is never modified manually."""
316 if any(f.LocalPath().endswith('.DEPS.git') for f in
317 input_api.AffectedFiles()):
318 return [output_api.PresubmitError(
319 'Never commit changes to .DEPS.git. This file is maintained by an\n'
320 'automated system based on what\'s in DEPS and your changes will be\n'
321 'overwritten.\n'
322 'See http://code.google.com/p/chromium/wiki/UsingNewGit#Rolling_DEPS\n'
323 'for more information')]
324 return []
325
326
[email protected]127f18ec2012-06-16 05:05:59327def _CheckNoBannedFunctions(input_api, output_api):
328 """Make sure that banned functions are not used."""
329 warnings = []
330 errors = []
331
332 file_filter = lambda f: f.LocalPath().endswith(('.mm', '.m', '.h'))
333 for f in input_api.AffectedFiles(file_filter=file_filter):
334 for line_num, line in f.ChangedContents():
335 for func_name, message, error in _BANNED_OBJC_FUNCTIONS:
336 if func_name in line:
337 problems = warnings;
338 if error:
339 problems = errors;
340 problems.append(' %s:%d:' % (f.LocalPath(), line_num))
341 for message_line in message:
342 problems.append(' %s' % message_line)
343
344 file_filter = lambda f: f.LocalPath().endswith(('.cc', '.mm', '.h'))
345 for f in input_api.AffectedFiles(file_filter=file_filter):
346 for line_num, line in f.ChangedContents():
347 for func_name, message, error in _BANNED_CPP_FUNCTIONS:
348 if func_name in line:
349 problems = warnings;
350 if error:
351 problems = errors;
352 problems.append(' %s:%d:' % (f.LocalPath(), line_num))
353 for message_line in message:
354 problems.append(' %s' % message_line)
355
356 result = []
357 if (warnings):
358 result.append(output_api.PresubmitPromptWarning(
359 'Banned functions were used.\n' + '\n'.join(warnings)))
360 if (errors):
361 result.append(output_api.PresubmitError(
362 'Banned functions were used.\n' + '\n'.join(errors)))
363 return result
364
365
[email protected]6c063c62012-07-11 19:11:06366def _CheckNoPragmaOnce(input_api, output_api):
367 """Make sure that banned functions are not used."""
368 files = []
369 pattern = input_api.re.compile(r'^#pragma\s+once',
370 input_api.re.MULTILINE)
371 for f in input_api.AffectedSourceFiles(input_api.FilterSourceFile):
372 if not f.LocalPath().endswith('.h'):
373 continue
374 contents = input_api.ReadFile(f)
375 if pattern.search(contents):
376 files.append(f)
377
378 if files:
379 return [output_api.PresubmitError(
380 'Do not use #pragma once in header files.\n'
381 'See http://www.chromium.org/developers/coding-style#TOC-File-headers',
382 files)]
383 return []
384
[email protected]127f18ec2012-06-16 05:05:59385
[email protected]55f9f382012-07-31 11:02:18386def _CheckUnwantedDependencies(input_api, output_api):
387 """Runs checkdeps on #include statements added in this
388 change. Breaking - rules is an error, breaking ! rules is a
389 warning.
390 """
391 # We need to wait until we have an input_api object and use this
392 # roundabout construct to import checkdeps because this file is
393 # eval-ed and thus doesn't have __file__.
394 original_sys_path = sys.path
395 try:
396 sys.path = sys.path + [input_api.os_path.join(
397 input_api.PresubmitLocalPath(), 'tools', 'checkdeps')]
398 import checkdeps
399 from cpp_checker import CppChecker
400 from rules import Rule
401 finally:
402 # Restore sys.path to what it was before.
403 sys.path = original_sys_path
404
405 added_includes = []
406 for f in input_api.AffectedFiles():
407 if not CppChecker.IsCppFile(f.LocalPath()):
408 continue
409
410 changed_lines = [line for line_num, line in f.ChangedContents()]
411 added_includes.append([f.LocalPath(), changed_lines])
412
413 deps_checker = checkdeps.DepsChecker()
414
415 error_descriptions = []
416 warning_descriptions = []
417 for path, rule_type, rule_description in deps_checker.CheckAddedCppIncludes(
418 added_includes):
419 description_with_path = '%s\n %s' % (path, rule_description)
420 if rule_type == Rule.DISALLOW:
421 error_descriptions.append(description_with_path)
422 else:
423 warning_descriptions.append(description_with_path)
424
425 results = []
426 if error_descriptions:
427 results.append(output_api.PresubmitError(
428 'You added one or more #includes that violate checkdeps rules.',
429 error_descriptions))
430 if warning_descriptions:
431 results.append(output_api.PresubmitPromptWarning(
432 'You added one or more #includes of files that are temporarily\n'
433 'allowed but being removed. Can you avoid introducing the\n'
434 '#include? See relevant DEPS file(s) for details and contacts.',
435 warning_descriptions))
436 return results
437
438
[email protected]fbcafe5a2012-08-08 15:31:22439def _CheckFilePermissions(input_api, output_api):
440 """Check that all files have their permissions properly set."""
441 args = [sys.executable, 'tools/checkperms/checkperms.py', '--root',
442 input_api.change.RepositoryRoot()]
443 for f in input_api.AffectedFiles():
444 args += ['--file', f.LocalPath()]
445 errors = []
446 (errors, stderrdata) = subprocess.Popen(args).communicate()
447
448 results = []
449 if errors:
450 results.append(output_api.PreSubmitError('checkperms.py failed.',
451 errors))
452 return results
453
454
[email protected]22c9bd72011-03-27 16:47:39455def _CommonChecks(input_api, output_api):
456 """Checks common to both upload and commit."""
457 results = []
458 results.extend(input_api.canned_checks.PanProjectChecks(
459 input_api, output_api, excluded_paths=_EXCLUDED_PATHS))
[email protected]66daa702011-05-28 14:41:46460 results.extend(_CheckAuthorizedAuthor(input_api, output_api))
[email protected]55459852011-08-10 15:17:19461 results.extend(
462 _CheckNoProductionCodeUsingTestOnlyFunctions(input_api, output_api))
[email protected]10689ca2011-09-02 02:31:54463 results.extend(_CheckNoIOStreamInHeaders(input_api, output_api))
[email protected]72df4e782012-06-21 16:28:18464 results.extend(_CheckNoUNIT_TESTInSourceFiles(input_api, output_api))
[email protected]8ea5d4b2011-09-13 21:49:22465 results.extend(_CheckNoNewWStrings(input_api, output_api))
[email protected]2a8ac9c2011-10-19 17:20:44466 results.extend(_CheckNoDEPSGIT(input_api, output_api))
[email protected]127f18ec2012-06-16 05:05:59467 results.extend(_CheckNoBannedFunctions(input_api, output_api))
[email protected]6c063c62012-07-11 19:11:06468 results.extend(_CheckNoPragmaOnce(input_api, output_api))
[email protected]55f9f382012-07-31 11:02:18469 results.extend(_CheckUnwantedDependencies(input_api, output_api))
[email protected]fbcafe5a2012-08-08 15:31:22470 results.extend(_CheckFilePermissions(input_api, output_api))
[email protected]22c9bd72011-03-27 16:47:39471 return results
[email protected]1f7b4172010-01-28 01:17:34472
[email protected]b337cb5b2011-01-23 21:24:05473
474def _CheckSubversionConfig(input_api, output_api):
475 """Verifies the subversion config file is correctly setup.
476
477 Checks that autoprops are enabled, returns an error otherwise.
478 """
479 join = input_api.os_path.join
480 if input_api.platform == 'win32':
481 appdata = input_api.environ.get('APPDATA', '')
482 if not appdata:
483 return [output_api.PresubmitError('%APPDATA% is not configured.')]
484 path = join(appdata, 'Subversion', 'config')
485 else:
486 home = input_api.environ.get('HOME', '')
487 if not home:
488 return [output_api.PresubmitError('$HOME is not configured.')]
489 path = join(home, '.subversion', 'config')
490
491 error_msg = (
492 'Please look at http://dev.chromium.org/developers/coding-style to\n'
493 'configure your subversion configuration file. This enables automatic\n'
[email protected]c6a3c10b2011-01-24 16:14:20494 'properties to simplify the project maintenance.\n'
495 'Pro-tip: just download and install\n'
496 'http://src.chromium.org/viewvc/chrome/trunk/tools/build/slave/config\n')
[email protected]b337cb5b2011-01-23 21:24:05497
498 try:
499 lines = open(path, 'r').read().splitlines()
500 # Make sure auto-props is enabled and check for 2 Chromium standard
501 # auto-prop.
502 if (not '*.cc = svn:eol-style=LF' in lines or
503 not '*.pdf = svn:mime-type=application/pdf' in lines or
504 not 'enable-auto-props = yes' in lines):
505 return [
[email protected]79ed7e62011-02-21 21:08:53506 output_api.PresubmitNotifyResult(
[email protected]b337cb5b2011-01-23 21:24:05507 'It looks like you have not configured your subversion config '
[email protected]b5359c02011-02-01 20:29:56508 'file or it is not up-to-date.\n' + error_msg)
[email protected]b337cb5b2011-01-23 21:24:05509 ]
510 except (OSError, IOError):
511 return [
[email protected]79ed7e62011-02-21 21:08:53512 output_api.PresubmitNotifyResult(
[email protected]b337cb5b2011-01-23 21:24:05513 'Can\'t find your subversion config file.\n' + error_msg)
514 ]
515 return []
516
517
[email protected]66daa702011-05-28 14:41:46518def _CheckAuthorizedAuthor(input_api, output_api):
519 """For non-googler/chromites committers, verify the author's email address is
520 in AUTHORS.
521 """
[email protected]9bb9cb82011-06-13 20:43:01522 # TODO(maruel): Add it to input_api?
523 import fnmatch
524
[email protected]66daa702011-05-28 14:41:46525 author = input_api.change.author_email
[email protected]9bb9cb82011-06-13 20:43:01526 if not author:
527 input_api.logging.info('No author, skipping AUTHOR check')
[email protected]66daa702011-05-28 14:41:46528 return []
[email protected]c99663292011-05-31 19:46:08529 authors_path = input_api.os_path.join(
[email protected]66daa702011-05-28 14:41:46530 input_api.PresubmitLocalPath(), 'AUTHORS')
531 valid_authors = (
532 input_api.re.match(r'[^#]+\s+\<(.+?)\>\s*$', line)
533 for line in open(authors_path))
[email protected]ac54b132011-06-06 18:11:18534 valid_authors = [item.group(1).lower() for item in valid_authors if item]
[email protected]9bb9cb82011-06-13 20:43:01535 if input_api.verbose:
536 print 'Valid authors are %s' % ', '.join(valid_authors)
[email protected]d8b50be2011-06-15 14:19:44537 if not any(fnmatch.fnmatch(author.lower(), valid) for valid in valid_authors):
[email protected]66daa702011-05-28 14:41:46538 return [output_api.PresubmitPromptWarning(
539 ('%s is not in AUTHORS file. If you are a new contributor, please visit'
540 '\n'
541 'http://www.chromium.org/developers/contributing-code and read the '
542 '"Legal" section\n'
543 'If you are a chromite, verify the contributor signed the CLA.') %
544 author)]
545 return []
546
547
[email protected]1f7b4172010-01-28 01:17:34548def CheckChangeOnUpload(input_api, output_api):
549 results = []
550 results.extend(_CommonChecks(input_api, output_api))
[email protected]fe5f57c52009-06-05 14:25:54551 return results
[email protected]ca8d1982009-02-19 16:33:12552
553
554def CheckChangeOnCommit(input_api, output_api):
[email protected]fe5f57c52009-06-05 14:25:54555 results = []
[email protected]1f7b4172010-01-28 01:17:34556 results.extend(_CommonChecks(input_api, output_api))
[email protected]dd805fe2009-10-01 08:11:51557 # TODO(thestig) temporarily disabled, doesn't work in third_party/
558 #results.extend(input_api.canned_checks.CheckSvnModifiedDirectories(
559 # input_api, output_api, sources))
[email protected]fe5f57c52009-06-05 14:25:54560 # Make sure the tree is 'open'.
[email protected]806e98e2010-03-19 17:49:27561 results.extend(input_api.canned_checks.CheckTreeIsOpen(
[email protected]7f238152009-08-12 19:00:34562 input_api,
563 output_api,
[email protected]4efa42142010-08-26 01:29:26564 json_url='http://chromium-status.appspot.com/current?format=json'))
[email protected]806e98e2010-03-19 17:49:27565 results.extend(input_api.canned_checks.CheckRietveldTryJobExecution(input_api,
[email protected]4ddc5df2011-12-12 03:05:04566 output_api, 'http://codereview.chromium.org',
[email protected]c1ba4c52012-03-09 14:23:28567 ('win_rel', 'linux_rel', 'mac_rel, win:compile'),
568 '[email protected]'))
[email protected]806e98e2010-03-19 17:49:27569
[email protected]3e4eb112011-01-18 03:29:54570 results.extend(input_api.canned_checks.CheckChangeHasBugField(
571 input_api, output_api))
[email protected]c4b47562011-12-05 23:39:41572 results.extend(input_api.canned_checks.CheckChangeHasDescription(
573 input_api, output_api))
[email protected]b337cb5b2011-01-23 21:24:05574 results.extend(_CheckSubversionConfig(input_api, output_api))
[email protected]fe5f57c52009-06-05 14:25:54575 return results
[email protected]ca8d1982009-02-19 16:33:12576
577
[email protected]5efb2a822011-09-27 23:06:13578def GetPreferredTrySlaves(project, change):
[email protected]4ce995ea2012-06-27 02:13:10579 files = change.LocalPaths()
580
[email protected]3019c902012-06-29 00:09:03581 if not files:
582 return []
583
[email protected]4ce995ea2012-06-27 02:13:10584 if all(re.search('\.(m|mm)$|[/_]mac[/_.]', f) for f in files):
[email protected]4ddc5df2011-12-12 03:05:04585 return ['mac_rel']
[email protected]4ce995ea2012-06-27 02:13:10586 if all(re.search('[/_]win[/_.]', f) for f in files):
587 return ['win_rel']
588 if all(re.search('[/_]android[/_.]', f) for f in files):
589 return ['android']
590
[email protected]d602b902012-07-19 16:30:31591 trybots = ['win_rel', 'linux_rel', 'mac_rel', 'linux_clang:compile',
592 'android']
[email protected]911753b2012-08-02 12:11:54593
594 # Match things like path/aura/file.cc and path/file_aura.cc.
[email protected]0be9553a2012-08-10 00:14:45595 # Same for ash and chromeos.
596 if any(re.search('[/_](ash|aura)', f) for f in files):
597 trybots += ['linux_chromeos', 'linux_chromeos_clang:compile', 'win_aura']
598 else:
599 if any(re.search('[/_]chromeos', f) for f in files):
600 trybots += ['linux_chromeos', 'linux_chromeos_clang:compile']
[email protected]4ce995ea2012-06-27 02:13:10601
[email protected]4ce995ea2012-06-27 02:13:10602 return trybots