blob: 7de25ab64b87132e84fc59a1e750e2ec55a22634 [file] [log] [blame]
Kent Tamurac3e44312018-04-07 16:30:241# Copyright (c) 2013 The Chromium Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
Kent Tamurac3e44312018-04-07 16:30:244"""Top-level presubmit script for Blink.
5
Daniel McArdlef8838172019-12-06 21:36:486See https://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts
Kent Tamurac3e44312018-04-07 16:30:247for more details about the presubmit API built into gcl.
8"""
9
10import imp
11import inspect
12import os
Daniel McArdlef8838172019-12-06 21:36:4813import re
Kent Tamurac3e44312018-04-07 16:30:2414
Fabrice de Gans954c9922021-06-23 15:26:1215USE_PYTHON3 = True
16
Kent Tamurac3e44312018-04-07 16:30:2417try:
18 # pylint: disable=C0103
19 audit_non_blink_usage = imp.load_source(
20 'audit_non_blink_usage',
Fergal Daly5f61cbe2018-10-05 04:30:3421 os.path.join(os.path.dirname(inspect.stack()[0][1]),
22 'tools/blinkpy/presubmit/audit_non_blink_usage.py'))
Kent Tamurac3e44312018-04-07 16:30:2423except IOError:
Kent Tamurac9bbe0a2020-12-22 14:39:5624 # One of the presubmit upload tests tries to exec this script, which
25 # doesn't interact so well with the import hack... just ignore the
26 # exception here and hope for the best.
Kent Tamurac3e44312018-04-07 16:30:2427 pass
28
Kent Tamurac3e44312018-04-07 16:30:2429_EXCLUDED_PATHS = (
Robert Maad740d92019-06-03 13:18:1230 # These are third-party dependencies that we don't directly control.
31 r'^third_party[\\/]blink[\\/]tools[\\/]blinkpy[\\/]third_party[\\/]wpt[\\/]wpt[\\/].*',
Robert Maad740d92019-06-03 13:18:1232 r'^third_party[\\/]blink[\\/]web_tests[\\/]external[\\/]wpt[\\/]resources[\\/]webidl2[\\/].*',
Kent Tamurac3e44312018-04-07 16:30:2433)
34
35
36def _CheckForWrongMojomIncludes(input_api, output_api):
37 # In blink the code should either use -blink.h or -shared.h mojom
38 # headers, except in public where only -shared.h headers should be
39 # used to avoid exporting Blink types outside Blink.
40 def source_file_filter(path):
Kent Tamurac9bbe0a2020-12-22 14:39:5641 return input_api.FilterSourceFile(
42 path,
43 files_to_skip=[
Dave Tapuskacf95aaa2022-07-20 17:00:5444 r'.*_test.*\.(cc|h)$',
Matt Menke132d70e2021-06-29 01:19:2845 r'third_party[\\/]blink[\\/]common[\\/]',
46 r'third_party[\\/]blink[\\/]public[\\/]common[\\/]',
47 r'third_party[\\/]blink[\\/]renderer[\\/]platform[\\/]loader[\\/]fetch[\\/]url_loader[\\/]',
Yuzu Saijoe12e7ae2022-08-22 05:56:5548 r'third_party[\\/]blink[\\/]renderer[\\/]core[\\/]frame[\\/]web_view_impl.*\.(cc|h)$',
Dave Tapuskacf95aaa2022-07-20 17:00:5449 r'third_party[\\/]blink[\\/]renderer[\\/]core[\\/]frame[\\/]web.*frame.*\.(cc|h)$',
Kent Tamurac9bbe0a2020-12-22 14:39:5650 ])
Kent Tamurac3e44312018-04-07 16:30:2451
Dave Tapuska8cc25392020-01-22 18:36:4852 pattern = input_api.re.compile(r'#include\s+[<"](.+)\.mojom(.*)\.h[>"]')
Kent Tamurac3e44312018-04-07 16:30:2453 public_folder = input_api.os_path.normpath('third_party/blink/public/')
54 non_blink_mojom_errors = []
55 public_blink_mojom_errors = []
Dave Tapuska8cc25392020-01-22 18:36:4856
Kent Tamurac9bbe0a2020-12-22 14:39:5657 # Allow including specific non-blink interfaces that are used in the
58 # public C++ API. Adding to these allowed interfaces should meet the
59 # following conditions:
60 # - Its pros/cons is discussed and have consensus on
61 # platform-architecture-dev@ and/or
62 # - It uses POD types that will not import STL (or base string) types into
63 # blink (such as no strings or vectors).
Makoto Shimazu9e4b946a2020-03-09 05:19:1764 #
Kent Tamurac9bbe0a2020-12-22 14:39:5665 # So far, non-blink interfaces are allowed only for loading / loader and
66 # media interfaces so that we don't need type conversions to get through
67 # the boundary between Blink and non-Blink.
68 allowed_interfaces = (
69 'services/network/public/mojom/cross_origin_embedder_policy',
Hans Wennborga61b3042021-06-15 12:06:3170 'services/network/public/mojom/early_hints',
Kent Tamurac9bbe0a2020-12-22 14:39:5671 'services/network/public/mojom/fetch_api',
72 'services/network/public/mojom/load_timing_info',
73 'services/network/public/mojom/url_loader',
74 'services/network/public/mojom/url_loader_factory',
75 'services/network/public/mojom/url_response_head',
76 'third_party/blink/public/mojom/blob/serialized_blob',
77 'third_party/blink/public/mojom/fetch/fetch_api_request',
78 'third_party/blink/public/mojom/loader/resource_load_info',
79 'third_party/blink/public/mojom/loader/resource_load_info_notifier',
80 'third_party/blink/public/mojom/worker/subresource_loader_updater',
81 'third_party/blink/public/mojom/loader/transferrable_url_loader',
Mythri Afefc0c462021-05-26 08:37:2682 'third_party/blink/public/mojom/loader/code_cache',
Kent Tamurac9bbe0a2020-12-22 14:39:5683 'media/mojo/mojom/interface_factory', 'media/mojo/mojom/audio_decoder',
Dale Curtis4c84c0692022-05-12 21:03:1484 'media/mojo/mojom/audio_encoder', 'media/mojo/mojom/video_decoder',
Guido Urdanetaa5c57ea2021-03-02 10:53:5785 'media/mojo/mojom/media_metrics_provider')
Dave Tapuska8cc25392020-01-22 18:36:4886
Kent Tamurac3e44312018-04-07 16:30:2487 for f in input_api.AffectedFiles(file_filter=source_file_filter):
88 for line_num, line in f.ChangedContents():
89 error_list = None
Kent Tamurac3e44312018-04-07 16:30:2490 match = pattern.match(line)
Dave Tapuska8cc25392020-01-22 18:36:4891 if (match and match.group(1) not in allowed_interfaces):
Eriko Kurimoto61f12812020-01-31 08:06:5092 if match.group(2) not in ('-shared', '-forward'):
Leon Hanb6bd8e62019-05-29 03:18:2093 if f.LocalPath().startswith(public_folder):
Kent Tamurac3e44312018-04-07 16:30:2494 error_list = public_blink_mojom_errors
Kent Tamurac9bbe0a2020-12-22 14:39:5695 elif match.group(2) not in ('-blink', '-blink-forward',
96 '-blink-test-utils'):
97 # Neither -shared.h, -blink.h, -blink-forward.h nor
98 # -blink-test-utils.h.
Kent Tamurac3e44312018-04-07 16:30:2499 error_list = non_blink_mojom_errors
100
101 if error_list is not None:
Kent Tamurac9bbe0a2020-12-22 14:39:56102 error_list.append(' %s:%d %s' %
103 (f.LocalPath(), line_num, line))
Kent Tamurac3e44312018-04-07 16:30:24104
105 results = []
106 if non_blink_mojom_errors:
Kent Tamurac9bbe0a2020-12-22 14:39:56107 results.append(
108 output_api.PresubmitError(
109 'Files that include non-Blink variant mojoms found. '
110 'You must include .mojom-blink.h, .mojom-forward.h or '
111 '.mojom-shared.h instead:', non_blink_mojom_errors))
Kent Tamurac3e44312018-04-07 16:30:24112
113 if public_blink_mojom_errors:
Kent Tamurac9bbe0a2020-12-22 14:39:56114 results.append(
115 output_api.PresubmitError(
116 'Public blink headers using Blink variant mojoms found. '
117 'You must include .mojom-forward.h or .mojom-shared.h '
118 'instead:', public_blink_mojom_errors))
Kent Tamurac3e44312018-04-07 16:30:24119
120 return results
121
122
123def _CommonChecks(input_api, output_api):
124 """Checks common to both upload and commit."""
125 # We should figure out what license checks we actually want to use.
126 license_header = r'.*'
127
128 results = []
Kent Tamurac9bbe0a2020-12-22 14:39:56129 results.extend(
130 input_api.canned_checks.PanProjectChecks(
131 input_api,
132 output_api,
133 excluded_paths=_EXCLUDED_PATHS,
Bruce Dawsonae257be2022-07-22 15:48:26134 owners_check=False,
Kent Tamurac9bbe0a2020-12-22 14:39:56135 maxlen=800,
Bruce Dawsone7f7956e2022-05-03 16:42:17136 license_header=license_header,
137 global_checks=False))
Kent Tamurac3e44312018-04-07 16:30:24138 results.extend(_CheckForWrongMojomIncludes(input_api, output_api))
139 return results
140
141
Fergal Daly4fc8a212018-10-01 08:43:26142def _FilterPaths(input_api):
143 """Returns input files with certain paths removed."""
Kent Tamurac3e44312018-04-07 16:30:24144 files = []
145 for f in input_api.AffectedFiles():
146 file_path = f.LocalPath()
Fergal Daly4fc8a212018-10-01 08:43:26147 # Filter out changes in web_tests/.
Kent Tamurad9102342022-06-15 19:47:35148 if 'web_tests' + input_api.os_path.sep in file_path:
Kent Tamurac3e44312018-04-07 16:30:24149 continue
150 if '/PRESUBMIT' in file_path:
151 continue
Daniel McArdlef8838172019-12-06 21:36:48152 # Skip files that were generated by bison.
Kent Tamurac9bbe0a2020-12-22 14:39:56153 if re.search(
154 'third_party/blink/renderer/' +
155 'core/xml/xpath_grammar_generated\.(cc|h)$', file_path):
Dave Tapuska8cc25392020-01-22 18:36:48156 continue
Kent Tamurac3e44312018-04-07 16:30:24157 files.append(input_api.os_path.join('..', '..', file_path))
Fergal Daly4fc8a212018-10-01 08:43:26158 return files
159
160
161def _CheckStyle(input_api, output_api):
162 files = _FilterPaths(input_api)
Kent Tamuraf76ea8f2018-04-17 04:45:07163 # Do not call check_blink_style.py with empty affected file list if all
Kent Tamurac3e44312018-04-07 16:30:24164 # input_api.AffectedFiles got filtered.
165 if not files:
166 return []
Kent Tamurac3e44312018-04-07 16:30:24167
Fergal Daly4fc8a212018-10-01 08:43:26168 style_checker_path = input_api.os_path.join(input_api.PresubmitLocalPath(),
Kent Tamurac9bbe0a2020-12-22 14:39:56169 'tools',
170 'check_blink_style.py')
Bruce Dawson5f7cbff2022-05-25 17:36:44171 # When running git cl presubmit --all this presubmit may be asked to check
172 # ~260 files, leading to a command line that is about 17,000 characters.
173 # This goes past the Windows 8191 character cmd.exe limit and causes cryptic
174 # failures. To avoid these we break the command up into smaller pieces.
175 # Depending on how long the command is on Windows the error may be:
176 # The command line is too long.
177 # Or it may be:
178 # OSError: Execution failed with error: [WinError 206] The filename or
179 # extension is too long.
180 # The latter error comes from CreateProcess hitting its 32768 character
181 # limit.
Bruce Dawson5130baf2022-06-23 22:25:12182 files_per_command = 40 if input_api.is_windows else 1000
Fergal Daly4fc8a212018-10-01 08:43:26183 results = []
Bruce Dawson5f7cbff2022-05-25 17:36:44184 for i in range(0, len(files), files_per_command):
185 args = [
Bruce Dawson5130baf2022-06-23 22:25:12186 input_api.python3_executable, style_checker_path, '--diff-files'
Bruce Dawson5f7cbff2022-05-25 17:36:44187 ]
188 args += files[i:i + files_per_command]
189
190 try:
191 child = input_api.subprocess.Popen(
192 args, stderr=input_api.subprocess.PIPE)
193 _, stderrdata = child.communicate()
194 if child.returncode != 0:
195 results.append(
196 output_api.PresubmitError('check_blink_style.py failed',
197 [stderrdata]))
198 except Exception as e:
Kent Tamurac9bbe0a2020-12-22 14:39:56199 results.append(
Bruce Dawson5f7cbff2022-05-25 17:36:44200 output_api.PresubmitNotifyResult(
201 'Could not run check_blink_style.py', [str(e)]))
Kent Tamurac3e44312018-04-07 16:30:24202
203 return results
204
205
206def _CheckForPrintfDebugging(input_api, output_api):
207 """Generally speaking, we'd prefer not to land patches that printf
208 debug output.
209 """
210 printf_re = input_api.re.compile(r'^\s*(printf\(|fprintf\(stderr,)')
211 errors = input_api.canned_checks._FindNewViolationsOfRule(
Kent Tamurac9bbe0a2020-12-22 14:39:56212 lambda _, x: not printf_re.search(x), input_api, None)
Kent Tamurac3e44312018-04-07 16:30:24213 errors = [' * %s' % violation for violation in errors]
214 if errors:
Kent Tamurac9bbe0a2020-12-22 14:39:56215 return [
216 output_api.PresubmitPromptOrNotify(
217 'printf debugging is best debugging! That said, it might '
218 'be a good idea to drop the following occurences from '
219 'your patch before uploading:\n%s' % '\n'.join(errors))
220 ]
Kent Tamurac3e44312018-04-07 16:30:24221 return []
222
223
224def _CheckForForbiddenChromiumCode(input_api, output_api):
Kent Tamurac9bbe0a2020-12-22 14:39:56225 """Checks that Blink uses Chromium classes and namespaces only in
226 permitted code.
227 """
228 # TODO(dcheng): This is pretty similar to _FindNewViolationsOfRule.
229 # Unfortunately, that can't be used directly because it doesn't give the
230 # callable enough information (namely the path to the file), so we
231 # duplicate the logic here...
Kent Tamurac3e44312018-04-07 16:30:24232 results = []
233 for f in input_api.AffectedFiles():
234 path = f.LocalPath()
Kent Tamurac9bbe0a2020-12-22 14:39:56235 errors = audit_non_blink_usage.check(
236 path, [(i + 1, l) for i, l in enumerate(f.NewContents())])
Kent Tamurac3e44312018-04-07 16:30:24237 if errors:
238 errors = audit_non_blink_usage.check(path, f.ChangedContents())
239 if errors:
Fergal Daly5f9d2962018-10-05 08:46:07240 for error in errors:
241 msg = '%s:%d uses disallowed identifier %s' % (
242 path, error.line, error.identifier)
243 if error.advice:
244 msg += ". Advice: %s" % "\n".join(error.advice)
Miyoung Shinba0f172b2020-01-23 09:10:41245 if error.warning:
246 results.append(output_api.PresubmitPromptWarning(msg))
247 else:
248 results.append(output_api.PresubmitError(msg))
Kent Tamurac3e44312018-04-07 16:30:24249 return results
250
251
252def CheckChangeOnUpload(input_api, output_api):
253 results = []
254 results.extend(_CommonChecks(input_api, output_api))
255 results.extend(_CheckStyle(input_api, output_api))
256 results.extend(_CheckForPrintfDebugging(input_api, output_api))
257 results.extend(_CheckForForbiddenChromiumCode(input_api, output_api))
258 return results
259
260
261def CheckChangeOnCommit(input_api, output_api):
262 results = []
263 results.extend(_CommonChecks(input_api, output_api))
Kent Tamurac3e44312018-04-07 16:30:24264 return results