blob: da193b4867c4afdfdec0465e440b8be0e09f68c5 [file] [log] [blame]
andrew@webrtc.org2442de12012-01-23 17:45:411# 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:348
kjellander986ee082015-06-16 11:32:139import json
kjellander@webrtc.orgaefe61a2014-12-08 13:00:3010import os
kjellander986ee082015-06-16 11:32:1311import platform
kjellander@webrtc.org85759802013-10-22 16:47:4012import re
kjellander986ee082015-06-16 11:32:1313import subprocess
kjellander@webrtc.org3bd41562014-09-01 11:06:3714import sys
kjellander@webrtc.org85759802013-10-22 16:47:4015
16
kjellander@webrtc.org0fcaf992015-11-26 14:24:5217# Directories that will be scanned by cpplint by the presubmit script.
18CPPLINT_DIRS = [
Fredrik Solenbergea073732015-12-01 10:26:3419 'webrtc/audio',
20 'webrtc/call',
jbauch0f2e9392015-12-10 11:11:4221 'webrtc/common_video',
jbauch70625e52015-12-09 22:18:1422 'webrtc/examples',
aleloidf9e4d92016-08-08 17:26:0923 'webrtc/modules/audio_mixer',
jbauchf91e6d02016-01-25 07:05:2124 'webrtc/modules/bitrate_controller',
Stefan Holmer80e12072016-02-23 12:30:4225 'webrtc/modules/congestion_controller',
jbauchd2a22962016-02-09 07:18:2526 'webrtc/modules/pacing',
terelius8f09f172015-12-15 08:51:5427 'webrtc/modules/remote_bitrate_estimator',
danilchap377b5e62015-12-15 12:33:4428 'webrtc/modules/rtp_rtcp',
philipel5908c712015-12-21 16:23:2029 'webrtc/modules/video_coding',
mflodman88eeac42015-12-08 08:21:2830 'webrtc/modules/video_processing',
jbauch0f2e9392015-12-10 11:11:4231 'webrtc/tools',
mflodmand1590b22015-12-09 15:07:5932 'webrtc/video',
kjellander@webrtc.org0fcaf992015-11-26 14:24:5233]
34
jbauchc4e3ead2016-02-19 08:25:5535# 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 09:32:1242# - whitespace/operators: Same as above (doesn't seem sufficient to eliminate
43# all move-related errors).
jbauchc4e3ead2016-02-19 08:25:5544BLACKLIST_LINT_FILTERS = [
45 '-build/c++11',
kjellandere5a87a52016-04-27 09:32:1246 '-whitespace/operators',
jbauchc4e3ead2016-02-19 08:25:5547]
48
kjellanderfd595232015-12-04 10:44:0949# 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-03 07:56:1456NATIVE_API_DIRS = (
kjellander53047c92015-12-03 07:56:1457 'webrtc',
kjellanderdd705472016-06-09 18:17:2758 'webrtc/api',
59 'webrtc/media',
kjellander53047c92015-12-03 07:56:1460 'webrtc/modules/audio_device/include',
kjellanderdd705472016-06-09 18:17:2761 '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 18:17:2766 'webrtc/base',
67 'webrtc/common_audio/include',
68 'webrtc/modules/audio_coding/include',
69 'webrtc/modules/audio_conference_mixer/include',
kjellander53047c92015-12-03 07:56:1470 'webrtc/modules/audio_processing/include',
71 'webrtc/modules/bitrate_controller/include',
Stefan Holmer80e12072016-02-23 12:30:4272 'webrtc/modules/congestion_controller/include',
kjellander53047c92015-12-03 07:56:1473 'webrtc/modules/include',
74 'webrtc/modules/remote_bitrate_estimator/include',
75 'webrtc/modules/rtp_rtcp/include',
kjellanderdd705472016-06-09 18:17:2776 'webrtc/modules/rtp_rtcp/source',
kjellander53047c92015-12-03 07:56:1477 '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 18:17:2783 'webrtc/system_wrappers/include',
kjellander53047c92015-12-03 07:56:1484 'webrtc/voice_engine/include',
85)
kjellanderdd705472016-06-09 18:17:2786API_DIRS = NATIVE_API_DIRS[:] + LEGACY_API_DIRS[:]
kjellander53047c92015-12-03 07:56:1487
88
89def _VerifyNativeApiHeadersListIsValid(input_api, output_api):
90 """Ensures the list of native API header directories is up to date."""
91 non_existing_paths = []
92 native_api_full_paths = [
93 input_api.os_path.join(input_api.PresubmitLocalPath(),
kjellanderdd705472016-06-09 18:17:2794 *path.split('/')) for path in API_DIRS]
kjellander53047c92015-12-03 07:56:1495 for path in native_api_full_paths:
96 if not os.path.isdir(path):
97 non_existing_paths.append(path)
98 if non_existing_paths:
99 return [output_api.PresubmitError(
100 'Directories to native API headers have changed which has made the '
101 'list in PRESUBMIT.py outdated.\nPlease update it to the current '
102 'location of our native APIs.',
103 non_existing_paths)]
104 return []
105
kwibergeb133022016-04-07 14:41:48106api_change_msg = """
107You seem to be changing native API header files. Please make sure that you:
108 1. Make compatible changes that don't break existing clients.
109 2. Mark the old stuff as deprecated.
110 3. Create a timeline and plan for when the deprecated stuff will be
111 removed. (The amount of time we give users to change their code
112 should be informed by how much work it is for them. If they just
113 need to replace one name with another or something equally
114 simple, 1-2 weeks might be good; if they need to do serious work,
115 up to 3 months may be called for.)
116 4. Update/inform existing downstream code owners to stop using the
117 deprecated stuff. (Send announcements to
118 discuss-webrtc@googlegroups.com and webrtc-users@google.com.)
119 5. Remove the deprecated stuff, once the agreed-upon amount of time
120 has passed.
121Related files:
122"""
kjellander53047c92015-12-03 07:56:14123
124def _CheckNativeApiHeaderChanges(input_api, output_api):
125 """Checks to remind proper changing of native APIs."""
126 files = []
127 for f in input_api.AffectedSourceFiles(input_api.FilterSourceFile):
128 if f.LocalPath().endswith('.h'):
kjellanderdd705472016-06-09 18:17:27129 for path in API_DIRS:
kjellander53047c92015-12-03 07:56:14130 if os.path.dirname(f.LocalPath()) == path:
131 files.append(f)
132
133 if files:
kwibergeb133022016-04-07 14:41:48134 return [output_api.PresubmitNotifyResult(api_change_msg, files)]
kjellander53047c92015-12-03 07:56:14135 return []
136
kjellander@webrtc.org0fcaf992015-11-26 14:24:52137
kjellander@webrtc.org51198f12012-02-21 17:53:46138def _CheckNoIOStreamInHeaders(input_api, output_api):
139 """Checks to make sure no .h files include <iostream>."""
140 files = []
141 pattern = input_api.re.compile(r'^#include\s*<iostream>',
142 input_api.re.MULTILINE)
143 for f in input_api.AffectedSourceFiles(input_api.FilterSourceFile):
144 if not f.LocalPath().endswith('.h'):
145 continue
146 contents = input_api.ReadFile(f)
147 if pattern.search(contents):
148 files.append(f)
149
150 if len(files):
Henrik Kjellander57e5fd22015-05-25 10:55:39151 return [output_api.PresubmitError(
kjellander@webrtc.org51198f12012-02-21 17:53:46152 'Do not #include <iostream> in header files, since it inserts static ' +
153 'initialization into every file including the header. Instead, ' +
154 '#include <ostream>. See http://crbug.com/94794',
Henrik Kjellander57e5fd22015-05-25 10:55:39155 files)]
kjellander@webrtc.org51198f12012-02-21 17:53:46156 return []
157
kjellander@webrtc.orge4158642014-08-06 09:11:18158
kjellander@webrtc.org51198f12012-02-21 17:53:46159def _CheckNoFRIEND_TEST(input_api, output_api):
160 """Make sure that gtest's FRIEND_TEST() macro is not used, the
161 FRIEND_TEST_ALL_PREFIXES() macro from testsupport/gtest_prod_util.h should be
162 used instead since that allows for FLAKY_, FAILS_ and DISABLED_ prefixes."""
163 problems = []
164
165 file_filter = lambda f: f.LocalPath().endswith(('.cc', '.h'))
166 for f in input_api.AffectedFiles(file_filter=file_filter):
167 for line_num, line in f.ChangedContents():
168 if 'FRIEND_TEST(' in line:
169 problems.append(' %s:%d' % (f.LocalPath(), line_num))
170
171 if not problems:
172 return []
173 return [output_api.PresubmitPromptWarning('WebRTC\'s code should not use '
174 'gtest\'s FRIEND_TEST() macro. Include testsupport/gtest_prod_util.h and '
175 'use FRIEND_TEST_ALL_PREFIXES() instead.\n' + '\n'.join(problems))]
176
kjellander@webrtc.orge4158642014-08-06 09:11:18177
kjellander@webrtc.org0fcaf992015-11-26 14:24:52178def _IsLintWhitelisted(whitelist_dirs, file_path):
179 """ Checks if a file is whitelisted for lint check."""
180 for path in whitelist_dirs:
181 if os.path.dirname(file_path).startswith(path):
182 return True
183 return False
184
185
mflodman@webrtc.org2a452092012-07-01 05:55:23186def _CheckApprovedFilesLintClean(input_api, output_api,
187 source_file_filter=None):
188 """Checks that all new or whitelisted .cc and .h files pass cpplint.py.
kjellander@webrtc.org51198f12012-02-21 17:53:46189 This check is based on _CheckChangeLintsClean in
190 depot_tools/presubmit_canned_checks.py but has less filters and only checks
191 added files."""
192 result = []
193
194 # Initialize cpplint.
195 import cpplint
196 # Access to a protected member _XX of a client class
197 # pylint: disable=W0212
198 cpplint._cpplint_state.ResetErrorCounts()
199
jbauchc4e3ead2016-02-19 08:25:55200 lint_filters = cpplint._Filters()
201 lint_filters.extend(BLACKLIST_LINT_FILTERS)
202 cpplint._SetFilters(','.join(lint_filters))
203
kjellander@webrtc.org0fcaf992015-11-26 14:24:52204 # Create a platform independent whitelist for the CPPLINT_DIRS.
205 whitelist_dirs = [input_api.os_path.join(*path.split('/'))
206 for path in CPPLINT_DIRS]
207
kjellander@webrtc.org51198f12012-02-21 17:53:46208 # Use the strictest verbosity level for cpplint.py (level 1) which is the
209 # default when running cpplint.py from command line.
210 # To make it possible to work with not-yet-converted code, we're only applying
mflodman@webrtc.org2a452092012-07-01 05:55:23211 # it to new (or moved/renamed) files and files listed in LINT_FOLDERS.
kjellander@webrtc.org51198f12012-02-21 17:53:46212 verbosity_level = 1
213 files = []
214 for f in input_api.AffectedSourceFiles(source_file_filter):
Henrik Kjellander57e5fd22015-05-25 10:55:39215 # Note that moved/renamed files also count as added.
kjellander@webrtc.org0fcaf992015-11-26 14:24:52216 if f.Action() == 'A' or _IsLintWhitelisted(whitelist_dirs, f.LocalPath()):
kjellander@webrtc.org51198f12012-02-21 17:53:46217 files.append(f.AbsoluteLocalPath())
mflodman@webrtc.org2a452092012-07-01 05:55:23218
kjellander@webrtc.org51198f12012-02-21 17:53:46219 for file_name in files:
220 cpplint.ProcessFile(file_name, verbosity_level)
221
222 if cpplint._cpplint_state.error_count > 0:
223 if input_api.is_committing:
224 # TODO(kjellander): Change back to PresubmitError below when we're
225 # confident with the lint settings.
226 res_type = output_api.PresubmitPromptWarning
227 else:
228 res_type = output_api.PresubmitPromptWarning
229 result = [res_type('Changelist failed cpplint.py check.')]
230
231 return result
232
henrike@webrtc.org83fe69d2014-09-30 21:54:26233def _CheckNoRtcBaseDeps(input_api, gyp_files, output_api):
234 pattern = input_api.re.compile(r"base.gyp:rtc_base\s*'")
235 violating_files = []
236 for f in gyp_files:
henrike@webrtc.org36b0c1a2014-10-01 14:40:58237 gyp_exceptions = (
maxmorinec623742016-09-15 12:11:55238 'audio_device.gypi',
henrike@webrtc.org36b0c1a2014-10-01 14:40:58239 'base_tests.gyp',
240 'desktop_capture.gypi',
kjellander@webrtc.orge7237282015-02-26 11:12:17241 'p2p.gyp',
tkchin9eeb6242016-04-27 08:54:20242 'sdk.gyp',
henrike@webrtc.org36b0c1a2014-10-01 14:40:58243 'webrtc_test_common.gyp',
244 'webrtc_tests.gypi',
245 )
246 if f.LocalPath().endswith(gyp_exceptions):
247 continue
henrike@webrtc.org83fe69d2014-09-30 21:54:26248 contents = input_api.ReadFile(f)
249 if pattern.search(contents):
250 violating_files.append(f)
251 if violating_files:
252 return [output_api.PresubmitError(
253 'Depending on rtc_base is not allowed. Change your dependency to '
254 'rtc_base_approved and possibly sanitize and move the desired source '
255 'file(s) to rtc_base_approved.\nChanged GYP files:',
256 items=violating_files)]
257 return []
kjellander@webrtc.orge4158642014-08-06 09:11:18258
ehmaldonado5b1ba082016-09-02 12:51:08259def _CheckNoRtcBaseDepsGn(input_api, gn_files, output_api):
260 pattern = input_api.re.compile(r'base:rtc_base\s*"')
261 violating_files = []
262 for f in gn_files:
263 gn_exceptions = (
maxmorinec623742016-09-15 12:11:55264 os.path.join('audio_device', 'BUILD.gn'),
ehmaldonado5b1ba082016-09-02 12:51:08265 os.path.join('base_tests', 'BUILD.gn'),
266 os.path.join('desktop_capture', 'BUILD.gn'),
267 os.path.join('p2p', 'BUILD.gn'),
268 os.path.join('sdk', 'BUILD.gn'),
269 os.path.join('webrtc_test_common', 'BUILD.gn'),
270 os.path.join('webrtc_tests', 'BUILD.gn'),
271
272 # TODO(ehmaldonado): Clean up references to rtc_base in these files.
273 # See https://bugs.chromium.org/p/webrtc/issues/detail?id=3806
274 os.path.join('webrtc', 'BUILD.gn'),
275 os.path.join('xmllite', 'BUILD.gn'),
276 os.path.join('xmpp', 'BUILD.gn'),
277 os.path.join('modules', 'BUILD.gn'),
278 os.path.join('audio_device', 'BUILD.gn'),
279 os.path.join('pc', 'BUILD.gn'),
280 )
281 if f.LocalPath().endswith(gn_exceptions):
282 continue
283 contents = input_api.ReadFile(f)
284 if pattern.search(contents):
285 violating_files.append(f)
286 if violating_files:
287 return [output_api.PresubmitError(
288 'Depending on rtc_base is not allowed. Change your dependency to '
289 'rtc_base_approved and possibly sanitize and move the desired source '
290 'file(s) to rtc_base_approved.\nChanged GN files:',
291 items=violating_files)]
292 return []
293
kjellander@webrtc.orgf68ffca2015-01-27 13:13:24294def _CheckNoSourcesAboveGyp(input_api, gyp_files, output_api):
295 # Disallow referencing source files with paths above the GYP file location.
kjellander@webrtc.org74290b92016-06-15 15:19:06296 source_pattern = input_api.re.compile(r'\'sources\'.*?\[(.*?)\]',
kjellander@webrtc.orgf68ffca2015-01-27 13:13:24297 re.MULTILINE | re.DOTALL)
kjellander@webrtc.orga33f05e2015-01-29 14:29:45298 file_pattern = input_api.re.compile(r"'((\.\./.*?)|(<\(webrtc_root\).*?))'")
kjellander@webrtc.orgf68ffca2015-01-27 13:13:24299 violating_gyp_files = set()
300 violating_source_entries = []
301 for gyp_file in gyp_files:
kjellanderc61635c2016-02-02 10:30:07302 if 'supplement.gypi' in gyp_file.LocalPath():
303 # Exclude supplement.gypi from this check, as the LSan and TSan
304 # suppression files are located in a different location.
305 continue
kjellander@webrtc.orgf68ffca2015-01-27 13:13:24306 contents = input_api.ReadFile(gyp_file)
307 for source_block_match in source_pattern.finditer(contents):
kjellander@webrtc.orgc98f6f32015-03-04 07:08:11308 # Find all source list entries starting with ../ in the source block
309 # (exclude overrides entries).
kjellander@webrtc.org74290b92016-06-15 15:19:06310 for file_list_match in file_pattern.finditer(source_block_match.group(1)):
311 source_file = file_list_match.group(1)
kjellander@webrtc.orgc98f6f32015-03-04 07:08:11312 if 'overrides/' not in source_file:
313 violating_source_entries.append(source_file)
314 violating_gyp_files.add(gyp_file)
kjellander@webrtc.orgf68ffca2015-01-27 13:13:24315 if violating_gyp_files:
316 return [output_api.PresubmitError(
317 'Referencing source files above the directory of the GYP file is not '
318 'allowed. Please introduce new GYP targets and/or GYP files in the '
319 'proper location instead.\n'
320 'Invalid source entries:\n'
321 '%s\n'
322 'Violating GYP files:' % '\n'.join(violating_source_entries),
323 items=violating_gyp_files)]
324 return []
325
ehmaldonado5b1ba082016-09-02 12:51:08326def _CheckNoSourcesAboveGn(input_api, gn_files, output_api):
327 # Disallow referencing source files with paths above the GN file location.
328 source_pattern = input_api.re.compile(r' +sources \+?= \[(.*?)\]',
329 re.MULTILINE | re.DOTALL)
330 file_pattern = input_api.re.compile(r'"((\.\./.*?)|(//.*?))"')
331 violating_gn_files = set()
332 violating_source_entries = []
333 for gn_file in gn_files:
334 contents = input_api.ReadFile(gn_file)
335 for source_block_match in source_pattern.finditer(contents):
336 # Find all source list entries starting with ../ in the source block
337 # (exclude overrides entries).
338 for file_list_match in file_pattern.finditer(source_block_match.group(1)):
339 source_file = file_list_match.group(1)
340 if 'overrides/' not in source_file:
341 violating_source_entries.append(source_file)
342 violating_gn_files.add(gn_file)
343 if violating_gn_files:
344 return [output_api.PresubmitError(
345 'Referencing source files above the directory of the GN file is not '
346 'allowed. Please introduce new GYP targets and/or GN files in the '
347 'proper location instead.\n'
348 'Invalid source entries:\n'
349 '%s\n'
350 'Violating GN files:' % '\n'.join(violating_source_entries),
351 items=violating_gn_files)]
352 return []
353
kjellander@webrtc.orge4158642014-08-06 09:11:18354def _CheckGypChanges(input_api, output_api):
355 source_file_filter = lambda x: input_api.FilterSourceFile(
356 x, white_list=(r'.+\.(gyp|gypi)$',))
357
358 gyp_files = []
359 for f in input_api.AffectedSourceFiles(source_file_filter):
kjellander@webrtc.org3398a4a2014-11-24 10:05:37360 if f.LocalPath().startswith('webrtc'):
361 gyp_files.append(f)
kjellander@webrtc.orge4158642014-08-06 09:11:18362
363 result = []
364 if gyp_files:
365 result.append(output_api.PresubmitNotifyResult(
366 'As you\'re changing GYP files: please make sure corresponding '
367 'BUILD.gn files are also updated.\nChanged GYP files:',
368 items=gyp_files))
henrike@webrtc.org83fe69d2014-09-30 21:54:26369 result.extend(_CheckNoRtcBaseDeps(input_api, gyp_files, output_api))
kjellander@webrtc.orgf68ffca2015-01-27 13:13:24370 result.extend(_CheckNoSourcesAboveGyp(input_api, gyp_files, output_api))
kjellander@webrtc.orge4158642014-08-06 09:11:18371 return result
372
ehmaldonado5b1ba082016-09-02 12:51:08373def _CheckGnChanges(input_api, output_api):
374 source_file_filter = lambda x: input_api.FilterSourceFile(
375 x, white_list=(r'.+\.(gn|gni)$',))
376
377 gn_files = []
378 for f in input_api.AffectedSourceFiles(source_file_filter):
379 if f.LocalPath().startswith('webrtc'):
380 gn_files.append(f)
381
382 result = []
383 if gn_files:
384 result.append(output_api.PresubmitNotifyResult(
385 'As you\'re changing GN files: please make sure corresponding GYP'
386 'files are also updated.\nChanged GN files:',
387 items=gn_files))
388 result.extend(_CheckNoRtcBaseDepsGn(input_api, gn_files, output_api))
389 result.extend(_CheckNoSourcesAboveGn(input_api, gn_files, output_api))
390 return result
391
kjellander@webrtc.org3bd41562014-09-01 11:06:37392def _CheckUnwantedDependencies(input_api, output_api):
393 """Runs checkdeps on #include statements added in this
394 change. Breaking - rules is an error, breaking ! rules is a
395 warning.
396 """
397 # Copied from Chromium's src/PRESUBMIT.py.
398
399 # We need to wait until we have an input_api object and use this
400 # roundabout construct to import checkdeps because this file is
401 # eval-ed and thus doesn't have __file__.
402 original_sys_path = sys.path
403 try:
kjellander@webrtc.orgaefe61a2014-12-08 13:00:30404 checkdeps_path = input_api.os_path.join(input_api.PresubmitLocalPath(),
405 'buildtools', 'checkdeps')
406 if not os.path.exists(checkdeps_path):
407 return [output_api.PresubmitError(
408 'Cannot find checkdeps at %s\nHave you run "gclient sync" to '
409 'download Chromium and setup the symlinks?' % checkdeps_path)]
410 sys.path.append(checkdeps_path)
kjellander@webrtc.org3bd41562014-09-01 11:06:37411 import checkdeps
412 from cpp_checker import CppChecker
413 from rules import Rule
414 finally:
415 # Restore sys.path to what it was before.
416 sys.path = original_sys_path
417
418 added_includes = []
419 for f in input_api.AffectedFiles():
420 if not CppChecker.IsCppFile(f.LocalPath()):
421 continue
422
Henrik Kjellander57e5fd22015-05-25 10:55:39423 changed_lines = [line for _, line in f.ChangedContents()]
kjellander@webrtc.org3bd41562014-09-01 11:06:37424 added_includes.append([f.LocalPath(), changed_lines])
425
426 deps_checker = checkdeps.DepsChecker(input_api.PresubmitLocalPath())
427
428 error_descriptions = []
429 warning_descriptions = []
430 for path, rule_type, rule_description in deps_checker.CheckAddedCppIncludes(
431 added_includes):
432 description_with_path = '%s\n %s' % (path, rule_description)
433 if rule_type == Rule.DISALLOW:
434 error_descriptions.append(description_with_path)
435 else:
436 warning_descriptions.append(description_with_path)
437
438 results = []
439 if error_descriptions:
440 results.append(output_api.PresubmitError(
441 'You added one or more #includes that violate checkdeps rules.',
442 error_descriptions))
443 if warning_descriptions:
444 results.append(output_api.PresubmitPromptOrNotify(
445 'You added one or more #includes of files that are temporarily\n'
446 'allowed but being removed. Can you avoid introducing the\n'
447 '#include? See relevant DEPS file(s) for details and contacts.',
448 warning_descriptions))
449 return results
450
kjellanderd1e26a92016-09-19 15:11:16451def _CheckChangeHasBugField(input_api, output_api):
452 """Requires that the changelist have a BUG= field.
453
454 This check is stricter than the one in depot_tools/presubmit_canned_checks.py
455 since it fails the presubmit if the BUG= field is missing or doesn't contain
456 a bug reference.
457 """
458 if input_api.change.BUG:
459 return []
460 else:
461 return [output_api.PresubmitError(
462 'The BUG=[bug number] field is mandatory. Please create a bug and '
463 'reference it using either of:\n'
464 ' * https://bugs.webrtc.org - reference it using BUG=webrtc:XXXX\n'
465 ' * https://crbug.com - reference it using BUG=chromium:XXXXXX')]
kjellander@webrtc.orge4158642014-08-06 09:11:18466
kjellander569cf942016-02-11 13:02:59467def _CheckJSONParseErrors(input_api, output_api):
468 """Check that JSON files do not contain syntax errors."""
469
470 def FilterFile(affected_file):
471 return input_api.os_path.splitext(affected_file.LocalPath())[1] == '.json'
472
473 def GetJSONParseError(input_api, filename):
474 try:
475 contents = input_api.ReadFile(filename)
476 input_api.json.loads(contents)
477 except ValueError as e:
478 return e
479 return None
480
481 results = []
482 for affected_file in input_api.AffectedFiles(
483 file_filter=FilterFile, include_deletes=False):
484 parse_error = GetJSONParseError(input_api,
485 affected_file.AbsoluteLocalPath())
486 if parse_error:
487 results.append(output_api.PresubmitError('%s could not be parsed: %s' %
488 (affected_file.LocalPath(), parse_error)))
489 return results
490
491
Henrik Kjellander8d3ad822015-05-26 17:52:05492def _RunPythonTests(input_api, output_api):
493 def join(*args):
494 return input_api.os_path.join(input_api.PresubmitLocalPath(), *args)
495
496 test_directories = [
497 join('tools', 'autoroller', 'unittests'),
aleloi7ebbf902016-06-20 14:39:15498 join('webrtc', 'tools', 'py_event_log_analyzer'),
Henrik Kjellander8d3ad822015-05-26 17:52:05499 ]
500
501 tests = []
502 for directory in test_directories:
503 tests.extend(
504 input_api.canned_checks.GetUnitTestsInDirectory(
505 input_api,
506 output_api,
507 directory,
508 whitelist=[r'.+_test\.py$']))
509 return input_api.RunTests(tests, parallel=True)
510
511
andrew@webrtc.org53df1362012-01-26 21:24:23512def _CommonChecks(input_api, output_api):
513 """Checks common to both upload and commit."""
niklase@google.comda159d62011-05-30 11:51:34514 results = []
tkchin42f580e2015-11-27 07:18:23515 # Filter out files that are in objc or ios dirs from being cpplint-ed since
516 # they do not follow C++ lint rules.
517 black_list = input_api.DEFAULT_BLACK_LIST + (
518 r".*\bobjc[\\\/].*",
Kári Tristan Helgason3fa35172016-09-09 08:55:05519 r".*objc\.[hcm]+$",
hjon65ae2d82016-08-03 06:55:44520 r"webrtc\/build\/ios\/SDK\/.*",
tkchin42f580e2015-11-27 07:18:23521 )
522 source_file_filter = lambda x: input_api.FilterSourceFile(x, None, black_list)
523 results.extend(_CheckApprovedFilesLintClean(
524 input_api, output_api, source_file_filter))
phoglund@webrtc.org5d3713932013-03-07 09:59:43525 results.extend(input_api.canned_checks.RunPylint(input_api, output_api,
526 black_list=(r'^.*gviz_api\.py$',
527 r'^.*gaeunit\.py$',
fischman@webrtc.org33584f92013-07-25 16:43:30528 # Embedded shell-script fakes out pylint.
Henrik Kjellander14771ac2015-06-02 11:10:04529 r'^build[\\\/].*\.py$',
530 r'^buildtools[\\\/].*\.py$',
531 r'^chromium[\\\/].*\.py$',
kjellanderd620f822016-04-04 13:07:08532 r'^mojo.*[\\\/].*\.py$',
Henrik Kjellander14771ac2015-06-02 11:10:04533 r'^out.*[\\\/].*\.py$',
534 r'^testing[\\\/].*\.py$',
535 r'^third_party[\\\/].*\.py$',
Henrik Kjellander14771ac2015-06-02 11:10:04536 r'^tools[\\\/]clang[\\\/].*\.py$',
537 r'^tools[\\\/]generate_library_loader[\\\/].*\.py$',
kjellanderd620f822016-04-04 13:07:08538 r'^tools[\\\/]generate_stubs[\\\/].*\.py$',
Henrik Kjellander14771ac2015-06-02 11:10:04539 r'^tools[\\\/]gn[\\\/].*\.py$',
540 r'^tools[\\\/]gyp[\\\/].*\.py$',
Henrik Kjellanderd6d27e72015-09-25 20:19:11541 r'^tools[\\\/]isolate_driver.py$',
kjellanderd620f822016-04-04 13:07:08542 r'^tools[\\\/]mb[\\\/].*\.py$',
Henrik Kjellander14771ac2015-06-02 11:10:04543 r'^tools[\\\/]protoc_wrapper[\\\/].*\.py$',
544 r'^tools[\\\/]python[\\\/].*\.py$',
545 r'^tools[\\\/]python_charts[\\\/]data[\\\/].*\.py$',
546 r'^tools[\\\/]refactoring[\\\/].*\.py$',
547 r'^tools[\\\/]swarming_client[\\\/].*\.py$',
548 r'^tools[\\\/]vim[\\\/].*\.py$',
phoglund@webrtc.org5d3713932013-03-07 09:59:43549 # TODO(phoglund): should arguably be checked.
Henrik Kjellander14771ac2015-06-02 11:10:04550 r'^tools[\\\/]valgrind-webrtc[\\\/].*\.py$',
551 r'^tools[\\\/]valgrind[\\\/].*\.py$',
552 r'^tools[\\\/]win[\\\/].*\.py$',
553 r'^xcodebuild.*[\\\/].*\.py$',),
phoglund@webrtc.org5d3713932013-03-07 09:59:43554 disabled_warnings=['F0401', # Failed to import x
555 'E0611', # No package y in x
556 'W0232', # Class has no __init__ method
Henrik Kjellander57e5fd22015-05-25 10:55:39557 ],
558 pylintrc='pylintrc'))
kjellander569cf942016-02-11 13:02:59559
nisse3d21e232016-09-02 10:07:06560 # TODO(nisse): talk/ is no more, so make below checks simpler?
Henrik Kjellander57e5fd22015-05-25 10:55:39561 # WebRTC can't use the presubmit_canned_checks.PanProjectChecks function since
562 # we need to have different license checks in talk/ and webrtc/ directories.
563 # Instead, hand-picked checks are included below.
Henrik Kjellander63224672015-09-08 06:03:56564
tkchin3cd9a302016-06-08 19:40:28565 # .m and .mm files are ObjC files. For simplicity we will consider .h files in
566 # ObjC subdirectories ObjC headers.
567 objc_filter_list = (r'.+\.m$', r'.+\.mm$', r'.+objc\/.+\.h$')
Henrik Kjellander63224672015-09-08 06:03:56568 # Skip long-lines check for DEPS, GN and GYP files.
tkchin3cd9a302016-06-08 19:40:28569 build_file_filter_list = (r'.+\.gyp$', r'.+\.gypi$', r'.+\.gn$', r'.+\.gni$',
570 'DEPS')
571 eighty_char_sources = lambda x: input_api.FilterSourceFile(x,
572 black_list=build_file_filter_list + objc_filter_list)
573 hundred_char_sources = lambda x: input_api.FilterSourceFile(x,
574 white_list=objc_filter_list)
andrew@webrtc.org2442de12012-01-23 17:45:41575 results.extend(input_api.canned_checks.CheckLongLines(
tkchin3cd9a302016-06-08 19:40:28576 input_api, output_api, maxlen=80, source_file_filter=eighty_char_sources))
577 results.extend(input_api.canned_checks.CheckLongLines(
578 input_api, output_api, maxlen=100,
579 source_file_filter=hundred_char_sources))
580
andrew@webrtc.org2442de12012-01-23 17:45:41581 results.extend(input_api.canned_checks.CheckChangeHasNoTabs(
582 input_api, output_api))
andrew@webrtc.org53df1362012-01-26 21:24:23583 results.extend(input_api.canned_checks.CheckChangeHasNoStrayWhitespace(
584 input_api, output_api))
585 results.extend(input_api.canned_checks.CheckChangeTodoHasOwner(
586 input_api, output_api))
kjellander53047c92015-12-03 07:56:14587 results.extend(_CheckNativeApiHeaderChanges(input_api, output_api))
kjellander@webrtc.org51198f12012-02-21 17:53:46588 results.extend(_CheckNoIOStreamInHeaders(input_api, output_api))
589 results.extend(_CheckNoFRIEND_TEST(input_api, output_api))
kjellander@webrtc.orge4158642014-08-06 09:11:18590 results.extend(_CheckGypChanges(input_api, output_api))
ehmaldonado5b1ba082016-09-02 12:51:08591 results.extend(_CheckGnChanges(input_api, output_api))
kjellander@webrtc.org3bd41562014-09-01 11:06:37592 results.extend(_CheckUnwantedDependencies(input_api, output_api))
kjellander569cf942016-02-11 13:02:59593 results.extend(_CheckJSONParseErrors(input_api, output_api))
Henrik Kjellander8d3ad822015-05-26 17:52:05594 results.extend(_RunPythonTests(input_api, output_api))
andrew@webrtc.org53df1362012-01-26 21:24:23595 return results
andrew@webrtc.org2442de12012-01-23 17:45:41596
kjellander@webrtc.orge4158642014-08-06 09:11:18597
andrew@webrtc.org53df1362012-01-26 21:24:23598def CheckChangeOnUpload(input_api, output_api):
599 results = []
600 results.extend(_CommonChecks(input_api, output_api))
Henrik Kjellander57e5fd22015-05-25 10:55:39601 results.extend(
602 input_api.canned_checks.CheckGNFormatted(input_api, output_api))
niklase@google.comda159d62011-05-30 11:51:34603 return results
604
kjellander@webrtc.orge4158642014-08-06 09:11:18605
andrew@webrtc.org2442de12012-01-23 17:45:41606def CheckChangeOnCommit(input_api, output_api):
niklase@google.com1198db92011-06-09 07:07:24607 results = []
andrew@webrtc.org53df1362012-01-26 21:24:23608 results.extend(_CommonChecks(input_api, output_api))
kjellander53047c92015-12-03 07:56:14609 results.extend(_VerifyNativeApiHeadersListIsValid(input_api, output_api))
niklase@google.com1198db92011-06-09 07:07:24610 results.extend(input_api.canned_checks.CheckOwners(input_api, output_api))
andrew@webrtc.org53df1362012-01-26 21:24:23611 results.extend(input_api.canned_checks.CheckChangeWasUploaded(
612 input_api, output_api))
613 results.extend(input_api.canned_checks.CheckChangeHasDescription(
614 input_api, output_api))
kjellanderd1e26a92016-09-19 15:11:16615 results.extend(_CheckChangeHasBugField(input_api, output_api))
kjellander@webrtc.org51198f12012-02-21 17:53:46616 results.extend(input_api.canned_checks.CheckChangeHasTestField(
617 input_api, output_api))
kjellander@webrtc.org12cb88c2014-02-13 11:53:43618 results.extend(input_api.canned_checks.CheckTreeIsOpen(
619 input_api, output_api,
620 json_url='http://webrtc-status.appspot.com/current?format=json'))
niklase@google.com1198db92011-06-09 07:07:24621 return results
kjellander@webrtc.org85759802013-10-22 16:47:40622
kjellander@webrtc.orge4158642014-08-06 09:11:18623
kjellander@webrtc.org85759802013-10-22 16:47:40624# pylint: disable=W0613
kjellander@webrtc.orgc7b8b2f2014-04-03 20:19:36625def GetPreferredTryMasters(project, change):
kjellander986ee082015-06-16 11:32:13626 cq_config_path = os.path.join(
tandrii04465d22015-06-20 11:00:49627 change.RepositoryRoot(), 'infra', 'config', 'cq.cfg')
kjellander986ee082015-06-16 11:32:13628 # commit_queue.py below is a script in depot_tools directory, which has a
629 # 'builders' command to retrieve a list of CQ builders from the CQ config.
630 is_win = platform.system() == 'Windows'
631 masters = json.loads(subprocess.check_output(
632 ['commit_queue', 'builders', cq_config_path], shell=is_win))
kjellander@webrtc.org85759802013-10-22 16:47:40633
kjellander986ee082015-06-16 11:32:13634 try_config = {}
635 for master in masters:
636 try_config.setdefault(master, {})
637 for builder in masters[master]:
638 if 'presubmit' in builder:
639 # Do not trigger presubmit builders, since they're likely to fail
640 # (e.g. OWNERS checks before finished code review), and we're running
641 # local presubmit anyway.
642 pass
643 else:
644 try_config[master][builder] = ['defaulttests']
kjellander@webrtc.org85759802013-10-22 16:47:40645
kjellander986ee082015-06-16 11:32:13646 return try_config