blob: 86d5c210432a7df5a4d45f5f4b163d22a2319a3c [file] [log] [blame]
andrew@webrtc.org2442de12012-01-23 17:45:41 +00001# Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
2#
3# Use of this source code is governed by a BSD-style license
4# that can be found in the LICENSE file in the root of the source
5# tree. An additional intellectual property rights grant can be found
6# in the file PATENTS. All contributing project authors may
7# be found in the AUTHORS file in the root of the source tree.
niklase@google.comda159d62011-05-30 11:51:34 +00008
kjellander7439f972016-12-05 22:47:46 -08009import json
kjellander@webrtc.orgaefe61a2014-12-08 13:00:30 +000010import os
kjellander@webrtc.org85759802013-10-22 16:47:40 +000011import re
kjellander@webrtc.org3bd41562014-09-01 11:06:37 +000012import sys
kjellander@webrtc.org85759802013-10-22 16:47:40 +000013
14
kjellander@webrtc.org0fcaf992015-11-26 15:24:52 +010015# Directories that will be scanned by cpplint by the presubmit script.
16CPPLINT_DIRS = [
Fredrik Solenbergea073732015-12-01 11:26:34 +010017 'webrtc/audio',
18 'webrtc/call',
jbauch0f2e9392015-12-10 03:11:42 -080019 'webrtc/common_video',
jbauch70625e52015-12-09 14:18:14 -080020 'webrtc/examples',
aleloidf9e4d92016-08-08 10:26:09 -070021 'webrtc/modules/audio_mixer',
jbauchf91e6d02016-01-24 23:05:21 -080022 'webrtc/modules/bitrate_controller',
Stefan Holmer80e12072016-02-23 13:30:42 +010023 'webrtc/modules/congestion_controller',
jbauchd2a22962016-02-08 23:18:25 -080024 'webrtc/modules/pacing',
terelius8f09f172015-12-15 00:51:54 -080025 'webrtc/modules/remote_bitrate_estimator',
danilchap377b5e62015-12-15 04:33:44 -080026 'webrtc/modules/rtp_rtcp',
philipel5908c712015-12-21 08:23:20 -080027 'webrtc/modules/video_coding',
mflodman88eeac42015-12-08 09:21:28 +010028 'webrtc/modules/video_processing',
jbauch0f2e9392015-12-10 03:11:42 -080029 'webrtc/tools',
mflodmand1590b22015-12-09 07:07:59 -080030 'webrtc/video',
kjellander@webrtc.org0fcaf992015-11-26 15:24:52 +010031]
32
jbauchc4e3ead2016-02-19 00:25:55 -080033# These filters will always be removed, even if the caller specifies a filter
34# set, as they are problematic or broken in some way.
35#
36# Justifications for each filter:
37# - build/c++11 : Rvalue ref checks are unreliable (false positives),
38# include file and feature blacklists are
39# google3-specific.
kjellandere5a87a52016-04-27 02:32:12 -070040# - whitespace/operators: Same as above (doesn't seem sufficient to eliminate
41# all move-related errors).
jbauchc4e3ead2016-02-19 00:25:55 -080042BLACKLIST_LINT_FILTERS = [
43 '-build/c++11',
kjellandere5a87a52016-04-27 02:32:12 -070044 '-whitespace/operators',
jbauchc4e3ead2016-02-19 00:25:55 -080045]
46
kjellanderfd595232015-12-04 02:44:09 -080047# List of directories of "supported" native APIs. That means changes to headers
48# will be done in a compatible way following this scheme:
49# 1. Non-breaking changes are made.
50# 2. The old APIs as marked as deprecated (with comments).
51# 3. Deprecation is announced to discuss-webrtc@googlegroups.com and
52# webrtc-users@google.com (internal list).
53# 4. (later) The deprecated APIs are removed.
kjellander53047c92015-12-02 23:56:14 -080054NATIVE_API_DIRS = (
kjellander53047c92015-12-02 23:56:14 -080055 'webrtc',
kjellanderdd705472016-06-09 11:17:27 -070056 'webrtc/api',
57 'webrtc/media',
kjellander53047c92015-12-02 23:56:14 -080058 'webrtc/modules/audio_device/include',
kjellanderdd705472016-06-09 11:17:27 -070059 'webrtc/pc',
60)
61# These directories should not be used but are maintained only to avoid breaking
62# some legacy downstream code.
63LEGACY_API_DIRS = (
kjellanderdd705472016-06-09 11:17:27 -070064 'webrtc/base',
65 'webrtc/common_audio/include',
66 'webrtc/modules/audio_coding/include',
67 'webrtc/modules/audio_conference_mixer/include',
kjellander53047c92015-12-02 23:56:14 -080068 'webrtc/modules/audio_processing/include',
69 'webrtc/modules/bitrate_controller/include',
Stefan Holmer80e12072016-02-23 13:30:42 +010070 'webrtc/modules/congestion_controller/include',
kjellander53047c92015-12-02 23:56:14 -080071 'webrtc/modules/include',
72 'webrtc/modules/remote_bitrate_estimator/include',
73 'webrtc/modules/rtp_rtcp/include',
kjellanderdd705472016-06-09 11:17:27 -070074 'webrtc/modules/rtp_rtcp/source',
kjellander53047c92015-12-02 23:56:14 -080075 'webrtc/modules/utility/include',
76 'webrtc/modules/video_coding/codecs/h264/include',
77 'webrtc/modules/video_coding/codecs/i420/include',
78 'webrtc/modules/video_coding/codecs/vp8/include',
79 'webrtc/modules/video_coding/codecs/vp9/include',
80 'webrtc/modules/video_coding/include',
kjellanderdd705472016-06-09 11:17:27 -070081 'webrtc/system_wrappers/include',
kjellander53047c92015-12-02 23:56:14 -080082 'webrtc/voice_engine/include',
83)
kjellanderdd705472016-06-09 11:17:27 -070084API_DIRS = NATIVE_API_DIRS[:] + LEGACY_API_DIRS[:]
kjellander53047c92015-12-02 23:56:14 -080085
86
87def _VerifyNativeApiHeadersListIsValid(input_api, output_api):
88 """Ensures the list of native API header directories is up to date."""
89 non_existing_paths = []
90 native_api_full_paths = [
91 input_api.os_path.join(input_api.PresubmitLocalPath(),
kjellanderdd705472016-06-09 11:17:27 -070092 *path.split('/')) for path in API_DIRS]
kjellander53047c92015-12-02 23:56:14 -080093 for path in native_api_full_paths:
94 if not os.path.isdir(path):
95 non_existing_paths.append(path)
96 if non_existing_paths:
97 return [output_api.PresubmitError(
98 'Directories to native API headers have changed which has made the '
99 'list in PRESUBMIT.py outdated.\nPlease update it to the current '
100 'location of our native APIs.',
101 non_existing_paths)]
102 return []
103
kwibergeb133022016-04-07 07:41:48 -0700104api_change_msg = """
105You seem to be changing native API header files. Please make sure that you:
106 1. Make compatible changes that don't break existing clients.
107 2. Mark the old stuff as deprecated.
108 3. Create a timeline and plan for when the deprecated stuff will be
109 removed. (The amount of time we give users to change their code
110 should be informed by how much work it is for them. If they just
111 need to replace one name with another or something equally
112 simple, 1-2 weeks might be good; if they need to do serious work,
113 up to 3 months may be called for.)
114 4. Update/inform existing downstream code owners to stop using the
115 deprecated stuff. (Send announcements to
116 discuss-webrtc@googlegroups.com and webrtc-users@google.com.)
117 5. Remove the deprecated stuff, once the agreed-upon amount of time
118 has passed.
119Related files:
120"""
kjellander53047c92015-12-02 23:56:14 -0800121
122def _CheckNativeApiHeaderChanges(input_api, output_api):
123 """Checks to remind proper changing of native APIs."""
124 files = []
125 for f in input_api.AffectedSourceFiles(input_api.FilterSourceFile):
126 if f.LocalPath().endswith('.h'):
kjellanderdd705472016-06-09 11:17:27 -0700127 for path in API_DIRS:
kjellander53047c92015-12-02 23:56:14 -0800128 if os.path.dirname(f.LocalPath()) == path:
129 files.append(f)
130
131 if files:
kwibergeb133022016-04-07 07:41:48 -0700132 return [output_api.PresubmitNotifyResult(api_change_msg, files)]
kjellander53047c92015-12-02 23:56:14 -0800133 return []
134
kjellander@webrtc.org0fcaf992015-11-26 15:24:52 +0100135
kjellander@webrtc.org51198f12012-02-21 17:53:46 +0000136def _CheckNoIOStreamInHeaders(input_api, output_api):
137 """Checks to make sure no .h files include <iostream>."""
138 files = []
139 pattern = input_api.re.compile(r'^#include\s*<iostream>',
140 input_api.re.MULTILINE)
141 for f in input_api.AffectedSourceFiles(input_api.FilterSourceFile):
142 if not f.LocalPath().endswith('.h'):
143 continue
144 contents = input_api.ReadFile(f)
145 if pattern.search(contents):
146 files.append(f)
147
148 if len(files):
Henrik Kjellander57e5fd22015-05-25 12:55:39 +0200149 return [output_api.PresubmitError(
kjellander@webrtc.org51198f12012-02-21 17:53:46 +0000150 'Do not #include <iostream> in header files, since it inserts static ' +
151 'initialization into every file including the header. Instead, ' +
152 '#include <ostream>. See http://crbug.com/94794',
Henrik Kjellander57e5fd22015-05-25 12:55:39 +0200153 files)]
kjellander@webrtc.org51198f12012-02-21 17:53:46 +0000154 return []
155
kjellander@webrtc.orge4158642014-08-06 09:11:18 +0000156
kjellander@webrtc.org51198f12012-02-21 17:53:46 +0000157def _CheckNoFRIEND_TEST(input_api, output_api):
158 """Make sure that gtest's FRIEND_TEST() macro is not used, the
159 FRIEND_TEST_ALL_PREFIXES() macro from testsupport/gtest_prod_util.h should be
160 used instead since that allows for FLAKY_, FAILS_ and DISABLED_ prefixes."""
161 problems = []
162
163 file_filter = lambda f: f.LocalPath().endswith(('.cc', '.h'))
164 for f in input_api.AffectedFiles(file_filter=file_filter):
165 for line_num, line in f.ChangedContents():
166 if 'FRIEND_TEST(' in line:
167 problems.append(' %s:%d' % (f.LocalPath(), line_num))
168
169 if not problems:
170 return []
171 return [output_api.PresubmitPromptWarning('WebRTC\'s code should not use '
172 'gtest\'s FRIEND_TEST() macro. Include testsupport/gtest_prod_util.h and '
173 'use FRIEND_TEST_ALL_PREFIXES() instead.\n' + '\n'.join(problems))]
174
kjellander@webrtc.orge4158642014-08-06 09:11:18 +0000175
kjellander@webrtc.org0fcaf992015-11-26 15:24:52 +0100176def _IsLintWhitelisted(whitelist_dirs, file_path):
177 """ Checks if a file is whitelisted for lint check."""
178 for path in whitelist_dirs:
179 if os.path.dirname(file_path).startswith(path):
180 return True
181 return False
182
183
mflodman@webrtc.org2a452092012-07-01 05:55:23 +0000184def _CheckApprovedFilesLintClean(input_api, output_api,
185 source_file_filter=None):
186 """Checks that all new or whitelisted .cc and .h files pass cpplint.py.
kjellander@webrtc.org51198f12012-02-21 17:53:46 +0000187 This check is based on _CheckChangeLintsClean in
188 depot_tools/presubmit_canned_checks.py but has less filters and only checks
189 added files."""
190 result = []
191
192 # Initialize cpplint.
193 import cpplint
194 # Access to a protected member _XX of a client class
195 # pylint: disable=W0212
196 cpplint._cpplint_state.ResetErrorCounts()
197
jbauchc4e3ead2016-02-19 00:25:55 -0800198 lint_filters = cpplint._Filters()
199 lint_filters.extend(BLACKLIST_LINT_FILTERS)
200 cpplint._SetFilters(','.join(lint_filters))
201
kjellander@webrtc.org0fcaf992015-11-26 15:24:52 +0100202 # Create a platform independent whitelist for the CPPLINT_DIRS.
203 whitelist_dirs = [input_api.os_path.join(*path.split('/'))
204 for path in CPPLINT_DIRS]
205
kjellander@webrtc.org51198f12012-02-21 17:53:46 +0000206 # Use the strictest verbosity level for cpplint.py (level 1) which is the
207 # default when running cpplint.py from command line.
208 # To make it possible to work with not-yet-converted code, we're only applying
mflodman@webrtc.org2a452092012-07-01 05:55:23 +0000209 # it to new (or moved/renamed) files and files listed in LINT_FOLDERS.
kjellander@webrtc.org51198f12012-02-21 17:53:46 +0000210 verbosity_level = 1
211 files = []
212 for f in input_api.AffectedSourceFiles(source_file_filter):
Henrik Kjellander57e5fd22015-05-25 12:55:39 +0200213 # Note that moved/renamed files also count as added.
kjellander@webrtc.org0fcaf992015-11-26 15:24:52 +0100214 if f.Action() == 'A' or _IsLintWhitelisted(whitelist_dirs, f.LocalPath()):
kjellander@webrtc.org51198f12012-02-21 17:53:46 +0000215 files.append(f.AbsoluteLocalPath())
mflodman@webrtc.org2a452092012-07-01 05:55:23 +0000216
kjellander@webrtc.org51198f12012-02-21 17:53:46 +0000217 for file_name in files:
218 cpplint.ProcessFile(file_name, verbosity_level)
219
220 if cpplint._cpplint_state.error_count > 0:
221 if input_api.is_committing:
222 # TODO(kjellander): Change back to PresubmitError below when we're
223 # confident with the lint settings.
224 res_type = output_api.PresubmitPromptWarning
225 else:
226 res_type = output_api.PresubmitPromptWarning
227 result = [res_type('Changelist failed cpplint.py check.')]
228
229 return result
230
Henrik Kjellanderb4af3d62016-11-16 20:11:29 +0100231def _CheckNoRtcBaseDeps(input_api, gn_files, output_api):
ehmaldonado5b1ba082016-09-02 05:51:08 -0700232 pattern = input_api.re.compile(r'base:rtc_base\s*"')
233 violating_files = []
234 for f in gn_files:
235 gn_exceptions = (
maxmorinec623742016-09-15 05:11:55 -0700236 os.path.join('audio_device', 'BUILD.gn'),
ehmaldonado5b1ba082016-09-02 05:51:08 -0700237 os.path.join('base_tests', 'BUILD.gn'),
238 os.path.join('desktop_capture', 'BUILD.gn'),
239 os.path.join('p2p', 'BUILD.gn'),
240 os.path.join('sdk', 'BUILD.gn'),
241 os.path.join('webrtc_test_common', 'BUILD.gn'),
242 os.path.join('webrtc_tests', 'BUILD.gn'),
243
244 # TODO(ehmaldonado): Clean up references to rtc_base in these files.
245 # See https://bugs.chromium.org/p/webrtc/issues/detail?id=3806
246 os.path.join('webrtc', 'BUILD.gn'),
247 os.path.join('xmllite', 'BUILD.gn'),
248 os.path.join('xmpp', 'BUILD.gn'),
249 os.path.join('modules', 'BUILD.gn'),
250 os.path.join('audio_device', 'BUILD.gn'),
251 os.path.join('pc', 'BUILD.gn'),
252 )
253 if f.LocalPath().endswith(gn_exceptions):
254 continue
255 contents = input_api.ReadFile(f)
256 if pattern.search(contents):
257 violating_files.append(f)
258 if violating_files:
259 return [output_api.PresubmitError(
260 'Depending on rtc_base is not allowed. Change your dependency to '
261 'rtc_base_approved and possibly sanitize and move the desired source '
262 'file(s) to rtc_base_approved.\nChanged GN files:',
263 items=violating_files)]
264 return []
265
kjellander@webrtc.orgf68ffca2015-01-27 13:13:24 +0000266
Henrik Kjellanderb4af3d62016-11-16 20:11:29 +0100267def _CheckNoSourcesAbove(input_api, gn_files, output_api):
ehmaldonado5b1ba082016-09-02 05:51:08 -0700268 # Disallow referencing source files with paths above the GN file location.
269 source_pattern = input_api.re.compile(r' +sources \+?= \[(.*?)\]',
270 re.MULTILINE | re.DOTALL)
271 file_pattern = input_api.re.compile(r'"((\.\./.*?)|(//.*?))"')
272 violating_gn_files = set()
273 violating_source_entries = []
274 for gn_file in gn_files:
275 contents = input_api.ReadFile(gn_file)
276 for source_block_match in source_pattern.finditer(contents):
277 # Find all source list entries starting with ../ in the source block
278 # (exclude overrides entries).
279 for file_list_match in file_pattern.finditer(source_block_match.group(1)):
280 source_file = file_list_match.group(1)
281 if 'overrides/' not in source_file:
282 violating_source_entries.append(source_file)
283 violating_gn_files.add(gn_file)
284 if violating_gn_files:
285 return [output_api.PresubmitError(
286 'Referencing source files above the directory of the GN file is not '
Henrik Kjellanderb4af3d62016-11-16 20:11:29 +0100287 'allowed. Please introduce new GN targets in the proper location '
288 'instead.\n'
ehmaldonado5b1ba082016-09-02 05:51:08 -0700289 'Invalid source entries:\n'
290 '%s\n'
291 'Violating GN files:' % '\n'.join(violating_source_entries),
292 items=violating_gn_files)]
293 return []
294
kjellander7439f972016-12-05 22:47:46 -0800295def _CheckNoMixingCAndCCSources(input_api, gn_files, output_api):
296 # Disallow mixing .c and .cc source files in the same target.
297 source_pattern = input_api.re.compile(r' +sources \+?= \[(.*?)\]',
298 re.MULTILINE | re.DOTALL)
299 file_pattern = input_api.re.compile(r'"(.*)"')
300 violating_gn_files = dict()
301 for gn_file in gn_files:
302 contents = input_api.ReadFile(gn_file)
303 for source_block_match in source_pattern.finditer(contents):
304 c_files = []
305 cc_files = []
306 for file_list_match in file_pattern.finditer(source_block_match.group(1)):
307 source_file = file_list_match.group(1)
308 if source_file.endswith('.c'):
309 c_files.append(source_file)
310 if source_file.endswith('.cc'):
311 cc_files.append(source_file)
312 if c_files and cc_files:
313 violating_gn_files[gn_file.LocalPath()] = sorted(c_files + cc_files)
314 if violating_gn_files:
315 return [output_api.PresubmitError(
316 'GN targets cannot mix .cc and .c source files. Please create a '
317 'separate target for each collection of sources.\n'
318 'Mixed sources: \n'
319 '%s\n'
320 'Violating GN files:' % json.dumps(violating_gn_files, indent=2),
321 items=violating_gn_files.keys())]
322 return []
323
ehmaldonado5b1ba082016-09-02 05:51:08 -0700324def _CheckGnChanges(input_api, output_api):
325 source_file_filter = lambda x: input_api.FilterSourceFile(
326 x, white_list=(r'.+\.(gn|gni)$',))
327
328 gn_files = []
329 for f in input_api.AffectedSourceFiles(source_file_filter):
330 if f.LocalPath().startswith('webrtc'):
331 gn_files.append(f)
332
333 result = []
334 if gn_files:
Henrik Kjellanderb4af3d62016-11-16 20:11:29 +0100335 result.extend(_CheckNoRtcBaseDeps(input_api, gn_files, output_api))
336 result.extend(_CheckNoSourcesAbove(input_api, gn_files, output_api))
kjellander7439f972016-12-05 22:47:46 -0800337 result.extend(_CheckNoMixingCAndCCSources(input_api, gn_files, output_api))
ehmaldonado5b1ba082016-09-02 05:51:08 -0700338 return result
339
kjellander@webrtc.org3bd41562014-09-01 11:06:37 +0000340def _CheckUnwantedDependencies(input_api, output_api):
341 """Runs checkdeps on #include statements added in this
342 change. Breaking - rules is an error, breaking ! rules is a
343 warning.
344 """
345 # Copied from Chromium's src/PRESUBMIT.py.
346
347 # We need to wait until we have an input_api object and use this
348 # roundabout construct to import checkdeps because this file is
349 # eval-ed and thus doesn't have __file__.
350 original_sys_path = sys.path
351 try:
kjellander@webrtc.orgaefe61a2014-12-08 13:00:30 +0000352 checkdeps_path = input_api.os_path.join(input_api.PresubmitLocalPath(),
353 'buildtools', 'checkdeps')
354 if not os.path.exists(checkdeps_path):
355 return [output_api.PresubmitError(
356 'Cannot find checkdeps at %s\nHave you run "gclient sync" to '
357 'download Chromium and setup the symlinks?' % checkdeps_path)]
358 sys.path.append(checkdeps_path)
kjellander@webrtc.org3bd41562014-09-01 11:06:37 +0000359 import checkdeps
360 from cpp_checker import CppChecker
361 from rules import Rule
362 finally:
363 # Restore sys.path to what it was before.
364 sys.path = original_sys_path
365
366 added_includes = []
367 for f in input_api.AffectedFiles():
368 if not CppChecker.IsCppFile(f.LocalPath()):
369 continue
370
Henrik Kjellander57e5fd22015-05-25 12:55:39 +0200371 changed_lines = [line for _, line in f.ChangedContents()]
kjellander@webrtc.org3bd41562014-09-01 11:06:37 +0000372 added_includes.append([f.LocalPath(), changed_lines])
373
374 deps_checker = checkdeps.DepsChecker(input_api.PresubmitLocalPath())
375
376 error_descriptions = []
377 warning_descriptions = []
378 for path, rule_type, rule_description in deps_checker.CheckAddedCppIncludes(
379 added_includes):
380 description_with_path = '%s\n %s' % (path, rule_description)
381 if rule_type == Rule.DISALLOW:
382 error_descriptions.append(description_with_path)
383 else:
384 warning_descriptions.append(description_with_path)
385
386 results = []
387 if error_descriptions:
388 results.append(output_api.PresubmitError(
389 'You added one or more #includes that violate checkdeps rules.',
390 error_descriptions))
391 if warning_descriptions:
392 results.append(output_api.PresubmitPromptOrNotify(
393 'You added one or more #includes of files that are temporarily\n'
394 'allowed but being removed. Can you avoid introducing the\n'
395 '#include? See relevant DEPS file(s) for details and contacts.',
396 warning_descriptions))
397 return results
398
kjellanderd1e26a92016-09-19 08:11:16 -0700399def _CheckChangeHasBugField(input_api, output_api):
400 """Requires that the changelist have a BUG= field.
401
402 This check is stricter than the one in depot_tools/presubmit_canned_checks.py
403 since it fails the presubmit if the BUG= field is missing or doesn't contain
404 a bug reference.
405 """
406 if input_api.change.BUG:
407 return []
408 else:
409 return [output_api.PresubmitError(
410 'The BUG=[bug number] field is mandatory. Please create a bug and '
411 'reference it using either of:\n'
412 ' * https://bugs.webrtc.org - reference it using BUG=webrtc:XXXX\n'
413 ' * https://crbug.com - reference it using BUG=chromium:XXXXXX')]
kjellander@webrtc.orge4158642014-08-06 09:11:18 +0000414
kjellander569cf942016-02-11 05:02:59 -0800415def _CheckJSONParseErrors(input_api, output_api):
416 """Check that JSON files do not contain syntax errors."""
417
418 def FilterFile(affected_file):
419 return input_api.os_path.splitext(affected_file.LocalPath())[1] == '.json'
420
421 def GetJSONParseError(input_api, filename):
422 try:
423 contents = input_api.ReadFile(filename)
424 input_api.json.loads(contents)
425 except ValueError as e:
426 return e
427 return None
428
429 results = []
430 for affected_file in input_api.AffectedFiles(
431 file_filter=FilterFile, include_deletes=False):
432 parse_error = GetJSONParseError(input_api,
433 affected_file.AbsoluteLocalPath())
434 if parse_error:
435 results.append(output_api.PresubmitError('%s could not be parsed: %s' %
436 (affected_file.LocalPath(), parse_error)))
437 return results
438
439
Henrik Kjellander8d3ad822015-05-26 19:52:05 +0200440def _RunPythonTests(input_api, output_api):
441 def join(*args):
442 return input_api.os_path.join(input_api.PresubmitLocalPath(), *args)
443
444 test_directories = [
445 join('tools', 'autoroller', 'unittests'),
aleloi7ebbf902016-06-20 07:39:15 -0700446 join('webrtc', 'tools', 'py_event_log_analyzer'),
Henrik Kjellander8d3ad822015-05-26 19:52:05 +0200447 ]
448
449 tests = []
450 for directory in test_directories:
451 tests.extend(
452 input_api.canned_checks.GetUnitTestsInDirectory(
453 input_api,
454 output_api,
455 directory,
456 whitelist=[r'.+_test\.py$']))
457 return input_api.RunTests(tests, parallel=True)
458
459
andrew@webrtc.org53df1362012-01-26 21:24:23 +0000460def _CommonChecks(input_api, output_api):
461 """Checks common to both upload and commit."""
niklase@google.comda159d62011-05-30 11:51:34 +0000462 results = []
tkchin42f580e2015-11-26 23:18:23 -0800463 # Filter out files that are in objc or ios dirs from being cpplint-ed since
464 # they do not follow C++ lint rules.
465 black_list = input_api.DEFAULT_BLACK_LIST + (
466 r".*\bobjc[\\\/].*",
Kári Tristan Helgason3fa35172016-09-09 08:55:05 +0000467 r".*objc\.[hcm]+$",
hjon65ae2d82016-08-02 23:55:44 -0700468 r"webrtc\/build\/ios\/SDK\/.*",
tkchin42f580e2015-11-26 23:18:23 -0800469 )
470 source_file_filter = lambda x: input_api.FilterSourceFile(x, None, black_list)
471 results.extend(_CheckApprovedFilesLintClean(
472 input_api, output_api, source_file_filter))
phoglund@webrtc.org5d3713932013-03-07 09:59:43 +0000473 results.extend(input_api.canned_checks.RunPylint(input_api, output_api,
474 black_list=(r'^.*gviz_api\.py$',
475 r'^.*gaeunit\.py$',
fischman@webrtc.org33584f92013-07-25 16:43:30 +0000476 # Embedded shell-script fakes out pylint.
Henrik Kjellander14771ac2015-06-02 13:10:04 +0200477 r'^build[\\\/].*\.py$',
478 r'^buildtools[\\\/].*\.py$',
479 r'^chromium[\\\/].*\.py$',
kjellanderd620f822016-04-04 06:07:08 -0700480 r'^mojo.*[\\\/].*\.py$',
Henrik Kjellander14771ac2015-06-02 13:10:04 +0200481 r'^out.*[\\\/].*\.py$',
482 r'^testing[\\\/].*\.py$',
483 r'^third_party[\\\/].*\.py$',
Henrik Kjellander14771ac2015-06-02 13:10:04 +0200484 r'^tools[\\\/]clang[\\\/].*\.py$',
485 r'^tools[\\\/]generate_library_loader[\\\/].*\.py$',
kjellanderd620f822016-04-04 06:07:08 -0700486 r'^tools[\\\/]generate_stubs[\\\/].*\.py$',
Henrik Kjellander14771ac2015-06-02 13:10:04 +0200487 r'^tools[\\\/]gn[\\\/].*\.py$',
Henrik Kjellanderd6d27e72015-09-25 22:19:11 +0200488 r'^tools[\\\/]isolate_driver.py$',
kjellanderd620f822016-04-04 06:07:08 -0700489 r'^tools[\\\/]mb[\\\/].*\.py$',
Henrik Kjellander14771ac2015-06-02 13:10:04 +0200490 r'^tools[\\\/]protoc_wrapper[\\\/].*\.py$',
491 r'^tools[\\\/]python[\\\/].*\.py$',
492 r'^tools[\\\/]python_charts[\\\/]data[\\\/].*\.py$',
493 r'^tools[\\\/]refactoring[\\\/].*\.py$',
494 r'^tools[\\\/]swarming_client[\\\/].*\.py$',
495 r'^tools[\\\/]vim[\\\/].*\.py$',
phoglund@webrtc.org5d3713932013-03-07 09:59:43 +0000496 # TODO(phoglund): should arguably be checked.
Henrik Kjellander14771ac2015-06-02 13:10:04 +0200497 r'^tools[\\\/]valgrind-webrtc[\\\/].*\.py$',
498 r'^tools[\\\/]valgrind[\\\/].*\.py$',
499 r'^tools[\\\/]win[\\\/].*\.py$',
500 r'^xcodebuild.*[\\\/].*\.py$',),
phoglund@webrtc.org5d3713932013-03-07 09:59:43 +0000501 disabled_warnings=['F0401', # Failed to import x
502 'E0611', # No package y in x
503 'W0232', # Class has no __init__ method
Henrik Kjellander57e5fd22015-05-25 12:55:39 +0200504 ],
505 pylintrc='pylintrc'))
kjellander569cf942016-02-11 05:02:59 -0800506
nisse3d21e232016-09-02 03:07:06 -0700507 # TODO(nisse): talk/ is no more, so make below checks simpler?
Henrik Kjellander57e5fd22015-05-25 12:55:39 +0200508 # WebRTC can't use the presubmit_canned_checks.PanProjectChecks function since
509 # we need to have different license checks in talk/ and webrtc/ directories.
510 # Instead, hand-picked checks are included below.
Henrik Kjellander63224672015-09-08 08:03:56 +0200511
tkchin3cd9a302016-06-08 12:40:28 -0700512 # .m and .mm files are ObjC files. For simplicity we will consider .h files in
513 # ObjC subdirectories ObjC headers.
514 objc_filter_list = (r'.+\.m$', r'.+\.mm$', r'.+objc\/.+\.h$')
Henrik Kjellanderb4af3d62016-11-16 20:11:29 +0100515 # Skip long-lines check for DEPS and GN files.
516 build_file_filter_list = (r'.+\.gn$', r'.+\.gni$', 'DEPS')
tkchin3cd9a302016-06-08 12:40:28 -0700517 eighty_char_sources = lambda x: input_api.FilterSourceFile(x,
518 black_list=build_file_filter_list + objc_filter_list)
519 hundred_char_sources = lambda x: input_api.FilterSourceFile(x,
520 white_list=objc_filter_list)
andrew@webrtc.org2442de12012-01-23 17:45:41 +0000521 results.extend(input_api.canned_checks.CheckLongLines(
tkchin3cd9a302016-06-08 12:40:28 -0700522 input_api, output_api, maxlen=80, source_file_filter=eighty_char_sources))
523 results.extend(input_api.canned_checks.CheckLongLines(
524 input_api, output_api, maxlen=100,
525 source_file_filter=hundred_char_sources))
526
andrew@webrtc.org2442de12012-01-23 17:45:41 +0000527 results.extend(input_api.canned_checks.CheckChangeHasNoTabs(
528 input_api, output_api))
andrew@webrtc.org53df1362012-01-26 21:24:23 +0000529 results.extend(input_api.canned_checks.CheckChangeHasNoStrayWhitespace(
530 input_api, output_api))
531 results.extend(input_api.canned_checks.CheckChangeTodoHasOwner(
532 input_api, output_api))
kjellander53047c92015-12-02 23:56:14 -0800533 results.extend(_CheckNativeApiHeaderChanges(input_api, output_api))
kjellander@webrtc.org51198f12012-02-21 17:53:46 +0000534 results.extend(_CheckNoIOStreamInHeaders(input_api, output_api))
535 results.extend(_CheckNoFRIEND_TEST(input_api, output_api))
ehmaldonado5b1ba082016-09-02 05:51:08 -0700536 results.extend(_CheckGnChanges(input_api, output_api))
kjellander@webrtc.org3bd41562014-09-01 11:06:37 +0000537 results.extend(_CheckUnwantedDependencies(input_api, output_api))
kjellander569cf942016-02-11 05:02:59 -0800538 results.extend(_CheckJSONParseErrors(input_api, output_api))
Henrik Kjellander8d3ad822015-05-26 19:52:05 +0200539 results.extend(_RunPythonTests(input_api, output_api))
andrew@webrtc.org53df1362012-01-26 21:24:23 +0000540 return results
andrew@webrtc.org2442de12012-01-23 17:45:41 +0000541
kjellander@webrtc.orge4158642014-08-06 09:11:18 +0000542
andrew@webrtc.org53df1362012-01-26 21:24:23 +0000543def CheckChangeOnUpload(input_api, output_api):
544 results = []
545 results.extend(_CommonChecks(input_api, output_api))
Henrik Kjellander57e5fd22015-05-25 12:55:39 +0200546 results.extend(
547 input_api.canned_checks.CheckGNFormatted(input_api, output_api))
niklase@google.comda159d62011-05-30 11:51:34 +0000548 return results
549
kjellander@webrtc.orge4158642014-08-06 09:11:18 +0000550
andrew@webrtc.org2442de12012-01-23 17:45:41 +0000551def CheckChangeOnCommit(input_api, output_api):
niklase@google.com1198db92011-06-09 07:07:24 +0000552 results = []
andrew@webrtc.org53df1362012-01-26 21:24:23 +0000553 results.extend(_CommonChecks(input_api, output_api))
kjellander53047c92015-12-02 23:56:14 -0800554 results.extend(_VerifyNativeApiHeadersListIsValid(input_api, output_api))
niklase@google.com1198db92011-06-09 07:07:24 +0000555 results.extend(input_api.canned_checks.CheckOwners(input_api, output_api))
andrew@webrtc.org53df1362012-01-26 21:24:23 +0000556 results.extend(input_api.canned_checks.CheckChangeWasUploaded(
557 input_api, output_api))
558 results.extend(input_api.canned_checks.CheckChangeHasDescription(
559 input_api, output_api))
kjellanderd1e26a92016-09-19 08:11:16 -0700560 results.extend(_CheckChangeHasBugField(input_api, output_api))
kjellander@webrtc.org51198f12012-02-21 17:53:46 +0000561 results.extend(input_api.canned_checks.CheckChangeHasTestField(
562 input_api, output_api))
kjellander@webrtc.org12cb88c2014-02-13 11:53:43 +0000563 results.extend(input_api.canned_checks.CheckTreeIsOpen(
564 input_api, output_api,
565 json_url='http://webrtc-status.appspot.com/current?format=json'))
niklase@google.com1198db92011-06-09 07:07:24 +0000566 return results