blob: f7500e80768f8c0750263afa5156f9e8cf6f48ec [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
ehmaldonado4fb97462017-01-30 05:27:22 -080012import subprocess
kjellander@webrtc.org3bd41562014-09-01 11:06:37 +000013import sys
kjellander@webrtc.org85759802013-10-22 16:47:40 +000014
15
kjellander@webrtc.org0fcaf992015-11-26 15:24:52 +010016# Directories that will be scanned by cpplint by the presubmit script.
17CPPLINT_DIRS = [
oprypin803dc292017-02-01 01:55:59 -080018 'webrtc/api',
Fredrik Solenbergea073732015-12-01 11:26:34 +010019 'webrtc/audio',
20 'webrtc/call',
jbauch0f2e9392015-12-10 03:11:42 -080021 'webrtc/common_video',
jbauch70625e52015-12-09 14:18:14 -080022 'webrtc/examples',
aleloidf9e4d92016-08-08 10:26:09 -070023 'webrtc/modules/audio_mixer',
jbauchf91e6d02016-01-24 23:05:21 -080024 'webrtc/modules/bitrate_controller',
Stefan Holmer80e12072016-02-23 13:30:42 +010025 'webrtc/modules/congestion_controller',
jbauchd2a22962016-02-08 23:18:25 -080026 'webrtc/modules/pacing',
terelius8f09f172015-12-15 00:51:54 -080027 'webrtc/modules/remote_bitrate_estimator',
danilchap377b5e62015-12-15 04:33:44 -080028 'webrtc/modules/rtp_rtcp',
philipel5908c712015-12-21 08:23:20 -080029 'webrtc/modules/video_coding',
mflodman88eeac42015-12-08 09:21:28 +010030 'webrtc/modules/video_processing',
jbauch0f2e9392015-12-10 03:11:42 -080031 'webrtc/tools',
mflodmand1590b22015-12-09 07:07:59 -080032 'webrtc/video',
kjellander@webrtc.org0fcaf992015-11-26 15:24:52 +010033]
34
jbauchc4e3ead2016-02-19 00:25:55 -080035# These filters will always be removed, even if the caller specifies a filter
36# set, as they are problematic or broken in some way.
37#
38# Justifications for each filter:
39# - build/c++11 : Rvalue ref checks are unreliable (false positives),
40# include file and feature blacklists are
41# google3-specific.
kjellandere5a87a52016-04-27 02:32:12 -070042# - whitespace/operators: Same as above (doesn't seem sufficient to eliminate
43# all move-related errors).
jbauchc4e3ead2016-02-19 00:25:55 -080044BLACKLIST_LINT_FILTERS = [
45 '-build/c++11',
kjellandere5a87a52016-04-27 02:32:12 -070046 '-whitespace/operators',
jbauchc4e3ead2016-02-19 00:25:55 -080047]
48
kjellanderfd595232015-12-04 02:44:09 -080049# List of directories of "supported" native APIs. That means changes to headers
50# will be done in a compatible way following this scheme:
51# 1. Non-breaking changes are made.
52# 2. The old APIs as marked as deprecated (with comments).
53# 3. Deprecation is announced to discuss-webrtc@googlegroups.com and
54# webrtc-users@google.com (internal list).
55# 4. (later) The deprecated APIs are removed.
kjellander53047c92015-12-02 23:56:14 -080056NATIVE_API_DIRS = (
kjellander53047c92015-12-02 23:56:14 -080057 'webrtc',
kjellanderdd705472016-06-09 11:17:27 -070058 'webrtc/api',
59 'webrtc/media',
kjellander53047c92015-12-02 23:56:14 -080060 'webrtc/modules/audio_device/include',
kjellanderdd705472016-06-09 11:17:27 -070061 'webrtc/pc',
62)
63# These directories should not be used but are maintained only to avoid breaking
64# some legacy downstream code.
65LEGACY_API_DIRS = (
kjellanderdd705472016-06-09 11:17:27 -070066 'webrtc/base',
67 'webrtc/common_audio/include',
68 'webrtc/modules/audio_coding/include',
69 'webrtc/modules/audio_conference_mixer/include',
kjellander53047c92015-12-02 23:56:14 -080070 'webrtc/modules/audio_processing/include',
71 'webrtc/modules/bitrate_controller/include',
Stefan Holmer80e12072016-02-23 13:30:42 +010072 'webrtc/modules/congestion_controller/include',
kjellander53047c92015-12-02 23:56:14 -080073 'webrtc/modules/include',
74 'webrtc/modules/remote_bitrate_estimator/include',
75 'webrtc/modules/rtp_rtcp/include',
kjellanderdd705472016-06-09 11:17:27 -070076 'webrtc/modules/rtp_rtcp/source',
kjellander53047c92015-12-02 23:56:14 -080077 'webrtc/modules/utility/include',
78 'webrtc/modules/video_coding/codecs/h264/include',
79 'webrtc/modules/video_coding/codecs/i420/include',
80 'webrtc/modules/video_coding/codecs/vp8/include',
81 'webrtc/modules/video_coding/codecs/vp9/include',
82 'webrtc/modules/video_coding/include',
kjellanderdd705472016-06-09 11:17:27 -070083 'webrtc/system_wrappers/include',
kjellander53047c92015-12-02 23:56:14 -080084 'webrtc/voice_engine/include',
85)
kjellanderdd705472016-06-09 11:17:27 -070086API_DIRS = NATIVE_API_DIRS[:] + LEGACY_API_DIRS[:]
kjellander53047c92015-12-02 23:56:14 -080087
88
ehmaldonado4fb97462017-01-30 05:27:22 -080089def _RunCommand(command, cwd):
90 """Runs a command and returns the output from that command."""
91 p = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
92 cwd=cwd)
93 stdout = p.stdout.read()
94 stderr = p.stderr.read()
95 p.wait()
96 p.stdout.close()
97 p.stderr.close()
98 return p.returncode, stdout, stderr
99
100
kjellander53047c92015-12-02 23:56:14 -0800101def _VerifyNativeApiHeadersListIsValid(input_api, output_api):
102 """Ensures the list of native API header directories is up to date."""
103 non_existing_paths = []
104 native_api_full_paths = [
105 input_api.os_path.join(input_api.PresubmitLocalPath(),
kjellanderdd705472016-06-09 11:17:27 -0700106 *path.split('/')) for path in API_DIRS]
kjellander53047c92015-12-02 23:56:14 -0800107 for path in native_api_full_paths:
108 if not os.path.isdir(path):
109 non_existing_paths.append(path)
110 if non_existing_paths:
111 return [output_api.PresubmitError(
112 'Directories to native API headers have changed which has made the '
113 'list in PRESUBMIT.py outdated.\nPlease update it to the current '
114 'location of our native APIs.',
115 non_existing_paths)]
116 return []
117
kwibergeb133022016-04-07 07:41:48 -0700118api_change_msg = """
119You seem to be changing native API header files. Please make sure that you:
oprypin375b9ac2017-02-13 04:13:23 -0800120 1. Make compatible changes that don't break existing clients. Usually
121 this is done by keeping the existing method signatures unchanged.
122 2. Mark the old stuff as deprecated (see RTC_DEPRECATED macro).
kwibergeb133022016-04-07 07:41:48 -0700123 3. Create a timeline and plan for when the deprecated stuff will be
124 removed. (The amount of time we give users to change their code
125 should be informed by how much work it is for them. If they just
126 need to replace one name with another or something equally
127 simple, 1-2 weeks might be good; if they need to do serious work,
128 up to 3 months may be called for.)
129 4. Update/inform existing downstream code owners to stop using the
130 deprecated stuff. (Send announcements to
131 discuss-webrtc@googlegroups.com and webrtc-users@google.com.)
132 5. Remove the deprecated stuff, once the agreed-upon amount of time
133 has passed.
134Related files:
135"""
kjellander53047c92015-12-02 23:56:14 -0800136
137def _CheckNativeApiHeaderChanges(input_api, output_api):
138 """Checks to remind proper changing of native APIs."""
139 files = []
140 for f in input_api.AffectedSourceFiles(input_api.FilterSourceFile):
141 if f.LocalPath().endswith('.h'):
kjellanderdd705472016-06-09 11:17:27 -0700142 for path in API_DIRS:
kjellander53047c92015-12-02 23:56:14 -0800143 if os.path.dirname(f.LocalPath()) == path:
144 files.append(f)
145
146 if files:
kwibergeb133022016-04-07 07:41:48 -0700147 return [output_api.PresubmitNotifyResult(api_change_msg, files)]
kjellander53047c92015-12-02 23:56:14 -0800148 return []
149
kjellander@webrtc.org0fcaf992015-11-26 15:24:52 +0100150
kjellander@webrtc.org51198f12012-02-21 17:53:46 +0000151def _CheckNoIOStreamInHeaders(input_api, output_api):
152 """Checks to make sure no .h files include <iostream>."""
153 files = []
154 pattern = input_api.re.compile(r'^#include\s*<iostream>',
155 input_api.re.MULTILINE)
156 for f in input_api.AffectedSourceFiles(input_api.FilterSourceFile):
157 if not f.LocalPath().endswith('.h'):
158 continue
159 contents = input_api.ReadFile(f)
160 if pattern.search(contents):
161 files.append(f)
162
163 if len(files):
Henrik Kjellander57e5fd22015-05-25 12:55:39 +0200164 return [output_api.PresubmitError(
kjellander@webrtc.org51198f12012-02-21 17:53:46 +0000165 'Do not #include <iostream> in header files, since it inserts static ' +
166 'initialization into every file including the header. Instead, ' +
167 '#include <ostream>. See http://crbug.com/94794',
Henrik Kjellander57e5fd22015-05-25 12:55:39 +0200168 files)]
kjellander@webrtc.org51198f12012-02-21 17:53:46 +0000169 return []
170
kjellander@webrtc.orge4158642014-08-06 09:11:18 +0000171
kjellander6aeef742017-02-20 01:13:18 -0800172def _CheckNoPragmaOnce(input_api, output_api):
173 """Make sure that banned functions are not used."""
174 files = []
175 pattern = input_api.re.compile(r'^#pragma\s+once',
176 input_api.re.MULTILINE)
177 for f in input_api.AffectedSourceFiles(input_api.FilterSourceFile):
178 if not f.LocalPath().endswith('.h'):
179 continue
180 contents = input_api.ReadFile(f)
181 if pattern.search(contents):
182 files.append(f)
183
184 if files:
185 return [output_api.PresubmitError(
186 'Do not use #pragma once in header files.\n'
187 'See http://www.chromium.org/developers/coding-style#TOC-File-headers',
188 files)]
189 return []
190
191
kjellander@webrtc.org51198f12012-02-21 17:53:46 +0000192def _CheckNoFRIEND_TEST(input_api, output_api):
193 """Make sure that gtest's FRIEND_TEST() macro is not used, the
194 FRIEND_TEST_ALL_PREFIXES() macro from testsupport/gtest_prod_util.h should be
195 used instead since that allows for FLAKY_, FAILS_ and DISABLED_ prefixes."""
196 problems = []
197
198 file_filter = lambda f: f.LocalPath().endswith(('.cc', '.h'))
199 for f in input_api.AffectedFiles(file_filter=file_filter):
200 for line_num, line in f.ChangedContents():
201 if 'FRIEND_TEST(' in line:
202 problems.append(' %s:%d' % (f.LocalPath(), line_num))
203
204 if not problems:
205 return []
206 return [output_api.PresubmitPromptWarning('WebRTC\'s code should not use '
207 'gtest\'s FRIEND_TEST() macro. Include testsupport/gtest_prod_util.h and '
208 'use FRIEND_TEST_ALL_PREFIXES() instead.\n' + '\n'.join(problems))]
209
kjellander@webrtc.orge4158642014-08-06 09:11:18 +0000210
kjellander@webrtc.org0fcaf992015-11-26 15:24:52 +0100211def _IsLintWhitelisted(whitelist_dirs, file_path):
212 """ Checks if a file is whitelisted for lint check."""
213 for path in whitelist_dirs:
214 if os.path.dirname(file_path).startswith(path):
215 return True
216 return False
217
218
mflodman@webrtc.org2a452092012-07-01 05:55:23 +0000219def _CheckApprovedFilesLintClean(input_api, output_api,
220 source_file_filter=None):
221 """Checks that all new or whitelisted .cc and .h files pass cpplint.py.
kjellander@webrtc.org51198f12012-02-21 17:53:46 +0000222 This check is based on _CheckChangeLintsClean in
223 depot_tools/presubmit_canned_checks.py but has less filters and only checks
224 added files."""
225 result = []
226
227 # Initialize cpplint.
228 import cpplint
229 # Access to a protected member _XX of a client class
230 # pylint: disable=W0212
231 cpplint._cpplint_state.ResetErrorCounts()
232
jbauchc4e3ead2016-02-19 00:25:55 -0800233 lint_filters = cpplint._Filters()
234 lint_filters.extend(BLACKLIST_LINT_FILTERS)
235 cpplint._SetFilters(','.join(lint_filters))
236
kjellander@webrtc.org0fcaf992015-11-26 15:24:52 +0100237 # Create a platform independent whitelist for the CPPLINT_DIRS.
238 whitelist_dirs = [input_api.os_path.join(*path.split('/'))
239 for path in CPPLINT_DIRS]
240
kjellander@webrtc.org51198f12012-02-21 17:53:46 +0000241 # Use the strictest verbosity level for cpplint.py (level 1) which is the
242 # default when running cpplint.py from command line.
243 # To make it possible to work with not-yet-converted code, we're only applying
mflodman@webrtc.org2a452092012-07-01 05:55:23 +0000244 # it to new (or moved/renamed) files and files listed in LINT_FOLDERS.
kjellander@webrtc.org51198f12012-02-21 17:53:46 +0000245 verbosity_level = 1
246 files = []
247 for f in input_api.AffectedSourceFiles(source_file_filter):
Henrik Kjellander57e5fd22015-05-25 12:55:39 +0200248 # Note that moved/renamed files also count as added.
kjellander@webrtc.org0fcaf992015-11-26 15:24:52 +0100249 if f.Action() == 'A' or _IsLintWhitelisted(whitelist_dirs, f.LocalPath()):
kjellander@webrtc.org51198f12012-02-21 17:53:46 +0000250 files.append(f.AbsoluteLocalPath())
mflodman@webrtc.org2a452092012-07-01 05:55:23 +0000251
kjellander@webrtc.org51198f12012-02-21 17:53:46 +0000252 for file_name in files:
253 cpplint.ProcessFile(file_name, verbosity_level)
254
255 if cpplint._cpplint_state.error_count > 0:
256 if input_api.is_committing:
257 # TODO(kjellander): Change back to PresubmitError below when we're
258 # confident with the lint settings.
259 res_type = output_api.PresubmitPromptWarning
260 else:
261 res_type = output_api.PresubmitPromptWarning
262 result = [res_type('Changelist failed cpplint.py check.')]
263
264 return result
265
Henrik Kjellanderb4af3d62016-11-16 20:11:29 +0100266def _CheckNoSourcesAbove(input_api, gn_files, output_api):
ehmaldonado5b1ba082016-09-02 05:51:08 -0700267 # Disallow referencing source files with paths above the GN file location.
268 source_pattern = input_api.re.compile(r' +sources \+?= \[(.*?)\]',
269 re.MULTILINE | re.DOTALL)
270 file_pattern = input_api.re.compile(r'"((\.\./.*?)|(//.*?))"')
271 violating_gn_files = set()
272 violating_source_entries = []
273 for gn_file in gn_files:
274 contents = input_api.ReadFile(gn_file)
275 for source_block_match in source_pattern.finditer(contents):
276 # Find all source list entries starting with ../ in the source block
277 # (exclude overrides entries).
278 for file_list_match in file_pattern.finditer(source_block_match.group(1)):
279 source_file = file_list_match.group(1)
280 if 'overrides/' not in source_file:
281 violating_source_entries.append(source_file)
282 violating_gn_files.add(gn_file)
283 if violating_gn_files:
284 return [output_api.PresubmitError(
285 'Referencing source files above the directory of the GN file is not '
Henrik Kjellanderb4af3d62016-11-16 20:11:29 +0100286 'allowed. Please introduce new GN targets in the proper location '
287 'instead.\n'
ehmaldonado5b1ba082016-09-02 05:51:08 -0700288 'Invalid source entries:\n'
289 '%s\n'
290 'Violating GN files:' % '\n'.join(violating_source_entries),
291 items=violating_gn_files)]
292 return []
293
kjellander7439f972016-12-05 22:47:46 -0800294def _CheckNoMixingCAndCCSources(input_api, gn_files, output_api):
295 # Disallow mixing .c and .cc source files in the same target.
296 source_pattern = input_api.re.compile(r' +sources \+?= \[(.*?)\]',
297 re.MULTILINE | re.DOTALL)
298 file_pattern = input_api.re.compile(r'"(.*)"')
299 violating_gn_files = dict()
300 for gn_file in gn_files:
301 contents = input_api.ReadFile(gn_file)
302 for source_block_match in source_pattern.finditer(contents):
303 c_files = []
304 cc_files = []
305 for file_list_match in file_pattern.finditer(source_block_match.group(1)):
306 source_file = file_list_match.group(1)
307 if source_file.endswith('.c'):
308 c_files.append(source_file)
309 if source_file.endswith('.cc'):
310 cc_files.append(source_file)
311 if c_files and cc_files:
312 violating_gn_files[gn_file.LocalPath()] = sorted(c_files + cc_files)
313 if violating_gn_files:
314 return [output_api.PresubmitError(
315 'GN targets cannot mix .cc and .c source files. Please create a '
316 'separate target for each collection of sources.\n'
317 'Mixed sources: \n'
318 '%s\n'
319 'Violating GN files:' % json.dumps(violating_gn_files, indent=2),
320 items=violating_gn_files.keys())]
321 return []
322
ehmaldonado4fb97462017-01-30 05:27:22 -0800323def _CheckNoPackageBoundaryViolations(input_api, gn_files, output_api):
324 cwd = input_api.PresubmitLocalPath()
325 script_path = os.path.join('tools-webrtc', 'check_package_boundaries.py')
326 webrtc_path = os.path.join('webrtc')
327 command = [sys.executable, script_path, webrtc_path]
328 command += [gn_file.LocalPath() for gn_file in gn_files]
329 returncode, _, stderr = _RunCommand(command, cwd)
330 if returncode:
331 return [output_api.PresubmitError(
332 'There are package boundary violations in the following GN files:\n\n'
333 '%s' % stderr)]
334 return []
335
ehmaldonado5b1ba082016-09-02 05:51:08 -0700336def _CheckGnChanges(input_api, output_api):
337 source_file_filter = lambda x: input_api.FilterSourceFile(
338 x, white_list=(r'.+\.(gn|gni)$',))
339
340 gn_files = []
341 for f in input_api.AffectedSourceFiles(source_file_filter):
342 if f.LocalPath().startswith('webrtc'):
343 gn_files.append(f)
344
345 result = []
346 if gn_files:
Henrik Kjellanderb4af3d62016-11-16 20:11:29 +0100347 result.extend(_CheckNoSourcesAbove(input_api, gn_files, output_api))
kjellander7439f972016-12-05 22:47:46 -0800348 result.extend(_CheckNoMixingCAndCCSources(input_api, gn_files, output_api))
ehmaldonado4fb97462017-01-30 05:27:22 -0800349 result.extend(_CheckNoPackageBoundaryViolations(
350 input_api, gn_files, output_api))
ehmaldonado5b1ba082016-09-02 05:51:08 -0700351 return result
352
kjellander@webrtc.org3bd41562014-09-01 11:06:37 +0000353def _CheckUnwantedDependencies(input_api, output_api):
354 """Runs checkdeps on #include statements added in this
355 change. Breaking - rules is an error, breaking ! rules is a
356 warning.
357 """
358 # Copied from Chromium's src/PRESUBMIT.py.
359
360 # We need to wait until we have an input_api object and use this
361 # roundabout construct to import checkdeps because this file is
362 # eval-ed and thus doesn't have __file__.
363 original_sys_path = sys.path
364 try:
kjellander@webrtc.orgaefe61a2014-12-08 13:00:30 +0000365 checkdeps_path = input_api.os_path.join(input_api.PresubmitLocalPath(),
366 'buildtools', 'checkdeps')
367 if not os.path.exists(checkdeps_path):
368 return [output_api.PresubmitError(
369 'Cannot find checkdeps at %s\nHave you run "gclient sync" to '
370 'download Chromium and setup the symlinks?' % checkdeps_path)]
371 sys.path.append(checkdeps_path)
kjellander@webrtc.org3bd41562014-09-01 11:06:37 +0000372 import checkdeps
373 from cpp_checker import CppChecker
374 from rules import Rule
375 finally:
376 # Restore sys.path to what it was before.
377 sys.path = original_sys_path
378
379 added_includes = []
380 for f in input_api.AffectedFiles():
381 if not CppChecker.IsCppFile(f.LocalPath()):
382 continue
383
Henrik Kjellander57e5fd22015-05-25 12:55:39 +0200384 changed_lines = [line for _, line in f.ChangedContents()]
kjellander@webrtc.org3bd41562014-09-01 11:06:37 +0000385 added_includes.append([f.LocalPath(), changed_lines])
386
387 deps_checker = checkdeps.DepsChecker(input_api.PresubmitLocalPath())
388
389 error_descriptions = []
390 warning_descriptions = []
391 for path, rule_type, rule_description in deps_checker.CheckAddedCppIncludes(
392 added_includes):
393 description_with_path = '%s\n %s' % (path, rule_description)
394 if rule_type == Rule.DISALLOW:
395 error_descriptions.append(description_with_path)
396 else:
397 warning_descriptions.append(description_with_path)
398
399 results = []
400 if error_descriptions:
401 results.append(output_api.PresubmitError(
402 'You added one or more #includes that violate checkdeps rules.',
403 error_descriptions))
404 if warning_descriptions:
405 results.append(output_api.PresubmitPromptOrNotify(
406 'You added one or more #includes of files that are temporarily\n'
407 'allowed but being removed. Can you avoid introducing the\n'
408 '#include? See relevant DEPS file(s) for details and contacts.',
409 warning_descriptions))
410 return results
411
kjellanderd1e26a92016-09-19 08:11:16 -0700412def _CheckChangeHasBugField(input_api, output_api):
413 """Requires that the changelist have a BUG= field.
414
415 This check is stricter than the one in depot_tools/presubmit_canned_checks.py
416 since it fails the presubmit if the BUG= field is missing or doesn't contain
417 a bug reference.
418 """
419 if input_api.change.BUG:
420 return []
421 else:
422 return [output_api.PresubmitError(
423 'The BUG=[bug number] field is mandatory. Please create a bug and '
424 'reference it using either of:\n'
425 ' * https://bugs.webrtc.org - reference it using BUG=webrtc:XXXX\n'
426 ' * https://crbug.com - reference it using BUG=chromium:XXXXXX')]
kjellander@webrtc.orge4158642014-08-06 09:11:18 +0000427
kjellander569cf942016-02-11 05:02:59 -0800428def _CheckJSONParseErrors(input_api, output_api):
429 """Check that JSON files do not contain syntax errors."""
430
431 def FilterFile(affected_file):
432 return input_api.os_path.splitext(affected_file.LocalPath())[1] == '.json'
433
434 def GetJSONParseError(input_api, filename):
435 try:
436 contents = input_api.ReadFile(filename)
437 input_api.json.loads(contents)
438 except ValueError as e:
439 return e
440 return None
441
442 results = []
443 for affected_file in input_api.AffectedFiles(
444 file_filter=FilterFile, include_deletes=False):
445 parse_error = GetJSONParseError(input_api,
446 affected_file.AbsoluteLocalPath())
447 if parse_error:
448 results.append(output_api.PresubmitError('%s could not be parsed: %s' %
449 (affected_file.LocalPath(), parse_error)))
450 return results
451
452
Henrik Kjellander8d3ad822015-05-26 19:52:05 +0200453def _RunPythonTests(input_api, output_api):
454 def join(*args):
455 return input_api.os_path.join(input_api.PresubmitLocalPath(), *args)
456
457 test_directories = [
ehmaldonado4fb97462017-01-30 05:27:22 -0800458 join('webrtc', 'tools', 'py_event_log_analyzer')
459 ] + [
460 root for root, _, files in os.walk(join('tools-webrtc'))
461 if any(f.endswith('_test.py') for f in files)
Henrik Kjellander8d3ad822015-05-26 19:52:05 +0200462 ]
463
464 tests = []
465 for directory in test_directories:
466 tests.extend(
467 input_api.canned_checks.GetUnitTestsInDirectory(
468 input_api,
469 output_api,
470 directory,
471 whitelist=[r'.+_test\.py$']))
472 return input_api.RunTests(tests, parallel=True)
473
474
andrew@webrtc.org53df1362012-01-26 21:24:23 +0000475def _CommonChecks(input_api, output_api):
476 """Checks common to both upload and commit."""
niklase@google.comda159d62011-05-30 11:51:34 +0000477 results = []
tkchin42f580e2015-11-26 23:18:23 -0800478 # Filter out files that are in objc or ios dirs from being cpplint-ed since
479 # they do not follow C++ lint rules.
480 black_list = input_api.DEFAULT_BLACK_LIST + (
481 r".*\bobjc[\\\/].*",
Kári Tristan Helgason3fa35172016-09-09 08:55:05 +0000482 r".*objc\.[hcm]+$",
hjon65ae2d82016-08-02 23:55:44 -0700483 r"webrtc\/build\/ios\/SDK\/.*",
tkchin42f580e2015-11-26 23:18:23 -0800484 )
485 source_file_filter = lambda x: input_api.FilterSourceFile(x, None, black_list)
486 results.extend(_CheckApprovedFilesLintClean(
487 input_api, output_api, source_file_filter))
phoglund@webrtc.org5d3713932013-03-07 09:59:43 +0000488 results.extend(input_api.canned_checks.RunPylint(input_api, output_api,
kjellander@webrtc.org177567c2016-12-22 10:40:28 +0100489 black_list=(r'^base[\\\/].*\.py$',
Henrik Kjellander14771ac2015-06-02 13:10:04 +0200490 r'^build[\\\/].*\.py$',
491 r'^buildtools[\\\/].*\.py$',
Henrik Kjellander0779e8f2016-12-22 12:01:17 +0100492 r'^ios[\\\/].*\.py$',
Henrik Kjellander14771ac2015-06-02 13:10:04 +0200493 r'^out.*[\\\/].*\.py$',
494 r'^testing[\\\/].*\.py$',
495 r'^third_party[\\\/].*\.py$',
kjellander@webrtc.org177567c2016-12-22 10:40:28 +0100496 r'^tools[\\\/].*\.py$',
kjellanderafd54942016-12-17 12:21:39 -0800497 # TODO(phoglund): should arguably be checked.
Henrik Kjellanderb2d55772016-12-18 22:14:50 +0100498 r'^tools-webrtc[\\\/]mb[\\\/].*\.py$',
kjellanderafd54942016-12-17 12:21:39 -0800499 r'^tools-webrtc[\\\/]valgrind[\\\/].*\.py$',
Henrik Kjellander14771ac2015-06-02 13:10:04 +0200500 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))
kjellandere5dc62a2016-12-14 00:16:21 -0800531 results.extend(input_api.canned_checks.CheckAuthorizedAuthor(
532 input_api, output_api))
andrew@webrtc.org53df1362012-01-26 21:24:23 +0000533 results.extend(input_api.canned_checks.CheckChangeTodoHasOwner(
534 input_api, output_api))
kjellander53047c92015-12-02 23:56:14 -0800535 results.extend(_CheckNativeApiHeaderChanges(input_api, output_api))
kjellander@webrtc.org51198f12012-02-21 17:53:46 +0000536 results.extend(_CheckNoIOStreamInHeaders(input_api, output_api))
kjellander6aeef742017-02-20 01:13:18 -0800537 results.extend(_CheckNoPragmaOnce(input_api, output_api))
kjellander@webrtc.org51198f12012-02-21 17:53:46 +0000538 results.extend(_CheckNoFRIEND_TEST(input_api, output_api))
ehmaldonado5b1ba082016-09-02 05:51:08 -0700539 results.extend(_CheckGnChanges(input_api, output_api))
kjellander@webrtc.org3bd41562014-09-01 11:06:37 +0000540 results.extend(_CheckUnwantedDependencies(input_api, output_api))
kjellander569cf942016-02-11 05:02:59 -0800541 results.extend(_CheckJSONParseErrors(input_api, output_api))
Henrik Kjellander8d3ad822015-05-26 19:52:05 +0200542 results.extend(_RunPythonTests(input_api, output_api))
andrew@webrtc.org53df1362012-01-26 21:24:23 +0000543 return results
andrew@webrtc.org2442de12012-01-23 17:45:41 +0000544
kjellander@webrtc.orge4158642014-08-06 09:11:18 +0000545
andrew@webrtc.org53df1362012-01-26 21:24:23 +0000546def CheckChangeOnUpload(input_api, output_api):
547 results = []
548 results.extend(_CommonChecks(input_api, output_api))
Henrik Kjellander57e5fd22015-05-25 12:55:39 +0200549 results.extend(
550 input_api.canned_checks.CheckGNFormatted(input_api, output_api))
niklase@google.comda159d62011-05-30 11:51:34 +0000551 return results
552
kjellander@webrtc.orge4158642014-08-06 09:11:18 +0000553
andrew@webrtc.org2442de12012-01-23 17:45:41 +0000554def CheckChangeOnCommit(input_api, output_api):
niklase@google.com1198db92011-06-09 07:07:24 +0000555 results = []
andrew@webrtc.org53df1362012-01-26 21:24:23 +0000556 results.extend(_CommonChecks(input_api, output_api))
kjellander53047c92015-12-02 23:56:14 -0800557 results.extend(_VerifyNativeApiHeadersListIsValid(input_api, output_api))
niklase@google.com1198db92011-06-09 07:07:24 +0000558 results.extend(input_api.canned_checks.CheckOwners(input_api, output_api))
andrew@webrtc.org53df1362012-01-26 21:24:23 +0000559 results.extend(input_api.canned_checks.CheckChangeWasUploaded(
560 input_api, output_api))
561 results.extend(input_api.canned_checks.CheckChangeHasDescription(
562 input_api, output_api))
kjellanderd1e26a92016-09-19 08:11:16 -0700563 results.extend(_CheckChangeHasBugField(input_api, output_api))
kjellander@webrtc.org51198f12012-02-21 17:53:46 +0000564 results.extend(input_api.canned_checks.CheckChangeHasTestField(
565 input_api, output_api))
kjellander@webrtc.org12cb88c2014-02-13 11:53:43 +0000566 results.extend(input_api.canned_checks.CheckTreeIsOpen(
567 input_api, output_api,
568 json_url='http://webrtc-status.appspot.com/current?format=json'))
niklase@google.com1198db92011-06-09 07:07:24 +0000569 return results