blob: cdfe0ed07c52e57ef4522b231413a442b86656e5 [file] [log] [blame]
Avi Drissman047c7dc2022-09-27 23:23:141# Copyright 2013 The Chromium Authors
Kent Tamurac3e44312018-04-07 16:30:242# 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
Ho Cheungc07ebfa2023-10-27 02:59:5710import importlib
Kent Tamurac3e44312018-04-07 16:30:2411import inspect
12import os
Daniel McArdlef8838172019-12-06 21:36:4813import re
Kent Tamurac3e44312018-04-07 16:30:2414
15try:
16 # pylint: disable=C0103
Ho Cheungc07ebfa2023-10-27 02:59:5717 module_name = 'audit_non_blink_usage'
18 module_path = os.path.join(
19 os.path.dirname(inspect.stack()[0][1]),
20 'tools/blinkpy/presubmit/audit_non_blink_usage.py')
21 audit_non_blink_usage = importlib.machinery.SourceFileLoader(
22 module_name, module_path).load_module()
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)$',
Yao Xiao7503daff2024-10-16 17:14:4245 r'.*_unittest.*\.(cc|h)$',
Matt Menke132d70e2021-06-29 01:19:2846 r'third_party[\\/]blink[\\/]common[\\/]',
47 r'third_party[\\/]blink[\\/]public[\\/]common[\\/]',
48 r'third_party[\\/]blink[\\/]renderer[\\/]platform[\\/]loader[\\/]fetch[\\/]url_loader[\\/]',
Yuzu Saijoe12e7ae2022-08-22 05:56:5549 r'third_party[\\/]blink[\\/]renderer[\\/]core[\\/]frame[\\/]web_view_impl.*\.(cc|h)$',
Dave Tapuskacf95aaa2022-07-20 17:00:5450 r'third_party[\\/]blink[\\/]renderer[\\/]core[\\/]frame[\\/]web.*frame.*\.(cc|h)$',
Kent Tamurac9bbe0a2020-12-22 14:39:5651 ])
Kent Tamurac3e44312018-04-07 16:30:2452
Dave Tapuska8cc25392020-01-22 18:36:4853 pattern = input_api.re.compile(r'#include\s+[<"](.+)\.mojom(.*)\.h[>"]')
Kent Tamurac3e44312018-04-07 16:30:2454 public_folder = input_api.os_path.normpath('third_party/blink/public/')
55 non_blink_mojom_errors = []
56 public_blink_mojom_errors = []
Dave Tapuska8cc25392020-01-22 18:36:4857
Kent Tamurac9bbe0a2020-12-22 14:39:5658 # Allow including specific non-blink interfaces that are used in the
59 # public C++ API. Adding to these allowed interfaces should meet the
60 # following conditions:
61 # - Its pros/cons is discussed and have consensus on
Erik Chen0fbe13a2023-10-02 22:51:5262 # platform-architecture-dev@ or
Kent Tamurac9bbe0a2020-12-22 14:39:5663 # - It uses POD types that will not import STL (or base string) types into
64 # blink (such as no strings or vectors).
Makoto Shimazu9e4b946a2020-03-09 05:19:1765 #
Kent Tamurac9bbe0a2020-12-22 14:39:5666 # So far, non-blink interfaces are allowed only for loading / loader and
67 # media interfaces so that we don't need type conversions to get through
68 # the boundary between Blink and non-Blink.
69 allowed_interfaces = (
70 'services/network/public/mojom/cross_origin_embedder_policy',
Camille Lamyf29b0e22025-01-23 11:48:5471 'services/network/public/mojom/document_isolation_policy',
Hans Wennborga61b3042021-06-15 12:06:3172 'services/network/public/mojom/early_hints',
Kent Tamurac9bbe0a2020-12-22 14:39:5673 'services/network/public/mojom/fetch_api',
74 'services/network/public/mojom/load_timing_info',
75 'services/network/public/mojom/url_loader',
76 'services/network/public/mojom/url_loader_factory',
77 'services/network/public/mojom/url_response_head',
Marijn Kruisselbrinkaae1e882022-09-23 22:54:1778 'third_party/blink/public/mojom/blob/blob',
Kent Tamurac9bbe0a2020-12-22 14:39:5679 'third_party/blink/public/mojom/blob/serialized_blob',
Yao Xiao94203f52024-09-13 17:35:5780 'third_party/blink/public/mojom/browser_interface_broker',
Kent Tamurac9bbe0a2020-12-22 14:39:5681 'third_party/blink/public/mojom/fetch/fetch_api_request',
Erik Chen5fe571f2023-10-11 23:01:1582 'third_party/blink/public/mojom/loader/code_cache',
Ming-Ying Chung2715fbbe2023-10-18 04:13:1983 'third_party/blink/public/mojom/loader/fetch_later',
Alex Yangcc8ef632024-10-08 20:13:3784 'third_party/blink/public/mojom/loader/local_resource_loader_config',
Kent Tamurac9bbe0a2020-12-22 14:39:5685 'third_party/blink/public/mojom/loader/resource_load_info',
86 'third_party/blink/public/mojom/loader/resource_load_info_notifier',
Erik Chen5fe571f2023-10-11 23:01:1587 'third_party/blink/public/mojom/loader/transferrable_url_loader',
88 'third_party/blink/public/mojom/navigation/renderer_content_settings',
Lingqi Chi2a7b3c42024-05-31 03:50:0689 'third_party/blink/public/mojom/page/prerender_page_param',
Ari Chivukulacc91f9222024-08-21 14:44:5190 'third_party/blink/public/mojom/partitioned_popins/partitioned_popin_params',
Kent Tamurac9bbe0a2020-12-22 14:39:5691 'third_party/blink/public/mojom/worker/subresource_loader_updater',
Yao Xiaoc20779e2023-08-25 16:27:3092 'third_party/blink/public/mojom/worker/worklet_global_scope_creation_params',
Yao Xiaoc20779e2023-08-25 16:27:3093 'media/mojo/mojom/interface_factory', 'media/mojo/mojom/audio_decoder',
94 'media/mojo/mojom/audio_encoder', 'media/mojo/mojom/video_decoder',
Guido Urdanetaa5c57ea2021-03-02 10:53:5795 'media/mojo/mojom/media_metrics_provider')
Dave Tapuska8cc25392020-01-22 18:36:4896
Kent Tamurac3e44312018-04-07 16:30:2497 for f in input_api.AffectedFiles(file_filter=source_file_filter):
98 for line_num, line in f.ChangedContents():
99 error_list = None
Kent Tamurac3e44312018-04-07 16:30:24100 match = pattern.match(line)
Dave Tapuska8cc25392020-01-22 18:36:48101 if (match and match.group(1) not in allowed_interfaces):
Eriko Kurimoto61f12812020-01-31 08:06:50102 if match.group(2) not in ('-shared', '-forward'):
Leon Hanb6bd8e62019-05-29 03:18:20103 if f.LocalPath().startswith(public_folder):
Kent Tamurac3e44312018-04-07 16:30:24104 error_list = public_blink_mojom_errors
Kent Tamurac9bbe0a2020-12-22 14:39:56105 elif match.group(2) not in ('-blink', '-blink-forward',
106 '-blink-test-utils'):
107 # Neither -shared.h, -blink.h, -blink-forward.h nor
108 # -blink-test-utils.h.
Kent Tamurac3e44312018-04-07 16:30:24109 error_list = non_blink_mojom_errors
110
111 if error_list is not None:
Kent Tamurac9bbe0a2020-12-22 14:39:56112 error_list.append(' %s:%d %s' %
113 (f.LocalPath(), line_num, line))
Kent Tamurac3e44312018-04-07 16:30:24114
115 results = []
116 if non_blink_mojom_errors:
Kent Tamurac9bbe0a2020-12-22 14:39:56117 results.append(
118 output_api.PresubmitError(
119 'Files that include non-Blink variant mojoms found. '
120 'You must include .mojom-blink.h, .mojom-forward.h or '
121 '.mojom-shared.h instead:', non_blink_mojom_errors))
Kent Tamurac3e44312018-04-07 16:30:24122
123 if public_blink_mojom_errors:
Kent Tamurac9bbe0a2020-12-22 14:39:56124 results.append(
125 output_api.PresubmitError(
126 'Public blink headers using Blink variant mojoms found. '
127 'You must include .mojom-forward.h or .mojom-shared.h '
128 'instead:', public_blink_mojom_errors))
Kent Tamurac3e44312018-04-07 16:30:24129
130 return results
131
132
133def _CommonChecks(input_api, output_api):
134 """Checks common to both upload and commit."""
135 # We should figure out what license checks we actually want to use.
136 license_header = r'.*'
137
138 results = []
Kent Tamurac9bbe0a2020-12-22 14:39:56139 results.extend(
140 input_api.canned_checks.PanProjectChecks(
141 input_api,
142 output_api,
143 excluded_paths=_EXCLUDED_PATHS,
Bruce Dawsonae257be2022-07-22 15:48:26144 owners_check=False,
Kent Tamurac9bbe0a2020-12-22 14:39:56145 maxlen=800,
Bruce Dawsone7f7956e2022-05-03 16:42:17146 license_header=license_header,
147 global_checks=False))
Kent Tamurac3e44312018-04-07 16:30:24148 results.extend(_CheckForWrongMojomIncludes(input_api, output_api))
149 return results
150
151
Andrew Grieve713b89b2024-10-15 20:20:08152def FilterPaths(input_api):
Fergal Daly4fc8a212018-10-01 08:43:26153 """Returns input files with certain paths removed."""
Kent Tamurac3e44312018-04-07 16:30:24154 files = []
155 for f in input_api.AffectedFiles():
Jonathan Lee4c5f1f52022-09-26 20:43:04156 file_path = f.AbsoluteLocalPath()
157 # Filter out changes in web_tests/ so they are not linted. Some files
158 # are intentionally malformed for testing. Also, external WPTs may have
159 # non-Chromium authors.
Kent Tamurad9102342022-06-15 19:47:35160 if 'web_tests' + input_api.os_path.sep in file_path:
Kent Tamurac3e44312018-04-07 16:30:24161 continue
Andrew Grieve713b89b2024-10-15 20:20:08162 if input_api.os_path.sep + 'PRESUBMIT' in file_path:
Kent Tamurac3e44312018-04-07 16:30:24163 continue
Daniel McArdlef8838172019-12-06 21:36:48164 # Skip files that were generated by bison.
Kent Tamurac9bbe0a2020-12-22 14:39:56165 if re.search(
Andrew Grieve713b89b2024-10-15 20:20:08166 'third_party.blink.renderer.'
167 'core.xml.xpath_grammar_generated\.(cc|h)$', file_path):
Dave Tapuska8cc25392020-01-22 18:36:48168 continue
Jonathan Lee4c5f1f52022-09-26 20:43:04169 files.append(file_path)
Fergal Daly4fc8a212018-10-01 08:43:26170 return files
171
172
173def _CheckStyle(input_api, output_api):
Andrew Grieve713b89b2024-10-15 20:20:08174 files = FilterPaths(input_api)
Kent Tamuraf76ea8f2018-04-17 04:45:07175 # Do not call check_blink_style.py with empty affected file list if all
Kent Tamurac3e44312018-04-07 16:30:24176 # input_api.AffectedFiles got filtered.
177 if not files:
178 return []
Kent Tamurac3e44312018-04-07 16:30:24179
Fergal Daly4fc8a212018-10-01 08:43:26180 style_checker_path = input_api.os_path.join(input_api.PresubmitLocalPath(),
Kent Tamurac9bbe0a2020-12-22 14:39:56181 'tools',
182 'check_blink_style.py')
Bruce Dawson5f7cbff2022-05-25 17:36:44183 # When running git cl presubmit --all this presubmit may be asked to check
184 # ~260 files, leading to a command line that is about 17,000 characters.
185 # This goes past the Windows 8191 character cmd.exe limit and causes cryptic
186 # failures. To avoid these we break the command up into smaller pieces.
187 # Depending on how long the command is on Windows the error may be:
188 # The command line is too long.
189 # Or it may be:
190 # OSError: Execution failed with error: [WinError 206] The filename or
191 # extension is too long.
192 # The latter error comes from CreateProcess hitting its 32768 character
193 # limit.
Bruce Dawson5130baf2022-06-23 22:25:12194 files_per_command = 40 if input_api.is_windows else 1000
Fergal Daly4fc8a212018-10-01 08:43:26195 results = []
Bruce Dawson5f7cbff2022-05-25 17:36:44196 for i in range(0, len(files), files_per_command):
197 args = [
Bruce Dawson5130baf2022-06-23 22:25:12198 input_api.python3_executable, style_checker_path, '--diff-files'
Bruce Dawson5f7cbff2022-05-25 17:36:44199 ]
200 args += files[i:i + files_per_command]
201
202 try:
203 child = input_api.subprocess.Popen(
204 args, stderr=input_api.subprocess.PIPE)
205 _, stderrdata = child.communicate()
206 if child.returncode != 0:
207 results.append(
208 output_api.PresubmitError('check_blink_style.py failed',
Kent Tamura2b1330c2022-08-29 05:20:07209 [stderrdata.decode('utf-8')]))
Bruce Dawson5f7cbff2022-05-25 17:36:44210 except Exception as e:
Kent Tamurac9bbe0a2020-12-22 14:39:56211 results.append(
Bruce Dawson5f7cbff2022-05-25 17:36:44212 output_api.PresubmitNotifyResult(
213 'Could not run check_blink_style.py', [str(e)]))
Kent Tamurac3e44312018-04-07 16:30:24214
Jonathan Lee4c5f1f52022-09-26 20:43:04215 # By default, the pylint canned check lints all Python files together to
216 # check for potential problems between dependencies. This is slow to run
217 # across all of Blink (>2 min), so only lint affected files.
218 affected_python_files = [
219 input_api.os_path.relpath(file_path, input_api.PresubmitLocalPath())
220 for file_path in files if input_api.fnmatch.fnmatch(file_path, '*.py')
221 ]
Jonathan Lee6da63fc2023-08-15 04:23:07222 if affected_python_files:
223 pylintrc = input_api.os_path.join('tools', 'blinkpy', 'pylintrc')
224 results.extend(
225 input_api.RunTests(
226 input_api.canned_checks.GetPylint(
227 input_api,
228 output_api,
229 files_to_check=[
230 re.escape(path) for path in affected_python_files
231 ],
232 pylintrc=pylintrc)))
Kent Tamurac3e44312018-04-07 16:30:24233 return results
234
235
236def _CheckForPrintfDebugging(input_api, output_api):
237 """Generally speaking, we'd prefer not to land patches that printf
238 debug output.
239 """
240 printf_re = input_api.re.compile(r'^\s*(printf\(|fprintf\(stderr,)')
241 errors = input_api.canned_checks._FindNewViolationsOfRule(
Kent Tamurac9bbe0a2020-12-22 14:39:56242 lambda _, x: not printf_re.search(x), input_api, None)
Kent Tamurac3e44312018-04-07 16:30:24243 errors = [' * %s' % violation for violation in errors]
244 if errors:
Kent Tamurac9bbe0a2020-12-22 14:39:56245 return [
246 output_api.PresubmitPromptOrNotify(
247 'printf debugging is best debugging! That said, it might '
248 'be a good idea to drop the following occurences from '
249 'your patch before uploading:\n%s' % '\n'.join(errors))
250 ]
Kent Tamurac3e44312018-04-07 16:30:24251 return []
252
253
254def _CheckForForbiddenChromiumCode(input_api, output_api):
Kent Tamurac9bbe0a2020-12-22 14:39:56255 """Checks that Blink uses Chromium classes and namespaces only in
256 permitted code.
257 """
258 # TODO(dcheng): This is pretty similar to _FindNewViolationsOfRule.
259 # Unfortunately, that can't be used directly because it doesn't give the
260 # callable enough information (namely the path to the file), so we
261 # duplicate the logic here...
Kent Tamurac3e44312018-04-07 16:30:24262 results = []
263 for f in input_api.AffectedFiles():
264 path = f.LocalPath()
Kent Tamurac9bbe0a2020-12-22 14:39:56265 errors = audit_non_blink_usage.check(
266 path, [(i + 1, l) for i, l in enumerate(f.NewContents())])
Kent Tamurac3e44312018-04-07 16:30:24267 if errors:
268 errors = audit_non_blink_usage.check(path, f.ChangedContents())
269 if errors:
Fergal Daly5f9d2962018-10-05 08:46:07270 for error in errors:
Daniel Chenga09856d2025-05-29 01:04:45271 if not results:
272 results.append(
273 output_api.PresubmitNotifyResult(
274 'Non-Blink usage violations detected. Please '
275 'check if there are usable Blink equivalents; '
276 'if none exist, please allowlist the new uses '
277 'in third_party/blink/tools/blinkpy/presubmit/'
278 'audit_non_blink_usage.py'))
Fergal Daly5f9d2962018-10-05 08:46:07279 msg = '%s:%d uses disallowed identifier %s' % (
280 path, error.line, error.identifier)
281 if error.advice:
282 msg += ". Advice: %s" % "\n".join(error.advice)
Miyoung Shinba0f172b2020-01-23 09:10:41283 if error.warning:
284 results.append(output_api.PresubmitPromptWarning(msg))
285 else:
286 results.append(output_api.PresubmitError(msg))
Kent Tamurac3e44312018-04-07 16:30:24287 return results
288
289
290def CheckChangeOnUpload(input_api, output_api):
291 results = []
292 results.extend(_CommonChecks(input_api, output_api))
293 results.extend(_CheckStyle(input_api, output_api))
294 results.extend(_CheckForPrintfDebugging(input_api, output_api))
295 results.extend(_CheckForForbiddenChromiumCode(input_api, output_api))
296 return results
297
298
299def CheckChangeOnCommit(input_api, output_api):
300 results = []
301 results.extend(_CommonChecks(input_api, output_api))
Kent Tamurac3e44312018-04-07 16:30:24302 return results