blob: d9e9db43b0b7c5aa4c69a7e0aee4963598ea7397 [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.
4
5"""Top-level presubmit script for Blink.
6
Daniel McArdlef8838172019-12-06 21:36:487See https://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts
Kent Tamurac3e44312018-04-07 16:30:248for more details about the presubmit API built into gcl.
9"""
10
11import imp
12import inspect
13import os
Daniel McArdlef8838172019-12-06 21:36:4814import re
Kent Tamurac3e44312018-04-07 16:30:2415
16try:
17 # pylint: disable=C0103
18 audit_non_blink_usage = imp.load_source(
19 'audit_non_blink_usage',
Fergal Daly5f61cbe2018-10-05 04:30:3420 os.path.join(os.path.dirname(inspect.stack()[0][1]),
21 'tools/blinkpy/presubmit/audit_non_blink_usage.py'))
Kent Tamurac3e44312018-04-07 16:30:2422except IOError:
23 # One of the presubmit upload tests tries to exec this script, which doesn't interact so well
24 # with the import hack... just ignore the exception here and hope for the best.
25 pass
26
27
28_EXCLUDED_PATHS = (
Robert Maad740d92019-06-03 13:18:1229 # These are third-party dependencies that we don't directly control.
30 r'^third_party[\\/]blink[\\/]tools[\\/]blinkpy[\\/]third_party[\\/]wpt[\\/]wpt[\\/].*',
31 r'^third_party[\\/]blink[\\/]web_tests[\\/]external[\\/]wpt[\\/]tools[\\/].*',
32 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):
41 return input_api.FilterSourceFile(path,
42 black_list=[r'third_party/blink/common/', r'third_party/blink/public/common'])
43
Dave Tapuska8cc25392020-01-22 18:36:4844 pattern = input_api.re.compile(r'#include\s+[<"](.+)\.mojom(.*)\.h[>"]')
Kent Tamurac3e44312018-04-07 16:30:2445 public_folder = input_api.os_path.normpath('third_party/blink/public/')
46 non_blink_mojom_errors = []
47 public_blink_mojom_errors = []
Dave Tapuska8cc25392020-01-22 18:36:4848
49 # Allow including specific non-blink interfaces that are used in the public C++ API.
50 # Adding to these allowed interfaces should meet the following conditions:
51 # - Its pros/cons is discussed and have consensus on platform-architecture-dev@ and/or
52 # - It uses POD types that will not import STL (or base string) types into blink
53 # (such as no strings or vectors).
54 allowed_interfaces = (r'services/network/public/mojom/load_timing_info.mojom')
55
Kent Tamurac3e44312018-04-07 16:30:2456 for f in input_api.AffectedFiles(file_filter=source_file_filter):
57 for line_num, line in f.ChangedContents():
58 error_list = None
Kent Tamurac3e44312018-04-07 16:30:2459 match = pattern.match(line)
Dave Tapuska8cc25392020-01-22 18:36:4860 if (match and match.group(1) not in allowed_interfaces):
61 if match.group(2) != '-shared':
Leon Hanb6bd8e62019-05-29 03:18:2062 if f.LocalPath().startswith(public_folder):
Kent Tamurac3e44312018-04-07 16:30:2463 error_list = public_blink_mojom_errors
Dave Tapuska8cc25392020-01-22 18:36:4864 elif match.group(2) not in ('-blink', '-blink-forward', '-blink-test-utils'):
Oksana Zhuravlova2b5fe2832019-02-22 05:44:1465 # Neither -shared.h, -blink.h, -blink-forward.h nor -blink-test-utils.h.
Kent Tamurac3e44312018-04-07 16:30:2466 error_list = non_blink_mojom_errors
67
68 if error_list is not None:
69 error_list.append(' %s:%d %s' % (
70 f.LocalPath(), line_num, line))
71
72 results = []
73 if non_blink_mojom_errors:
74 results.append(output_api.PresubmitError(
75 'Files that include non-Blink variant mojoms found. '
76 'You must include .mojom-blink.h or .mojom-shared.h instead:',
77 non_blink_mojom_errors))
78
79 if public_blink_mojom_errors:
80 results.append(output_api.PresubmitError(
81 'Public blink headers using Blink variant mojoms found. '
82 'You must include .mojom-shared.h instead:',
83 public_blink_mojom_errors))
84
85 return results
86
87
88def _CommonChecks(input_api, output_api):
89 """Checks common to both upload and commit."""
90 # We should figure out what license checks we actually want to use.
91 license_header = r'.*'
92
93 results = []
94 results.extend(input_api.canned_checks.PanProjectChecks(
95 input_api, output_api, excluded_paths=_EXCLUDED_PATHS,
96 maxlen=800, license_header=license_header))
97 results.extend(_CheckForWrongMojomIncludes(input_api, output_api))
98 return results
99
100
Fergal Daly4fc8a212018-10-01 08:43:26101def _FilterPaths(input_api):
102 """Returns input files with certain paths removed."""
Kent Tamurac3e44312018-04-07 16:30:24103 files = []
104 for f in input_api.AffectedFiles():
105 file_path = f.LocalPath()
Fergal Daly4fc8a212018-10-01 08:43:26106 # Filter out changes in web_tests/.
107 if ('web_tests' + input_api.os_path.sep in file_path
108 and 'TestExpectations' not in file_path):
Kent Tamurac3e44312018-04-07 16:30:24109 continue
110 if '/PRESUBMIT' in file_path:
111 continue
Daniel McArdlef8838172019-12-06 21:36:48112 # Skip files that were generated by bison.
113 if re.search('third_party/blink/renderer/' +
114 'core/xml/xpath_grammar_generated\.(cc|h)$', file_path):
Dave Tapuska8cc25392020-01-22 18:36:48115 continue
Kent Tamurac3e44312018-04-07 16:30:24116 files.append(input_api.os_path.join('..', '..', file_path))
Fergal Daly4fc8a212018-10-01 08:43:26117 return files
118
119
120def _CheckStyle(input_api, output_api):
121 files = _FilterPaths(input_api)
Kent Tamuraf76ea8f2018-04-17 04:45:07122 # Do not call check_blink_style.py with empty affected file list if all
Kent Tamurac3e44312018-04-07 16:30:24123 # input_api.AffectedFiles got filtered.
124 if not files:
125 return []
Kent Tamurac3e44312018-04-07 16:30:24126
Fergal Daly4fc8a212018-10-01 08:43:26127 style_checker_path = input_api.os_path.join(input_api.PresubmitLocalPath(),
128 'tools', 'check_blink_style.py')
129 args = [input_api.python_executable, style_checker_path, '--diff-files']
130 args += files
131
132 results = []
Kent Tamurac3e44312018-04-07 16:30:24133 try:
134 child = input_api.subprocess.Popen(args,
135 stderr=input_api.subprocess.PIPE)
136 _, stderrdata = child.communicate()
137 if child.returncode != 0:
138 results.append(output_api.PresubmitError(
Kent Tamuraf76ea8f2018-04-17 04:45:07139 'check_blink_style.py failed', [stderrdata]))
Kent Tamurac3e44312018-04-07 16:30:24140 except Exception as e:
141 results.append(output_api.PresubmitNotifyResult(
Kent Tamuraf76ea8f2018-04-17 04:45:07142 'Could not run check_blink_style.py', [str(e)]))
Kent Tamurac3e44312018-04-07 16:30:24143
144 return results
145
146
147def _CheckForPrintfDebugging(input_api, output_api):
148 """Generally speaking, we'd prefer not to land patches that printf
149 debug output.
150 """
151 printf_re = input_api.re.compile(r'^\s*(printf\(|fprintf\(stderr,)')
152 errors = input_api.canned_checks._FindNewViolationsOfRule(
153 lambda _, x: not printf_re.search(x),
154 input_api, None)
155 errors = [' * %s' % violation for violation in errors]
156 if errors:
157 return [output_api.PresubmitPromptOrNotify(
158 'printf debugging is best debugging! That said, it might '
159 'be a good idea to drop the following occurences from '
160 'your patch before uploading:\n%s' % '\n'.join(errors))]
161 return []
162
163
164def _CheckForForbiddenChromiumCode(input_api, output_api):
165 """Checks that Blink uses Chromium classes and namespaces only in permitted code."""
166 # TODO(dcheng): This is pretty similar to _FindNewViolationsOfRule. Unfortunately, that can;'t
167 # be used directly because it doesn't give the callable enough information (namely the path to
168 # the file), so we duplicate the logic here...
169 results = []
170 for f in input_api.AffectedFiles():
171 path = f.LocalPath()
172 errors = audit_non_blink_usage.check(path, [(i + 1, l) for i, l in enumerate(f.NewContents())])
173 if errors:
174 errors = audit_non_blink_usage.check(path, f.ChangedContents())
175 if errors:
Fergal Daly5f9d2962018-10-05 08:46:07176 for error in errors:
177 msg = '%s:%d uses disallowed identifier %s' % (
178 path, error.line, error.identifier)
179 if error.advice:
180 msg += ". Advice: %s" % "\n".join(error.advice)
Miyoung Shinba0f172b2020-01-23 09:10:41181 if error.warning:
182 results.append(output_api.PresubmitPromptWarning(msg))
183 else:
184 results.append(output_api.PresubmitError(msg))
Kent Tamurac3e44312018-04-07 16:30:24185 return results
186
187
188def CheckChangeOnUpload(input_api, output_api):
189 results = []
190 results.extend(_CommonChecks(input_api, output_api))
191 results.extend(_CheckStyle(input_api, output_api))
192 results.extend(_CheckForPrintfDebugging(input_api, output_api))
193 results.extend(_CheckForForbiddenChromiumCode(input_api, output_api))
194 return results
195
196
197def CheckChangeOnCommit(input_api, output_api):
198 results = []
199 results.extend(_CommonChecks(input_api, output_api))
200 results.extend(input_api.canned_checks.CheckTreeIsOpen(
201 input_api, output_api,
202 json_url='http://chromium-status.appspot.com/current?format=json'))
203 results.extend(input_api.canned_checks.CheckChangeHasDescription(
204 input_api, output_api))
205 return results