Movatterモバイル変換


[0]ホーム

URL:


Google Git
Sign in
chromium /chromium /src.git /refs/tags/121.0.6136.0 /. /PRESUBMIT.py
blob: 18a8bed5961dad1c5bc4723ed5ed84198311c753 [file] [log] [blame]
Avi Drissman24976592022-09-12 15:24:31[diff] [blame]1# Copyright 2012 The Chromium Authors
maruel@chromium.orgca8d19842009-02-19 16:33:12[diff] [blame]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 Chromium.
6
Daniel Chengd88244472022-05-16 09:08:47[diff] [blame]7See https://www.chromium.org/developers/how-tos/depottools/presubmit-scripts/
tfarina78bb92f42015-01-31 00:20:48[diff] [blame]8for more details about the presubmit API built into depot_tools.
maruel@chromium.orgca8d19842009-02-19 16:33:12[diff] [blame]9"""
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]10
Daniel Chenga37c03db2022-05-12 17:20:34[diff] [blame]11from typingimportCallable
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]12from typingimportOptional
13from typingimportSequence
14from dataclassesimport dataclass
15
Saagar Sanghavifceeaae2020-08-12 16:40:36[diff] [blame]16PRESUBMIT_VERSION='2.0.0'
joi@chromium.orgeea609a2011-11-18 13:10:12[diff] [blame]17
Dirk Prankee3c9c62d2021-05-18 18:35:59[diff] [blame]18
maruel@chromium.org379e7dd2010-01-28 17:39:21[diff] [blame]19_EXCLUDED_PATHS=(
Bruce Dawson7f8566b2022-05-06 16:22:18[diff] [blame]20# Generated file
Bruce Dawson40fece62022-09-16 19:58:31[diff] [blame]21(r"chrome/android/webapk/shell_apk/src/org/chromium"
22 r"/webapk/lib/runtime_library/IWebApkApi.java"),
Mila Greene3aa7222021-09-07 16:34:08[diff] [blame]23# File needs to write to stdout to emulate a tool it's replacing.
Bruce Dawson40fece62022-09-16 19:58:31[diff] [blame]24 r"chrome/updater/mac/keystone/ksadmin.mm",
Ilya Shermane8a7d2d2020-07-25 04:33:47[diff] [blame]25# Generated file.
Bruce Dawson40fece62022-09-16 19:58:31[diff] [blame]26(r"^components/variations/proto/devtools/"
Ilya Shermanc167a962020-08-18 18:40:26[diff] [blame]27 r"client_variations.js"),
Bruce Dawson3bd976c2022-05-06 22:47:52[diff] [blame]28# These are video files, not typescript.
Bruce Dawson40fece62022-09-16 19:58:31[diff] [blame]29 r"^media/test/data/.*.ts",
30 r"^native_client_sdksrc/build_tools/make_rules.py",
31 r"^native_client_sdk/src/build_tools/make_simple.py",
32 r"^native_client_sdk/src/tools/.*.mk",
33 r"^net/tools/spdyshark/.*",
34 r"^skia/.*",
35 r"^third_party/blink/.*",
36 r"^third_party/breakpad/.*",
Darwin Huangd74a9d32019-07-17 17:58:46[diff] [blame]37# sqlite is an imported third party dependency.
Bruce Dawson40fece62022-09-16 19:58:31[diff] [blame]38 r"^third_party/sqlite/.*",
39 r"^v8/.*",
maruel@chromium.org3e4eb112011-01-18 03:29:54[diff] [blame]40 r".*MakeFile$",
gman@chromium.org1084ccc2012-03-14 03:22:53[diff] [blame]41 r".+_autogen\.h$",
Yue Shecf1380552022-08-23 20:59:20[diff] [blame]42 r".+_pb2(_grpc)?\.py$",
Bruce Dawson40fece62022-09-16 19:58:31[diff] [blame]43 r".+/pnacl_shim\.c$",
44 r"^gpu/config/.*_list_json\.cc$",
45 r"tools/md_browser/.*\.css$",
Kenneth Russell077c8d92017-12-16 02:52:14[diff] [blame]46# Test pages for Maps telemetry tests.
Bruce Dawson40fece62022-09-16 19:58:31[diff] [blame]47 r"tools/perf/page_sets/maps_perf_test.*",
ehmaldonado78eee2ed2017-03-28 13:16:54[diff] [blame]48# Test pages for WebRTC telemetry tests.
Bruce Dawson40fece62022-09-16 19:58:31[diff] [blame]49 r"tools/perf/page_sets/webrtc_cases.*",
dpapad2efd4452023-04-06 01:43:45[diff] [blame]50# Test file compared with generated output.
51 r"tools/polymer/tests/html_to_wrapper/.*.html.ts$",
maruel@chromium.org4306417642009-06-11 00:33:40[diff] [blame]52)
maruel@chromium.orgca8d19842009-02-19 16:33:12[diff] [blame]53
John Abd-El-Malek759fea62021-03-13 03:41:14[diff] [blame]54_EXCLUDED_SET_NO_PARENT_PATHS=(
55# It's for historical reasons that blink isn't a top level directory, where
56# it would be allowed to have "set noparent" to avoid top level owners
57# accidentally +1ing changes.
58'third_party/blink/OWNERS',
59)
60
wnwenbdc444e2016-05-25 13:44:15[diff] [blame]61
joi@chromium.org06e6d0ff2012-12-11 01:36:44[diff] [blame]62# Fragment of a regular expression that matches C++ and Objective-C++
63# implementation files.
64_IMPLEMENTATION_EXTENSIONS= r'\.(cc|cpp|cxx|mm)$'
65
wnwenbdc444e2016-05-25 13:44:15[diff] [blame]66
Wei-Yin Chen (陳威尹)c0624d002018-07-30 18:22:19[diff] [blame]67# Fragment of a regular expression that matches C++ and Objective-C++
68# header files.
69_HEADER_EXTENSIONS= r'\.(h|hpp|hxx)$'
70
71
Aleksey Khoroshilov9b28c032022-06-03 16:35:32[diff] [blame]72# Paths with sources that don't use //base.
73_NON_BASE_DEPENDENT_PATHS=(
Bruce Dawson40fece62022-09-16 19:58:31[diff] [blame]74 r"^chrome/browser/browser_switcher/bho/",
75 r"^tools/win/",
Aleksey Khoroshilov9b28c032022-06-03 16:35:32[diff] [blame]76)
77
78
joi@chromium.org06e6d0ff2012-12-11 01:36:44[diff] [blame]79# Regular expression that matches code only used for test binaries
80# (best effort).
81_TEST_CODE_EXCLUDED_PATHS=(
Bruce Dawson40fece62022-09-16 19:58:31[diff] [blame]82 r'.*/(fake_|test_|mock_).+%s'% _IMPLEMENTATION_EXTENSIONS,
joi@chromium.org06e6d0ff2012-12-11 01:36:44[diff] [blame]83 r'.+_test_(base|support|util)%s'% _IMPLEMENTATION_EXTENSIONS,
James Cook1b4dc132021-03-09 22:45:13[diff] [blame]84# Test suite files, like:
85# foo_browsertest.cc
86# bar_unittest_mac.cc (suffix)
87# baz_unittests.cc (plural)
88 r'.+_(api|browser|eg|int|perf|pixel|unit|ui)?test(s)?(_[a-z]+)?%s'%
danakj@chromium.orge2d7e6f2013-04-23 12:57:12[diff] [blame]89 _IMPLEMENTATION_EXTENSIONS,
Matthew Denton63ea1e62019-03-25 20:39:18[diff] [blame]90 r'.+_(fuzz|fuzzer)(_[a-z]+)?%s'% _IMPLEMENTATION_EXTENSIONS,
Victor Hugo Vianna Silvac22e0202021-06-09 19:46:21[diff] [blame]91 r'.+sync_service_impl_harness%s'% _IMPLEMENTATION_EXTENSIONS,
Bruce Dawson40fece62022-09-16 19:58:31[diff] [blame]92 r'.*/(test|tool(s)?)/.*',
danakj89f47082020-09-02 17:53:43[diff] [blame]93# content_shell is used for running content_browsertests.
Bruce Dawson40fece62022-09-16 19:58:31[diff] [blame]94 r'content/shell/.*',
danakj89f47082020-09-02 17:53:43[diff] [blame]95# Web test harness.
Bruce Dawson40fece62022-09-16 19:58:31[diff] [blame]96 r'content/web_test/.*',
darin@chromium.org7b054982013-11-27 00:44:47[diff] [blame]97# Non-production example code.
Bruce Dawson40fece62022-09-16 19:58:31[diff] [blame]98 r'mojo/examples/.*',
lliabraa@chromium.org8176de12014-06-20 19:07:08[diff] [blame]99# Launcher for running iOS tests on the simulator.
Bruce Dawson40fece62022-09-16 19:58:31[diff] [blame]100 r'testing/iossim/iossim\.mm$',
Olivier Robinbcea0fa2019-11-12 08:56:41[diff] [blame]101# EarlGrey app side code for tests.
Bruce Dawson40fece62022-09-16 19:58:31[diff] [blame]102 r'ios/.*_app_interface\.mm$',
Allen Bauer0678d772020-05-11 22:25:17[diff] [blame]103# Views Examples code
Bruce Dawson40fece62022-09-16 19:58:31[diff] [blame]104 r'ui/views/examples/.*',
Austin Sullivan33da70a2020-10-07 15:39:41[diff] [blame]105# Chromium Codelab
Bruce Dawson40fece62022-09-16 19:58:31[diff] [blame]106 r'codelabs/*'
joi@chromium.org06e6d0ff2012-12-11 01:36:44[diff] [blame]107)
maruel@chromium.orgca8d19842009-02-19 16:33:12[diff] [blame]108
Daniel Bratell609102be2019-03-27 20:53:21[diff] [blame]109_THIRD_PARTY_EXCEPT_BLINK='third_party/(?!blink/)'
wnwenbdc444e2016-05-25 13:44:15[diff] [blame]110
joi@chromium.orgeea609a2011-11-18 13:10:12[diff] [blame]111_TEST_ONLY_WARNING=(
112'You might be calling functions intended only for testing from\n'
danakj5f6e3b82020-09-10 13:52:55[diff] [blame]113'production code. If you are doing this from inside another method\n'
114'named as *ForTesting(), then consider exposing things to have tests\n'
115'make that same call directly.\n'
116'If that is not possible, you may put a comment on the same line with\n'
117' // IN-TEST \n'
118'to tell the PRESUBMIT script that the code is inside a *ForTesting()\n'
119'method and can be ignored. Do not do this inside production code.\n'
120'The android-binary-size trybot will block if the method exists in the\n'
121'release apk.')
joi@chromium.orgeea609a2011-11-18 13:10:12[diff] [blame]122
123
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]124@dataclass
125classBanRule:
Daniel Chenga37c03db2022-05-12 17:20:34[diff] [blame]126# String pattern. If the pattern begins with a slash, the pattern will be
127# treated as a regular expression instead.
128 pattern: str
129# Explanation as a sequence of strings. Each string in the sequence will be
130# printed on its own line.
131 explanation:Sequence[str]
132# Whether or not to treat this ban as a fatal error. If unspecified,
133# defaults to true.
134 treat_as_error:Optional[bool]=None
135# Paths that should be excluded from the ban check. Each string is a regular
136# expression that will be matched against the path of the file being checked
137# relative to the root of the source tree.
138 excluded_paths:Optional[Sequence[str]]=None
marja@chromium.orgcf9b78f2012-11-14 11:40:28[diff] [blame]139
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]140
Daniel Cheng917ce542022-03-15 20:46:57[diff] [blame]141_BANNED_JAVA_IMPORTS:Sequence[BanRule]=(
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]142BanRule(
143'import java.net.URI;',
144(
145'Use org.chromium.url.GURL instead of java.net.URI, where possible.',
146),
147 excluded_paths=(
148(r'net/android/javatests/src/org/chromium/net/'
149'AndroidProxySelectorTest\.java'),
150 r'components/cronet/',
151 r'third_party/robolectric/local/',
152),
Michael Thiessen44457642020-02-06 00:24:15[diff] [blame]153),
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]154BanRule(
155'import android.annotation.TargetApi;',
156(
157'Do not use TargetApi, use @androidx.annotation.RequiresApi instead. '
158'RequiresApi ensures that any calls are guarded by the appropriate '
159'SDK_INT check. See https://crbug.com/1116486.',
160),
161),
162BanRule(
Mohamed Heikal3d7a94c2023-03-28 16:55:24[diff] [blame]163'import androidx.test.rule.UiThreadTestRule;',
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]164(
165'Do not use UiThreadTestRule, just use '
166'@org.chromium.base.test.UiThreadTest on test methods that should run '
167'on the UI thread. See https://crbug.com/1111893.',
168),
169),
170BanRule(
Mohamed Heikal3d7a94c2023-03-28 16:55:24[diff] [blame]171'import androidx.test.annotation.UiThreadTest;',
172('Do not use androidx.test.annotation.UiThreadTest, use '
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]173'org.chromium.base.test.UiThreadTest instead. See '
174'https://crbug.com/1111893.',
175),
176),
177BanRule(
Mohamed Heikal3d7a94c2023-03-28 16:55:24[diff] [blame]178'import androidx.test.rule.ActivityTestRule;',
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]179(
180'Do not use ActivityTestRule, use '
181'org.chromium.base.test.BaseActivityTestRule instead.',
182),
183 excluded_paths=(
184'components/cronet/',
185),
186),
Min Qinbc44383c2023-02-22 17:25:26[diff] [blame]187BanRule(
188'import androidx.vectordrawable.graphics.drawable.VectorDrawableCompat;',
189(
190'Do not use VectorDrawableCompat, use getResources().getDrawable() to '
191'avoid extra indirections. Please also add trace event as the call '
192'might take more than 20 ms to complete.',
193),
194),
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]195)
wnwenbdc444e2016-05-25 13:44:15[diff] [blame]196
Daniel Cheng917ce542022-03-15 20:46:57[diff] [blame]197_BANNED_JAVA_FUNCTIONS:Sequence[BanRule]=(
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]198BanRule(
Eric Stevensona9a980972017-09-23 00:04:41[diff] [blame]199'StrictMode.allowThreadDiskReads()',
200(
201'Prefer using StrictModeContext.allowDiskReads() to using StrictMode '
202'directly.',
203),
204False,
205),
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]206BanRule(
Eric Stevensona9a980972017-09-23 00:04:41[diff] [blame]207'StrictMode.allowThreadDiskWrites()',
208(
209'Prefer using StrictModeContext.allowDiskWrites() to using StrictMode '
210'directly.',
211),
212False,
213),
Daniel Cheng917ce542022-03-15 20:46:57[diff] [blame]214BanRule(
Michael Thiessen0f2547e2020-07-27 21:55:36[diff] [blame]215'.waitForIdleSync()',
216(
217'Do not use waitForIdleSync as it masks underlying issues. There is '
218'almost always something else you should wait on instead.',
219),
220False,
221),
Ashley Newson09cbd602022-10-26 11:40:14[diff] [blame]222BanRule(
Ashley Newsoneb6f5ced2022-10-26 14:45:42[diff] [blame]223 r'/(?<!\bsuper\.)(?<!\bIntent )\bregisterReceiver\(',
Ashley Newson09cbd602022-10-26 11:40:14[diff] [blame]224(
225'Do not call android.content.Context.registerReceiver (or an override) '
226'directly. Use one of the wrapper methods defined in '
227'org.chromium.base.ContextUtils, such as '
228'registerProtectedBroadcastReceiver, '
229'registerExportedBroadcastReceiver, or '
230'registerNonExportedBroadcastReceiver. See their documentation for '
231'which one to use.',
232),
233True,
234 excluded_paths=(
Ashley Newson22bc26d2022-11-01 20:30:57[diff] [blame]235 r'.*Test[^a-z]',
236 r'third_party/',
Ashley Newson09cbd602022-10-26 11:40:14[diff] [blame]237'base/android/java/src/org/chromium/base/ContextUtils.java',
Brandon Mousseau7e76a9c2022-12-08 22:08:38[diff] [blame]238'chromecast/browser/android/apk/src/org/chromium/chromecast/shell/BroadcastReceiverScope.java',
Ashley Newson09cbd602022-10-26 11:40:14[diff] [blame]239),
240),
Ted Chocd5b327b12022-11-05 02:13:22[diff] [blame]241BanRule(
242 r'/(?:extends|new)\s*(?:android.util.)?Property<[A-Za-z.]+,\s*(?:Integer|Float)>',
243(
244'Do not use Property<..., Integer|Float>, but use FloatProperty or '
245'IntProperty because it will avoid unnecessary autoboxing of '
246'primitives.',
247),
248),
Peilin Wangbba4a8652022-11-10 16:33:57[diff] [blame]249BanRule(
250'requestLayout()',
251(
252'Layouts can be expensive. Prefer using ViewUtils.requestLayout(), '
253'which emits a trace event with additional information to help with '
254'scroll jank investigations. See http://crbug.com/1354176.',
255),
256False,
257 excluded_paths=(
258'ui/android/java/src/org/chromium/ui/base/ViewUtils.java',
259),
260),
Ted Chocf40ea9152023-02-14 19:02:39[diff] [blame]261BanRule(
262'Profile.getLastUsedRegularProfile()',
263(
264'Prefer passing in the Profile reference instead of relying on the '
265'static getLastUsedRegularProfile() call. Only top level entry points '
266'(e.g. Activities) should call this method. Otherwise, the Profile '
267'should either be passed in explicitly or retreived from an existing '
268'entity with a reference to the Profile (e.g. WebContents).',
269),
270False,
271 excluded_paths=(
272 r'.*Test[A-Z]?.*\.java',
273),
274),
Min Qinbc44383c2023-02-22 17:25:26[diff] [blame]275BanRule(
276 r'/(ResourcesCompat|getResources\(\))\.getDrawable\(\)',
277(
278'getDrawable() can be expensive. If you have a lot of calls to '
279'GetDrawable() or your code may introduce janks, please put your calls '
280'inside a trace().',
281),
282False,
283 excluded_paths=(
284 r'.*Test[A-Z]?.*\.java',
285),
286),
Henrique Nakashimabbf2b262023-03-10 17:21:39[diff] [blame]287BanRule(
288 r'/RecordHistogram\.getHistogram(ValueCount|TotalCount|Samples)ForTesting\(',
289(
290'Raw histogram counts are easy to misuse; for example they don\'t reset '
Thiago Perrotta099034f2023-06-05 18:10:20[diff] [blame]291'between batched tests. Use HistogramWatcher to check histogram records '
292'instead.',
Henrique Nakashimabbf2b262023-03-10 17:21:39[diff] [blame]293),
294False,
295 excluded_paths=(
296'base/android/javatests/src/org/chromium/base/metrics/RecordHistogramTest.java',
297'base/test/android/javatests/src/org/chromium/base/test/util/HistogramWatcher.java',
298),
299),
Eric Stevensona9a980972017-09-23 00:04:41[diff] [blame]300)
301
Clement Yan9b330cb2022-11-17 05:25:29[diff] [blame]302_BANNED_JAVASCRIPT_FUNCTIONS:Sequence[BanRule]=(
303BanRule(
304 r'/\bchrome\.send\b',
305(
306'The use of chrome.send is disallowed in Chrome (context: https://chromium.googlesource.com/chromium/src/+/refs/heads/main/docs/security/handling-messages-from-web-content.md).',
307'Please use mojo instead for new webuis. https://docs.google.com/document/d/1RF-GSUoveYa37eoyZ9EhwMtaIwoW7Z88pIgNZ9YzQi4/edit#heading=h.gkk22wgk6wff',
308),
309True,
310(
311 r'^(?!ash\/webui).+',
312# TODO(crbug.com/1385601): pre-existing violations still need to be
313# cleaned up.
Rebekah Potter57aa94df2022-12-13 20:30:58[diff] [blame]314'ash/webui/common/resources/cr.m.js',
Clement Yan9b330cb2022-11-17 05:25:29[diff] [blame]315'ash/webui/common/resources/multidevice_setup/multidevice_setup_browser_proxy.js',
Martin Bidlingmaiera921fee72023-06-03 07:52:22[diff] [blame]316'ash/webui/common/resources/quick_unlock/lock_screen_constants.ts',
Clement Yan9b330cb2022-11-17 05:25:29[diff] [blame]317'ash/webui/common/resources/smb_shares/smb_browser_proxy.js',
318'ash/webui/connectivity_diagnostics/resources/connectivity_diagnostics.js',
319'ash/webui/diagnostics_ui/resources/diagnostics_browser_proxy.ts',
320'ash/webui/multidevice_debug/resources/logs.js',
321'ash/webui/multidevice_debug/resources/webui.js',
322'ash/webui/projector_app/resources/annotator/trusted/annotator_browser_proxy.js',
323'ash/webui/projector_app/resources/app/trusted/projector_browser_proxy.js',
Ashley Prasad71f9024e2023-09-25 22:33:55[diff] [blame]324# TODO(b/301634378): Remove violation exception once Scanning App
325# migrated off usage of `chrome.send`.
326'ash/webui/scanning/resources/scanning_browser_proxy.ts',
Clement Yan9b330cb2022-11-17 05:25:29[diff] [blame]327),
328),
329)
330
Daniel Cheng917ce542022-03-15 20:46:57[diff] [blame]331_BANNED_OBJC_FUNCTIONS:Sequence[BanRule]=(
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]332BanRule(
avi@chromium.org127f18ec2012-06-16 05:05:59[diff] [blame]333'addTrackingRect:',
avi@chromium.org23e6cbc2012-06-16 18:51:20[diff] [blame]334(
335'The use of -[NSView addTrackingRect:owner:userData:assumeInside:] is'
avi@chromium.org127f18ec2012-06-16 05:05:59[diff] [blame]336'prohibited. Please use CrTrackingArea instead.',
337'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts',
338),
339False,
340),
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]341BanRule(
leng@chromium.orgeaae1972014-04-16 04:17:26[diff] [blame]342 r'/NSTrackingArea\W',
avi@chromium.org23e6cbc2012-06-16 18:51:20[diff] [blame]343(
344'The use of NSTrackingAreas is prohibited. Please use CrTrackingArea',
avi@chromium.org127f18ec2012-06-16 05:05:59[diff] [blame]345'instead.',
346'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts',
347),
348False,
349),
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]350BanRule(
avi@chromium.org127f18ec2012-06-16 05:05:59[diff] [blame]351'convertPointFromBase:',
avi@chromium.org23e6cbc2012-06-16 18:51:20[diff] [blame]352(
353'The use of -[NSView convertPointFromBase:] is almost certainly wrong.',
avi@chromium.org127f18ec2012-06-16 05:05:59[diff] [blame]354'Please use |convertPoint:(point) fromView:nil| instead.',
355'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts',
356),
357True,
358),
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]359BanRule(
avi@chromium.org127f18ec2012-06-16 05:05:59[diff] [blame]360'convertPointToBase:',
avi@chromium.org23e6cbc2012-06-16 18:51:20[diff] [blame]361(
362'The use of -[NSView convertPointToBase:] is almost certainly wrong.',
avi@chromium.org127f18ec2012-06-16 05:05:59[diff] [blame]363'Please use |convertPoint:(point) toView:nil| instead.',
364'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts',
365),
366True,
367),
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]368BanRule(
avi@chromium.org127f18ec2012-06-16 05:05:59[diff] [blame]369'convertRectFromBase:',
avi@chromium.org23e6cbc2012-06-16 18:51:20[diff] [blame]370(
371'The use of -[NSView convertRectFromBase:] is almost certainly wrong.',
avi@chromium.org127f18ec2012-06-16 05:05:59[diff] [blame]372'Please use |convertRect:(point) fromView:nil| instead.',
373'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts',
374),
375True,
376),
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]377BanRule(
avi@chromium.org127f18ec2012-06-16 05:05:59[diff] [blame]378'convertRectToBase:',
avi@chromium.org23e6cbc2012-06-16 18:51:20[diff] [blame]379(
380'The use of -[NSView convertRectToBase:] is almost certainly wrong.',
avi@chromium.org127f18ec2012-06-16 05:05:59[diff] [blame]381'Please use |convertRect:(point) toView:nil| instead.',
382'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts',
383),
384True,
385),
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]386BanRule(
avi@chromium.org127f18ec2012-06-16 05:05:59[diff] [blame]387'convertSizeFromBase:',
avi@chromium.org23e6cbc2012-06-16 18:51:20[diff] [blame]388(
389'The use of -[NSView convertSizeFromBase:] is almost certainly wrong.',
avi@chromium.org127f18ec2012-06-16 05:05:59[diff] [blame]390'Please use |convertSize:(point) fromView:nil| instead.',
391'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts',
392),
393True,
394),
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]395BanRule(
avi@chromium.org127f18ec2012-06-16 05:05:59[diff] [blame]396'convertSizeToBase:',
avi@chromium.org23e6cbc2012-06-16 18:51:20[diff] [blame]397(
398'The use of -[NSView convertSizeToBase:] is almost certainly wrong.',
avi@chromium.org127f18ec2012-06-16 05:05:59[diff] [blame]399'Please use |convertSize:(point) toView:nil| instead.',
400'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts',
401),
402True,
403),
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]404BanRule(
jif65398702016-10-27 10:19:48[diff] [blame]405 r"/\s+UTF8String\s*]",
406(
407'The use of -[NSString UTF8String] is dangerous as it can return null',
408'even if |canBeConvertedToEncoding:NSUTF8StringEncoding| returns YES.',
409'Please use |SysNSStringToUTF8| instead.',
410),
411True,
Marijn Kruisselbrink1b7c48952023-08-31 16:58:34[diff] [blame]412 excluded_paths=(
413'^third_party/ocmock/OCMock/',
414),
jif65398702016-10-27 10:19:48[diff] [blame]415),
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]416BanRule(
Sylvain Defresne4cf1d182017-09-18 14:16:34[diff] [blame]417 r'__unsafe_unretained',
418(
419'The use of __unsafe_unretained is almost certainly wrong, unless',
420'when interacting with NSFastEnumeration or NSInvocation.',
421'Please use __weak in files build with ARC, nothing otherwise.',
422),
423False,
424),
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]425BanRule(
Avi Drissman7382afa02019-04-29 23:27:13[diff] [blame]426'freeWhenDone:NO',
427(
428'The use of "freeWhenDone:NO" with the NoCopy creation of ',
429'Foundation types is prohibited.',
430),
431True,
432),
Avi Drissman3d243a42023-08-01 16:53:59[diff] [blame]433BanRule(
434'This file requires ARC support.',
435(
436'ARC compilation is default in Chromium; do not add boilerplate to ',
437'files that require ARC.',
438),
439True,
440),
avi@chromium.org127f18ec2012-06-16 05:05:59[diff] [blame]441)
442
Sylvain Defresnea8b73d252018-02-28 15:45:54[diff] [blame]443_BANNED_IOS_OBJC_FUNCTIONS=(
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]444BanRule(
Sylvain Defresnea8b73d252018-02-28 15:45:54[diff] [blame]445 r'/\bTEST[(]',
446(
447'TEST() macro should not be used in Objective-C++ code as it does not ',
448'drain the autorelease pool at the end of the test. Use TEST_F() ',
449'macro instead with a fixture inheriting from PlatformTest (or a ',
450'typedef).'
451),
452True,
453),
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]454BanRule(
Sylvain Defresnea8b73d252018-02-28 15:45:54[diff] [blame]455 r'/\btesting::Test\b',
456(
457'testing::Test should not be used in Objective-C++ code as it does ',
458'not drain the autorelease pool at the end of the test. Use ',
459'PlatformTest instead.'
460),
461True,
462),
Ewann2ecc8d72022-07-18 07:41:23[diff] [blame]463BanRule(
464' systemImageNamed:',
465(
466'+[UIImage systemImageNamed:] should not be used to create symbols.',
467'Instead use a wrapper defined in:',
Victor Vianna77a40f62023-01-31 19:04:53[diff] [blame]468'ios/chrome/browser/ui/icons/symbol_helpers.h'
Ewann2ecc8d72022-07-18 07:41:23[diff] [blame]469),
470True,
Ewann450a2ef2022-07-19 14:38:23[diff] [blame]471 excluded_paths=(
Gauthier Ambard4d8756b2023-04-07 17:26:41[diff] [blame]472'ios/chrome/browser/shared/ui/symbols/symbol_helpers.mm',
Gauthier Ambardd36c10b12023-03-16 08:45:03[diff] [blame]473'ios/chrome/search_widget_extension/',
Ewann450a2ef2022-07-19 14:38:23[diff] [blame]474),
Ewann2ecc8d72022-07-18 07:41:23[diff] [blame]475),
Sylvain Defresnea8b73d252018-02-28 15:45:54[diff] [blame]476)
477
Daniel Cheng917ce542022-03-15 20:46:57[diff] [blame]478_BANNED_IOS_EGTEST_FUNCTIONS:Sequence[BanRule]=(
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]479BanRule(
Peter K. Lee6c03ccff2019-07-15 14:40:05[diff] [blame]480 r'/\bEXPECT_OCMOCK_VERIFY\b',
481(
482'EXPECT_OCMOCK_VERIFY should not be used in EarlGrey tests because ',
483'it is meant for GTests. Use [mock verify] instead.'
484),
485True,
486),
487)
488
Daniel Cheng917ce542022-03-15 20:46:57[diff] [blame]489_BANNED_CPP_FUNCTIONS:Sequence[BanRule]=(
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]490BanRule(
Peter Kasting7c0d98a2023-10-06 15:42:39[diff] [blame]491'%#0',
492(
493'Zero-padded values that use "#" to add prefixes don\'t exhibit ',
494'consistent behavior, since the prefix is not prepended for zero ',
495'values. Use "0x%0..." instead.',
496),
497False,
498[_THIRD_PARTY_EXCEPT_BLINK],# Don't warn in third_party folders.
499),
500BanRule(
Peter Kasting94a56c42019-10-25 21:54:04[diff] [blame]501 r'/\busing namespace ',
502(
503'Using directives ("using namespace x") are banned by the Google Style',
504'Guide ( http://google.github.io/styleguide/cppguide.html#Namespaces ).',
505'Explicitly qualify symbols or use using declarations ("using x::foo").',
506),
507True,
508[_THIRD_PARTY_EXCEPT_BLINK],# Don't warn in third_party folders.
509),
Antonio Gomes07300d02019-03-13 20:59:57[diff] [blame]510# Make sure that gtest's FRIEND_TEST() macro is not used; the
511# FRIEND_TEST_ALL_PREFIXES() macro from base/gtest_prod_util.h should be
512# used instead since that allows for FLAKY_ and DISABLED_ prefixes.
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]513BanRule(
avi@chromium.org23e6cbc2012-06-16 18:51:20[diff] [blame]514'FRIEND_TEST(',
515(
jam@chromium.orge3c945502012-06-26 20:01:49[diff] [blame]516'Chromium code should not use gtest\'s FRIEND_TEST() macro. Include',
avi@chromium.org23e6cbc2012-06-16 18:51:20[diff] [blame]517'base/gtest_prod_util.h and use FRIEND_TEST_ALL_PREFIXES() instead.',
518),
519False,
Arthur Sonzogni19aa4922023-08-28 17:28:59[diff] [blame]520 excluded_paths=(
521"base/gtest_prod_util.h",
Arthur Sonzogni0bcc0232023-10-03 08:48:32[diff] [blame]522"base/allocator/partition_allocator/src/partition_alloc/partition_alloc_base/gtest_prod_util.h",
Arthur Sonzogni19aa4922023-08-28 17:28:59[diff] [blame]523),
avi@chromium.org23e6cbc2012-06-16 18:51:20[diff] [blame]524),
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]525BanRule(
tomhudsone2c14d552016-05-26 17:07:46[diff] [blame]526'setMatrixClip',
527(
528'Overriding setMatrixClip() is prohibited; ',
529'the base function is deprecated. ',
530),
531True,
532(),
533),
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]534BanRule(
enne@chromium.org52657f62013-05-20 05:30:31[diff] [blame]535'SkRefPtr',
536(
537'The use of SkRefPtr is prohibited. ',
tomhudson7e6e0512016-04-19 19:27:22[diff] [blame]538'Please use sk_sp<> instead.'
enne@chromium.org52657f62013-05-20 05:30:31[diff] [blame]539),
540True,
541(),
542),
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]543BanRule(
enne@chromium.org52657f62013-05-20 05:30:31[diff] [blame]544'SkAutoRef',
545(
546'The indirect use of SkRefPtr via SkAutoRef is prohibited. ',
tomhudson7e6e0512016-04-19 19:27:22[diff] [blame]547'Please use sk_sp<> instead.'
enne@chromium.org52657f62013-05-20 05:30:31[diff] [blame]548),
549True,
550(),
551),
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]552BanRule(
enne@chromium.org52657f62013-05-20 05:30:31[diff] [blame]553'SkAutoTUnref',
554(
555'The use of SkAutoTUnref is dangerous because it implicitly ',
tomhudson7e6e0512016-04-19 19:27:22[diff] [blame]556'converts to a raw pointer. Please use sk_sp<> instead.'
enne@chromium.org52657f62013-05-20 05:30:31[diff] [blame]557),
558True,
559(),
560),
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]561BanRule(
enne@chromium.org52657f62013-05-20 05:30:31[diff] [blame]562'SkAutoUnref',
563(
564'The indirect use of SkAutoTUnref through SkAutoUnref is dangerous ',
565'because it implicitly converts to a raw pointer. ',
tomhudson7e6e0512016-04-19 19:27:22[diff] [blame]566'Please use sk_sp<> instead.'
enne@chromium.org52657f62013-05-20 05:30:31[diff] [blame]567),
568True,
569(),
570),
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]571BanRule(
mark@chromium.orgd89eec82013-12-03 14:10:59[diff] [blame]572 r'/HANDLE_EINTR\(.*close',
573(
574'HANDLE_EINTR(close) is invalid. If close fails with EINTR, the file',
575'descriptor will be closed, and it is incorrect to retry the close.',
576'Either call close directly and ignore its return value, or wrap close',
577'in IGNORE_EINTR to use its return value. See http://crbug.com/269623'
578),
579True,
580(),
581),
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]582BanRule(
mark@chromium.orgd89eec82013-12-03 14:10:59[diff] [blame]583 r'/IGNORE_EINTR\((?!.*close)',
584(
585'IGNORE_EINTR is only valid when wrapping close. To wrap other system',
586'calls, use HANDLE_EINTR. See http://crbug.com/269623',
587),
588True,
589(
590# Files that #define IGNORE_EINTR.
Bruce Dawson40fece62022-09-16 19:58:31[diff] [blame]591 r'^base/posix/eintr_wrapper\.h$',
592 r'^ppapi/tests/test_broker\.cc$',
mark@chromium.orgd89eec82013-12-03 14:10:59[diff] [blame]593),
594),
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]595BanRule(
jochen@chromium.orgec5b3f02014-04-04 18:43:43[diff] [blame]596 r'/v8::Extension\(',
597(
598'Do not introduce new v8::Extensions into the code base, use',
599'gin::Wrappable instead. See http://crbug.com/334679',
600),
601True,
rockot@chromium.orgf55c90ee62014-04-12 00:50:03[diff] [blame]602(
Bruce Dawson40fece62022-09-16 19:58:31[diff] [blame]603 r'extensions/renderer/safe_builtins\.*',
rockot@chromium.orgf55c90ee62014-04-12 00:50:03[diff] [blame]604),
jochen@chromium.orgec5b3f02014-04-04 18:43:43[diff] [blame]605),
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]606BanRule(
jame2d1a952016-04-02 00:27:10[diff] [blame]607'#pragma comment(lib,',
608(
609'Specify libraries to link with in build files and not in the source.',
610),
611True,
Mirko Bonadeif4f0f0e2018-04-12 09:29:41[diff] [blame]612(
Bruce Dawson40fece62022-09-16 19:58:31[diff] [blame]613 r'^base/third_party/symbolize/.*',
614 r'^third_party/abseil-cpp/.*',
Mirko Bonadeif4f0f0e2018-04-12 09:29:41[diff] [blame]615),
jame2d1a952016-04-02 00:27:10[diff] [blame]616),
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]617BanRule(
Gabriel Charette7cc6c432018-04-25 20:52:02[diff] [blame]618 r'/base::SequenceChecker\b',
gabd52c912a2017-05-11 04:15:59[diff] [blame]619(
620'Consider using SEQUENCE_CHECKER macros instead of the class directly.',
621),
622False,
623(),
624),
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]625BanRule(
Gabriel Charette7cc6c432018-04-25 20:52:02[diff] [blame]626 r'/base::ThreadChecker\b',
gabd52c912a2017-05-11 04:15:59[diff] [blame]627(
628'Consider using THREAD_CHECKER macros instead of the class directly.',
629),
630False,
631(),
632),
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]633BanRule(
Sean Maher03efef12022-09-23 22:43:13[diff] [blame]634 r'/\b(?!(Sequenced|SingleThread))\w*TaskRunner::(GetCurrentDefault|CurrentDefaultHandle)',
635(
636'It is not allowed to call these methods from the subclasses ',
637'of Sequenced or SingleThread task runners.',
638),
639True,
640(),
641),
642BanRule(
Yuri Wiitala2f8de5c2017-07-21 00:11:06[diff] [blame]643 r'/(Time(|Delta|Ticks)|ThreadTicks)::FromInternalValue|ToInternalValue',
644(
645'base::TimeXXX::FromInternalValue() and ToInternalValue() are',
646'deprecated (http://crbug.com/634507). Please avoid converting away',
647'from the Time types in Chromium code, especially if any math is',
648'being done on time values. For interfacing with platform/library',
Peter Kasting8a2605652023-09-14 03:57:15[diff] [blame]649'APIs, use base::Time::(From,To)DeltaSinceWindowsEpoch() or',
650'base::{TimeDelta::In}Microseconds(), or one of the other type',
651'converter methods instead. For faking TimeXXX values (for unit',
Peter Kasting53fd6ee2021-10-05 20:40:48[diff] [blame]652'testing only), use TimeXXX() + Microseconds(N). For',
Yuri Wiitala2f8de5c2017-07-21 00:11:06[diff] [blame]653'other use cases, please contact base/time/OWNERS.',
654),
655False,
Arthur Sonzogni19aa4922023-08-28 17:28:59[diff] [blame]656 excluded_paths=(
657"base/time/time.h",
Arthur Sonzogni0bcc0232023-10-03 08:48:32[diff] [blame]658"base/allocator/partition_allocator/src/partition_alloc/partition_alloc_base/time/time.h",
Arthur Sonzogni19aa4922023-08-28 17:28:59[diff] [blame]659),
Yuri Wiitala2f8de5c2017-07-21 00:11:06[diff] [blame]660),
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]661BanRule(
dbeamb6f4fde2017-06-15 04:03:06[diff] [blame]662'CallJavascriptFunctionUnsafe',
663(
664"Don't use CallJavascriptFunctionUnsafe() in new code. Instead, use",
665'AllowJavascript(), OnJavascriptAllowed()/OnJavascriptDisallowed(),',
666'and CallJavascriptFunction(). See https://goo.gl/qivavq.',
667),
668False,
669(
Bruce Dawson40fece62022-09-16 19:58:31[diff] [blame]670 r'^content/browser/webui/web_ui_impl\.(cc|h)$',
671 r'^content/public/browser/web_ui\.h$',
672 r'^content/public/test/test_web_ui\.(cc|h)$',
dbeamb6f4fde2017-06-15 04:03:06[diff] [blame]673),
674),
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]675BanRule(
dskiba1474c2bfd62017-07-20 02:19:24[diff] [blame]676'leveldb::DB::Open',
677(
678'Instead of leveldb::DB::Open() use leveldb_env::OpenDB() from',
679'third_party/leveldatabase/env_chromium.h. It exposes databases to',
680"Chrome's tracing, making their memory usage visible.",
681),
682True,
683(
684 r'^third_party/leveldatabase/.*\.(cc|h)$',
685),
Gabriel Charette0592c3a2017-07-26 12:02:04[diff] [blame]686),
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]687BanRule(
Chris Mumfordc38afb62017-10-09 17:55:08[diff] [blame]688'leveldb::NewMemEnv',
689(
690'Instead of leveldb::NewMemEnv() use leveldb_chrome::NewMemEnv() from',
Chris Mumford8d26d10a2018-04-20 17:07:58[diff] [blame]691'third_party/leveldatabase/leveldb_chrome.h. It exposes environments',
692"to Chrome's tracing, making their memory usage visible.",
Chris Mumfordc38afb62017-10-09 17:55:08[diff] [blame]693),
694True,
695(
696 r'^third_party/leveldatabase/.*\.(cc|h)$',
697),
698),
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]699BanRule(
Gabriel Charetted9839bc2017-07-29 14:17:47[diff] [blame]700'RunLoop::QuitCurrent',
701(
Robert Liao64b7ab22017-08-04 23:03:43[diff] [blame]702'Please migrate away from RunLoop::QuitCurrent*() methods. Use member',
703'methods of a specific RunLoop instance instead.',
Gabriel Charetted9839bc2017-07-29 14:17:47[diff] [blame]704),
Gabriel Charettec0a8f3ee2018-04-25 20:49:41[diff] [blame]705False,
Gabriel Charetted9839bc2017-07-29 14:17:47[diff] [blame]706(),
Gabriel Charettea44975052017-08-21 23:14:04[diff] [blame]707),
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]708BanRule(
Gabriel Charettea44975052017-08-21 23:14:04[diff] [blame]709'base::ScopedMockTimeMessageLoopTaskRunner',
710(
Gabriel Charette87cc1af2018-04-25 20:52:51[diff] [blame]711'ScopedMockTimeMessageLoopTaskRunner is deprecated. Prefer',
Gabriel Charettedfa36042019-08-19 17:30:11[diff] [blame]712'TaskEnvironment::TimeSource::MOCK_TIME. There are still a',
Gabriel Charette87cc1af2018-04-25 20:52:51[diff] [blame]713'few cases that may require a ScopedMockTimeMessageLoopTaskRunner',
714'(i.e. mocking the main MessageLoopForUI in browser_tests), but check',
715'with gab@ first if you think you need it)',
Gabriel Charettea44975052017-08-21 23:14:04[diff] [blame]716),
Gabriel Charette87cc1af2018-04-25 20:52:51[diff] [blame]717False,
Gabriel Charettea44975052017-08-21 23:14:04[diff] [blame]718(),
Eric Stevenson6b47b44c2017-08-30 20:41:57[diff] [blame]719),
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]720BanRule(
Dave Tapuska98199b612019-07-10 13:30:44[diff] [blame]721'std::regex',
Eric Stevenson6b47b44c2017-08-30 20:41:57[diff] [blame]722(
723'Using std::regex adds unnecessary binary size to Chrome. Please use',
Mostyn Bramley-Moore6b427322017-12-21 22:11:02[diff] [blame]724're2::RE2 instead (crbug.com/755321)',
Eric Stevenson6b47b44c2017-08-30 20:41:57[diff] [blame]725),
726True,
Robert Ogden4c43a712023-06-28 22:03:19[diff] [blame]727[
728# Abseil's benchmarks never linked into chrome.
729'third_party/abseil-cpp/.*_benchmark.cc',
Robert Ogden4c43a712023-06-28 22:03:19[diff] [blame]730],
Francois Doray43670e32017-09-27 12:40:38[diff] [blame]731),
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]732BanRule(
Peter Kastinge2c5ee82023-02-15 17:23:08[diff] [blame]733 r'/\bstd::sto(i|l|ul|ll|ull)\b',
Peter Kasting991618a62019-06-17 22:00:09[diff] [blame]734(
Peter Kastinge2c5ee82023-02-15 17:23:08[diff] [blame]735'std::sto{i,l,ul,ll,ull}() use exceptions to communicate results. ',
736'Use base::StringTo[U]Int[64]() instead.',
Peter Kasting991618a62019-06-17 22:00:09[diff] [blame]737),
738True,
739[_THIRD_PARTY_EXCEPT_BLINK],# Don't warn in third_party folders.
740),
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]741BanRule(
Peter Kastinge2c5ee82023-02-15 17:23:08[diff] [blame]742 r'/\bstd::sto(f|d|ld)\b',
Peter Kasting991618a62019-06-17 22:00:09[diff] [blame]743(
Peter Kastinge2c5ee82023-02-15 17:23:08[diff] [blame]744'std::sto{f,d,ld}() use exceptions to communicate results. ',
Peter Kasting991618a62019-06-17 22:00:09[diff] [blame]745'For locale-independent values, e.g. reading numbers from disk',
746'profiles, use base::StringToDouble().',
747'For user-visible values, parse using ICU.',
748),
749True,
750[_THIRD_PARTY_EXCEPT_BLINK],# Don't warn in third_party folders.
751),
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]752BanRule(
Daniel Bratell69334cc2019-03-26 11:07:45[diff] [blame]753 r'/\bstd::to_string\b',
754(
Peter Kastinge2c5ee82023-02-15 17:23:08[diff] [blame]755'std::to_string() is locale dependent and slower than alternatives.',
Peter Kasting991618a62019-06-17 22:00:09[diff] [blame]756'For locale-independent strings, e.g. writing numbers to disk',
757'profiles, use base::NumberToString().',
Daniel Bratell69334cc2019-03-26 11:07:45[diff] [blame]758'For user-visible strings, use base::FormatNumber() and',
759'the related functions in base/i18n/number_formatting.h.',
760),
Peter Kasting991618a62019-06-17 22:00:09[diff] [blame]761False,# Only a warning since it is already used.
Daniel Bratell609102be2019-03-27 20:53:21[diff] [blame]762[_THIRD_PARTY_EXCEPT_BLINK],# Don't warn in third_party folders.
Daniel Bratell69334cc2019-03-26 11:07:45[diff] [blame]763),
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]764BanRule(
Peter Kasting6f79b202023-08-09 21:25:41[diff] [blame]765 r'/#include <(cctype|ctype\.h|cwctype|wctype.h)>',
766(
767'<cctype>/<ctype.h>/<cwctype>/<wctype.h> are banned. Use',
768'"third_party/abseil-cpp/absl/strings/ascii.h" instead.',
769),
770True,
771[_THIRD_PARTY_EXCEPT_BLINK],# Not an error in third_party folders.
772),
773BanRule(
Daniel Bratell69334cc2019-03-26 11:07:45[diff] [blame]774 r'/\bstd::shared_ptr\b',
775(
Peter Kastinge2c5ee82023-02-15 17:23:08[diff] [blame]776'std::shared_ptr is banned. Use scoped_refptr instead.',
Daniel Bratell69334cc2019-03-26 11:07:45[diff] [blame]777),
778True,
Ulan Degenbaev947043882021-02-10 14:02:31[diff] [blame]779[
780# Needed for interop with third-party library.
781'^third_party/blink/renderer/core/typed_arrays/array_buffer/'+
Alex Chau9eb03cdd52020-07-13 21:04:57[diff] [blame]782'array_buffer_contents\.(cc|h)',
Ben Kelly39bf6bef2021-10-04 22:54:58[diff] [blame]783'^third_party/blink/renderer/bindings/core/v8/'+
784'v8_wasm_response_extensions.cc',
Wez5f56be52021-05-04 09:30:58[diff] [blame]785'^gin/array_buffer\.(cc|h)',
Jiahe Zhange97ba772023-07-27 02:46:41[diff] [blame]786'^gin/per_isolate_data\.(cc|h)',
Wez5f56be52021-05-04 09:30:58[diff] [blame]787'^chrome/services/sharing/nearby/',
Stephen Nuskoe09c8ef22022-09-29 00:47:28[diff] [blame]788# Needed for interop with third-party library libunwindstack.
Stephen Nuskoe51c1382022-09-26 15:49:03[diff] [blame]789'^base/profiler/libunwindstack_unwinder_android\.(cc|h)',
Thiabaud Engelbrecht42e09812023-08-29 21:19:30[diff] [blame]790'^base/profiler/native_unwinder_android_memory_regions_map_impl.(cc|h)',
Bob Beck03509d282022-12-07 21:49:05[diff] [blame]791# Needed for interop with third-party boringssl cert verifier
792'^third_party/boringssl/',
793'^net/cert/',
794'^net/tools/cert_verify_tool/',
795'^services/cert_verifier/',
796'^components/certificate_transparency/',
797'^components/media_router/common/providers/cast/certificate/',
Meilin Wang00efc7c2021-05-13 01:12:42[diff] [blame]798# gRPC provides some C++ libraries that use std::shared_ptr<>.
Yeunjoo Choi1b644402022-08-25 02:36:10[diff] [blame]799'^chromeos/ash/services/libassistant/grpc/',
Vigen Issahhanjanfdf9de52021-12-22 21:13:59[diff] [blame]800'^chromecast/cast_core/grpc',
801'^chromecast/cast_core/runtime/browser',
Yue Shef83d95202022-09-26 20:23:45[diff] [blame]802'^ios/chrome/test/earl_grey/chrome_egtest_plugin_client\.(mm|h)',
Wez5f56be52021-05-04 09:30:58[diff] [blame]803# Fuchsia provides C++ libraries that use std::shared_ptr<>.
Wez6da2e412022-11-23 11:28:48[diff] [blame]804'^base/fuchsia/.*\.(cc|h)',
Wez5f56be52021-05-04 09:30:58[diff] [blame]805'.*fuchsia.*test\.(cc|h)',
miktb599ed12023-05-26 07:03:56[diff] [blame]806# Clang plugins have different build config.
807'^tools/clang/plugins/',
Alex Chau9eb03cdd52020-07-13 21:04:57[diff] [blame]808 _THIRD_PARTY_EXCEPT_BLINK],# Not an error in third_party folders.
Daniel Bratell609102be2019-03-27 20:53:21[diff] [blame]809),
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]810BanRule(
Peter Kasting991618a62019-06-17 22:00:09[diff] [blame]811 r'/\bstd::weak_ptr\b',
812(
Peter Kastinge2c5ee82023-02-15 17:23:08[diff] [blame]813'std::weak_ptr is banned. Use base::WeakPtr instead.',
Peter Kasting991618a62019-06-17 22:00:09[diff] [blame]814),
815True,
816[_THIRD_PARTY_EXCEPT_BLINK],# Not an error in third_party folders.
817),
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]818BanRule(
Daniel Bratell609102be2019-03-27 20:53:21[diff] [blame]819 r'/\blong long\b',
820(
Peter Kastinge2c5ee82023-02-15 17:23:08[diff] [blame]821'long long is banned. Use [u]int64_t instead.',
Daniel Bratell609102be2019-03-27 20:53:21[diff] [blame]822),
823False,# Only a warning since it is already used.
824[_THIRD_PARTY_EXCEPT_BLINK],# Don't warn in third_party folders.
825),
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]826BanRule(
Daniel Cheng192683f2022-11-01 20:52:44[diff] [blame]827 r'/\b(absl|std)::any\b',
Daniel Chengc05fcc62022-01-12 16:54:29[diff] [blame]828(
Peter Kastinge2c5ee82023-02-15 17:23:08[diff] [blame]829'{absl,std}::any are banned due to incompatibility with the component ',
830'build.',
Daniel Chengc05fcc62022-01-12 16:54:29[diff] [blame]831),
832True,
833# Not an error in third party folders, though it probably should be :)
834[_THIRD_PARTY_EXCEPT_BLINK],
835),
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]836BanRule(
Daniel Bratell609102be2019-03-27 20:53:21[diff] [blame]837 r'/\bstd::bind\b',
838(
Peter Kastinge2c5ee82023-02-15 17:23:08[diff] [blame]839'std::bind() is banned because of lifetime risks. Use ',
840'base::Bind{Once,Repeating}() instead.',
Daniel Bratell609102be2019-03-27 20:53:21[diff] [blame]841),
842True,
843[_THIRD_PARTY_EXCEPT_BLINK],# Not an error in third_party folders.
844),
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]845BanRule(
Daniel Cheng192683f2022-11-01 20:52:44[diff] [blame]846(
Peter Kastingc7460d982023-03-14 21:01:42[diff] [blame]847 r'/\bstd::(?:'
848 r'linear_congruential_engine|mersenne_twister_engine|'
849 r'subtract_with_carry_engine|discard_block_engine|'
850 r'independent_bits_engine|shuffle_order_engine|'
851 r'minstd_rand0?|mt19937(_64)?|ranlux(24|48)(_base)?|knuth_b|'
852 r'default_random_engine|'
853 r'random_device|'
854 r'seed_seq'
Daniel Cheng192683f2022-11-01 20:52:44[diff] [blame]855 r')\b'
856),
857(
858'STL random number engines and generators are banned. Use the ',
859'helpers in base/rand_util.h instead, e.g. base::RandBytes() or ',
860'base::RandomBitGenerator.'
Daniel Cheng57d967762023-10-10 19:03:06[diff] [blame]861'',
862'Please reach out to cxx@chromium.org if the base APIs are ',
863'insufficient for your needs.',
Daniel Cheng192683f2022-11-01 20:52:44[diff] [blame]864),
865True,
866[
867# Not an error in third_party folders.
868 _THIRD_PARTY_EXCEPT_BLINK,
869# Various tools which build outside of Chrome.
870 r'testing/libfuzzer',
871 r'tools/android/io_benchmark/',
872# Fuzzers are allowed to use standard library random number generators
873# since fuzzing speed + reproducibility is important.
874 r'tools/ipc_fuzzer/',
875 r'.+_fuzzer\.cc$',
876 r'.+_fuzzertest\.cc$',
877# TODO(https://crbug.com/1380528): These are all unsanctioned uses of
878# the standard library's random number generators, and should be
879# migrated to the //base equivalent.
880 r'ash/ambient/model/ambient_topic_queue\.cc',
Arthur Sonzogni0bcc0232023-10-03 08:48:32[diff] [blame]881 r'base/allocator/partition_allocator/src/partition_alloc/partition_alloc_unittest\.cc',
Daniel Cheng192683f2022-11-01 20:52:44[diff] [blame]882 r'base/ranges/algorithm_unittest\.cc',
883 r'base/test/launcher/test_launcher\.cc',
884 r'cc/metrics/video_playback_roughness_reporter_unittest\.cc',
885 r'chrome/browser/apps/app_service/metrics/website_metrics\.cc',
886 r'chrome/browser/ash/power/auto_screen_brightness/monotone_cubic_spline_unittest\.cc',
887 r'chrome/browser/ash/printing/zeroconf_printer_detector_unittest\.cc',
888 r'chrome/browser/nearby_sharing/contacts/nearby_share_contact_manager_impl_unittest\.cc',
889 r'chrome/browser/nearby_sharing/contacts/nearby_share_contacts_sorter_unittest\.cc',
890 r'chrome/browser/privacy_budget/mesa_distribution_unittest\.cc',
891 r'chrome/browser/web_applications/test/web_app_test_utils\.cc',
892 r'chrome/browser/web_applications/test/web_app_test_utils\.cc',
893 r'chrome/browser/win/conflicts/module_blocklist_cache_util_unittest\.cc',
894 r'chrome/chrome_cleaner/logging/detailed_info_sampler\.cc',
895 r'chromeos/ash/components/memory/userspace_swap/swap_storage_unittest\.cc',
896 r'chromeos/ash/components/memory/userspace_swap/userspace_swap\.cc',
897 r'components/metrics/metrics_state_manager\.cc',
898 r'components/omnibox/browser/history_quick_provider_performance_unittest\.cc',
899 r'components/zucchini/disassembler_elf_unittest\.cc',
900 r'content/browser/webid/federated_auth_request_impl\.cc',
901 r'content/browser/webid/federated_auth_request_impl\.cc',
902 r'media/cast/test/utility/udp_proxy\.h',
903 r'sql/recover_module/module_unittest\.cc',
Samarc64873a72023-10-10 09:19:12[diff] [blame]904 r'components/search_engines/template_url_prepopulate_data.cc',
Daniel Cheng57d967762023-10-10 19:03:06[diff] [blame]905# Do not add new entries to this list. If you have a use case which is
906# not satisfied by the current APIs (i.e. you need an explicitly-seeded
907# sequence, or stability of some sort is required), please contact
908# cxx@chromium.org.
Daniel Cheng192683f2022-11-01 20:52:44[diff] [blame]909],
910),
911BanRule(
Peter Kastinge2c5ee82023-02-15 17:23:08[diff] [blame]912 r'/\b(absl,std)::bind_front\b',
Peter Kasting4f35bfc2022-10-18 18:39:12[diff] [blame]913(
Peter Kastinge2c5ee82023-02-15 17:23:08[diff] [blame]914'{absl,std}::bind_front() are banned. Use base::Bind{Once,Repeating}() '
915'instead.',
Peter Kasting4f35bfc2022-10-18 18:39:12[diff] [blame]916),
917True,
918[_THIRD_PARTY_EXCEPT_BLINK],# Not an error in third_party folders.
919),
920BanRule(
921 r'/\bABSL_FLAG\b',
922(
923'ABSL_FLAG is banned. Use base::CommandLine instead.',
924),
925True,
926[_THIRD_PARTY_EXCEPT_BLINK],# Not an error in third_party folders.
927),
928BanRule(
929 r'/\babsl::c_',
930(
Peter Kastinge2c5ee82023-02-15 17:23:08[diff] [blame]931'Abseil container utilities are banned. Use base/ranges/algorithm.h ',
Peter Kasting4f35bfc2022-10-18 18:39:12[diff] [blame]932'instead.',
933),
934True,
935[_THIRD_PARTY_EXCEPT_BLINK],# Not an error in third_party folders.
936),
937BanRule(
Peter Kasting431239a2023-09-29 03:11:44[diff] [blame]938 r'/\babsl::FixedArray\b',
939(
940'absl::FixedArray is banned. Use base::FixedArray instead.',
941),
942True,
943[
944# base::FixedArray provides canonical access.
945 r'^base/types/fixed_array.h',
946# Not an error in third_party folders.
947 _THIRD_PARTY_EXCEPT_BLINK,
948],
949),
950BanRule(
Peter Kasting4f35bfc2022-10-18 18:39:12[diff] [blame]951 r'/\babsl::FunctionRef\b',
952(
953'absl::FunctionRef is banned. Use base::FunctionRef instead.',
954),
955True,
956[
957# base::Bind{Once,Repeating} references absl::FunctionRef to disallow
958# interoperability.
959 r'^base/functional/bind_internal\.h',
960# base::FunctionRef is implemented on top of absl::FunctionRef.
961 r'^base/functional/function_ref.*\..+',
962# Not an error in third_party folders.
963 _THIRD_PARTY_EXCEPT_BLINK,
964],
965),
966BanRule(
967 r'/\babsl::(Insecure)?BitGen\b',
968(
Daniel Cheng192683f2022-11-01 20:52:44[diff] [blame]969'absl random number generators are banned. Use the helpers in '
970'base/rand_util.h instead, e.g. base::RandBytes() or ',
971'base::RandomBitGenerator.'
Peter Kasting4f35bfc2022-10-18 18:39:12[diff] [blame]972),
973True,
974[_THIRD_PARTY_EXCEPT_BLINK],# Not an error in third_party folders.
975),
976BanRule(
Peter Kastinge2c5ee82023-02-15 17:23:08[diff] [blame]977 r'/(\babsl::Span\b|#include <span>)',
Peter Kasting4f35bfc2022-10-18 18:39:12[diff] [blame]978(
Peter Kastinge2c5ee82023-02-15 17:23:08[diff] [blame]979'absl::Span is banned and <span> is not allowed yet ',
980'(https://crbug.com/1414652). Use base::span instead.',
Peter Kasting4f35bfc2022-10-18 18:39:12[diff] [blame]981),
982True,
Victor Vasiliev23b9ea6a2023-01-05 19:42:29[diff] [blame]983[
984# Needed to use QUICHE API.
985 r'services/network/web_transport\.cc',
Brianna Goldstein846d8002023-05-16 19:24:30[diff] [blame]986 r'chrome/browser/ip_protection/.*',
Victor Vasiliev23b9ea6a2023-01-05 19:42:29[diff] [blame]987# Not an error in third_party folders.
988 _THIRD_PARTY_EXCEPT_BLINK
989],
Peter Kasting4f35bfc2022-10-18 18:39:12[diff] [blame]990),
991BanRule(
992 r'/\babsl::StatusOr\b',
993(
994'absl::StatusOr is banned. Use base::expected instead.',
995),
996True,
Adithya Srinivasanb2041882022-10-21 19:34:20[diff] [blame]997[
998# Needed to use liburlpattern API.
999 r'third_party/blink/renderer/core/url_pattern/.*',
Louise Brettc6d23872023-04-11 02:48:32[diff] [blame]1000 r'third_party/blink/renderer/modules/manifest/manifest_parser\.cc',
Brianna Goldstein846d8002023-05-16 19:24:30[diff] [blame]1001# Needed to use QUICHE API.
1002 r'chrome/browser/ip_protection/.*',
Piotr Bialecki7f2549fd2023-10-17 17:49:46[diff] [blame]1003# Needed to use MediaPipe API.
1004 r'components/media_effects/.*\.cc',
Adithya Srinivasanb2041882022-10-21 19:34:20[diff] [blame]1005# Not an error in third_party folders.
1006 _THIRD_PARTY_EXCEPT_BLINK
1007],
Peter Kasting4f35bfc2022-10-18 18:39:12[diff] [blame]1008),
1009BanRule(
1010 r'/\babsl::StrFormat\b',
1011(
Peter Kastinge2c5ee82023-02-15 17:23:08[diff] [blame]1012'absl::StrFormat() is not allowed yet (https://crbug.com/1371963). ',
1013'Use base::StringPrintf() instead.',
Peter Kasting4f35bfc2022-10-18 18:39:12[diff] [blame]1014),
1015True,
1016[_THIRD_PARTY_EXCEPT_BLINK],# Not an error in third_party folders.
1017),
1018BanRule(
Peter Kasting4f35bfc2022-10-18 18:39:12[diff] [blame]1019 r'/\babsl::(StrSplit|StrJoin|StrCat|StrAppend|Substitute|StrContains)\b',
1020(
1021'Abseil string utilities are banned. Use base/strings instead.',
1022),
1023True,
1024[_THIRD_PARTY_EXCEPT_BLINK],# Not an error in third_party folders.
1025),
1026BanRule(
1027 r'/\babsl::(Mutex|CondVar|Notification|Barrier|BlockingCounter)\b',
1028(
1029'Abseil synchronization primitives are banned. Use',
1030'base/synchronization instead.',
1031),
1032True,
1033[_THIRD_PARTY_EXCEPT_BLINK],# Not an error in third_party folders.
1034),
1035BanRule(
1036 r'/\babsl::(Duration|Time|TimeZone|CivilDay)\b',
1037(
1038'Abseil\'s time library is banned. Use base/time instead.',
1039),
1040True,
Dustin J. Mitchell626a6d322023-06-26 15:02:48[diff] [blame]1041[
1042# Needed to use QUICHE API.
1043 r'chrome/browser/ip_protection/.*',
Victor Vasilieva8638882023-09-25 16:41:04[diff] [blame]1044 r'services/network/web_transport.*',
Dustin J. Mitchell626a6d322023-06-26 15:02:48[diff] [blame]1045 _THIRD_PARTY_EXCEPT_BLINK# Not an error in third_party folders.
1046],
Peter Kasting4f35bfc2022-10-18 18:39:12[diff] [blame]1047),
1048BanRule(
Peter Kastinge2c5ee82023-02-15 17:23:08[diff] [blame]1049 r'/#include <chrono>',
Daniel Bratell609102be2019-03-27 20:53:21[diff] [blame]1050(
Peter Kastinge2c5ee82023-02-15 17:23:08[diff] [blame]1051'<chrono> is banned. Use base/time instead.',
Daniel Bratell609102be2019-03-27 20:53:21[diff] [blame]1052),
1053True,
Arthur Sonzogni2ee5e382023-09-11 09:13:03[diff] [blame]1054[
1055# Not an error in third_party folders:
1056 _THIRD_PARTY_EXCEPT_BLINK,
1057# PartitionAlloc's starscan, doesn't depend on base/. It can't use
1058# base::ConditionalVariable::TimedWait(..).
Arthur Sonzogni0bcc0232023-10-03 08:48:32[diff] [blame]1059"base/allocator/partition_allocator/src/partition_alloc/starscan/pcscan_internal.cc",
Arthur Sonzogni2ee5e382023-09-11 09:13:03[diff] [blame]1060]
Daniel Bratell609102be2019-03-27 20:53:21[diff] [blame]1061),
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]1062BanRule(
Peter Kastinge2c5ee82023-02-15 17:23:08[diff] [blame]1063 r'/#include <exception>',
Daniel Bratell609102be2019-03-27 20:53:21[diff] [blame]1064(
1065'Exceptions are banned and disabled in Chromium.',
1066),
1067True,
1068[_THIRD_PARTY_EXCEPT_BLINK],# Not an error in third_party folders.
1069),
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]1070BanRule(
Daniel Bratell609102be2019-03-27 20:53:21[diff] [blame]1071 r'/\bstd::function\b',
1072(
Peter Kastinge2c5ee82023-02-15 17:23:08[diff] [blame]1073'std::function is banned. Use base::{Once,Repeating}Callback instead.',
Daniel Bratell609102be2019-03-27 20:53:21[diff] [blame]1074),
Daniel Chenge5583e3c2022-09-22 00:19:41[diff] [blame]1075True,
Daniel Chengcd23b8b2022-09-16 17:16:24[diff] [blame]1076[
1077# Has tests that template trait helpers don't unintentionally match
1078# std::function.
Daniel Chenge5583e3c2022-09-22 00:19:41[diff] [blame]1079 r'base/functional/callback_helpers_unittest\.cc',
1080# Required to implement interfaces from the third-party perfetto
1081# library.
1082 r'base/tracing/perfetto_task_runner\.cc',
1083 r'base/tracing/perfetto_task_runner\.h',
1084# Needed for interop with the third-party nearby library type
1085# location::nearby::connections::ResultCallback.
1086'chrome/services/sharing/nearby/nearby_connections_conversions\.cc'
1087# Needed for interop with the internal libassistant library.
1088'chromeos/ash/services/libassistant/callback_utils\.h',
1089# Needed for interop with Fuchsia fidl APIs.
1090'fuchsia_web/webengine/browser/context_impl_browsertest\.cc',
1091'fuchsia_web/webengine/browser/cookie_manager_impl_unittest\.cc',
1092'fuchsia_web/webengine/browser/media_player_impl_unittest\.cc',
1093# Required to interop with interfaces from the third-party perfetto
1094# library.
1095'services/tracing/public/cpp/perfetto/custom_event_recorder\.cc',
1096'services/tracing/public/cpp/perfetto/perfetto_traced_process\.cc',
1097'services/tracing/public/cpp/perfetto/perfetto_traced_process\.h',
1098'services/tracing/public/cpp/perfetto/perfetto_tracing_backend\.cc',
1099'services/tracing/public/cpp/perfetto/producer_client\.cc',
1100'services/tracing/public/cpp/perfetto/producer_client\.h',
1101'services/tracing/public/cpp/perfetto/producer_test_utils\.cc',
1102'services/tracing/public/cpp/perfetto/producer_test_utils\.h',
1103# Required for interop with the third-party webrtc library.
1104'third_party/blink/renderer/modules/peerconnection/mock_peer_connection_impl\.cc',
1105'third_party/blink/renderer/modules/peerconnection/mock_peer_connection_impl\.h',
Daniel Chenge5583e3c2022-09-22 00:19:41[diff] [blame]1106# TODO(https://crbug.com/1364577): Various uses that should be
1107# migrated to something else.
1108# Should use base::OnceCallback or base::RepeatingCallback.
1109'base/allocator/dispatcher/initializer_unittest\.cc',
1110'chrome/browser/ash/accessibility/speech_monitor\.cc',
1111'chrome/browser/ash/accessibility/speech_monitor\.h',
1112'chrome/browser/ash/login/ash_hud_login_browsertest\.cc',
1113'chromecast/base/observer_unittest\.cc',
1114'chromecast/browser/cast_web_view\.h',
1115'chromecast/public/cast_media_shlib\.h',
1116'device/bluetooth/floss/exported_callback_manager\.h',
1117'device/bluetooth/floss/floss_dbus_client\.h',
1118'device/fido/cable/v2_handshake_unittest\.cc',
1119'device/fido/pin\.cc',
1120'services/tracing/perfetto/test_utils\.h',
1121# Should use base::FunctionRef.
1122'chrome/browser/media/webrtc/test_stats_dictionary\.cc',
1123'chrome/browser/media/webrtc/test_stats_dictionary\.h',
1124'chromeos/ash/services/libassistant/device_settings_controller\.cc',
1125'components/browser_ui/client_certificate/android/ssl_client_certificate_request\.cc',
1126'components/gwp_asan/client/sampling_malloc_shims_unittest\.cc',
1127'content/browser/font_unique_name_lookup/font_unique_name_lookup_unittest\.cc',
1128# Does not need std::function at all.
1129'components/omnibox/browser/autocomplete_result\.cc',
1130'device/fido/win/webauthn_api\.cc',
1131'media/audio/alsa/alsa_util\.cc',
1132'media/remoting/stream_provider\.h',
1133'sql/vfs_wrapper\.cc',
1134# TODO(https://crbug.com/1364585): Remove usage and exception list
1135# entries.
1136'extensions/renderer/api/automation/automation_internal_custom_bindings\.cc',
1137'extensions/renderer/api/automation/automation_internal_custom_bindings\.h',
1138# TODO(https://crbug.com/1364579): Remove usage and exception list
1139# entry.
1140'ui/views/controls/focus_ring\.h',
1141
1142# Various pre-existing uses in //tools that is low-priority to fix.
1143'tools/binary_size/libsupersize/viewer/caspian/diff\.cc',
1144'tools/binary_size/libsupersize/viewer/caspian/model\.cc',
1145'tools/binary_size/libsupersize/viewer/caspian/model\.h',
1146'tools/binary_size/libsupersize/viewer/caspian/tree_builder\.h',
1147'tools/clang/base_bind_rewriters/BaseBindRewriters\.cpp',
1148
Daniel Chengcd23b8b2022-09-16 17:16:24[diff] [blame]1149# Not an error in third_party folders.
1150 _THIRD_PARTY_EXCEPT_BLINK
1151],
Daniel Bratell609102be2019-03-27 20:53:21[diff] [blame]1152),
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]1153BanRule(
Peter Kastinge2c5ee82023-02-15 17:23:08[diff] [blame]1154 r'/#include <X11/',
Tom Andersona95e12042020-09-09 23:08:00[diff] [blame]1155(
1156'Do not use Xlib. Use xproto (from //ui/gfx/x:xproto) instead.',
1157),
1158True,
1159[_THIRD_PARTY_EXCEPT_BLINK],# Not an error in third_party folders.
1160),
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]1161BanRule(
Daniel Bratell609102be2019-03-27 20:53:21[diff] [blame]1162 r'/\bstd::ratio\b',
1163(
1164'std::ratio is banned by the Google Style Guide.',
1165),
1166True,
1167[_THIRD_PARTY_EXCEPT_BLINK],# Not an error in third_party folders.
Daniel Bratell69334cc2019-03-26 11:07:45[diff] [blame]1168),
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]1169BanRule(
Peter Kasting6d77e9d2023-02-09 21:58:18[diff] [blame]1170 r'/\bstd::aligned_alloc\b',
1171(
Peter Kastinge2c5ee82023-02-15 17:23:08[diff] [blame]1172'std::aligned_alloc() is not yet allowed (crbug.com/1412818). Use ',
1173'base::AlignedAlloc() instead.',
Peter Kasting6d77e9d2023-02-09 21:58:18[diff] [blame]1174),
1175True,
1176[_THIRD_PARTY_EXCEPT_BLINK],# Don't warn in third_party folders.
1177),
1178BanRule(
Peter Kastinge2c5ee82023-02-15 17:23:08[diff] [blame]1179 r'/#include <(barrier|latch|semaphore|stop_token)>',
Peter Kasting6d77e9d2023-02-09 21:58:18[diff] [blame]1180(
Peter Kastinge2c5ee82023-02-15 17:23:08[diff] [blame]1181'The thread support library is banned. Use base/synchronization '
1182'instead.',
Peter Kasting6d77e9d2023-02-09 21:58:18[diff] [blame]1183),
1184True,
1185[_THIRD_PARTY_EXCEPT_BLINK],# Don't warn in third_party folders.
1186),
1187BanRule(
Peter Kastinge2c5ee82023-02-15 17:23:08[diff] [blame]1188 r'/\bstd::(c8rtomb|mbrtoc8)\b',
Peter Kasting6d77e9d2023-02-09 21:58:18[diff] [blame]1189(
Peter Kastinge2c5ee82023-02-15 17:23:08[diff] [blame]1190'std::c8rtomb() and std::mbrtoc8() are banned.',
Peter Kasting6d77e9d2023-02-09 21:58:18[diff] [blame]1191),
1192True,
1193[_THIRD_PARTY_EXCEPT_BLINK],# Don't warn in third_party folders.
1194),
1195BanRule(
Peter Kastinge2c5ee82023-02-15 17:23:08[diff] [blame]1196 r'/\bchar8_t|std::u8string\b',
Peter Kasting6d77e9d2023-02-09 21:58:18[diff] [blame]1197(
Peter Kastinge2c5ee82023-02-15 17:23:08[diff] [blame]1198'char8_t and std::u8string are not yet allowed. Can you use [unsigned]',
1199' char and std::string instead?',
1200),
1201True,
Daniel Cheng893c563f2023-04-21 09:54:52[diff] [blame]1202[
1203# The demangler does not use this type but needs to know about it.
1204'base/third_party/symbolize/demangle\.cc',
1205# Don't warn in third_party folders.
1206 _THIRD_PARTY_EXCEPT_BLINK
1207],
Peter Kastinge2c5ee82023-02-15 17:23:08[diff] [blame]1208),
1209BanRule(
1210 r'/(\b(co_await|co_return|co_yield)\b|#include <coroutine>)',
1211(
1212'Coroutines are not yet allowed (https://crbug.com/1403840).',
1213),
1214True,
1215[_THIRD_PARTY_EXCEPT_BLINK],# Don't warn in third_party folders.
1216),
1217BanRule(
Peter Kastingcc152522023-03-22 20:17:37[diff] [blame]1218 r'/^\s*(export\s|import\s+["<:\w]|module(;|\s+[:\w]))',
Peter Kasting69357dc2023-03-14 01:34:29[diff] [blame]1219(
1220'Modules are disallowed for now due to lack of toolchain support.',
1221),
1222True,
1223[_THIRD_PARTY_EXCEPT_BLINK],# Don't warn in third_party folders.
1224),
1225BanRule(
Peter Kastinge2c5ee82023-02-15 17:23:08[diff] [blame]1226 r'/\[\[(un)?likely\]\]',
1227(
1228'[[likely]] and [[unlikely]] are not yet allowed ',
1229'(https://crbug.com/1414620). Use [UN]LIKELY instead.',
1230),
1231True,
1232[_THIRD_PARTY_EXCEPT_BLINK],# Don't warn in third_party folders.
1233),
1234BanRule(
Peter Kasting8bc046d22023-11-14 00:38:03[diff] [blame]1235 r'/\[\[(\w*::)?no_unique_address\]\]',
1236(
1237'[[no_unique_address]] does not work as expected on Windows ',
1238'(https://crbug.com/1414621). Use NO_UNIQUE_ADDRESS instead.',
1239),
1240True,
1241[
1242# NO_UNIQUE_ADDRESS provides canonical access.
1243 r'^base/compiler_specific.h',
1244# Not an error in third_party folders.
1245 _THIRD_PARTY_EXCEPT_BLINK,
1246],
1247),
1248BanRule(
Peter Kastinge2c5ee82023-02-15 17:23:08[diff] [blame]1249 r'/#include <format>',
1250(
1251'<format> is not yet allowed. Use base::StringPrintf() instead.',
1252),
1253True,
1254[_THIRD_PARTY_EXCEPT_BLINK],# Don't warn in third_party folders.
1255),
1256BanRule(
1257 r'/#include <ranges>',
1258(
1259'<ranges> is not yet allowed. Use base/ranges/algorithm.h instead.',
1260),
1261True,
1262[_THIRD_PARTY_EXCEPT_BLINK],# Don't warn in third_party folders.
1263),
1264BanRule(
1265 r'/#include <source_location>',
1266(
1267'<source_location> is not yet allowed. Use base/location.h instead.',
1268),
1269True,
1270[_THIRD_PARTY_EXCEPT_BLINK],# Don't warn in third_party folders.
1271),
1272BanRule(
1273 r'/#include <syncstream>',
1274(
1275'<syncstream> is banned.',
Peter Kasting6d77e9d2023-02-09 21:58:18[diff] [blame]1276),
1277True,
1278[_THIRD_PARTY_EXCEPT_BLINK],# Don't warn in third_party folders.
1279),
1280BanRule(
Michael Giuffrida7f93d6922019-04-19 14:39:58[diff] [blame]1281 r'/\bRunMessageLoop\b',
Gabriel Charette147335ea2018-03-22 15:59:19[diff] [blame]1282(
1283'RunMessageLoop is deprecated, use RunLoop instead.',
1284),
1285False,
1286(),
1287),
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]1288BanRule(
Dave Tapuska98199b612019-07-10 13:30:44[diff] [blame]1289'RunAllPendingInMessageLoop()',
Gabriel Charette147335ea2018-03-22 15:59:19[diff] [blame]1290(
1291"Prefer RunLoop over RunAllPendingInMessageLoop, please contact gab@",
1292"if you're convinced you need this.",
1293),
1294False,
1295(),
1296),
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]1297BanRule(
Dave Tapuska98199b612019-07-10 13:30:44[diff] [blame]1298'RunAllPendingInMessageLoop(BrowserThread',
Gabriel Charette147335ea2018-03-22 15:59:19[diff] [blame]1299(
1300'RunAllPendingInMessageLoop is deprecated. Use RunLoop for',
Gabriel Charette798fde72019-08-20 22:24:04[diff] [blame]1301'BrowserThread::UI, BrowserTaskEnvironment::RunIOThreadUntilIdle',
Gabriel Charette147335ea2018-03-22 15:59:19[diff] [blame]1302'for BrowserThread::IO, and prefer RunLoop::QuitClosure to observe',
1303'async events instead of flushing threads.',
1304),
1305False,
1306(),
1307),
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]1308BanRule(
Gabriel Charette147335ea2018-03-22 15:59:19[diff] [blame]1309 r'MessageLoopRunner',
1310(
1311'MessageLoopRunner is deprecated, use RunLoop instead.',
1312),
1313False,
1314(),
1315),
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]1316BanRule(
Dave Tapuska98199b612019-07-10 13:30:44[diff] [blame]1317'GetDeferredQuitTaskForRunLoop',
Gabriel Charette147335ea2018-03-22 15:59:19[diff] [blame]1318(
1319"GetDeferredQuitTaskForRunLoop shouldn't be needed, please contact",
1320"gab@ if you found a use case where this is the only solution.",
1321),
1322False,
1323(),
1324),
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]1325BanRule(
Victor Costane48a2e82019-03-15 22:02:34[diff] [blame]1326'sqlite3_initialize(',
Victor Costan3653df62018-02-08 21:38:16[diff] [blame]1327(
Victor Costane48a2e82019-03-15 22:02:34[diff] [blame]1328'Instead of calling sqlite3_initialize(), depend on //sql, ',
Victor Costan3653df62018-02-08 21:38:16[diff] [blame]1329'#include "sql/initialize.h" and use sql::EnsureSqliteInitialized().',
1330),
1331True,
1332(
1333 r'^sql/initialization\.(cc|h)$',
1334 r'^third_party/sqlite/.*\.(c|cc|h)$',
1335),
1336),
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]1337BanRule(
Austin Sullivand661ab52022-11-16 08:55:15[diff] [blame]1338'CREATE VIEW',
1339(
1340'SQL views are disabled in Chromium feature code',
1341'https://chromium.googlesource.com/chromium/src/+/HEAD/sql#no-views',
1342),
1343True,
1344(
1345 _THIRD_PARTY_EXCEPT_BLINK,
1346# sql/ itself uses views when using memory-mapped IO.
1347 r'^sql/.*',
1348# Various performance tools that do not build as part of Chrome.
1349 r'^infra/.*',
1350 r'^tools/perf.*',
1351 r'.*perfetto.*',
1352),
1353),
1354BanRule(
1355'CREATE VIRTUAL TABLE',
1356(
1357'SQL virtual tables are disabled in Chromium feature code',
1358'https://chromium.googlesource.com/chromium/src/+/HEAD/sql#no-virtual-tables',
1359),
1360True,
1361(
1362 _THIRD_PARTY_EXCEPT_BLINK,
1363# sql/ itself uses virtual tables in the recovery module and tests.
1364 r'^sql/.*',
1365# TODO(https://crbug.com/695592): Remove once WebSQL is deprecated.
1366 r'third_party/blink/web_tests/storage/websql/.*'
1367# Various performance tools that do not build as part of Chrome.
1368 r'^tools/perf.*',
1369 r'.*perfetto.*',
1370),
1371),
1372BanRule(
Dave Tapuska98199b612019-07-10 13:30:44[diff] [blame]1373'std::random_shuffle',
tzik5de2157f2018-05-08 03:42:47[diff] [blame]1374(
1375'std::random_shuffle is deprecated in C++14, and removed in C++17. Use',
1376'base::RandomShuffle instead.'
1377),
1378True,
1379(),
1380),
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]1381BanRule(
Javier Ernesto Flores Robles749e6c22018-10-08 09:36:24[diff] [blame]1382'ios/web/public/test/http_server',
1383(
1384'web::HTTPserver is deprecated use net::EmbeddedTestServer instead.',
1385),
1386False,
1387(),
1388),
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]1389BanRule(
Robert Liao764c9492019-01-24 18:46:28[diff] [blame]1390'GetAddressOf',
1391(
1392'Improper use of Microsoft::WRL::ComPtr<T>::GetAddressOf() has been ',
Xiaohan Wangfb31b4cd2020-07-08 01:18:53[diff] [blame]1393'implicated in a few leaks. ReleaseAndGetAddressOf() is safe but ',
Joshua Berenhaus8b972ec2020-09-11 20:00:11[diff] [blame]1394'operator& is generally recommended. So always use operator& instead. ',
Xiaohan Wangfb31b4cd2020-07-08 01:18:53[diff] [blame]1395'See http://crbug.com/914910 for more conversion guidance.'
Robert Liao764c9492019-01-24 18:46:28[diff] [blame]1396),
1397True,
1398(),
1399),
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]1400BanRule(
Ben Lewisa9514602019-04-29 17:53:05[diff] [blame]1401'SHFileOperation',
1402(
1403'SHFileOperation was deprecated in Windows Vista, and there are less ',
1404'complex functions to achieve the same goals. Use IFileOperation for ',
1405'any esoteric actions instead.'
1406),
1407True,
1408(),
1409),
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]1410BanRule(
Cliff Smolinsky81951642019-04-30 21:39:51[diff] [blame]1411'StringFromGUID2',
1412(
1413'StringFromGUID2 introduces an unnecessary dependency on ole32.dll.',
Jan Wilken Dörrieec815922020-07-22 07:46:24[diff] [blame]1414'Use base::win::WStringFromGUID instead.'
Cliff Smolinsky81951642019-04-30 21:39:51[diff] [blame]1415),
1416True,
1417(
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]1418 r'/base/win/win_util_unittest.cc',
Cliff Smolinsky81951642019-04-30 21:39:51[diff] [blame]1419),
1420),
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]1421BanRule(
Cliff Smolinsky81951642019-04-30 21:39:51[diff] [blame]1422'StringFromCLSID',
1423(
1424'StringFromCLSID introduces an unnecessary dependency on ole32.dll.',
Jan Wilken Dörrieec815922020-07-22 07:46:24[diff] [blame]1425'Use base::win::WStringFromGUID instead.'
Cliff Smolinsky81951642019-04-30 21:39:51[diff] [blame]1426),
1427True,
1428(
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]1429 r'/base/win/win_util_unittest.cc',
Cliff Smolinsky81951642019-04-30 21:39:51[diff] [blame]1430),
1431),
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]1432BanRule(
Avi Drissman7382afa02019-04-29 23:27:13[diff] [blame]1433'kCFAllocatorNull',
1434(
1435'The use of kCFAllocatorNull with the NoCopy creation of ',
1436'CoreFoundation types is prohibited.',
1437),
1438True,
1439(),
1440),
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]1441BanRule(
Oksana Zhuravlovafd247772019-05-16 16:57:29[diff] [blame]1442'mojo::ConvertTo',
1443(
1444'mojo::ConvertTo and TypeConverter are deprecated. Please consider',
1445'StructTraits / UnionTraits / EnumTraits / ArrayTraits / MapTraits /',
1446'StringTraits if you would like to convert between custom types and',
1447'the wire format of mojom types.'
1448),
Oksana Zhuravlova1d3b59de2019-05-17 00:08:22[diff] [blame]1449False,
Oksana Zhuravlovafd247772019-05-16 16:57:29[diff] [blame]1450(
David Dorwin13dc48b2022-06-03 21:18:42[diff] [blame]1451 r'^fuchsia_web/webengine/browser/url_request_rewrite_rules_manager\.cc$',
1452 r'^fuchsia_web/webengine/url_request_rewrite_type_converters\.cc$',
Oksana Zhuravlovafd247772019-05-16 16:57:29[diff] [blame]1453 r'^third_party/blink/.*\.(cc|h)$',
1454 r'^content/renderer/.*\.(cc|h)$',
1455),
1456),
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]1457BanRule(
Oksana Zhuravlovac8222d22019-12-19 19:21:16[diff] [blame]1458'GetInterfaceProvider',
1459(
1460'InterfaceProvider is deprecated.',
1461'Please use ExecutionContext::GetBrowserInterfaceBroker and overrides',
1462'or Platform::GetBrowserInterfaceBroker.'
1463),
1464False,
1465(),
1466),
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]1467BanRule(
Robert Liao1d78df52019-11-11 20:02:01[diff] [blame]1468'CComPtr',
1469(
1470'New code should use Microsoft::WRL::ComPtr from wrl/client.h as a ',
1471'replacement for CComPtr from ATL. See http://crbug.com/5027 for more ',
1472'details.'
1473),
1474False,
1475(),
1476),
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]1477BanRule(
Xiaohan Wang72bd2ba2020-02-18 21:38:20[diff] [blame]1478 r'/\b(IFACE|STD)METHOD_?\(',
1479(
1480'IFACEMETHOD() and STDMETHOD() make code harder to format and read.',
1481'Instead, always use IFACEMETHODIMP in the declaration.'
1482),
1483False,
1484[_THIRD_PARTY_EXCEPT_BLINK],# Not an error in third_party folders.
1485),
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]1486BanRule(
Allen Bauer53b43fb12020-03-12 17:21:47[diff] [blame]1487'set_owned_by_client',
1488(
1489'set_owned_by_client is deprecated.',
1490'views::View already owns the child views by default. This introduces ',
1491'a competing ownership model which makes the code difficult to reason ',
1492'about. See http://crbug.com/1044687 for more details.'
1493),
1494False,
1495(),
1496),
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]1497BanRule(
Peter Boström7ff41522021-07-29 03:43:27[diff] [blame]1498'RemoveAllChildViewsWithoutDeleting',
1499(
1500'RemoveAllChildViewsWithoutDeleting is deprecated.',
1501'This method is deemed dangerous as, unless raw pointers are re-added,',
1502'calls to this method introduce memory leaks.'
1503),
1504False,
1505(),
1506),
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]1507BanRule(
Eric Secklerbe6f48d2020-05-06 18:09:12[diff] [blame]1508 r'/\bTRACE_EVENT_ASYNC_',
1509(
1510'Please use TRACE_EVENT_NESTABLE_ASYNC_.. macros instead',
1511'of TRACE_EVENT_ASYNC_.. (crbug.com/1038710).',
1512),
1513False,
1514(
1515 r'^base/trace_event/.*',
1516 r'^base/tracing/.*',
1517),
1518),
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]1519BanRule(
Aditya Kushwah5a286b72022-02-10 04:54:43[diff] [blame]1520 r'/\bbase::debug::DumpWithoutCrashingUnthrottled[(][)]',
1521(
1522'base::debug::DumpWithoutCrashingUnthrottled() does not throttle',
1523'dumps and may spam crash reports. Consider if the throttled',
1524'variants suffice instead.',
1525),
1526False,
1527(),
1528),
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]1529BanRule(
Robert Liao22f66a52021-04-10 00:57:52[diff] [blame]1530'RoInitialize',
1531(
Robert Liao48018922021-04-16 23:03:02[diff] [blame]1532'Improper use of [base::win]::RoInitialize() has been implicated in a ',
Robert Liao22f66a52021-04-10 00:57:52[diff] [blame]1533'few COM initialization leaks. Use base::win::ScopedWinrtInitializer ',
1534'instead. See http://crbug.com/1197722 for more information.'
1535),
1536True,
Robert Liao48018922021-04-16 23:03:02[diff] [blame]1537(
Bruce Dawson40fece62022-09-16 19:58:31[diff] [blame]1538 r'^base/win/scoped_winrt_initializer\.cc$',
Danil Chapovalov07694382023-05-24 17:55:21[diff] [blame]1539 r'^third_party/abseil-cpp/absl/.*',
Robert Liao48018922021-04-16 23:03:02[diff] [blame]1540),
Robert Liao22f66a52021-04-10 00:57:52[diff] [blame]1541),
Patrick Monettec343bb982022-06-01 17:18:45[diff] [blame]1542BanRule(
1543 r'base::Watchdog',
1544(
1545'base::Watchdog is deprecated because it creates its own thread.',
1546'Instead, manually start a timer on a SequencedTaskRunner.',
1547),
1548False,
1549(),
1550),
Andrew Rayskiy04a51ce2022-06-07 11:47:09[diff] [blame]1551BanRule(
1552'base::Passed',
1553(
1554'Do not use base::Passed. It is a legacy helper for capturing ',
1555'move-only types with base::BindRepeating, but invoking the ',
1556'resulting RepeatingCallback moves the captured value out of ',
1557'the callback storage, and subsequent invocations may pass the ',
1558'value in a valid but undefined state. Prefer base::BindOnce().',
1559'See http://crbug.com/1326449 for context.'
1560),
1561False,
Daniel Cheng91f6fbaf2022-09-16 12:07:48[diff] [blame]1562(
1563# False positive, but it is also fine to let bind internals reference
1564# base::Passed.
Daniel Chengcd23b8b2022-09-16 17:16:24[diff] [blame]1565 r'^base[\\/]functional[\\/]bind\.h',
Daniel Cheng91f6fbaf2022-09-16 12:07:48[diff] [blame]1566 r'^base[\\/]functional[\\/]bind_internal\.h',
1567),
Andrew Rayskiy04a51ce2022-06-07 11:47:09[diff] [blame]1568),
Daniel Cheng2248b332022-07-27 06:16:59[diff] [blame]1569BanRule(
Daniel Chengba3bc2e2022-10-03 02:45:43[diff] [blame]1570 r'base::Feature k',
1571(
1572'Please use BASE_DECLARE_FEATURE() or BASE_FEATURE() instead of ',
1573'directly declaring/defining features.'
1574),
1575True,
1576[
1577 _THIRD_PARTY_EXCEPT_BLINK,
1578],
1579),
Robert Ogden92101dcb2022-10-19 23:49:36[diff] [blame]1580BanRule(
Arthur Sonzogni1da65fa2023-03-27 16:01:52[diff] [blame]1581 r'/\bchartorune\b',
Robert Ogden92101dcb2022-10-19 23:49:36[diff] [blame]1582(
1583'chartorune is not memory-safe, unless you can guarantee the input ',
1584'string is always null-terminated. Otherwise, please use charntorune ',
1585'from libphonenumber instead.'
1586),
1587True,
1588[
1589 _THIRD_PARTY_EXCEPT_BLINK,
1590# Exceptions to this rule should have a fuzzer.
1591],
1592),
Arthur Sonzogni1da65fa2023-03-27 16:01:52[diff] [blame]1593BanRule(
1594 r'/\b#include "base/atomicops\.h"\b',
1595(
1596'Do not use base::subtle atomics, but std::atomic, which are simpler '
1597'to use, have better understood, clearer and richer semantics, and are '
1598'harder to mis-use. See details in base/atomicops.h.',
1599),
1600False,
1601[_THIRD_PARTY_EXCEPT_BLINK],# Not an error in third_party folders.
Benoit Lize79cf0592023-01-27 10:01:57[diff] [blame]1602),
Arthur Sonzogni60348572e2023-04-07 10:22:52[diff] [blame]1603BanRule(
1604 r'CrossThreadPersistent<',
1605(
1606'Do not use blink::CrossThreadPersistent, but '
1607'blink::CrossThreadHandle. It is harder to mis-use.',
1608'More info: '
1609'https://docs.google.com/document/d/1GIT0ysdQ84sGhIo1r9EscF_fFt93lmNVM_q4vvHj2FQ/edit#heading=h.3e4d6y61tgs',
1610'Please contact platform-architecture-dev@ before adding new instances.'
1611),
1612False,
1613[]
1614),
1615BanRule(
1616 r'CrossThreadWeakPersistent<',
1617(
1618'Do not use blink::CrossThreadWeakPersistent, but '
1619'blink::CrossThreadWeakHandle. It is harder to mis-use.',
1620'More info: '
1621'https://docs.google.com/document/d/1GIT0ysdQ84sGhIo1r9EscF_fFt93lmNVM_q4vvHj2FQ/edit#heading=h.3e4d6y61tgs',
1622'Please contact platform-architecture-dev@ before adding new instances.'
1623),
1624False,
1625[]
1626),
Avi Drissman491617c2023-04-13 17:33:15[diff] [blame]1627BanRule(
1628 r'objc/objc.h',
1629(
1630'Do not include <objc/objc.h>. It defines away ARC lifetime '
1631'annotations, and is thus dangerous.',
1632'Please use the pimpl pattern; search for `ObjCStorage` for examples.',
1633'For further reading on how to safely mix C++ and Obj-C, see',
1634'https://chromium.googlesource.com/chromium/src/+/main/docs/mac/mixing_cpp_and_objc.md'
1635),
1636True,
1637[]
1638),
Grace Park8d59b54b2023-04-26 17:53:35[diff] [blame]1639BanRule(
1640 r'/#include <filesystem>',
1641(
1642'libc++ <filesystem> is banned per the Google C++ styleguide.',
1643),
1644True,
1645# This fuzzing framework is a standalone open source project and
1646# cannot rely on Chromium base.
1647(r'third_party/centipede'),
1648),
Daniel Cheng72153e02023-05-18 21:18:14[diff] [blame]1649BanRule(
1650 r'TopDocument()',
1651(
1652'TopDocument() does not work correctly with out-of-process iframes. '
1653'Please do not introduce new uses.',
1654),
1655True,
1656(
1657# TODO(crbug.com/617677): Remove all remaining uses.
1658 r'^third_party/blink/renderer/core/dom/document\.cc',
1659 r'^third_party/blink/renderer/core/dom/document\.h',
1660 r'^third_party/blink/renderer/core/dom/element\.cc',
1661 r'^third_party/blink/renderer/core/exported/web_disallow_transition_scope_test\.cc',
1662 r'^third_party/blink/renderer/core/exported/web_document_test\.cc',
Daniel Cheng72153e02023-05-18 21:18:14[diff] [blame]1663 r'^third_party/blink/renderer/core/html/html_anchor_element\.cc',
1664 r'^third_party/blink/renderer/core/html/html_dialog_element\.cc',
1665 r'^third_party/blink/renderer/core/html/html_element\.cc',
1666 r'^third_party/blink/renderer/core/html/html_frame_owner_element\.cc',
1667 r'^third_party/blink/renderer/core/html/media/video_wake_lock\.cc',
1668 r'^third_party/blink/renderer/core/loader/anchor_element_interaction_tracker\.cc',
1669 r'^third_party/blink/renderer/core/page/scrolling/root_scroller_controller\.cc',
1670 r'^third_party/blink/renderer/core/page/scrolling/top_document_root_scroller_controller\.cc',
1671 r'^third_party/blink/renderer/core/page/scrolling/top_document_root_scroller_controller\.h',
1672 r'^third_party/blink/renderer/core/script/classic_pending_script\.cc',
1673 r'^third_party/blink/renderer/core/script/script_loader\.cc',
1674),
1675),
Arthur Sonzognif0eea302023-08-18 19:20:31[diff] [blame]1676BanRule(
1677 pattern= r'base::raw_ptr<',
1678 explanation=(
1679'Do not use base::raw_ptr, use raw_ptr.',
1680),
1681 treat_as_error=True,
1682 excluded_paths=(
1683'^base/',
1684'^tools/',
1685),
1686),
1687BanRule(
1688 pattern= r'base:raw_ref<',
1689 explanation=(
1690'Do not use base::raw_ref, use raw_ref.',
1691),
1692 treat_as_error=True,
1693 excluded_paths=(
1694'^base/',
1695'^tools/',
1696),
1697),
Anton Maliev66751812023-08-24 16:28:13[diff] [blame]1698BanRule(
Tom Sepez41eb158d2023-09-12 16:16:22[diff] [blame]1699 pattern= r'/raw_ptr<[^;}]*\w{};',
1700 explanation=(
1701'Do not use {} for raw_ptr initialization, use = nullptr instead.',
1702),
1703 treat_as_error=True,
1704 excluded_paths=(
1705'^base/',
1706'^tools/',
1707),
1708),
1709BanRule(
Arthur Sonzogni48c6aea22023-09-04 22:25:20[diff] [blame]1710 pattern= r'/#include "base/allocator/.*/raw_'
1711 r'(ptr|ptr_cast|ptr_exclusion|ref).h"',
1712 explanation=(
1713'Please include the corresponding facade headers:',
1714'- #include "base/memory/raw_ptr.h"',
1715'- #include "base/memory/raw_ptr_cast.h"',
1716'- #include "base/memory/raw_ptr_exclusion.h"',
1717'- #include "base/memory/raw_ref.h"',
1718),
1719 treat_as_error=True,
1720 excluded_paths=(
1721'^base/',
1722'^tools/',
1723),
1724),
1725BanRule(
Anton Maliev66751812023-08-24 16:28:13[diff] [blame]1726 pattern= r'ContentSettingsType::COOKIES',
1727 explanation=(
1728'Do not use ContentSettingsType::COOKIES to check whether cookies are '
1729'supported in the provided context. Instead rely on the '
1730'content_settings::CookieSettings API. If you are using '
1731'ContentSettingsType::COOKIES to check the user preference setting '
1732'specifically, disregard this warning.',
1733),
1734 treat_as_error=False,
1735 excluded_paths=(
1736'^chrome/browser/ui/content_settings/',
1737'^components/content_settings/',
Christian Dullweber61416642023-10-05 11:46:43[diff] [blame]1738'^services/network/cookie_settings.cc',
1739'.*test.cc',
Anton Maliev66751812023-08-24 16:28:13[diff] [blame]1740),
1741),
Tom Andersoncd522072023-10-03 00:52:35[diff] [blame]1742BanRule(
1743 pattern= r'\bg_signal_connect',
1744 explanation=(
1745'Use ScopedGSignal instead of g_signal_connect*()',
1746),
1747 treat_as_error=True,
1748 excluded_paths=(
1749'^ui/base/glib/scoped_gsignal.h',
1750),
1751),
Christian Flach8da3bf82023-10-12 09:42:53[diff] [blame]1752BanRule(
1753 pattern= r'features::kIsolatedWebApps',
1754 explanation=(
1755'Do not use `features::kIsolatedWebApps` directly to guard Isolated ',
1756'Web App code. ',
1757'Use `content::IsolatedWebAppsPolicy::AreIsolatedWebAppsEnabled()` in ',
1758'the browser process or check the `kEnableIsolatedWebAppsInRenderer` ',
1759'command line flag in the renderer process.',
1760),
1761 treat_as_error=True,
1762 excluded_paths= _TEST_CODE_EXCLUDED_PATHS+(
1763'^chrome/browser/about_flags.cc',
1764'^chrome/browser/chrome_content_browser_client.cc',
1765'^chrome/browser/ui/startup/bad_flags_prompt.cc',
1766'^content/shell/browser/shell_content_browser_client.cc'
1767)
1768),
avi@chromium.org127f18ec2012-06-16 05:05:59[diff] [blame]1769)
1770
Daniel Cheng92c15e32022-03-16 17:48:22[diff] [blame]1771_BANNED_MOJOM_PATTERNS:Sequence[BanRule]=(
1772BanRule(
1773'handle<shared_buffer>',
1774(
1775'Please use one of the more specific shared memory types instead:',
1776' mojo_base.mojom.ReadOnlySharedMemoryRegion',
1777' mojo_base.mojom.WritableSharedMemoryRegion',
1778' mojo_base.mojom.UnsafeSharedMemoryRegion',
1779),
1780True,
1781),
1782)
1783
mlamouria82272622014-09-16 18:45:04[diff] [blame]1784_IPC_ENUM_TRAITS_DEPRECATED=(
1785'You are using IPC_ENUM_TRAITS() in your code. It has been deprecated.\n'
Vaclav Brozekd5de76a2018-03-17 07:57:50[diff] [blame]1786'See http://www.chromium.org/Home/chromium-security/education/'
1787'security-tips-for-ipc')
mlamouria82272622014-09-16 18:45:04[diff] [blame]1788
Stephen Martinis97a394142018-06-07 23:06:05[diff] [blame]1789_LONG_PATH_ERROR=(
1790'Some files included in this CL have file names that are too long (> 200'
1791' characters). If committed, these files will cause issues on Windows. See'
1792' https://crbug.com/612667 for more details.'
1793)
1794
Shenghua Zhangbfaa38b82017-11-16 21:58:02[diff] [blame]1795_JAVA_MULTIPLE_DEFINITION_EXCLUDED_PATHS=[
Bruce Dawson40fece62022-09-16 19:58:31[diff] [blame]1796 r".*/AppHooksImpl\.java",
1797 r".*/BuildHooksAndroidImpl\.java",
1798 r".*/LicenseContentProvider\.java",
1799 r".*/PlatformServiceBridgeImpl.java",
1800 r".*chrome/android/feed/dummy/.*\.java",
Shenghua Zhangbfaa38b82017-11-16 21:58:02[diff] [blame]1801]
avi@chromium.org127f18ec2012-06-16 05:05:59[diff] [blame]1802
Mohamed Heikald048240a2019-11-12 16:57:37[diff] [blame]1803# List of image extensions that are used as resources in chromium.
1804_IMAGE_EXTENSIONS=['.svg','.png','.webp']
1805
Sean Kau46e29bc2017-08-28 16:31:16[diff] [blame]1806# These paths contain test data and other known invalid JSON files.
Erik Staab2dd72b12020-04-16 15:03:40[diff] [blame]1807_KNOWN_TEST_DATA_AND_INVALID_JSON_FILE_PATTERNS=[
Bruce Dawson40fece62022-09-16 19:58:31[diff] [blame]1808 r'test/data/',
1809 r'testing/buildbot/',
1810 r'^components/policy/resources/policy_templates\.json$',
1811 r'^third_party/protobuf/',
Camillo Bruni1411a352023-05-24 12:39:03[diff] [blame]1812 r'^third_party/blink/perf_tests/speedometer.*/resources/todomvc/learn\.json',
Bruce Dawson40fece62022-09-16 19:58:31[diff] [blame]1813 r'^third_party/blink/renderer/devtools/protocol\.json$',
1814 r'^third_party/blink/web_tests/external/wpt/',
1815 r'^tools/perf/',
1816 r'^tools/traceline/svgui/startup-release.json',
Daniel Cheng2d4c2d192022-07-01 01:38:31[diff] [blame]1817# vscode configuration files allow comments
Bruce Dawson40fece62022-09-16 19:58:31[diff] [blame]1818 r'^tools/vscode/',
Sean Kau46e29bc2017-08-28 16:31:16[diff] [blame]1819]
1820
Andrew Grieveb773bad2020-06-05 18:00:38[diff] [blame]1821# These are not checked on the public chromium-presubmit trybot.
1822# Add files here that rely on .py files that exists only for target_os="android"
Samuel Huangc2f5d6bb2020-08-17 23:46:04[diff] [blame]1823# checkouts.
agrievef32bcc72016-04-04 14:57:40[diff] [blame]1824_ANDROID_SPECIFIC_PYDEPS_FILES=[
Andrew Grieveb773bad2020-06-05 18:00:38[diff] [blame]1825'chrome/android/features/create_stripped_java_factory.pydeps',
Andrew Grieveb773bad2020-06-05 18:00:38[diff] [blame]1826]
1827
1828
1829_GENERIC_PYDEPS_FILES=[
Bruce Dawson853b739e62022-05-03 23:03:10[diff] [blame]1830'android_webview/test/components/run_webview_component_smoketest.pydeps',
Samuel Huangc2f5d6bb2020-08-17 23:46:04[diff] [blame]1831'android_webview/tools/run_cts.pydeps',
Andrew Grieve4c4cede2020-11-20 22:09:36[diff] [blame]1832'build/android/apk_operations.pydeps',
Samuel Huangc2f5d6bb2020-08-17 23:46:04[diff] [blame]1833'build/android/devil_chromium.pydeps',
David 'Digit' Turner0006f4732018-08-07 07:12:36[diff] [blame]1834'build/android/gyp/aar.pydeps',
1835'build/android/gyp/aidl.pydeps',
Tibor Goldschwendt0bef2d7a2019-10-24 21:19:27[diff] [blame]1836'build/android/gyp/allot_native_libraries.pydeps',
David 'Digit' Turner0006f4732018-08-07 07:12:36[diff] [blame]1837'build/android/gyp/apkbuilder.pydeps',
Andrew Grievea417ad302019-02-06 19:54:38[diff] [blame]1838'build/android/gyp/assert_static_initializers.pydeps',
Mohamed Heikal133e1f22023-04-18 20:04:37[diff] [blame]1839'build/android/gyp/binary_baseline_profile.pydeps',
David 'Digit' Turner0006f4732018-08-07 07:12:36[diff] [blame]1840'build/android/gyp/bytecode_processor.pydeps',
Robbie McElrath360e54d2020-11-12 20:38:02[diff] [blame]1841'build/android/gyp/bytecode_rewriter.pydeps',
Mohamed Heikal6305bcc2021-03-15 15:34:22[diff] [blame]1842'build/android/gyp/check_flag_expectations.pydeps',
Andrew Grieve8d083ea2019-12-13 06:49:11[diff] [blame]1843'build/android/gyp/compile_java.pydeps',
Peter Weneaa963f2023-01-20 19:40:30[diff] [blame]1844'build/android/gyp/compile_kt.pydeps',
David 'Digit' Turner0006f4732018-08-07 07:12:36[diff] [blame]1845'build/android/gyp/compile_resources.pydeps',
David 'Digit' Turner0006f4732018-08-07 07:12:36[diff] [blame]1846'build/android/gyp/copy_ex.pydeps',
David 'Digit' Turner0006f4732018-08-07 07:12:36[diff] [blame]1847'build/android/gyp/create_apk_operations_script.pydeps',
Andrew Grieve8d083ea2019-12-13 06:49:11[diff] [blame]1848'build/android/gyp/create_app_bundle.pydeps',
Samuel Huangc2f5d6bb2020-08-17 23:46:04[diff] [blame]1849'build/android/gyp/create_app_bundle_apks.pydeps',
1850'build/android/gyp/create_bundle_wrapper_script.pydeps',
David 'Digit' Turner0006f4732018-08-07 07:12:36[diff] [blame]1851'build/android/gyp/create_java_binary_script.pydeps',
Mohamed Heikaladbe4e482020-07-09 19:25:12[diff] [blame]1852'build/android/gyp/create_r_java.pydeps',
Mohamed Heikal8cd763a52021-02-01 23:32:09[diff] [blame]1853'build/android/gyp/create_r_txt.pydeps',
Andrew Grieveb838d832019-02-11 16:55:22[diff] [blame]1854'build/android/gyp/create_size_info_files.pydeps',
Peter Wene6e017e2022-07-27 21:40:40[diff] [blame]1855'build/android/gyp/create_test_apk_wrapper_script.pydeps',
Andrew Grieve5a01ad32020-06-25 18:06:00[diff] [blame]1856'build/android/gyp/create_ui_locale_resources.pydeps',
David 'Digit' Turner0006f4732018-08-07 07:12:36[diff] [blame]1857'build/android/gyp/dex.pydeps',
1858'build/android/gyp/dist_aar.pydeps',
David 'Digit' Turner0006f4732018-08-07 07:12:36[diff] [blame]1859'build/android/gyp/filter_zip.pydeps',
Mohamed Heikal21e1994b2021-11-12 21:37:21[diff] [blame]1860'build/android/gyp/flatc_java.pydeps',
David 'Digit' Turner0006f4732018-08-07 07:12:36[diff] [blame]1861'build/android/gyp/gcc_preprocess.pydeps',
Christopher Grant99e0e20062018-11-21 21:22:36[diff] [blame]1862'build/android/gyp/generate_linker_version_script.pydeps',
David 'Digit' Turner0006f4732018-08-07 07:12:36[diff] [blame]1863'build/android/gyp/ijar.pydeps',
Yun Liueb4075ddf2019-05-13 19:47:58[diff] [blame]1864'build/android/gyp/jacoco_instr.pydeps',
David 'Digit' Turner0006f4732018-08-07 07:12:36[diff] [blame]1865'build/android/gyp/java_cpp_enum.pydeps',
Nate Fischerac07b2622020-10-01 20:20:14[diff] [blame]1866'build/android/gyp/java_cpp_features.pydeps',
Ian Vollickb99472e2019-03-07 21:35:26[diff] [blame]1867'build/android/gyp/java_cpp_strings.pydeps',
Andrew Grieve09457912021-04-27 15:22:47[diff] [blame]1868'build/android/gyp/java_google_api_keys.pydeps',
Samuel Huangc2f5d6bb2020-08-17 23:46:04[diff] [blame]1869'build/android/gyp/jinja_template.pydeps',
David 'Digit' Turner0006f4732018-08-07 07:12:36[diff] [blame]1870'build/android/gyp/lint.pydeps',
David 'Digit' Turner0006f4732018-08-07 07:12:36[diff] [blame]1871'build/android/gyp/merge_manifest.pydeps',
Bruce Dawson853b739e62022-05-03 23:03:10[diff] [blame]1872'build/android/gyp/optimize_resources.pydeps',
David 'Digit' Turner0006f4732018-08-07 07:12:36[diff] [blame]1873'build/android/gyp/prepare_resources.pydeps',
Mohamed Heikalf85138b2020-10-06 15:43:22[diff] [blame]1874'build/android/gyp/process_native_prebuilt.pydeps',
David 'Digit' Turner0006f4732018-08-07 07:12:36[diff] [blame]1875'build/android/gyp/proguard.pydeps',
Andrew Grievee3a775ab2022-05-16 15:59:22[diff] [blame]1876'build/android/gyp/system_image_apks.pydeps',
Bruce Dawson853b739e62022-05-03 23:03:10[diff] [blame]1877'build/android/gyp/trace_event_bytecode_rewriter.pydeps',
Peter Wen578730b2020-03-19 19:55:46[diff] [blame]1878'build/android/gyp/turbine.pydeps',
Mohamed Heikal246710c2021-06-14 15:34:30[diff] [blame]1879'build/android/gyp/unused_resources.pydeps',
Eric Stevensona82cf6082019-07-24 14:35:24[diff] [blame]1880'build/android/gyp/validate_static_library_dex_references.pydeps',
David 'Digit' Turner0006f4732018-08-07 07:12:36[diff] [blame]1881'build/android/gyp/write_build_config.pydeps',
Tibor Goldschwendtc4caae92019-07-12 00:33:46[diff] [blame]1882'build/android/gyp/write_native_libraries_java.pydeps',
Andrew Grieve9ff17792018-11-30 04:55:56[diff] [blame]1883'build/android/gyp/zip.pydeps',
David 'Digit' Turner0006f4732018-08-07 07:12:36[diff] [blame]1884'build/android/incremental_install/generate_android_manifest.pydeps',
1885'build/android/incremental_install/write_installer_json.pydeps',
Stephanie Kim392913b452022-06-15 17:25:32[diff] [blame]1886'build/android/pylib/results/presentation/test_results_presentation.pydeps',
Samuel Huangc2f5d6bb2020-08-17 23:46:04[diff] [blame]1887'build/android/resource_sizes.pydeps',
1888'build/android/test_runner.pydeps',
1889'build/android/test_wrapper/logdog_wrapper.pydeps',
Samuel Huange65eb3f12020-08-14 19:04:36[diff] [blame]1890'build/lacros/lacros_resource_sizes.pydeps',
David 'Digit' Turner0006f4732018-08-07 07:12:36[diff] [blame]1891'build/protoc_java.pydeps',
Peter Kotwicz64667b02020-10-18 06:43:32[diff] [blame]1892'chrome/android/monochrome/scripts/monochrome_python_tests.pydeps',
Peter Wenefb56c72020-06-04 15:12:27[diff] [blame]1893'chrome/test/chromedriver/log_replay/client_replay_unittest.pydeps',
1894'chrome/test/chromedriver/test/run_py_tests.pydeps',
Junbo Kedcd3a452021-03-19 17:55:04[diff] [blame]1895'chromecast/resource_sizes/chromecast_resource_sizes.pydeps',
Andrew Grieve5a01ad32020-06-25 18:06:00[diff] [blame]1896'components/cronet/tools/generate_javadoc.pydeps',
1897'components/cronet/tools/jar_src.pydeps',
Andrew Grieveb773bad2020-06-05 18:00:38[diff] [blame]1898'components/module_installer/android/module_desc_java.pydeps',
Andrew Grieve5a01ad32020-06-25 18:06:00[diff] [blame]1899'content/public/android/generate_child_service.pydeps',
Andrew Grieveb773bad2020-06-05 18:00:38[diff] [blame]1900'net/tools/testserver/testserver.pydeps',
Peter Kotwicz3c339f32020-10-19 19:59:18[diff] [blame]1901'testing/scripts/run_isolated_script_test.pydeps',
Stephanie Kimc94072c2022-03-22 22:31:41[diff] [blame]1902'testing/merge_scripts/standard_isolated_script_merge.pydeps',
1903'testing/merge_scripts/standard_gtest_merge.pydeps',
1904'testing/merge_scripts/code_coverage/merge_results.pydeps',
1905'testing/merge_scripts/code_coverage/merge_steps.pydeps',
Samuel Huangc2f5d6bb2020-08-17 23:46:04[diff] [blame]1906'third_party/android_platform/development/scripts/stack.pydeps',
Hitoshi Yoshida0f228c42019-08-07 09:37:42[diff] [blame]1907'third_party/blink/renderer/bindings/scripts/build_web_idl_database.pydeps',
Yuki Shiino38eeaad12022-08-11 06:40:25[diff] [blame]1908'third_party/blink/renderer/bindings/scripts/check_generated_file_list.pydeps',
Hitoshi Yoshida0f228c42019-08-07 09:37:42[diff] [blame]1909'third_party/blink/renderer/bindings/scripts/collect_idl_files.pydeps',
Yuki Shiinoe7827aa2019-09-13 12:26:13[diff] [blame]1910'third_party/blink/renderer/bindings/scripts/generate_bindings.pydeps',
Yuki Shiinoea477d32023-08-21 06:24:34[diff] [blame]1911'third_party/blink/renderer/bindings/scripts/generate_event_interface_names.pydeps',
Canon Mukaif32f8f592021-04-23 18:56:50[diff] [blame]1912'third_party/blink/renderer/bindings/scripts/validate_web_idl.pydeps',
Stephanie Kimc94072c2022-03-22 22:31:41[diff] [blame]1913'third_party/blink/tools/blinkpy/web_tests/merge_results.pydeps',
1914'third_party/blink/tools/merge_web_test_results.pydeps',
John Budorickbc3571aa2019-04-25 02:20:06[diff] [blame]1915'tools/binary_size/sizes.pydeps',
Andrew Grievea7f1ee902018-05-18 16:17:22[diff] [blame]1916'tools/binary_size/supersize.pydeps',
Ben Pastene028104a2022-08-10 19:17:45[diff] [blame]1917'tools/perf/process_perf_results.pydeps',
agrievef32bcc72016-04-04 14:57:40[diff] [blame]1918]
1919
wnwenbdc444e2016-05-25 13:44:15[diff] [blame]1920
agrievef32bcc72016-04-04 14:57:40[diff] [blame]1921_ALL_PYDEPS_FILES= _ANDROID_SPECIFIC_PYDEPS_FILES+ _GENERIC_PYDEPS_FILES
1922
1923
Eric Boren6fd2b932018-01-25 15:05:08[diff] [blame]1924# Bypass the AUTHORS check for these accounts.
1925_KNOWN_ROBOTS= set(
Sergiy Byelozyorov47158a52018-06-13 22:38:59[diff] [blame]1926)| set('%s@appspot.gserviceaccount.com'% sfor sin('findit-for-me',)
Achuith Bhandarkar35905562018-07-25 19:28:45[diff] [blame]1927)| set('%s@developer.gserviceaccount.com'% sfor sin('3su6n15k.default',)
Sergiy Byelozyorov47158a52018-06-13 22:38:59[diff] [blame]1928)| set('%s@chops-service-accounts.iam.gserviceaccount.com'% s
smutde797052019-12-04 02:03:52[diff] [blame]1929for sin('bling-autoroll-builder','v8-ci-autoroll-builder',
Sven Zhengf7abd31d2021-08-09 19:06:23[diff] [blame]1930'wpt-autoroller','chrome-weblayer-builder',
Garrett Beaty4d4fcf62021-11-24 17:57:47[diff] [blame]1931'lacros-version-skew-roller','skylab-test-cros-roller',
Sven Zheng722960ba2022-07-18 16:40:46[diff] [blame]1932'infra-try-recipes-tester','lacros-tracking-roller',
Brian Sheedy1c951e62022-10-27 01:16:18[diff] [blame]1933'lacros-sdk-version-roller','chrome-automated-expectation',
Stephanie Kimb49bdd242023-04-28 16:46:04[diff] [blame]1934'chromium-automated-expectation','chrome-branch-day',
1935'chromium-autosharder')
Eric Boren835d71f2018-09-07 21:09:04[diff] [blame]1936)| set('%s@skia-public.iam.gserviceaccount.com'% s
Eric Boren66150e52020-01-08 11:20:27[diff] [blame]1937for sin('chromium-autoroll','chromium-release-autoroll')
Eric Boren835d71f2018-09-07 21:09:04[diff] [blame]1938)| set('%s@skia-corp.google.com.iam.gserviceaccount.com'% s
Yulan Lineb0cfba2021-04-09 18:43:16[diff] [blame]1939for sin('chromium-internal-autoroll',)
1940)| set('%s@owners-cleanup-prod.google.com.iam.gserviceaccount.com'% s
Chong Gub277e342022-10-15 03:30:55[diff] [blame]1941for sin('swarming-tasks',)
1942)| set('%s@fuchsia-infra.iam.gserviceaccount.com'% s
1943for sin('global-integration-try-builder',
Joey Scarr1103c5d2023-09-14 01:17:55[diff] [blame]1944'global-integration-ci-builder')
Suma Kasa3b9cf7a2023-09-21 22:05:54[diff] [blame]1945)| set('%s@prod.google.com'% s
1946for sin('chops-security-borg',
1947'chops-security-cronjobs-cpesuggest'))
Eric Boren6fd2b932018-01-25 15:05:08[diff] [blame]1948
Matt Stark6ef08872021-07-29 01:21:46[diff] [blame]1949_INVALID_GRD_FILE_LINE=[
1950(r'<file lang=.* path=.*','Path should come before lang in GRD files.')
1951]
Eric Boren6fd2b932018-01-25 15:05:08[diff] [blame]1952
Daniel Bratell65b033262019-04-23 08:17:06[diff] [blame]1953def_IsCPlusPlusFile(input_api, file_path):
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]1954"""Returns True if this file contains C++-like code (and not Python,
1955 Go, Java, MarkDown, ...)"""
Daniel Bratell65b033262019-04-23 08:17:06[diff] [blame]1956
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]1957 ext= input_api.os_path.splitext(file_path)[1]
1958# This list is compatible with CppChecker.IsCppFile but we should
1959# consider adding ".c" to it. If we do that we can use this function
1960# at more places in the code.
1961return extin(
1962'.h',
1963'.cc',
1964'.cpp',
1965'.m',
1966'.mm',
1967)
1968
Daniel Bratell65b033262019-04-23 08:17:06[diff] [blame]1969
1970def_IsCPlusPlusHeaderFile(input_api, file_path):
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]1971return input_api.os_path.splitext(file_path)[1]==".h"
Daniel Bratell65b033262019-04-23 08:17:06[diff] [blame]1972
1973
1974def_IsJavaFile(input_api, file_path):
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]1975return input_api.os_path.splitext(file_path)[1]==".java"
Daniel Bratell65b033262019-04-23 08:17:06[diff] [blame]1976
1977
1978def_IsProtoFile(input_api, file_path):
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]1979return input_api.os_path.splitext(file_path)[1]==".proto"
Daniel Bratell65b033262019-04-23 08:17:06[diff] [blame]1980
Mohamed Heikal5e5b7922020-10-29 18:57:59[diff] [blame]1981
Erik Staabc734cd7a2021-11-23 03:11:52[diff] [blame]1982def_IsXmlOrGrdFile(input_api, file_path):
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]1983 ext= input_api.os_path.splitext(file_path)[1]
1984return extin('.grd','.xml')
Erik Staabc734cd7a2021-11-23 03:11:52[diff] [blame]1985
1986
Sven Zheng76a79ea2022-12-21 21:25:24[diff] [blame]1987def_IsMojomFile(input_api, file_path):
1988return input_api.os_path.splitext(file_path)[1]==".mojom"
1989
1990
Mohamed Heikal5e5b7922020-10-29 18:57:59[diff] [blame]1991defCheckNoUpstreamDepsOnClank(input_api, output_api):
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]1992"""Prevent additions of dependencies from the upstream repo on //clank."""
1993# clank can depend on clank
1994if input_api.change.RepositoryRoot().endswith('clank'):
1995return[]
1996 build_file_patterns=[
1997 r'(.+/)?BUILD\.gn',
1998 r'.+\.gni',
1999]
2000 excluded_files=[r'build[/\\]config[/\\]android[/\\]config\.gni']
2001 bad_pattern= input_api.re.compile(r'^[^#]*//clank')
Mohamed Heikal5e5b7922020-10-29 18:57:59[diff] [blame]2002
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2003 error_message='Disallowed import on //clank in an upstream build file:'
Mohamed Heikal5e5b7922020-10-29 18:57:59[diff] [blame]2004
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2005defFilterFile(affected_file):
2006return input_api.FilterSourceFile(affected_file,
2007 files_to_check=build_file_patterns,
2008 files_to_skip=excluded_files)
Mohamed Heikal5e5b7922020-10-29 18:57:59[diff] [blame]2009
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2010 problems=[]
2011for fin input_api.AffectedSourceFiles(FilterFile):
2012 local_path= f.LocalPath()
2013for line_number, linein f.ChangedContents():
2014if(bad_pattern.search(line)):
2015 problems.append('%s:%d\n %s'%
2016(local_path, line_number, line.strip()))
2017if problems:
2018return[output_api.PresubmitPromptOrNotify(error_message, problems)]
2019else:
2020return[]
Mohamed Heikal5e5b7922020-10-29 18:57:59[diff] [blame]2021
2022
Saagar Sanghavifceeaae2020-08-12 16:40:36[diff] [blame]2023defCheckNoProductionCodeUsingTestOnlyFunctions(input_api, output_api):
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2024"""Attempts to prevent use of functions intended only for testing in
2025 non-testing code. For now this is just a best-effort implementation
2026 that ignores header files and may have some false positives. A
2027 better implementation would probably need a proper C++ parser.
2028 """
2029# We only scan .cc files and the like, as the declaration of
2030# for-testing functions in header files are hard to distinguish from
2031# calls to such functions without a proper C++ parser.
2032 file_inclusion_pattern=[r'.+%s'% _IMPLEMENTATION_EXTENSIONS]
joi@chromium.org55459852011-08-10 15:17:19[diff] [blame]2033
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2034 base_function_pattern= r'[ :]test::[^\s]+|ForTest(s|ing)?|for_test(s|ing)?'
2035 inclusion_pattern= input_api.re.compile(r'(%s)\s*\('%
2036 base_function_pattern)
2037 comment_pattern= input_api.re.compile(r'//.*(%s)'% base_function_pattern)
2038 allowlist_pattern= input_api.re.compile(r'// IN-TEST$')
2039 exclusion_pattern= input_api.re.compile(
2040 r'::[A-Za-z0-9_]+(%s)|(%s)[^;]+\{'%
2041(base_function_pattern, base_function_pattern))
2042# Avoid a false positive in this case, where the method name, the ::, and
2043# the closing { are all on different lines due to line wrapping.
2044# HelperClassForTesting::
2045# HelperClassForTesting(
2046# args)
2047# : member(0) {}
2048 method_defn_pattern= input_api.re.compile(r'[A-Za-z0-9_]+::$')
joi@chromium.org55459852011-08-10 15:17:19[diff] [blame]2049
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2050defFilterFile(affected_file):
2051 files_to_skip=(_EXCLUDED_PATHS+ _TEST_CODE_EXCLUDED_PATHS+
2052 input_api.DEFAULT_FILES_TO_SKIP)
2053return input_api.FilterSourceFile(
2054 affected_file,
2055 files_to_check=file_inclusion_pattern,
2056 files_to_skip=files_to_skip)
joi@chromium.org55459852011-08-10 15:17:19[diff] [blame]2057
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2058 problems=[]
2059for fin input_api.AffectedSourceFiles(FilterFile):
2060 local_path= f.LocalPath()
2061 in_method_defn=False
2062for line_number, linein f.ChangedContents():
2063if(inclusion_pattern.search(line)
2064andnot comment_pattern.search(line)
2065andnot exclusion_pattern.search(line)
2066andnot allowlist_pattern.search(line)
2067andnot in_method_defn):
2068 problems.append('%s:%d\n %s'%
2069(local_path, line_number, line.strip()))
2070 in_method_defn= method_defn_pattern.search(line)
joi@chromium.org55459852011-08-10 15:17:19[diff] [blame]2071
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2072if problems:
2073return[
2074 output_api.PresubmitPromptOrNotify(_TEST_ONLY_WARNING, problems)
2075]
2076else:
2077return[]
joi@chromium.org55459852011-08-10 15:17:19[diff] [blame]2078
2079
Saagar Sanghavifceeaae2020-08-12 16:40:36[diff] [blame]2080defCheckNoProductionCodeUsingTestOnlyFunctionsJava(input_api, output_api):
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2081"""This is a simplified version of
2082 CheckNoProductionCodeUsingTestOnlyFunctions for Java files.
2083 """
2084 javadoc_start_re= input_api.re.compile(r'^\s*/\*\*')
2085 javadoc_end_re= input_api.re.compile(r'^\s*\*/')
2086 name_pattern= r'ForTest(s|ing)?'
2087# Describes an occurrence of "ForTest*" inside a // comment.
2088 comment_re= input_api.re.compile(r'//.*%s'% name_pattern)
2089# Describes @VisibleForTesting(otherwise = VisibleForTesting.PROTECTED)
2090 annotation_re= input_api.re.compile(r'@VisibleForTesting\(')
2091# Catch calls.
2092 inclusion_re= input_api.re.compile(r'(%s)\s*\('% name_pattern)
2093# Ignore definitions. (Comments are ignored separately.)
2094 exclusion_re= input_api.re.compile(r'(%s)[^;]+\{'% name_pattern)
Andrew Grieve40f451d2023-07-06 19:46:51[diff] [blame]2095 allowlist_re= input_api.re.compile(r'// IN-TEST$')
Vaclav Brozek7dbc28c2018-03-27 08:35:23[diff] [blame]2096
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2097 problems=[]
2098 sources=lambda x: input_api.FilterSourceFile(
2099 x,
2100 files_to_skip=(('(?i).*test', r'.*\/junit\/')+ input_api.
2101 DEFAULT_FILES_TO_SKIP),
2102 files_to_check=[r'.*\.java$'])
2103for fin input_api.AffectedFiles(include_deletes=False,
2104 file_filter=sources):
2105 local_path= f.LocalPath()
Vaclav Brozek7dbc28c2018-03-27 08:35:23[diff] [blame]2106 is_inside_javadoc=False
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2107for line_number, linein f.ChangedContents():
2108if is_inside_javadocand javadoc_end_re.search(line):
2109 is_inside_javadoc=False
2110ifnot is_inside_javadocand javadoc_start_re.search(line):
2111 is_inside_javadoc=True
2112if is_inside_javadoc:
2113continue
2114if(inclusion_re.search(line)andnot comment_re.search(line)
2115andnot annotation_re.search(line)
Andrew Grieve40f451d2023-07-06 19:46:51[diff] [blame]2116andnot allowlist_re.search(line)
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2117andnot exclusion_re.search(line)):
2118 problems.append('%s:%d\n %s'%
2119(local_path, line_number, line.strip()))
Vaclav Brozek7dbc28c2018-03-27 08:35:23[diff] [blame]2120
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2121if problems:
2122return[
2123 output_api.PresubmitPromptOrNotify(_TEST_ONLY_WARNING, problems)
2124]
2125else:
2126return[]
Vaclav Brozek7dbc28c2018-03-27 08:35:23[diff] [blame]2127
2128
Saagar Sanghavifceeaae2020-08-12 16:40:36[diff] [blame]2129defCheckNoIOStreamInHeaders(input_api, output_api):
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2130"""Checks to make sure no .h files include <iostream>."""
2131 files=[]
2132 pattern= input_api.re.compile(r'^#include\s*<iostream>',
2133 input_api.re.MULTILINE)
2134for fin input_api.AffectedSourceFiles(input_api.FilterSourceFile):
2135ifnot f.LocalPath().endswith('.h'):
2136continue
2137 contents= input_api.ReadFile(f)
2138if pattern.search(contents):
2139 files.append(f)
thakis@chromium.org10689ca2011-09-02 02:31:54[diff] [blame]2140
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2141if len(files):
2142return[
2143 output_api.PresubmitError(
2144'Do not #include <iostream> in header files, since it inserts static '
2145'initialization into every file including the header. Instead, '
2146'#include <ostream>. See http://crbug.com/94794', files)
2147]
2148return[]
2149
thakis@chromium.org10689ca2011-09-02 02:31:54[diff] [blame]2150
Aleksey Khoroshilov9b28c032022-06-03 16:35:32[diff] [blame]2151defCheckNoStrCatRedefines(input_api, output_api):
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2152"""Checks no windows headers with StrCat redefined are included directly."""
2153 files=[]
Aleksey Khoroshilov9b28c032022-06-03 16:35:32[diff] [blame]2154 files_to_check=(r'.+%s'% _HEADER_EXTENSIONS,
2155 r'.+%s'% _IMPLEMENTATION_EXTENSIONS)
2156 files_to_skip=(input_api.DEFAULT_FILES_TO_SKIP+
2157 _NON_BASE_DEPENDENT_PATHS)
2158 sources_filter=lambda f: input_api.FilterSourceFile(
2159 f, files_to_check=files_to_check, files_to_skip=files_to_skip)
2160
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2161 pattern_deny= input_api.re.compile(
2162 r'^#include\s*[<"](shlwapi|atlbase|propvarutil|sphelper).h[">]',
2163 input_api.re.MULTILINE)
2164 pattern_allow= input_api.re.compile(
2165 r'^#include\s"base/win/windows_defines.inc"', input_api.re.MULTILINE)
Aleksey Khoroshilov9b28c032022-06-03 16:35:32[diff] [blame]2166for fin input_api.AffectedSourceFiles(sources_filter):
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2167 contents= input_api.ReadFile(f)
2168if pattern_deny.search(
2169 contents)andnot pattern_allow.search(contents):
2170 files.append(f.LocalPath())
Danil Chapovalov3518f362018-08-11 16:13:43[diff] [blame]2171
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2172if len(files):
2173return[
2174 output_api.PresubmitError(
2175'Do not #include shlwapi.h, atlbase.h, propvarutil.h or sphelper.h '
2176'directly since they pollute code with StrCat macro. Instead, '
2177'include matching header from base/win. See http://crbug.com/856536',
2178 files)
2179]
2180return[]
Danil Chapovalov3518f362018-08-11 16:13:43[diff] [blame]2181
thakis@chromium.org10689ca2011-09-02 02:31:54[diff] [blame]2182
Andrew Williamsc9f69b482023-07-10 16:07:36[diff] [blame]2183def_CheckNoUNIT_TESTInSourceFiles(input_api, f):
2184 problems=[]
2185
2186 unit_test_macro= input_api.re.compile(
2187'^\s*#.*(?:ifn?def\s+UNIT_TEST|defined\s*\(?\s*UNIT_TEST\s*\)?)(?:$|\s+)')
2188for line_num, linein f.ChangedContents():
2189if unit_test_macro.match(line):
2190 problems.append(' %s:%d'%(f.LocalPath(), line_num))
2191
2192return problems
2193
2194
Saagar Sanghavifceeaae2020-08-12 16:40:36[diff] [blame]2195defCheckNoUNIT_TESTInSourceFiles(input_api, output_api):
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2196"""Checks to make sure no source files use UNIT_TEST."""
2197 problems=[]
2198for fin input_api.AffectedFiles():
2199if(not f.LocalPath().endswith(('.cc','.mm'))):
2200continue
Andrew Williamsc9f69b482023-07-10 16:07:36[diff] [blame]2201 problems.extend(
2202_CheckNoUNIT_TESTInSourceFiles(input_api, f))
jam@chromium.org72df4e782012-06-21 16:28:18[diff] [blame]2203
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2204ifnot problems:
2205return[]
2206return[
2207 output_api.PresubmitPromptWarning('UNIT_TEST is only for headers.\n'+
2208'\n'.join(problems))
2209]
2210
jam@chromium.org72df4e782012-06-21 16:28:18[diff] [blame]2211
Saagar Sanghavifceeaae2020-08-12 16:40:36[diff] [blame]2212defCheckNoDISABLETypoInTests(input_api, output_api):
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2213"""Checks to prevent attempts to disable tests with DISABLE_ prefix.
Dominic Battre033531052018-09-24 15:45:34[diff] [blame]2214
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2215 This test warns if somebody tries to disable a test with the DISABLE_ prefix
2216 instead of DISABLED_. To filter false positives, reports are only generated
2217 if a corresponding MAYBE_ line exists.
2218 """
2219 problems=[]
Dominic Battre033531052018-09-24 15:45:34[diff] [blame]2220
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2221# The following two patterns are looked for in tandem - is a test labeled
2222# as MAYBE_ followed by a DISABLE_ (instead of the correct DISABLED)
2223 maybe_pattern= input_api.re.compile(r'MAYBE_([a-zA-Z0-9_]+)')
2224 disable_pattern= input_api.re.compile(r'DISABLE_([a-zA-Z0-9_]+)')
Dominic Battre033531052018-09-24 15:45:34[diff] [blame]2225
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2226# This is for the case that a test is disabled on all platforms.
2227 full_disable_pattern= input_api.re.compile(
2228 r'^\s*TEST[^(]*\([a-zA-Z0-9_]+,\s*DISABLE_[a-zA-Z0-9_]+\)',
2229 input_api.re.MULTILINE)
Dominic Battre033531052018-09-24 15:45:34[diff] [blame]2230
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2231for fin input_api.AffectedFiles(False):
2232ifnot'test'in f.LocalPath()ornot f.LocalPath().endswith('.cc'):
2233continue
Dominic Battre033531052018-09-24 15:45:34[diff] [blame]2234
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2235# Search for MABYE_, DISABLE_ pairs.
2236 disable_lines={}# Maps of test name to line number.
2237 maybe_lines={}
2238for line_num, linein f.ChangedContents():
2239 disable_match= disable_pattern.search(line)
2240if disable_match:
2241 disable_lines[disable_match.group(1)]= line_num
2242 maybe_match= maybe_pattern.search(line)
2243if maybe_match:
2244 maybe_lines[maybe_match.group(1)]= line_num
Dominic Battre033531052018-09-24 15:45:34[diff] [blame]2245
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2246# Search for DISABLE_ occurrences within a TEST() macro.
2247 disable_tests= set(disable_lines.keys())
2248 maybe_tests= set(maybe_lines.keys())
2249for testin disable_tests.intersection(maybe_tests):
2250 problems.append(' %s:%d'%(f.LocalPath(), disable_lines[test]))
Dominic Battre033531052018-09-24 15:45:34[diff] [blame]2251
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2252 contents= input_api.ReadFile(f)
2253 full_disable_match= full_disable_pattern.search(contents)
2254if full_disable_match:
2255 problems.append(' %s'% f.LocalPath())
Dominic Battre033531052018-09-24 15:45:34[diff] [blame]2256
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2257ifnot problems:
2258return[]
2259return[
2260 output_api.PresubmitPromptWarning(
2261'Attempt to disable a test with DISABLE_ instead of DISABLED_?\n'+
2262'\n'.join(problems))
2263]
2264
Dominic Battre033531052018-09-24 15:45:34[diff] [blame]2265
Nina Satragnof7660532021-09-20 18:03:35[diff] [blame]2266defCheckForgettingMAYBEInTests(input_api, output_api):
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2267"""Checks to make sure tests disabled conditionally are not missing a
2268 corresponding MAYBE_ prefix.
2269 """
2270# Expect at least a lowercase character in the test name. This helps rule out
2271# false positives with macros wrapping the actual tests name.
2272 define_maybe_pattern= input_api.re.compile(
2273 r'^\#define MAYBE_(?P<test_name>\w*[a-z]\w*)')
Bruce Dawsonffc55292022-04-20 04:18:19[diff] [blame]2274# The test_maybe_pattern needs to handle all of these forms. The standard:
2275# IN_PROC_TEST_F(SyncTest, MAYBE_Start) {
2276# With a wrapper macro around the test name:
2277# IN_PROC_TEST_F(SyncTest, E2E_ENABLED(MAYBE_Start)) {
2278# And the odd-ball NACL_BROWSER_TEST_f format:
2279# NACL_BROWSER_TEST_F(NaClBrowserTest, SimpleLoad, {
2280# The optional E2E_ENABLED-style is handled with (\w*\()?
2281# The NACL_BROWSER_TEST_F pattern is handled by allowing a trailing comma or
2282# trailing ')'.
2283 test_maybe_pattern=(
2284 r'^\s*\w*TEST[^(]*\(\s*\w+,\s*(\w*\()?MAYBE_{test_name}[\),]')
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2285 suite_maybe_pattern= r'^\s*\w*TEST[^(]*\(\s*MAYBE_{test_name}[\),]'
2286 warnings=[]
Nina Satragnof7660532021-09-20 18:03:35[diff] [blame]2287
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2288# Read the entire files. We can't just read the affected lines, forgetting to
2289# add MAYBE_ on a change would not show up otherwise.
2290for fin input_api.AffectedFiles(False):
2291ifnot'test'in f.LocalPath()ornot f.LocalPath().endswith('.cc'):
2292continue
2293 contents= input_api.ReadFile(f)
2294 lines= contents.splitlines(True)
2295 current_position=0
2296 warning_test_names= set()
2297for line_num, linein enumerate(lines, start=1):
2298 current_position+= len(line)
2299 maybe_match= define_maybe_pattern.search(line)
2300if maybe_match:
2301 test_name= maybe_match.group('test_name')
2302# Do not warn twice for the same test.
2303if(test_namein warning_test_names):
2304continue
2305 warning_test_names.add(test_name)
Nina Satragnof7660532021-09-20 18:03:35[diff] [blame]2306
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2307# Attempt to find the corresponding MAYBE_ test or suite, starting from
2308# the current position.
2309 test_match= input_api.re.compile(
2310 test_maybe_pattern.format(test_name=test_name),
2311 input_api.re.MULTILINE).search(contents, current_position)
2312 suite_match= input_api.re.compile(
2313 suite_maybe_pattern.format(test_name=test_name),
2314 input_api.re.MULTILINE).search(contents, current_position)
2315ifnot test_matchandnot suite_match:
2316 warnings.append(
2317 output_api.PresubmitPromptWarning(
2318'%s:%d found MAYBE_ defined without corresponding test %s'
2319%(f.LocalPath(), line_num, test_name)))
2320return warnings
2321
jam@chromium.org72df4e782012-06-21 16:28:18[diff] [blame]2322
Saagar Sanghavifceeaae2020-08-12 16:40:36[diff] [blame]2323defCheckDCHECK_IS_ONHasBraces(input_api, output_api):
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2324"""Checks to make sure DCHECK_IS_ON() does not skip the parentheses."""
2325 errors=[]
Kalvin Lee4a3b79de2022-05-26 16:00:16[diff] [blame]2326 pattern= input_api.re.compile(r'\bDCHECK_IS_ON\b(?!\(\))',
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2327 input_api.re.MULTILINE)
2328for fin input_api.AffectedSourceFiles(input_api.FilterSourceFile):
2329if(not f.LocalPath().endswith(('.cc','.mm','.h'))):
2330continue
2331for lnum, linein f.ChangedContents():
2332if input_api.re.search(pattern, line):
2333 errors.append(
2334 output_api.PresubmitError((
2335'%s:%d: Use of DCHECK_IS_ON() must be written as "#if '
2336+'DCHECK_IS_ON()", not forgetting the parentheses.')%
2337(f.LocalPath(), lnum)))
2338return errors
danakj61c1aa22015-10-26 19:55:52[diff] [blame]2339
2340
Weilun Shia487fad2020-10-28 00:10:34[diff] [blame]2341# TODO(crbug/1138055): Reimplement CheckUmaHistogramChangesOnUpload check in a
2342# more reliable way. See
2343# https://chromium-review.googlesource.com/c/chromium/src/+/2500269
mcasasb7440c282015-02-04 14:52:19[diff] [blame]2344
wnwenbdc444e2016-05-25 13:44:15[diff] [blame]2345
Saagar Sanghavifceeaae2020-08-12 16:40:36[diff] [blame]2346defCheckFlakyTestUsage(input_api, output_api):
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2347"""Check that FlakyTest annotation is our own instead of the android one"""
2348 pattern= input_api.re.compile(r'import android.test.FlakyTest;')
2349 files=[]
2350for fin input_api.AffectedSourceFiles(input_api.FilterSourceFile):
2351if f.LocalPath().endswith('Test.java'):
2352if pattern.search(input_api.ReadFile(f)):
2353 files.append(f)
2354if len(files):
2355return[
2356 output_api.PresubmitError(
2357'Use org.chromium.base.test.util.FlakyTest instead of '
2358'android.test.FlakyTest', files)
2359]
2360return[]
mcasasb7440c282015-02-04 14:52:19[diff] [blame]2361
wnwenbdc444e2016-05-25 13:44:15[diff] [blame]2362
Saagar Sanghavifceeaae2020-08-12 16:40:36[diff] [blame]2363defCheckNoDEPSGIT(input_api, output_api):
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2364"""Make sure .DEPS.git is never modified manually."""
2365if any(f.LocalPath().endswith('.DEPS.git')
2366for fin input_api.AffectedFiles()):
2367return[
2368 output_api.PresubmitError(
2369'Never commit changes to .DEPS.git. This file is maintained by an\n'
2370'automated system based on what\'s in DEPS and your changes will be\n'
2371'overwritten.\n'
2372'See https://sites.google.com/a/chromium.org/dev/developers/how-tos/'
2373'get-the-code#Rolling_DEPS\n'
2374'for more information')
2375]
2376return[]
maruel@chromium.org2a8ac9c2011-10-19 17:20:44[diff] [blame]2377
2378
Sven Zheng76a79ea2022-12-21 21:25:24[diff] [blame]2379defCheckCrosApiNeedBrowserTest(input_api, output_api):
2380"""Check new crosapi should add browser test."""
2381 has_new_crosapi=False
2382 has_browser_test=False
2383for fin input_api.AffectedFiles():
2384 path= f.LocalPath()
2385if(path.startswith('chromeos/crosapi/mojom')and
2386_IsMojomFile(input_api, path)and f.Action()=='A'):
2387 has_new_crosapi=True
2388if path.endswith('browsertest.cc')or path.endswith('browser_test.cc'):
2389 has_browser_test=True
2390if has_new_crosapiandnot has_browser_test:
2391return[
2392 output_api.PresubmitPromptWarning(
2393'You are adding a new crosapi, but there is no file ends with '
2394'browsertest.cc file being added or modified. It is important '
2395'to add crosapi browser test coverage to avoid version '
2396' skew issues.\n'
2397'Check //docs/lacros/test_instructions.md for more information.'
2398)
2399]
2400return[]
2401
2402
Saagar Sanghavifceeaae2020-08-12 16:40:36[diff] [blame]2403defCheckValidHostsInDEPSOnUpload(input_api, output_api):
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2404"""Checks that DEPS file deps are from allowed_hosts."""
2405# Run only if DEPS file has been modified to annoy fewer bystanders.
2406if all(f.LocalPath()!='DEPS'for fin input_api.AffectedFiles()):
2407return[]
2408# Outsource work to gclient verify
2409try:
2410 gclient_path= input_api.os_path.join(input_api.PresubmitLocalPath(),
2411'third_party','depot_tools',
2412'gclient.py')
2413 input_api.subprocess.check_output(
Bruce Dawson8a43cf72022-05-13 17:10:32[diff] [blame]2414[input_api.python3_executable, gclient_path,'verify'],
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2415 stderr=input_api.subprocess.STDOUT)
2416return[]
2417except input_api.subprocess.CalledProcessErroras error:
2418return[
2419 output_api.PresubmitError(
2420'DEPS file must have only git dependencies.',
2421 long_text=error.output)
2422]
tandriief664692014-09-23 14:51:47[diff] [blame]2423
2424
Mario Sanchez Prada2472cab2019-09-18 10:58:31[diff] [blame]2425def_GetMessageForMatchingType(input_api, affected_file, line_number, line,
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]2426 ban_rule):
Allen Bauer84778682022-09-22 16:28:56[diff] [blame]2427"""Helper method for checking for banned constructs.
Mario Sanchez Prada2472cab2019-09-18 10:58:31[diff] [blame]2428
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2429 Returns an string composed of the name of the file, the line number where the
2430 match has been found and the additional text passed as |message| in case the
2431 target type name matches the text inside the line passed as parameter.
2432 """
2433 result=[]
Peng Huang9c5949a02020-06-11 19:20:54[diff] [blame]2434
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]2435# Ignore comments about banned types.
2436if input_api.re.search(r"^ *//", line):
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2437return result
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]2438# A // nocheck comment will bypass this error.
2439if line.endswith(" nocheck"):
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2440return result
2441
2442 matched=False
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]2443if ban_rule.pattern[0:1]=='/':
2444 regex= ban_rule.pattern[1:]
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2445if input_api.re.search(regex, line):
2446 matched=True
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]2447elif ban_rule.patternin line:
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2448 matched=True
2449
2450if matched:
2451 result.append(' %s:%d:'%(affected_file.LocalPath(), line_number))
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]2452for linein ban_rule.explanation:
2453 result.append(' %s'% line)
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2454
danakjd18e8892020-12-17 17:42:01[diff] [blame]2455return result
Mario Sanchez Prada2472cab2019-09-18 10:58:31[diff] [blame]2456
2457
Saagar Sanghavifceeaae2020-08-12 16:40:36[diff] [blame]2458defCheckNoBannedFunctions(input_api, output_api):
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2459"""Make sure that banned functions are not used."""
2460 warnings=[]
2461 errors=[]
avi@chromium.org127f18ec2012-06-16 05:05:59[diff] [blame]2462
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2463defIsExcludedFile(affected_file, excluded_paths):
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]2464ifnot excluded_paths:
2465returnFalse
2466
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2467 local_path= affected_file.LocalPath()
Bruce Dawson40fece62022-09-16 19:58:31[diff] [blame]2468# Consistently use / as path separator to simplify the writing of regex
2469# expressions.
2470 local_path= local_path.replace(input_api.os_path.sep,'/')
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2471for itemin excluded_paths:
2472if input_api.re.match(item, local_path):
2473returnTrue
2474returnFalse
wnwenbdc444e2016-05-25 13:44:15[diff] [blame]2475
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2476defIsIosObjcFile(affected_file):
2477 local_path= affected_file.LocalPath()
2478if input_api.os_path.splitext(local_path)[-1]notin('.mm','.m',
2479'.h'):
2480returnFalse
2481 basename= input_api.os_path.basename(local_path)
2482if'ios'in basename.split('_'):
2483returnTrue
2484for sepin(input_api.os_path.sep, input_api.os_path.altsep):
2485if sepand'ios'in local_path.split(sep):
2486returnTrue
2487returnFalse
Sylvain Defresnea8b73d252018-02-28 15:45:54[diff] [blame]2488
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]2489defCheckForMatch(affected_file, line_num: int, line: str,
2490 ban_rule:BanRule):
2491ifIsExcludedFile(affected_file, ban_rule.excluded_paths):
2492return
2493
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2494 problems=_GetMessageForMatchingType(input_api, f, line_num, line,
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]2495 ban_rule)
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2496if problems:
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]2497if ban_rule.treat_as_errorisnotNoneand ban_rule.treat_as_error:
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2498 errors.extend(problems)
2499else:
2500 warnings.extend(problems)
wnwenbdc444e2016-05-25 13:44:15[diff] [blame]2501
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2502 file_filter=lambda f: f.LocalPath().endswith(('.java'))
2503for fin input_api.AffectedFiles(file_filter=file_filter):
2504for line_num, linein f.ChangedContents():
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]2505for ban_rulein _BANNED_JAVA_FUNCTIONS:
2506CheckForMatch(f, line_num, line, ban_rule)
Eric Stevensona9a980972017-09-23 00:04:41[diff] [blame]2507
Clement Yan9b330cb2022-11-17 05:25:29[diff] [blame]2508 file_filter=lambda f: f.LocalPath().endswith(('.js','.ts'))
2509for fin input_api.AffectedFiles(file_filter=file_filter):
2510for line_num, linein f.ChangedContents():
2511for ban_rulein _BANNED_JAVASCRIPT_FUNCTIONS:
2512CheckForMatch(f, line_num, line, ban_rule)
2513
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2514 file_filter=lambda f: f.LocalPath().endswith(('.mm','.m','.h'))
2515for fin input_api.AffectedFiles(file_filter=file_filter):
2516for line_num, linein f.ChangedContents():
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]2517for ban_rulein _BANNED_OBJC_FUNCTIONS:
2518CheckForMatch(f, line_num, line, ban_rule)
avi@chromium.org127f18ec2012-06-16 05:05:59[diff] [blame]2519
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2520for fin input_api.AffectedFiles(file_filter=IsIosObjcFile):
2521for line_num, linein f.ChangedContents():
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]2522for ban_rulein _BANNED_IOS_OBJC_FUNCTIONS:
2523CheckForMatch(f, line_num, line, ban_rule)
Sylvain Defresnea8b73d252018-02-28 15:45:54[diff] [blame]2524
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2525 egtest_filter=lambda f: f.LocalPath().endswith(('_egtest.mm'))
2526for fin input_api.AffectedFiles(file_filter=egtest_filter):
2527for line_num, linein f.ChangedContents():
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]2528for ban_rulein _BANNED_IOS_EGTEST_FUNCTIONS:
2529CheckForMatch(f, line_num, line, ban_rule)
Peter K. Lee6c03ccff2019-07-15 14:40:05[diff] [blame]2530
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2531 file_filter=lambda f: f.LocalPath().endswith(('.cc','.mm','.h'))
2532for fin input_api.AffectedFiles(file_filter=file_filter):
2533for line_num, linein f.ChangedContents():
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]2534for ban_rulein _BANNED_CPP_FUNCTIONS:
2535CheckForMatch(f, line_num, line, ban_rule)
avi@chromium.org127f18ec2012-06-16 05:05:59[diff] [blame]2536
Daniel Cheng92c15e32022-03-16 17:48:22[diff] [blame]2537 file_filter=lambda f: f.LocalPath().endswith(('.mojom'))
2538for fin input_api.AffectedFiles(file_filter=file_filter):
2539for line_num, linein f.ChangedContents():
2540for ban_rulein _BANNED_MOJOM_PATTERNS:
2541CheckForMatch(f, line_num, line, ban_rule)
2542
2543
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2544 result=[]
2545if(warnings):
2546 result.append(
2547 output_api.PresubmitPromptWarning('Banned functions were used.\n'+
2548'\n'.join(warnings)))
2549if(errors):
2550 result.append(
2551 output_api.PresubmitError('Banned functions were used.\n'+
2552'\n'.join(errors)))
2553return result
avi@chromium.org127f18ec2012-06-16 05:05:59[diff] [blame]2554
Allen Bauer84778682022-09-22 16:28:56[diff] [blame]2555defCheckNoLayoutCallsInTests(input_api, output_api):
2556"""Make sure there are no explicit calls to View::Layout() in tests"""
2557 warnings=[]
2558 ban_rule=BanRule(
2559 r'/(\.|->)Layout\(\);',
2560(
2561'Direct calls to View::Layout() are not allowed in tests. '
2562'If the view must be laid out here, use RunScheduledLayout(view). It '
2563'is found in //ui/views/test/views_test_utils.h. '
2564'See http://crbug.com/1350521 for more details.',
2565),
2566False,
2567)
2568 file_filter=lambda f: input_api.re.search(
2569 r'_(unittest|browsertest|ui_test).*\.(cc|mm)$', f.LocalPath())
2570for fin input_api.AffectedFiles(file_filter= file_filter):
2571for line_num, linein f.ChangedContents():
2572 problems=_GetMessageForMatchingType(input_api, f,
2573 line_num, line,
2574 ban_rule)
2575if problems:
2576 warnings.extend(problems)
2577 result=[]
2578if(warnings):
2579 result.append(
2580 output_api.PresubmitPromptWarning(
2581'Banned call to View::Layout() in tests.\n\n'.join(warnings)))
2582return result
avi@chromium.org127f18ec2012-06-16 05:05:59[diff] [blame]2583
Michael Thiessen44457642020-02-06 00:24:15[diff] [blame]2584def_CheckAndroidNoBannedImports(input_api, output_api):
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2585"""Make sure that banned java imports are not used."""
2586 errors=[]
Michael Thiessen44457642020-02-06 00:24:15[diff] [blame]2587
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2588 file_filter=lambda f: f.LocalPath().endswith(('.java'))
2589for fin input_api.AffectedFiles(file_filter=file_filter):
2590for line_num, linein f.ChangedContents():
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]2591for ban_rulein _BANNED_JAVA_IMPORTS:
2592# Consider merging this into the above function. There is no
2593# real difference anymore other than helping with a little
2594# bit of boilerplate text. Doing so means things like
2595# `treat_as_error` will also be uniformly handled.
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2596 problems=_GetMessageForMatchingType(input_api, f, line_num,
Daniel Chenga44a1bcd2022-03-15 20:00:15[diff] [blame]2597 line, ban_rule)
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2598if problems:
2599 errors.extend(problems)
2600 result=[]
2601if(errors):
2602 result.append(
2603 output_api.PresubmitError('Banned imports were used.\n'+
2604'\n'.join(errors)))
2605return result
Michael Thiessen44457642020-02-06 00:24:15[diff] [blame]2606
2607
Saagar Sanghavifceeaae2020-08-12 16:40:36[diff] [blame]2608defCheckNoPragmaOnce(input_api, output_api):
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2609"""Make sure that banned functions are not used."""
2610 files=[]
2611 pattern= input_api.re.compile(r'^#pragma\s+once', input_api.re.MULTILINE)
2612for fin input_api.AffectedSourceFiles(input_api.FilterSourceFile):
2613ifnot f.LocalPath().endswith('.h'):
2614continue
Bruce Dawson4c4c2922022-05-02 18:07:33[diff] [blame]2615if f.LocalPath().endswith('com_imported_mstscax.h'):
2616continue
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2617 contents= input_api.ReadFile(f)
2618if pattern.search(contents):
2619 files.append(f)
dcheng@chromium.org6c063c62012-07-11 19:11:06[diff] [blame]2620
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2621if files:
2622return[
2623 output_api.PresubmitError(
2624'Do not use #pragma once in header files.\n'
2625'See http://www.chromium.org/developers/coding-style#TOC-File-headers',
2626 files)
2627]
2628return[]
dcheng@chromium.org6c063c62012-07-11 19:11:06[diff] [blame]2629
avi@chromium.org127f18ec2012-06-16 05:05:59[diff] [blame]2630
Saagar Sanghavifceeaae2020-08-12 16:40:36[diff] [blame]2631defCheckNoTrinaryTrueFalse(input_api, output_api):
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2632"""Checks to make sure we don't introduce use of foo ? true : false."""
2633 problems=[]
2634 pattern= input_api.re.compile(r'\?\s*(true|false)\s*:\s*(true|false)')
2635for fin input_api.AffectedFiles():
2636ifnot f.LocalPath().endswith(('.cc','.h','.inl','.m','.mm')):
2637continue
thestig@chromium.orge7479052012-09-19 00:26:12[diff] [blame]2638
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2639for line_num, linein f.ChangedContents():
2640if pattern.match(line):
2641 problems.append(' %s:%d'%(f.LocalPath(), line_num))
thestig@chromium.orge7479052012-09-19 00:26:12[diff] [blame]2642
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2643ifnot problems:
2644return[]
2645return[
2646 output_api.PresubmitPromptWarning(
2647'Please consider avoiding the "? true : false" pattern if possible.\n'
2648+'\n'.join(problems))
2649]
thestig@chromium.orge7479052012-09-19 00:26:12[diff] [blame]2650
2651
Saagar Sanghavifceeaae2020-08-12 16:40:36[diff] [blame]2652defCheckUnwantedDependencies(input_api, output_api):
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2653"""Runs checkdeps on #include and import statements added in this
2654 change. Breaking - rules is an error, breaking ! rules is a
2655 warning.
2656 """
2657# Return early if no relevant file types were modified.
2658for fin input_api.AffectedFiles():
2659 path= f.LocalPath()
2660if(_IsCPlusPlusFile(input_api, path)or_IsProtoFile(input_api, path)
2661or_IsJavaFile(input_api, path)):
2662break
joi@chromium.org55f9f382012-07-31 11:02:18[diff] [blame]2663else:
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2664return[]
rhalavati08acd232017-04-03 07:23:28[diff] [blame]2665
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2666import sys
2667# We need to wait until we have an input_api object and use this
2668# roundabout construct to import checkdeps because this file is
2669# eval-ed and thus doesn't have __file__.
2670 original_sys_path= sys.path
2671try:
2672 sys.path= sys.path+[
2673 input_api.os_path.join(input_api.PresubmitLocalPath(),
2674'buildtools','checkdeps')
2675]
2676import checkdeps
2677from rulesimportRule
2678finally:
2679# Restore sys.path to what it was before.
2680 sys.path= original_sys_path
joi@chromium.org55f9f382012-07-31 11:02:18[diff] [blame]2681
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2682 added_includes=[]
2683 added_imports=[]
2684 added_java_imports=[]
2685for fin input_api.AffectedFiles():
2686if_IsCPlusPlusFile(input_api, f.LocalPath()):
2687 changed_lines=[linefor _, linein f.ChangedContents()]
2688 added_includes.append([f.AbsoluteLocalPath(), changed_lines])
2689elif_IsProtoFile(input_api, f.LocalPath()):
2690 changed_lines=[linefor _, linein f.ChangedContents()]
2691 added_imports.append([f.AbsoluteLocalPath(), changed_lines])
2692elif_IsJavaFile(input_api, f.LocalPath()):
2693 changed_lines=[linefor _, linein f.ChangedContents()]
2694 added_java_imports.append([f.AbsoluteLocalPath(), changed_lines])
Jinsuk Kim5a092672017-10-24 22:42:24[diff] [blame]2695
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2696 deps_checker= checkdeps.DepsChecker(input_api.PresubmitLocalPath())
2697
2698 error_descriptions=[]
2699 warning_descriptions=[]
2700 error_subjects= set()
2701 warning_subjects= set()
2702
2703for path, rule_type, rule_descriptionin deps_checker.CheckAddedCppIncludes(
2704 added_includes):
2705 path= input_api.os_path.relpath(path, input_api.PresubmitLocalPath())
2706 description_with_path='%s\n %s'%(path, rule_description)
2707if rule_type==Rule.DISALLOW:
2708 error_descriptions.append(description_with_path)
2709 error_subjects.add("#includes")
2710else:
2711 warning_descriptions.append(description_with_path)
2712 warning_subjects.add("#includes")
2713
2714for path, rule_type, rule_descriptionin deps_checker.CheckAddedProtoImports(
2715 added_imports):
2716 path= input_api.os_path.relpath(path, input_api.PresubmitLocalPath())
2717 description_with_path='%s\n %s'%(path, rule_description)
2718if rule_type==Rule.DISALLOW:
2719 error_descriptions.append(description_with_path)
2720 error_subjects.add("imports")
2721else:
2722 warning_descriptions.append(description_with_path)
2723 warning_subjects.add("imports")
2724
2725for path, rule_type, rule_descriptionin deps_checker.CheckAddedJavaImports(
2726 added_java_imports, _JAVA_MULTIPLE_DEFINITION_EXCLUDED_PATHS):
2727 path= input_api.os_path.relpath(path, input_api.PresubmitLocalPath())
2728 description_with_path='%s\n %s'%(path, rule_description)
2729if rule_type==Rule.DISALLOW:
2730 error_descriptions.append(description_with_path)
2731 error_subjects.add("imports")
2732else:
2733 warning_descriptions.append(description_with_path)
2734 warning_subjects.add("imports")
2735
2736 results=[]
2737if error_descriptions:
2738 results.append(
2739 output_api.PresubmitError(
2740'You added one or more %s that violate checkdeps rules.'%
2741" and ".join(error_subjects), error_descriptions))
2742if warning_descriptions:
2743 results.append(
2744 output_api.PresubmitPromptOrNotify(
2745'You added one or more %s of files that are temporarily\n'
2746'allowed but being removed. Can you avoid introducing the\n'
2747'%s? See relevant DEPS file(s) for details and contacts.'%
2748(" and ".join(warning_subjects),"/".join(warning_subjects)),
2749 warning_descriptions))
2750return results
joi@chromium.org55f9f382012-07-31 11:02:18[diff] [blame]2751
2752
Saagar Sanghavifceeaae2020-08-12 16:40:36[diff] [blame]2753defCheckFilePermissions(input_api, output_api):
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2754"""Check that all files have their permissions properly set."""
2755if input_api.platform=='win32':
2756return[]
2757 checkperms_tool= input_api.os_path.join(input_api.PresubmitLocalPath(),
2758'tools','checkperms',
2759'checkperms.py')
2760 args=[
Bruce Dawson8a43cf72022-05-13 17:10:32[diff] [blame]2761 input_api.python3_executable, checkperms_tool,'--root',
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2762 input_api.change.RepositoryRoot()
2763]
2764with input_api.CreateTemporaryFile()as file_list:
2765for fin input_api.AffectedFiles():
2766# checkperms.py file/directory arguments must be relative to the
2767# repository.
2768 file_list.write((f.LocalPath()+'\n').encode('utf8'))
2769 file_list.close()
2770 args+=['--file-list', file_list.name]
2771try:
2772 input_api.subprocess.check_output(args)
2773return[]
2774except input_api.subprocess.CalledProcessErroras error:
2775return[
2776 output_api.PresubmitError('checkperms.py failed:',
2777 long_text=error.output.decode(
2778'utf-8','ignore'))
2779]
csharp@chromium.orgfbcafe5a2012-08-08 15:31:22[diff] [blame]2780
2781
Saagar Sanghavifceeaae2020-08-12 16:40:36[diff] [blame]2782defCheckNoAuraWindowPropertyHInHeaders(input_api, output_api):
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2783"""Makes sure we don't include ui/aura/window_property.h
2784 in header files.
2785 """
2786 pattern= input_api.re.compile(r'^#include\s*"ui/aura/window_property.h"')
2787 errors=[]
2788for fin input_api.AffectedFiles():
2789ifnot f.LocalPath().endswith('.h'):
2790continue
2791for line_num, linein f.ChangedContents():
2792if pattern.match(line):
2793 errors.append(' %s:%d'%(f.LocalPath(), line_num))
oshima@chromium.orgc8278b32012-10-30 20:35:49[diff] [blame]2794
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2795 results=[]
2796if errors:
2797 results.append(
2798 output_api.PresubmitError(
2799'Header files should not include ui/aura/window_property.h',
2800 errors))
2801return results
oshima@chromium.orgc8278b32012-10-30 20:35:49[diff] [blame]2802
2803
Omer Katzcc77ea92021-04-26 10:23:28[diff] [blame]2804defCheckNoInternalHeapIncludes(input_api, output_api):
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2805"""Makes sure we don't include any headers from
2806 third_party/blink/renderer/platform/heap/impl or
2807 third_party/blink/renderer/platform/heap/v8_wrapper from files outside of
2808 third_party/blink/renderer/platform/heap
2809 """
2810 impl_pattern= input_api.re.compile(
2811 r'^\s*#include\s*"third_party/blink/renderer/platform/heap/impl/.*"')
2812 v8_wrapper_pattern= input_api.re.compile(
2813 r'^\s*#include\s*"third_party/blink/renderer/platform/heap/v8_wrapper/.*"'
2814)
Bruce Dawson40fece62022-09-16 19:58:31[diff] [blame]2815# Consistently use / as path separator to simplify the writing of regex
2816# expressions.
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2817 file_filter=lambda f:not input_api.re.match(
Bruce Dawson40fece62022-09-16 19:58:31[diff] [blame]2818 r"^third_party/blink/renderer/platform/heap/.*",
2819 f.LocalPath().replace(input_api.os_path.sep,'/'))
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2820 errors=[]
Omer Katzcc77ea92021-04-26 10:23:28[diff] [blame]2821
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2822for fin input_api.AffectedFiles(file_filter=file_filter):
2823for line_num, linein f.ChangedContents():
2824if impl_pattern.match(line)or v8_wrapper_pattern.match(line):
2825 errors.append(' %s:%d'%(f.LocalPath(), line_num))
Omer Katzcc77ea92021-04-26 10:23:28[diff] [blame]2826
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2827 results=[]
2828if errors:
2829 results.append(
2830 output_api.PresubmitError(
2831'Do not include files from third_party/blink/renderer/platform/heap/impl'
2832' or third_party/blink/renderer/platform/heap/v8_wrapper. Use the '
2833'relevant counterparts from third_party/blink/renderer/platform/heap',
2834 errors))
2835return results
Omer Katzcc77ea92021-04-26 10:23:28[diff] [blame]2836
2837
dbeam@chromium.org70ca77752012-11-20 03:45:03[diff] [blame]2838def_CheckForVersionControlConflictsInFile(input_api, f):
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2839 pattern= input_api.re.compile('^(?:<<<<<<<|>>>>>>>) |^=======$')
2840 errors=[]
2841for line_num, linein f.ChangedContents():
2842if f.LocalPath().endswith(('.md','.rst','.txt')):
2843# First-level headers in markdown look a lot like version control
2844# conflict markers. http://daringfireball.net/projects/markdown/basics
2845continue
2846if pattern.match(line):
2847 errors.append(' %s:%d %s'%(f.LocalPath(), line_num, line))
2848return errors
dbeam@chromium.org70ca77752012-11-20 03:45:03[diff] [blame]2849
2850
Saagar Sanghavifceeaae2020-08-12 16:40:36[diff] [blame]2851defCheckForVersionControlConflicts(input_api, output_api):
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2852"""Usually this is not intentional and will cause a compile failure."""
2853 errors=[]
2854for fin input_api.AffectedFiles():
2855 errors.extend(_CheckForVersionControlConflictsInFile(input_api, f))
dbeam@chromium.org70ca77752012-11-20 03:45:03[diff] [blame]2856
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2857 results=[]
2858if errors:
2859 results.append(
2860 output_api.PresubmitError(
2861'Version control conflict markers found, please resolve.',
2862 errors))
2863return results
dbeam@chromium.org70ca77752012-11-20 03:45:03[diff] [blame]2864
Wei-Yin Chen (陳威尹)f799d442018-07-31 02:20:20[diff] [blame]2865
Saagar Sanghavifceeaae2020-08-12 16:40:36[diff] [blame]2866defCheckGoogleSupportAnswerUrlOnUpload(input_api, output_api):
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2867 pattern= input_api.re.compile('support\.google\.com\/chrome.*/answer')
2868 errors=[]
2869for fin input_api.AffectedFiles():
2870for line_num, linein f.ChangedContents():
2871if pattern.search(line):
2872 errors.append(' %s:%d %s'%(f.LocalPath(), line_num, line))
estadee17314a02017-01-12 16:22:16[diff] [blame]2873
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2874 results=[]
2875if errors:
2876 results.append(
2877 output_api.PresubmitPromptWarning(
2878'Found Google support URL addressed by answer number. Please replace '
2879'with a p= identifier instead. See crbug.com/679462\n',
2880 errors))
2881return results
estadee17314a02017-01-12 16:22:16[diff] [blame]2882
dbeam@chromium.org70ca77752012-11-20 03:45:03[diff] [blame]2883
Saagar Sanghavifceeaae2020-08-12 16:40:36[diff] [blame]2884defCheckHardcodedGoogleHostsInLowerLayers(input_api, output_api):
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2885defFilterFile(affected_file):
2886"""Filter function for use with input_api.AffectedSourceFiles,
2887 below. This filters out everything except non-test files from
2888 top-level directories that generally speaking should not hard-code
2889 service URLs (e.g. src/android_webview/, src/content/ and others).
2890 """
2891return input_api.FilterSourceFile(
2892 affected_file,
Bruce Dawson40fece62022-09-16 19:58:31[diff] [blame]2893 files_to_check=[r'^(android_webview|base|content|net)/.*'],
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2894 files_to_skip=(_EXCLUDED_PATHS+ _TEST_CODE_EXCLUDED_PATHS+
2895 input_api.DEFAULT_FILES_TO_SKIP))
joi@chromium.org06e6d0ff2012-12-11 01:36:44[diff] [blame]2896
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2897 base_pattern=('"[^"]*(google|googleapis|googlezip|googledrive|appspot)'
2898'\.(com|net)[^"]*"')
2899 comment_pattern= input_api.re.compile('//.*%s'% base_pattern)
2900 pattern= input_api.re.compile(base_pattern)
2901 problems=[]# items are (filename, line_number, line)
2902for fin input_api.AffectedSourceFiles(FilterFile):
2903for line_num, linein f.ChangedContents():
2904ifnot comment_pattern.search(line)and pattern.search(line):
2905 problems.append((f.LocalPath(), line_num, line))
joi@chromium.org06e6d0ff2012-12-11 01:36:44[diff] [blame]2906
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2907if problems:
2908return[
2909 output_api.PresubmitPromptOrNotify(
2910'Most layers below src/chrome/ should not hardcode service URLs.\n'
2911'Are you sure this is correct?',[
2912' %s:%d: %s'%(problem[0], problem[1], problem[2])
2913for problemin problems
2914])
2915]
2916else:
2917return[]
joi@chromium.org06e6d0ff2012-12-11 01:36:44[diff] [blame]2918
2919
Saagar Sanghavifceeaae2020-08-12 16:40:36[diff] [blame]2920defCheckChromeOsSyncedPrefRegistration(input_api, output_api):
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2921"""Warns if Chrome OS C++ files register syncable prefs as browser prefs."""
James Cook6b6597c2019-11-06 22:05:29[diff] [blame]2922
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2923defFileFilter(affected_file):
2924"""Includes directories known to be Chrome OS only."""
2925return input_api.FilterSourceFile(
2926 affected_file,
2927 files_to_check=(
2928'^ash/',
2929'^chromeos/',# Top-level src/chromeos.
2930'.*/chromeos/',# Any path component.
2931'^components/arc',
2932'^components/exo'),
2933 files_to_skip=(input_api.DEFAULT_FILES_TO_SKIP))
James Cook6b6597c2019-11-06 22:05:29[diff] [blame]2934
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2935 prefs=[]
2936 priority_prefs=[]
2937for fin input_api.AffectedFiles(file_filter=FileFilter):
2938for line_num, linein f.ChangedContents():
2939if input_api.re.search('PrefRegistrySyncable::SYNCABLE_PREF',
2940 line):
2941 prefs.append(' %s:%d:'%(f.LocalPath(), line_num))
2942 prefs.append(' %s'% line)
2943if input_api.re.search(
2944'PrefRegistrySyncable::SYNCABLE_PRIORITY_PREF', line):
2945 priority_prefs.append(' %s:%d'%(f.LocalPath(), line_num))
2946 priority_prefs.append(' %s'% line)
2947
2948 results=[]
2949if(prefs):
2950 results.append(
2951 output_api.PresubmitPromptWarning(
2952'Preferences were registered as SYNCABLE_PREF and will be controlled '
2953'by browser sync settings. If these prefs should be controlled by OS '
2954'sync settings use SYNCABLE_OS_PREF instead.\n'+
2955'\n'.join(prefs)))
2956if(priority_prefs):
2957 results.append(
2958 output_api.PresubmitPromptWarning(
2959'Preferences were registered as SYNCABLE_PRIORITY_PREF and will be '
2960'controlled by browser sync settings. If these prefs should be '
2961'controlled by OS sync settings use SYNCABLE_OS_PRIORITY_PREF '
2962'instead.\n'+'\n'.join(prefs)))
2963return results
James Cook6b6597c2019-11-06 22:05:29[diff] [blame]2964
2965
Saagar Sanghavifceeaae2020-08-12 16:40:36[diff] [blame]2966defCheckNoAbbreviationInPngFileName(input_api, output_api):
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2967"""Makes sure there are no abbreviations in the name of PNG files.
2968 The native_client_sdk directory is excluded because it has auto-generated PNG
2969 files for documentation.
2970 """
2971 errors=[]
Yuanqing Zhu9eef02832022-12-04 14:42:17[diff] [blame]2972 files_to_check=[r'.*\.png$']
Bruce Dawson40fece62022-09-16 19:58:31[diff] [blame]2973 files_to_skip=[r'^native_client_sdk/',
2974 r'^services/test/',
2975 r'^third_party/blink/web_tests/',
Bruce Dawson3db456212022-05-02 05:34:18[diff] [blame]2976]
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2977 file_filter=lambda f: input_api.FilterSourceFile(
2978 f, files_to_check=files_to_check, files_to_skip=files_to_skip)
Yuanqing Zhu9eef02832022-12-04 14:42:17[diff] [blame]2979 abbreviation= input_api.re.compile('.+_[a-z]\.png|.+_[a-z]_.*\.png')
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2980for fin input_api.AffectedFiles(include_deletes=False,
2981 file_filter=file_filter):
Yuanqing Zhu9eef02832022-12-04 14:42:17[diff] [blame]2982 file_name= input_api.os_path.split(f.LocalPath())[1]
2983if abbreviation.search(file_name):
2984 errors.append(' %s'% f.LocalPath())
oshima@chromium.orgd2530012013-01-25 16:39:27[diff] [blame]2985
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]2986 results=[]
2987if errors:
2988 results.append(
2989 output_api.PresubmitError(
2990'The name of PNG files should not have abbreviations. \n'
2991'Use _hover.png, _center.png, instead of _h.png, _c.png.\n'
2992'Contact oshima@chromium.org if you have questions.', errors))
2993return results
oshima@chromium.orgd2530012013-01-25 16:39:27[diff] [blame]2994
Evan Stade7cd4a2c2022-08-04 23:37:25[diff] [blame]2995defCheckNoProductIconsAddedToPublicRepo(input_api, output_api):
2996"""Heuristically identifies product icons based on their file name and reminds
2997 contributors not to add them to the Chromium repository.
2998 """
2999 errors=[]
3000 files_to_check=[r'.*google.*\.png$|.*google.*\.svg$|.*google.*\.icon$']
3001 file_filter=lambda f: input_api.FilterSourceFile(
3002 f, files_to_check=files_to_check)
3003for fin input_api.AffectedFiles(include_deletes=False,
3004 file_filter=file_filter):
3005 errors.append(' %s'% f.LocalPath())
3006
3007 results=[]
3008if errors:
Bruce Dawson3bcf0c92022-08-12 00:03:08[diff] [blame]3009# Give warnings instead of errors on presubmit --all and presubmit
3010# --files.
3011 message_type=(output_api.PresubmitNotifyResultif input_api.no_diffs
3012else output_api.PresubmitError)
Evan Stade7cd4a2c2022-08-04 23:37:25[diff] [blame]3013 results.append(
Bruce Dawson3bcf0c92022-08-12 00:03:08[diff] [blame]3014 message_type(
Evan Stade7cd4a2c2022-08-04 23:37:25[diff] [blame]3015'Trademarked images should not be added to the public repo. '
3016'See crbug.com/944754', errors))
3017return results
3018
oshima@chromium.orgd2530012013-01-25 16:39:27[diff] [blame]3019
Daniel Cheng4dcdb6b2017-04-13 08:30:17[diff] [blame]3020def_ExtractAddRulesFromParsedDeps(parsed_deps):
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]3021"""Extract the rules that add dependencies from a parsed DEPS file.
Daniel Cheng4dcdb6b2017-04-13 08:30:17[diff] [blame]3022
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]3023 Args:
3024 parsed_deps: the locals dictionary from evaluating the DEPS file."""
3025 add_rules= set()
Daniel Cheng4dcdb6b2017-04-13 08:30:17[diff] [blame]3026 add_rules.update([
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]3027 rule[1:]for rulein parsed_deps.get('include_rules',[])
Daniel Cheng4dcdb6b2017-04-13 08:30:17[diff] [blame]3028if rule.startswith('+')or rule.startswith('!')
3029])
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]3030for _, rulesin parsed_deps.get('specific_include_rules',{}).items():
3031 add_rules.update([
3032 rule[1:]for rulein rules
3033if rule.startswith('+')or rule.startswith('!')
3034])
3035return add_rules
Daniel Cheng4dcdb6b2017-04-13 08:30:17[diff] [blame]3036
3037
3038def_ParseDeps(contents):
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]3039"""Simple helper for parsing DEPS files."""
Daniel Cheng4dcdb6b2017-04-13 08:30:17[diff] [blame]3040
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]3041# Stubs for handling special syntax in the root DEPS file.
3042class_VarImpl:
3043def __init__(self, local_scope):
3044 self._local_scope= local_scope
Daniel Cheng4dcdb6b2017-04-13 08:30:17[diff] [blame]3045
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]3046defLookup(self, var_name):
3047"""Implements the Var syntax."""
3048try:
3049return self._local_scope['vars'][var_name]
3050exceptKeyError:
3051raiseException('Var is not defined: %s'% var_name)
Daniel Cheng4dcdb6b2017-04-13 08:30:17[diff] [blame]3052
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]3053 local_scope={}
3054 global_scope={
3055'Var':_VarImpl(local_scope).Lookup,
3056'Str': str,
3057}
Dirk Pranke1b9e06382021-05-14 01:16:22[diff] [blame]3058
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]3059exec(contents, global_scope, local_scope)
3060return local_scope
Daniel Cheng4dcdb6b2017-04-13 08:30:17[diff] [blame]3061
3062
3063def_CalculateAddedDeps(os_path, old_contents, new_contents):
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]3064"""Helper method for CheckAddedDepsHaveTargetApprovals. Returns
3065 a set of DEPS entries that we should look up.
joi@chromium.org14a6131c2014-01-08 01:15:41[diff] [blame]3066
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]3067 For a directory (rather than a specific filename) we fake a path to
3068 a specific filename by adding /DEPS. This is chosen as a file that
3069 will seldom or never be subject to per-file include_rules.
3070 """
3071# We ignore deps entries on auto-generated directories.
3072 AUTO_GENERATED_DIRS=['grit','jni']
tony@chromium.orgf32e2d1e2013-07-26 21:39:08[diff] [blame]3073
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]3074 old_deps=_ExtractAddRulesFromParsedDeps(_ParseDeps(old_contents))
3075 new_deps=_ExtractAddRulesFromParsedDeps(_ParseDeps(new_contents))
Daniel Cheng4dcdb6b2017-04-13 08:30:17[diff] [blame]3076
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]3077 added_deps= new_deps.difference(old_deps)
Daniel Cheng4dcdb6b2017-04-13 08:30:17[diff] [blame]3078
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]3079 results= set()
3080for added_depin added_deps:
3081if added_dep.split('/')[0]in AUTO_GENERATED_DIRS:
3082continue
3083# Assume that a rule that ends in .h is a rule for a specific file.
3084if added_dep.endswith('.h'):
3085 results.add(added_dep)
3086else:
3087 results.add(os_path.join(added_dep,'DEPS'))
3088return results
tony@chromium.orgf32e2d1e2013-07-26 21:39:08[diff] [blame]3089
3090
Saagar Sanghavifceeaae2020-08-12 16:40:36[diff] [blame]3091defCheckAddedDepsHaveTargetApprovals(input_api, output_api):
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]3092"""When a dependency prefixed with + is added to a DEPS file, we
3093 want to make sure that the change is reviewed by an OWNER of the
3094 target file or directory, to avoid layering violations from being
3095 introduced. This check verifies that this happens.
3096 """
3097# We rely on Gerrit's code-owners to check approvals.
3098# input_api.gerrit is always set for Chromium, but other projects
3099# might not use Gerrit.
Bruce Dawson344ab262022-06-04 11:35:10[diff] [blame]3100ifnot input_api.gerritor input_api.no_diffs:
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]3101return[]
Bruce Dawsonb357aeb2022-08-09 15:38:30[diff] [blame]3102if'PRESUBMIT_SKIP_NETWORK'in input_api.environ:
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]3103return[]
Bruce Dawsonb357aeb2022-08-09 15:38:30[diff] [blame]3104try:
3105if(input_api.change.issueand
3106 input_api.gerrit.IsOwnersOverrideApproved(
3107 input_api.change.issue)):
3108# Skip OWNERS check when Owners-Override label is approved. This is
3109# intended for global owners, trusted bots, and on-call sheriffs.
3110# Review is still required for these changes.
3111return[]
3112exceptExceptionas e:
Sam Maier4cef9242022-10-03 14:21:24[diff] [blame]3113return[output_api.PresubmitPromptWarning(
3114'Failed to retrieve owner override status - %s'% str(e))]
Edward Lesmes6fba51082021-01-20 04:20:23[diff] [blame]3115
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]3116 virtual_depended_on_files= set()
jochen53efcdd2016-01-29 05:09:24[diff] [blame]3117
Bruce Dawson40fece62022-09-16 19:58:31[diff] [blame]3118# Consistently use / as path separator to simplify the writing of regex
3119# expressions.
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]3120 file_filter=lambda f:not input_api.re.match(
Bruce Dawson40fece62022-09-16 19:58:31[diff] [blame]3121 r"^third_party/blink/.*",
3122 f.LocalPath().replace(input_api.os_path.sep,'/'))
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]3123for fin input_api.AffectedFiles(include_deletes=False,
3124 file_filter=file_filter):
3125 filename= input_api.os_path.basename(f.LocalPath())
3126if filename=='DEPS':
3127 virtual_depended_on_files.update(
3128_CalculateAddedDeps(input_api.os_path,
3129'\n'.join(f.OldContents()),
3130'\n'.join(f.NewContents())))
joi@chromium.orge871964c2013-05-13 14:14:55[diff] [blame]3131
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]3132ifnot virtual_depended_on_files:
3133return[]
joi@chromium.orge871964c2013-05-13 14:14:55[diff] [blame]3134
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]3135if input_api.is_committing:
3136if input_api.tbr:
3137return[
3138 output_api.PresubmitNotifyResult(
3139'--tbr was specified, skipping OWNERS check for DEPS additions'
3140)
3141]
Daniel Cheng3008dc12022-05-13 04:02:11[diff] [blame]3142# TODO(dcheng): Make this generate an error on dry runs if the reviewer
3143# is not added, to prevent review serialization.
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]3144if input_api.dry_run:
3145return[
3146 output_api.PresubmitNotifyResult(
3147'This is a dry run, skipping OWNERS check for DEPS additions'
3148)
3149]
3150ifnot input_api.change.issue:
3151return[
3152 output_api.PresubmitError(
3153"DEPS approval by OWNERS check failed: this change has "
3154"no change number, so we can't check it for approvals.")
3155]
3156 output= output_api.PresubmitError
joi@chromium.org14a6131c2014-01-08 01:15:41[diff] [blame]3157else:
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]3158 output= output_api.PresubmitNotifyResult
joi@chromium.orge871964c2013-05-13 14:14:55[diff] [blame]3159
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]3160 owner_email, reviewers=(
3161 input_api.canned_checks.GetCodereviewOwnerAndReviewers(
3162 input_api,None, approval_needed=input_api.is_committing))
joi@chromium.orge871964c2013-05-13 14:14:55[diff] [blame]3163
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]3164 owner_email= owner_emailor input_api.change.author_email
3165
3166 approval_status= input_api.owners_client.GetFilesApprovalStatus(
3167 virtual_depended_on_files, reviewers.union([owner_email]),[])
3168 missing_files=[
3169 ffor fin virtual_depended_on_files
3170if approval_status[f]!= input_api.owners_client.APPROVED
3171]
3172
3173# We strip the /DEPS part that was added by
3174# _FilesToCheckForIncomingDeps to fake a path to a file in a
3175# directory.
3176defStripDeps(path):
3177 start_deps= path.rfind('/DEPS')
3178if start_deps!=-1:
3179return path[:start_deps]
3180else:
3181return path
3182
3183 unapproved_dependencies=[
3184"'+%s',"%StripDeps(path)for pathin missing_files
3185]
3186
3187if unapproved_dependencies:
3188 output_list=[
3189 output(
3190'You need LGTM from owners of depends-on paths in DEPS that were '
3191'modified in this CL:\n %s'%
3192'\n '.join(sorted(unapproved_dependencies)))
3193]
3194 suggested_owners= input_api.owners_client.SuggestOwners(
3195 missing_files, exclude=[owner_email])
3196 output_list.append(
3197 output('Suggested missing target path OWNERS:\n %s'%
3198'\n '.join(suggested_ownersor[])))
3199return output_list
3200
3201return[]
joi@chromium.orge871964c2013-05-13 14:14:55[diff] [blame]3202
3203
Wei-Yin Chen (陳威尹)dca729a2018-07-31 21:35:49[diff] [blame]3204# TODO: add unit tests.
Saagar Sanghavifceeaae2020-08-12 16:40:36[diff] [blame]3205defCheckSpamLogging(input_api, output_api):
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]3206 file_inclusion_pattern=[r'.+%s'% _IMPLEMENTATION_EXTENSIONS]
3207 files_to_skip=(
3208 _EXCLUDED_PATHS+ _TEST_CODE_EXCLUDED_PATHS+
3209 input_api.DEFAULT_FILES_TO_SKIP+(
Jaewon Jung2f323bb2022-12-07 23:55:01[diff] [blame]3210 r"^base/fuchsia/scoped_fx_logger\.cc$",
Bruce Dawson40fece62022-09-16 19:58:31[diff] [blame]3211 r"^base/logging\.h$",
3212 r"^base/logging\.cc$",
3213 r"^base/task/thread_pool/task_tracker\.cc$",
3214 r"^chrome/app/chrome_main_delegate\.cc$",
Yao Li359937b2023-02-15 23:43:03[diff] [blame]3215 r"^chrome/browser/ash/arc/enterprise/cert_store/arc_cert_installer\.cc$",
3216 r"^chrome/browser/ash/policy/remote_commands/user_command_arc_job\.cc$",
Bruce Dawson40fece62022-09-16 19:58:31[diff] [blame]3217 r"^chrome/browser/chrome_browser_main\.cc$",
3218 r"^chrome/browser/ui/startup/startup_browser_creator\.cc$",
3219 r"^chrome/browser/browser_switcher/bho/.*",
3220 r"^chrome/browser/diagnostics/diagnostics_writer\.cc$",
3221 r"^chrome/chrome_cleaner/.*",
3222 r"^chrome/chrome_elf/dll_hash/dll_hash_main\.cc$",
3223 r"^chrome/installer/setup/.*",
3224 r"^chromecast/",
Vigen Issahhanjane2d93822023-06-30 15:57:20[diff] [blame]3225 r"^components/cast",
Bruce Dawson40fece62022-09-16 19:58:31[diff] [blame]3226 r"^components/media_control/renderer/media_playback_options\.cc$",
Salma Elmahallawy52976452023-01-27 17:04:49[diff] [blame]3227 r"^components/policy/core/common/policy_logger\.cc$",
Bruce Dawson40fece62022-09-16 19:58:31[diff] [blame]3228 r"^components/viz/service/display/"
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]3229 r"overlay_strategy_underlay_cast\.cc$",
Bruce Dawson40fece62022-09-16 19:58:31[diff] [blame]3230 r"^components/zucchini/.*",
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]3231# TODO(peter): Remove exception. https://crbug.com/534537
Bruce Dawson40fece62022-09-16 19:58:31[diff] [blame]3232 r"^content/browser/notifications/"
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]3233 r"notification_event_dispatcher_impl\.cc$",
Bruce Dawson40fece62022-09-16 19:58:31[diff] [blame]3234 r"^content/common/gpu/client/gl_helper_benchmark\.cc$",
3235 r"^courgette/courgette_minimal_tool\.cc$",
3236 r"^courgette/courgette_tool\.cc$",
3237 r"^extensions/renderer/logging_native_handler\.cc$",
3238 r"^fuchsia_web/common/init_logging\.cc$",
3239 r"^fuchsia_web/runners/common/web_component\.cc$",
Caroline Liua7050132023-02-13 22:23:15[diff] [blame]3240 r"^fuchsia_web/shell/.*\.cc$",
Bruce Dawson40fece62022-09-16 19:58:31[diff] [blame]3241 r"^headless/app/headless_shell\.cc$",
3242 r"^ipc/ipc_logging\.cc$",
3243 r"^native_client_sdk/",
3244 r"^remoting/base/logging\.h$",
3245 r"^remoting/host/.*",
3246 r"^sandbox/linux/.*",
3247 r"^storage/browser/file_system/dump_file_system\.cc$",
3248 r"^tools/",
3249 r"^ui/base/resource/data_pack\.cc$",
3250 r"^ui/aura/bench/bench_main\.cc$",
3251 r"^ui/ozone/platform/cast/",
3252 r"^ui/base/x/xwmstartupcheck/"
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]3253 r"xwmstartupcheck\.cc$"))
3254 source_file_filter=lambda x: input_api.FilterSourceFile(
3255 x, files_to_check=file_inclusion_pattern, files_to_skip=files_to_skip)
thakis@chromium.org85218562013-11-22 07:41:40[diff] [blame]3256
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]3257 log_info= set([])
3258 printf= set([])
thakis@chromium.org85218562013-11-22 07:41:40[diff] [blame]3259
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]3260for fin input_api.AffectedSourceFiles(source_file_filter):
3261for _, linein f.ChangedContents():
3262if input_api.re.search(r"\bD?LOG\s*\(\s*INFO\s*\)", line):
3263 log_info.add(f.LocalPath())
3264elif input_api.re.search(r"\bD?LOG_IF\s*\(\s*INFO\s*,", line):
3265 log_info.add(f.LocalPath())
jln@chromium.org18b466b2013-12-02 22:01:37[diff] [blame]3266
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]3267if input_api.re.search(r"\bprintf\(", line):
3268 printf.add(f.LocalPath())
3269elif input_api.re.search(r"\bfprintf\((stdout|stderr)", line):
3270 printf.add(f.LocalPath())
thakis@chromium.org85218562013-11-22 07:41:40[diff] [blame]3271
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]3272if log_info:
3273return[
3274 output_api.PresubmitError(
3275'These files spam the console log with LOG(INFO):',
3276 items=log_info)
3277]
3278if printf:
3279return[
3280 output_api.PresubmitError(
3281'These files spam the console log with printf/fprintf:',
3282 items=printf)
3283]
3284return[]
thakis@chromium.org85218562013-11-22 07:41:40[diff] [blame]3285
3286
Saagar Sanghavifceeaae2020-08-12 16:40:36[diff] [blame]3287defCheckForAnonymousVariables(input_api, output_api):
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]3288"""These types are all expected to hold locks while in scope and
3289 so should never be anonymous (which causes them to be immediately
3290 destroyed)."""
3291 they_who_must_be_named=[
3292'base::AutoLock',
3293'base::AutoReset',
3294'base::AutoUnlock',
3295'SkAutoAlphaRestore',
3296'SkAutoBitmapShaderInstall',
3297'SkAutoBlitterChoose',
3298'SkAutoBounderCommit',
3299'SkAutoCallProc',
3300'SkAutoCanvasRestore',
3301'SkAutoCommentBlock',
3302'SkAutoDescriptor',
3303'SkAutoDisableDirectionCheck',
3304'SkAutoDisableOvalCheck',
3305'SkAutoFree',
3306'SkAutoGlyphCache',
3307'SkAutoHDC',
3308'SkAutoLockColors',
3309'SkAutoLockPixels',
3310'SkAutoMalloc',
3311'SkAutoMaskFreeImage',
3312'SkAutoMutexAcquire',
3313'SkAutoPathBoundsUpdate',
3314'SkAutoPDFRelease',
3315'SkAutoRasterClipValidate',
3316'SkAutoRef',
3317'SkAutoTime',
3318'SkAutoTrace',
3319'SkAutoUnref',
3320]
3321 anonymous= r'(%s)\s*[({]'%'|'.join(they_who_must_be_named)
3322# bad: base::AutoLock(lock.get());
3323# not bad: base::AutoLock lock(lock.get());
3324 bad_pattern= input_api.re.compile(anonymous)
3325# good: new base::AutoLock(lock.get())
3326 good_pattern= input_api.re.compile(r'\bnew\s*'+ anonymous)
3327 errors=[]
enne@chromium.org49aa76a2013-12-04 06:59:16[diff] [blame]3328
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]3329for fin input_api.AffectedFiles():
3330ifnot f.LocalPath().endswith(('.cc','.h','.inl','.m','.mm')):
3331continue
3332for linenum, linein f.ChangedContents():
3333if bad_pattern.search(line)andnot good_pattern.search(line):
3334 errors.append('%s:%d'%(f.LocalPath(), linenum))
enne@chromium.org49aa76a2013-12-04 06:59:16[diff] [blame]3335
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]3336if errors:
3337return[
3338 output_api.PresubmitError(
3339'These lines create anonymous variables that need to be named:',
3340 items=errors)
3341]
3342return[]
enne@chromium.org49aa76a2013-12-04 06:59:16[diff] [blame]3343
3344
Saagar Sanghavifceeaae2020-08-12 16:40:36[diff] [blame]3345defCheckUniquePtrOnUpload(input_api, output_api):
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]3346# Returns whether |template_str| is of the form <T, U...> for some types T
3347# and U. Assumes that |template_str| is already in the form <...>.
3348defHasMoreThanOneArg(template_str):
3349# Level of <...> nesting.
3350 nesting=0
3351for cin template_str:
3352if c=='<':
3353 nesting+=1
3354elif c=='>':
3355 nesting-=1
3356elif c==','and nesting==1:
3357returnTrue
3358returnFalse
Vaclav Brozekb7fadb692018-08-30 06:39:53[diff] [blame]3359
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]3360 file_inclusion_pattern=[r'.+%s'% _IMPLEMENTATION_EXTENSIONS]
3361 sources=lambda affected_file: input_api.FilterSourceFile(
3362 affected_file,
3363 files_to_skip=(_EXCLUDED_PATHS+ _TEST_CODE_EXCLUDED_PATHS+ input_api.
3364 DEFAULT_FILES_TO_SKIP),
3365 files_to_check=file_inclusion_pattern)
Vaclav Brozeka54c528b2018-04-06 19:23:55[diff] [blame]3366
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]3367# Pattern to capture a single "<...>" block of template arguments. It can
3368# handle linearly nested blocks, such as "<std::vector<std::set<T>>>", but
3369# cannot handle branching structures, such as "<pair<set<T>,set<U>>". The
3370# latter would likely require counting that < and > match, which is not
3371# expressible in regular languages. Should the need arise, one can introduce
3372# limited counting (matching up to a total number of nesting depth), which
3373# should cover all practical cases for already a low nesting limit.
3374 template_arg_pattern=(
3375 r'<[^>]*'# Opening block of <.
3376 r'>([^<]*>)?')# Closing block of >.
3377# Prefix expressing that whatever follows is not already inside a <...>
3378# block.
3379 not_inside_template_arg_pattern= r'(^|[^<,\s]\s*)'
3380 null_construct_pattern= input_api.re.compile(
3381 not_inside_template_arg_pattern+ r'\bstd::unique_ptr'+
3382 template_arg_pattern+ r'\(\)')
Vaclav Brozeka54c528b2018-04-06 19:23:55[diff] [blame]3383
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]3384# Same as template_arg_pattern, but excluding type arrays, e.g., <T[]>.
3385 template_arg_no_array_pattern=(
3386 r'<[^>]*[^]]'# Opening block of <.
3387 r'>([^(<]*[^]]>)?')# Closing block of >.
3388# Prefix saying that what follows is the start of an expression.
3389 start_of_expr_pattern= r'(=|\breturn|^)\s*'
3390# Suffix saying that what follows are call parentheses with a non-empty list
3391# of arguments.
3392 nonempty_arg_list_pattern= r'\(([^)]|$)'
3393# Put the template argument into a capture group for deeper examination later.
3394 return_construct_pattern= input_api.re.compile(
3395 start_of_expr_pattern+ r'std::unique_ptr'+'(?P<template_arg>'+
3396 template_arg_no_array_pattern+')'+ nonempty_arg_list_pattern)
Vaclav Brozeka54c528b2018-04-06 19:23:55[diff] [blame]3397
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]3398 problems_constructor=[]
3399 problems_nullptr=[]
3400for fin input_api.AffectedSourceFiles(sources):
3401for line_number, linein f.ChangedContents():
3402# Disallow:
3403# return std::unique_ptr<T>(foo);
3404# bar = std::unique_ptr<T>(foo);
3405# But allow:
3406# return std::unique_ptr<T[]>(foo);
3407# bar = std::unique_ptr<T[]>(foo);
3408# And also allow cases when the second template argument is present. Those
3409# cases cannot be handled by std::make_unique:
3410# return std::unique_ptr<T, U>(foo);
3411# bar = std::unique_ptr<T, U>(foo);
3412 local_path= f.LocalPath()
3413 return_construct_result= return_construct_pattern.search(line)
3414if return_construct_resultandnotHasMoreThanOneArg(
3415 return_construct_result.group('template_arg')):
3416 problems_constructor.append(
3417'%s:%d\n %s'%(local_path, line_number, line.strip()))
3418# Disallow:
3419# std::unique_ptr<T>()
3420if null_construct_pattern.search(line):
3421 problems_nullptr.append(
3422'%s:%d\n %s'%(local_path, line_number, line.strip()))
Vaclav Brozek851d9602018-04-04 16:13:05[diff] [blame]3423
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]3424 errors=[]
3425if problems_nullptr:
3426 errors.append(
3427 output_api.PresubmitPromptWarning(
3428'The following files use std::unique_ptr<T>(). Use nullptr instead.',
3429 problems_nullptr))
3430if problems_constructor:
3431 errors.append(
3432 output_api.PresubmitError(
3433'The following files use explicit std::unique_ptr constructor. '
3434'Use std::make_unique<T>() instead, or use base::WrapUnique if '
3435'std::make_unique is not an option.', problems_constructor))
3436return errors
Peter Kasting4844e46e2018-02-23 07:27:10[diff] [blame]3437
3438
Saagar Sanghavifceeaae2020-08-12 16:40:36[diff] [blame]3439defCheckUserActionUpdate(input_api, output_api):
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]3440"""Checks if any new user action has been added."""
3441if any('actions.xml'== input_api.os_path.basename(f)
3442for fin input_api.LocalPaths()):
3443# If actions.xml is already included in the changelist, the PRESUBMIT
3444# for actions.xml will do a more complete presubmit check.
3445return[]
3446
3447 file_inclusion_pattern=[r'.*\.(cc|mm)$']
3448 files_to_skip=(_EXCLUDED_PATHS+ _TEST_CODE_EXCLUDED_PATHS+
3449 input_api.DEFAULT_FILES_TO_SKIP)
3450 file_filter=lambda f: input_api.FilterSourceFile(
3451 f, files_to_check=file_inclusion_pattern, files_to_skip=files_to_skip)
3452
3453 action_re= r'[^a-zA-Z]UserMetricsAction\("([^"]*)'
3454 current_actions=None
3455for fin input_api.AffectedFiles(file_filter=file_filter):
3456for line_num, linein f.ChangedContents():
3457 match= input_api.re.search(action_re, line)
3458if match:
3459# Loads contents in tools/metrics/actions/actions.xml to memory. It's
3460# loaded only once.
3461ifnot current_actions:
Bruce Dawson6cb2d4d2023-03-01 21:35:09[diff] [blame]3462with open('tools/metrics/actions/actions.xml',
3463 encoding='utf-8')as actions_f:
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]3464 current_actions= actions_f.read()
3465# Search for the matched user action name in |current_actions|.
3466for action_namein match.groups():
3467 action='name="{0}"'.format(action_name)
3468if actionnotin current_actions:
3469return[
3470 output_api.PresubmitPromptWarning(
3471'File %s line %d: %s is missing in '
3472'tools/metrics/actions/actions.xml. Please run '
3473'tools/metrics/actions/extract_actions.py to update.'
3474%(f.LocalPath(), line_num, action_name))
3475]
yiyaoliu@chromium.org999261d2014-03-03 20:08:08[diff] [blame]3476return[]
3477
yiyaoliu@chromium.org999261d2014-03-03 20:08:08[diff] [blame]3478
Daniel Cheng13ca61a882017-08-25 15:11:25[diff] [blame]3479def_ImportJSONCommentEater(input_api):
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]3480import sys
3481 sys.path= sys.path+[
3482 input_api.os_path.join(input_api.PresubmitLocalPath(),'tools',
3483'json_comment_eater')
3484]
3485import json_comment_eater
3486return json_comment_eater
Daniel Cheng13ca61a882017-08-25 15:11:25[diff] [blame]3487
3488
yoz@chromium.org99171a92014-06-03 08:44:47[diff] [blame]3489def_GetJSONParseError(input_api, filename, eat_comments=True):
dchenge07de812016-06-20 19:27:17[diff] [blame]3490try:
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]3491 contents= input_api.ReadFile(filename)
3492if eat_comments:
3493 json_comment_eater=_ImportJSONCommentEater(input_api)
3494 contents= json_comment_eater.Nom(contents)
dchenge07de812016-06-20 19:27:17[diff] [blame]3495
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]3496 input_api.json.loads(contents)
3497exceptValueErroras e:
3498return e
Andrew Grieve4deedb12022-02-03 21:34:50[diff] [blame]3499returnNone
3500
3501
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]3502def_GetIDLParseError(input_api, filename):
3503try:
3504 contents= input_api.ReadFile(filename)
Devlin Croninf7582a12022-04-21 21:14:28[diff] [blame]3505for i, charin enumerate(contents):
Daniel Chenga37c03db2022-05-12 17:20:34[diff] [blame]3506ifnot char.isascii():
3507return(
3508'Non-ascii character "%s" (ord %d) found at offset %d.'%
3509(char, ord(char), i))
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]3510 idl_schema= input_api.os_path.join(input_api.PresubmitLocalPath(),
3511'tools','json_schema_compiler',
3512'idl_schema.py')
3513 process= input_api.subprocess.Popen(
Bruce Dawson679fb082022-04-14 00:47:28[diff] [blame]3514[input_api.python3_executable, idl_schema],
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]3515 stdin=input_api.subprocess.PIPE,
3516 stdout=input_api.subprocess.PIPE,
3517 stderr=input_api.subprocess.PIPE,
3518 universal_newlines=True)
3519(_, error)= process.communicate(input=contents)
3520return errororNone
3521exceptValueErroras e:
3522return e
agrievef32bcc72016-04-04 14:57:40[diff] [blame]3523
agrievef32bcc72016-04-04 14:57:40[diff] [blame]3524
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]3525defCheckParseErrors(input_api, output_api):
3526"""Check that IDL and JSON files do not contain syntax errors."""
3527 actions={
3528'.idl':_GetIDLParseError,
3529'.json':_GetJSONParseError,
3530}
3531# Most JSON files are preprocessed and support comments, but these do not.
3532 json_no_comments_patterns=[
Bruce Dawson40fece62022-09-16 19:58:31[diff] [blame]3533 r'^testing/',
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]3534]
3535# Only run IDL checker on files in these directories.
3536 idl_included_patterns=[
Bruce Dawson40fece62022-09-16 19:58:31[diff] [blame]3537 r'^chrome/common/extensions/api/',
3538 r'^extensions/common/api/',
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]3539]
agrievef32bcc72016-04-04 14:57:40[diff] [blame]3540
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]3541def get_action(affected_file):
3542 filename= affected_file.LocalPath()
3543return actions.get(input_api.os_path.splitext(filename)[1])
agrievef32bcc72016-04-04 14:57:40[diff] [blame]3544
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]3545defFilterFile(affected_file):
3546 action= get_action(affected_file)
3547ifnot action:
3548returnFalse
3549 path= affected_file.LocalPath()
agrievef32bcc72016-04-04 14:57:40[diff] [blame]3550
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]3551if_MatchesFile(input_api,
3552 _KNOWN_TEST_DATA_AND_INVALID_JSON_FILE_PATTERNS, path):
3553returnFalse
3554
3555if(action==_GetIDLParseError
3556andnot_MatchesFile(input_api, idl_included_patterns, path)):
3557returnFalse
3558returnTrue
3559
3560 results=[]
3561for affected_filein input_api.AffectedFiles(file_filter=FilterFile,
3562 include_deletes=False):
3563 action= get_action(affected_file)
3564 kwargs={}
3565if(action==_GetJSONParseError
3566and_MatchesFile(input_api, json_no_comments_patterns,
3567 affected_file.LocalPath())):
3568 kwargs['eat_comments']=False
3569 parse_error= action(input_api, affected_file.AbsoluteLocalPath(),
3570**kwargs)
3571if parse_error:
3572 results.append(
3573 output_api.PresubmitError(
3574'%s could not be parsed: %s'%
3575(affected_file.LocalPath(), parse_error)))
3576return results
3577
3578
3579defCheckJavaStyle(input_api, output_api):
3580"""Runs checkstyle on changed java files and returns errors if any exist."""
3581
3582# Return early if no java files were modified.
3583ifnot any(
3584_IsJavaFile(input_api, f.LocalPath())
3585for fin input_api.AffectedFiles()):
3586return[]
3587
3588import sys
3589 original_sys_path= sys.path
3590try:
3591 sys.path= sys.path+[
3592 input_api.os_path.join(input_api.PresubmitLocalPath(),'tools',
3593'android','checkstyle')
3594]
3595import checkstyle
3596finally:
3597# Restore sys.path to what it was before.
3598 sys.path= original_sys_path
3599
Andrew Grieve4f88e3ca2022-11-22 19:09:20[diff] [blame]3600return checkstyle.run_presubmit(
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]3601 input_api,
3602 output_api,
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]3603 files_to_skip=_EXCLUDED_PATHS+ input_api.DEFAULT_FILES_TO_SKIP)
3604
3605
3606defCheckPythonDevilInit(input_api, output_api):
3607"""Checks to make sure devil is initialized correctly in python scripts."""
3608 script_common_initialize_pattern= input_api.re.compile(
3609 r'script_common\.InitializeEnvironment\(')
3610 devil_env_config_initialize= input_api.re.compile(
3611 r'devil_env\.config\.Initialize\(')
3612
3613 errors=[]
3614
3615 sources=lambda affected_file: input_api.FilterSourceFile(
3616 affected_file,
3617 files_to_skip=(_EXCLUDED_PATHS+ input_api.DEFAULT_FILES_TO_SKIP+(
Bruce Dawson40fece62022-09-16 19:58:31[diff] [blame]3618 r'^build/android/devil_chromium\.py',
3619 r'^third_party/.*',
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]3620)),
3621 files_to_check=[r'.*\.py$'])
3622
3623for fin input_api.AffectedSourceFiles(sources):
3624for line_num, linein f.ChangedContents():
3625if(script_common_initialize_pattern.search(line)
3626or devil_env_config_initialize.search(line)):
3627 errors.append("%s:%d"%(f.LocalPath(), line_num))
3628
3629 results=[]
3630
3631if errors:
3632 results.append(
3633 output_api.PresubmitError(
3634'Devil initialization should always be done using '
3635'devil_chromium.Initialize() in the chromium project, to use better '
3636'defaults for dependencies (ex. up-to-date version of adb).',
3637 errors))
3638
3639return results
3640
3641
3642def_MatchesFile(input_api, patterns, path):
Bruce Dawson40fece62022-09-16 19:58:31[diff] [blame]3643# Consistently use / as path separator to simplify the writing of regex
3644# expressions.
3645 path= path.replace(input_api.os_path.sep,'/')
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]3646for patternin patterns:
3647if input_api.re.search(pattern, path):
3648returnTrue
3649returnFalse
3650
3651
Daniel Chenga37c03db2022-05-12 17:20:34[diff] [blame]3652def_ChangeHasSecurityReviewer(input_api, owners_file):
3653"""Returns True iff the CL has a reviewer from SECURITY_OWNERS.
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]3654
Daniel Chenga37c03db2022-05-12 17:20:34[diff] [blame]3655 Args:
3656 input_api: The presubmit input API.
3657 owners_file: OWNERS file with required reviewers. Typically, this is
3658 something like ipc/SECURITY_OWNERS.
3659
3660 Note: if the presubmit is running for commit rather than for upload, this
3661 only returns True if a security reviewer has also approved the CL.
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]3662 """
Daniel Chengd88244472022-05-16 09:08:47[diff] [blame]3663# Owners-Override should bypass all additional OWNERS enforcement checks.
3664# A CR+1 vote will still be required to land this change.
3665if(input_api.change.issueand input_api.gerrit.IsOwnersOverrideApproved(
3666 input_api.change.issue)):
3667returnTrue
3668
Daniel Chenga37c03db2022-05-12 17:20:34[diff] [blame]3669 owner_email, reviewers=(
3670 input_api.canned_checks.GetCodereviewOwnerAndReviewers(
Daniel Cheng3008dc12022-05-13 04:02:11[diff] [blame]3671 input_api,
3672None,
3673 approval_needed=input_api.is_committingandnot input_api.dry_run))
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]3674
Daniel Chenga37c03db2022-05-12 17:20:34[diff] [blame]3675 security_owners= input_api.owners_client.ListOwners(owners_file)
3676return any(ownerin reviewersfor ownerin security_owners)
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]3677
Daniel Chenga37c03db2022-05-12 17:20:34[diff] [blame]3678
3679@dataclass
Daniel Cheng171dad8d2022-05-21 00:40:25[diff] [blame]3680class_SecurityProblemWithItems:
3681 problem: str
3682 items:Sequence[str]
3683
3684
3685@dataclass
Daniel Chenga37c03db2022-05-12 17:20:34[diff] [blame]3686class_MissingSecurityOwnersResult:
Daniel Cheng171dad8d2022-05-21 00:40:25[diff] [blame]3687 owners_file_problems:Sequence[_SecurityProblemWithItems]
Daniel Chenga37c03db2022-05-12 17:20:34[diff] [blame]3688 has_security_sensitive_files: bool
Daniel Cheng171dad8d2022-05-21 00:40:25[diff] [blame]3689 missing_reviewer_problem:Optional[_SecurityProblemWithItems]
Daniel Chenga37c03db2022-05-12 17:20:34[diff] [blame]3690
3691
3692def_FindMissingSecurityOwners(input_api,
3693 output_api,
3694 file_patterns:Sequence[str],
3695 excluded_patterns:Sequence[str],
3696 required_owners_file: str,
3697 custom_rule_function:Optional[Callable]=None
3698)->_MissingSecurityOwnersResult:
3699"""Find OWNERS files missing per-file rules for security-sensitive files.
3700
3701 Args:
3702 input_api: the PRESUBMIT input API object.
3703 output_api: the PRESUBMIT output API object.
3704 file_patterns: basename patterns that require a corresponding per-file
3705 security restriction.
3706 excluded_patterns: path patterns that should be exempted from
3707 requiring a security restriction.
3708 required_owners_file: path to the required OWNERS file, e.g.
3709 ipc/SECURITY_OWNERS
3710 cc_alias: If not None, email that will be CCed automatically if the
3711 change contains security-sensitive files, as determined by
3712 `file_patterns` and `excluded_patterns`.
3713 custom_rule_function: If not None, will be called with `input_api` and
3714 the current file under consideration. Returning True will add an
3715 exact match per-file rule check for the current file.
3716 """
3717
3718# `to_check` is a mapping of an OWNERS file path to Patterns.
3719#
3720# Patterns is a dictionary mapping glob patterns (suitable for use in
3721# per-file rules) to a PatternEntry.
3722#
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]3723# PatternEntry is a dictionary with two keys:
3724# - 'files': the files that are matched by this pattern
3725# - 'rules': the per-file rules needed for this pattern
Daniel Chenga37c03db2022-05-12 17:20:34[diff] [blame]3726#
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]3727# For example, if we expect OWNERS file to contain rules for *.mojom and
3728# *_struct_traits*.*, Patterns might look like this:
3729# {
3730# '*.mojom': {
3731# 'files': ...,
3732# 'rules': [
3733# 'per-file *.mojom=set noparent',
3734# 'per-file *.mojom=file://ipc/SECURITY_OWNERS',
3735# ],
3736# },
3737# '*_struct_traits*.*': {
3738# 'files': ...,
3739# 'rules': [
3740# 'per-file *_struct_traits*.*=set noparent',
3741# 'per-file *_struct_traits*.*=file://ipc/SECURITY_OWNERS',
3742# ],
3743# },
3744# }
3745 to_check={}
Daniel Chenga37c03db2022-05-12 17:20:34[diff] [blame]3746 files_to_review=[]
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]3747
Daniel Chenga37c03db2022-05-12 17:20:34[diff] [blame]3748defAddPatternToCheck(file, pattern):
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]3749 owners_file= input_api.os_path.join(
Daniel Chengd88244472022-05-16 09:08:47[diff] [blame]3750 input_api.os_path.dirname(file.LocalPath()),'OWNERS')
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]3751if owners_filenotin to_check:
3752 to_check[owners_file]={}
3753if patternnotin to_check[owners_file]:
3754 to_check[owners_file][pattern]={
3755'files':[],
3756'rules':[
Daniel Chenga37c03db2022-05-12 17:20:34[diff] [blame]3757 f'per-file {pattern}=set noparent',
3758 f'per-file {pattern}=file://{required_owners_file}',
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]3759]
3760}
Daniel Chenged57a162022-05-25 02:56:34[diff] [blame]3761 to_check[owners_file][pattern]['files'].append(file.LocalPath())
Daniel Chenga37c03db2022-05-12 17:20:34[diff] [blame]3762 files_to_review.append(file.LocalPath())
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]3763
Daniel Chenga37c03db2022-05-12 17:20:34[diff] [blame]3764# Only enforce security OWNERS rules for a directory if that directory has a
3765# file that matches `file_patterns`. For example, if a directory only
3766# contains *.mojom files and no *_messages*.h files, the check should only
3767# ensure that rules for *.mojom files are present.
3768for filein input_api.AffectedFiles(include_deletes=False):
3769 file_basename= input_api.os_path.basename(file.LocalPath())
3770if custom_rule_functionisnotNoneand custom_rule_function(
3771 input_api, file):
3772AddPatternToCheck(file, file_basename)
3773continue
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]3774
Daniel Chenga37c03db2022-05-12 17:20:34[diff] [blame]3775if any(
3776 input_api.fnmatch.fnmatch(file.LocalPath(), pattern)
3777for patternin excluded_patterns):
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]3778continue
3779
3780for patternin file_patterns:
Daniel Chenga37c03db2022-05-12 17:20:34[diff] [blame]3781# Unlike `excluded_patterns`, `file_patterns` is checked only against the
3782# file's basename.
3783if input_api.fnmatch.fnmatch(file_basename, pattern):
3784AddPatternToCheck(file, pattern)
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]3785break
3786
Daniel Chenga37c03db2022-05-12 17:20:34[diff] [blame]3787 has_security_sensitive_files= bool(to_check)
Daniel Cheng171dad8d2022-05-21 00:40:25[diff] [blame]3788
3789# Check if any newly added lines in OWNERS files intersect with required
3790# per-file OWNERS lines. If so, ensure that a security reviewer is included.
3791# This is a hack, but is needed because the OWNERS check (by design) ignores
3792# new OWNERS entries; otherwise, a non-owner could add someone as a new
3793# OWNER and have that newly-added OWNER self-approve their own addition.
3794 newly_covered_files=[]
3795for filein input_api.AffectedFiles(include_deletes=False):
3796ifnot file.LocalPath()in to_check:
3797continue
3798for _, linein file.ChangedContents():
3799for _, entryin to_check[file.LocalPath()].items():
3800if linein entry['rules']:
3801 newly_covered_files.extend(entry['files'])
3802
3803 missing_reviewer_problems=None
3804if newly_covered_filesandnot_ChangeHasSecurityReviewer(
Daniel Chenga37c03db2022-05-12 17:20:34[diff] [blame]3805 input_api, required_owners_file):
Daniel Cheng171dad8d2022-05-21 00:40:25[diff] [blame]3806 missing_reviewer_problems=_SecurityProblemWithItems(
3807 f'Review from an owner in {required_owners_file} is required for '
3808'the following newly-added files:',
3809[f'{file}'for filein sorted(set(newly_covered_files))])
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]3810
3811# Go through the OWNERS files to check, filtering out rules that are already
3812# present in that OWNERS file.
3813for owners_file, patternsin to_check.items():
3814try:
Daniel Cheng171dad8d2022-05-21 00:40:25[diff] [blame]3815 lines= set(
3816 input_api.ReadFile(
3817 input_api.os_path.join(input_api.change.RepositoryRoot(),
3818 owners_file)).splitlines())
3819for entryin patterns.values():
3820 entry['rules']=[
3821 rulefor rulein entry['rules']if rulenotin lines
3822]
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]3823exceptIOError:
3824# No OWNERS file, so all the rules are definitely missing.
3825continue
3826
3827# All the remaining lines weren't found in OWNERS files, so emit an error.
Daniel Cheng171dad8d2022-05-21 00:40:25[diff] [blame]3828 owners_file_problems=[]
Daniel Chenga37c03db2022-05-12 17:20:34[diff] [blame]3829
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]3830for owners_file, patternsin to_check.items():
3831 missing_lines=[]
3832 files=[]
3833for _, entryin patterns.items():
Daniel Chenged57a162022-05-25 02:56:34[diff] [blame]3834 files.extend(entry['files'])
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]3835 missing_lines.extend(entry['rules'])
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]3836if missing_lines:
Daniel Cheng171dad8d2022-05-21 00:40:25[diff] [blame]3837 joined_missing_lines='\n'.join(linefor linein missing_lines)
3838 owners_file_problems.append(
3839_SecurityProblemWithItems(
3840'Found missing OWNERS lines for security-sensitive files. '
3841 f'Please add the following lines to {owners_file}:\n'
3842 f'{joined_missing_lines}\n\nTo ensure security review for:',
3843 files))
Daniel Chenga37c03db2022-05-12 17:20:34[diff] [blame]3844
Daniel Cheng171dad8d2022-05-21 00:40:25[diff] [blame]3845return_MissingSecurityOwnersResult(owners_file_problems,
Daniel Chenga37c03db2022-05-12 17:20:34[diff] [blame]3846 has_security_sensitive_files,
Daniel Cheng171dad8d2022-05-21 00:40:25[diff] [blame]3847 missing_reviewer_problems)
Daniel Chenga37c03db2022-05-12 17:20:34[diff] [blame]3848
3849
3850def_CheckChangeForIpcSecurityOwners(input_api, output_api):
3851# Whether or not a file affects IPC is (mostly) determined by a simple list
3852# of filename patterns.
3853 file_patterns=[
3854# Legacy IPC:
3855'*_messages.cc',
3856'*_messages*.h',
3857'*_param_traits*.*',
3858# Mojo IPC:
3859'*.mojom',
3860'*_mojom_traits*.*',
3861'*_type_converter*.*',
3862# Android native IPC:
3863'*.aidl',
3864]
3865
Daniel Chenga37c03db2022-05-12 17:20:34[diff] [blame]3866 excluded_patterns=[
Daniel Cheng518943f2022-05-12 22:15:46[diff] [blame]3867# These third_party directories do not contain IPCs, but contain files
3868# matching the above patterns, which trigger false positives.
Daniel Chenga37c03db2022-05-12 17:20:34[diff] [blame]3869'third_party/crashpad/*',
3870'third_party/blink/renderer/platform/bindings/*',
3871'third_party/protobuf/benchmarks/python/*',
3872'third_party/win_build_output/*',
Daniel Chengd88244472022-05-16 09:08:47[diff] [blame]3873# Enum-only mojoms used for web metrics, so no security review needed.
3874'third_party/blink/public/mojom/use_counter/metrics/*',
Daniel Chenga37c03db2022-05-12 17:20:34[diff] [blame]3875# These files are just used to communicate between class loaders running
3876# in the same process.
3877'weblayer/browser/java/org/chromium/weblayer_private/interfaces/*',
3878'weblayer/browser/java/org/chromium/weblayer_private/test_interfaces/*',
3879]
3880
3881defIsMojoServiceManifestFile(input_api, file):
3882 manifest_pattern= input_api.re.compile('manifests?\.(cc|h)$')
3883 test_manifest_pattern= input_api.re.compile('test_manifests?\.(cc|h)')
3884ifnot manifest_pattern.search(file.LocalPath()):
3885returnFalse
3886
3887if test_manifest_pattern.search(file.LocalPath()):
3888returnFalse
3889
3890# All actual service manifest files should contain at least one
3891# qualified reference to service_manager::Manifest.
3892return any('service_manager::Manifest'in line
3893for linein file.NewContents())
3894
3895return_FindMissingSecurityOwners(
3896 input_api,
3897 output_api,
3898 file_patterns,
3899 excluded_patterns,
3900'ipc/SECURITY_OWNERS',
3901 custom_rule_function=IsMojoServiceManifestFile)
3902
3903
3904def_CheckChangeForFuchsiaSecurityOwners(input_api, output_api):
3905 file_patterns=[
3906# Component specifications.
3907'*.cml',# Component Framework v2.
3908'*.cmx',# Component Framework v1.
3909
3910# Fuchsia IDL protocol specifications.
3911'*.fidl',
3912]
3913
3914# Don't check for owners files for changes in these directories.
3915 excluded_patterns=[
3916'third_party/crashpad/*',
3917]
3918
3919return_FindMissingSecurityOwners(input_api, output_api, file_patterns,
3920 excluded_patterns,
3921'build/fuchsia/SECURITY_OWNERS')
3922
3923
3924defCheckSecurityOwners(input_api, output_api):
3925"""Checks that various security-sensitive files have an IPC OWNERS rule."""
3926 ipc_results=_CheckChangeForIpcSecurityOwners(input_api, output_api)
3927 fuchsia_results=_CheckChangeForFuchsiaSecurityOwners(
3928 input_api, output_api)
3929
3930if ipc_results.has_security_sensitive_files:
3931 output_api.AppendCC('ipc-security-reviews@chromium.org')
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]3932
3933 results=[]
Daniel Chenga37c03db2022-05-12 17:20:34[diff] [blame]3934
Daniel Cheng171dad8d2022-05-21 00:40:25[diff] [blame]3935 missing_reviewer_problems=[]
3936if ipc_results.missing_reviewer_problem:
3937 missing_reviewer_problems.append(ipc_results.missing_reviewer_problem)
3938if fuchsia_results.missing_reviewer_problem:
3939 missing_reviewer_problems.append(
3940 fuchsia_results.missing_reviewer_problem)
Daniel Chenga37c03db2022-05-12 17:20:34[diff] [blame]3941
Daniel Cheng171dad8d2022-05-21 00:40:25[diff] [blame]3942# Missing reviewers are an error unless there's no issue number
3943# associated with this branch; in that case, the presubmit is being run
3944# with --all or --files.
3945#
3946# Note that upload should never be an error; otherwise, it would be
3947# impossible to upload changes at all.
3948if input_api.is_committingand input_api.change.issue:
3949 make_presubmit_message= output_api.PresubmitError
3950else:
3951 make_presubmit_message= output_api.PresubmitNotifyResult
3952for problemin missing_reviewer_problems:
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]3953 results.append(
Daniel Cheng171dad8d2022-05-21 00:40:25[diff] [blame]3954 make_presubmit_message(problem.problem, items=problem.items))
Daniel Chenga37c03db2022-05-12 17:20:34[diff] [blame]3955
Daniel Cheng171dad8d2022-05-21 00:40:25[diff] [blame]3956 owners_file_problems=[]
3957 owners_file_problems.extend(ipc_results.owners_file_problems)
3958 owners_file_problems.extend(fuchsia_results.owners_file_problems)
Daniel Chenga37c03db2022-05-12 17:20:34[diff] [blame]3959
Daniel Cheng171dad8d2022-05-21 00:40:25[diff] [blame]3960for problemin owners_file_problems:
Daniel Cheng3008dc12022-05-13 04:02:11[diff] [blame]3961# Missing per-file rules are always an error. While swarming and caching
3962# means that uploading a patchset with updated OWNERS files and sending
3963# it to the CQ again should not have a large incremental cost, it is
3964# still frustrating to discover the error only after the change has
3965# already been uploaded.
Daniel Chenga37c03db2022-05-12 17:20:34[diff] [blame]3966 results.append(
Daniel Cheng171dad8d2022-05-21 00:40:25[diff] [blame]3967 output_api.PresubmitError(problem.problem, items=problem.items))
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]3968
3969return results
3970
3971
3972def_GetFilesUsingSecurityCriticalFunctions(input_api):
3973"""Checks affected files for changes to security-critical calls. This
3974 function checks the full change diff, to catch both additions/changes
3975 and removals.
3976
3977 Returns a dict keyed by file name, and the value is a set of detected
3978 functions.
3979 """
3980# Map of function pretty name (displayed in an error) to the pattern to
3981# match it with.
3982 _PATTERNS_TO_CHECK={
3983'content::GetServiceSandboxType<>()':'GetServiceSandboxType\\<'
3984}
3985 _PATTERNS_TO_CHECK={
3986 k: input_api.re.compile(v)
3987for k, vin _PATTERNS_TO_CHECK.items()
3988}
3989
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]3990# We don't want to trigger on strings within this file.
3991def presubmit_file_filter(f):
Daniel Chenga37c03db2022-05-12 17:20:34[diff] [blame]3992return'PRESUBMIT.py'!= input_api.os_path.split(f.LocalPath())[1]
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]3993
3994# Scan all affected files for changes touching _FUNCTIONS_TO_CHECK.
3995 files_to_functions={}
3996for fin input_api.AffectedFiles(file_filter=presubmit_file_filter):
3997 diff= f.GenerateScmDiff()
3998for linein diff.split('\n'):
3999# Not using just RightHandSideLines() because removing a
4000# call to a security-critical function can be just as important
4001# as adding or changing the arguments.
4002if line.startswith('-')or(line.startswith('+')
4003andnot line.startswith('++')):
4004for name, patternin _PATTERNS_TO_CHECK.items():
4005if pattern.search(line):
4006 path= f.LocalPath()
4007ifnot pathin files_to_functions:
4008 files_to_functions[path]= set()
4009 files_to_functions[path].add(name)
4010return files_to_functions
4011
4012
4013defCheckSecurityChanges(input_api, output_api):
4014"""Checks that changes involving security-critical functions are reviewed
4015 by the security team.
4016 """
4017 files_to_functions=_GetFilesUsingSecurityCriticalFunctions(input_api)
4018ifnot len(files_to_functions):
4019return[]
4020
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]4021 owners_file='ipc/SECURITY_OWNERS'
Daniel Chenga37c03db2022-05-12 17:20:34[diff] [blame]4022if_ChangeHasSecurityReviewer(input_api, owners_file):
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]4023return[]
4024
Daniel Chenga37c03db2022-05-12 17:20:34[diff] [blame]4025 msg='The following files change calls to security-sensitive functions\n' \
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]4026'that need to be reviewed by {}.\n'.format(owners_file)
4027for path, namesin files_to_functions.items():
4028 msg+=' {}\n'.format(path)
4029for namein names:
4030 msg+=' {}\n'.format(name)
4031 msg+='\n'
4032
4033if input_api.is_committing:
4034 output= output_api.PresubmitError
Mohamed Heikale217fc852020-07-06 19:44:03[diff] [blame]4035else:
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]4036 output= output_api.PresubmitNotifyResult
4037return[output(msg)]
4038
4039
4040defCheckSetNoParent(input_api, output_api):
4041"""Checks that set noparent is only used together with an OWNERS file in
4042 //build/OWNERS.setnoparent (see also
4043 //docs/code_reviews.md#owners-files-details)
4044 """
4045# Return early if no OWNERS files were modified.
4046ifnot any(f.LocalPath().endswith('OWNERS')
4047for fin input_api.AffectedFiles(include_deletes=False)):
4048return[]
4049
4050 errors=[]
4051
4052 allowed_owners_files_file='build/OWNERS.setnoparent'
4053 allowed_owners_files= set()
Bruce Dawson58a45d22023-02-27 11:24:16[diff] [blame]4054with open(allowed_owners_files_file,'r', encoding='utf-8')as f:
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]4055for linein f:
4056 line= line.strip()
4057ifnot lineor line.startswith('#'):
4058continue
4059 allowed_owners_files.add(line)
4060
4061 per_file_pattern= input_api.re.compile('per-file (.+)=(.+)')
4062
4063for fin input_api.AffectedFiles(include_deletes=False):
4064ifnot f.LocalPath().endswith('OWNERS'):
4065continue
4066
4067 found_owners_files= set()
4068 found_set_noparent_lines= dict()
4069
4070# Parse the OWNERS file.
4071for lineno, linein enumerate(f.NewContents(),1):
4072 line= line.strip()
4073if line.startswith('set noparent'):
4074 found_set_noparent_lines['']= lineno
4075if line.startswith('file://'):
4076if linein allowed_owners_files:
4077 found_owners_files.add('')
4078if line.startswith('per-file'):
4079 match= per_file_pattern.match(line)
4080if match:
4081 glob= match.group(1).strip()
4082 directive= match.group(2).strip()
4083if directive=='set noparent':
4084 found_set_noparent_lines[glob]= lineno
4085if directive.startswith('file://'):
4086if directivein allowed_owners_files:
4087 found_owners_files.add(glob)
4088
4089# Check that every set noparent line has a corresponding file:// line
4090# listed in build/OWNERS.setnoparent. An exception is made for top level
4091# directories since src/OWNERS shouldn't review them.
Bruce Dawson6bb0d672022-04-06 15:13:49[diff] [blame]4092 linux_path= f.LocalPath().replace(input_api.os_path.sep,'/')
4093if(linux_path.count('/')!=1
4094and(not linux_pathin _EXCLUDED_SET_NO_PARENT_PATHS)):
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]4095for set_noparent_linein found_set_noparent_lines:
4096if set_noparent_linein found_owners_files:
4097continue
4098 errors.append(' %s:%d'%
Bruce Dawson6bb0d672022-04-06 15:13:49[diff] [blame]4099(linux_path,
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]4100 found_set_noparent_lines[set_noparent_line]))
4101
4102 results=[]
4103if errors:
4104if input_api.is_committing:
4105 output= output_api.PresubmitError
4106else:
4107 output= output_api.PresubmitPromptWarning
4108 results.append(
4109 output(
4110'Found the following "set noparent" restrictions in OWNERS files that '
4111'do not include owners from build/OWNERS.setnoparent:',
4112 long_text='\n\n'.join(errors)))
4113return results
4114
4115
4116defCheckUselessForwardDeclarations(input_api, output_api):
4117"""Checks that added or removed lines in non third party affected
4118 header files do not lead to new useless class or struct forward
4119 declaration.
4120 """
4121 results=[]
4122 class_pattern= input_api.re.compile(r'^class\s+(\w+);$',
4123 input_api.re.MULTILINE)
4124 struct_pattern= input_api.re.compile(r'^struct\s+(\w+);$',
4125 input_api.re.MULTILINE)
4126for fin input_api.AffectedFiles(include_deletes=False):
4127if(f.LocalPath().startswith('third_party')
4128andnot f.LocalPath().startswith('third_party/blink')
4129andnot f.LocalPath().startswith('third_party\\blink')):
4130continue
4131
4132ifnot f.LocalPath().endswith('.h'):
4133continue
4134
4135 contents= input_api.ReadFile(f)
4136 fwd_decls= input_api.re.findall(class_pattern, contents)
4137 fwd_decls.extend(input_api.re.findall(struct_pattern, contents))
4138
4139 useless_fwd_decls=[]
4140for declin fwd_decls:
4141 count= sum(1for _in input_api.re.finditer(
4142 r'\b%s\b'% input_api.re.escape(decl), contents))
4143if count==1:
4144 useless_fwd_decls.append(decl)
4145
4146ifnot useless_fwd_decls:
4147continue
4148
4149for linein f.GenerateScmDiff().splitlines():
4150if(line.startswith('-')andnot line.startswith('--')
4151or line.startswith('+')andnot line.startswith('++')):
4152for declin useless_fwd_decls:
4153if input_api.re.search(r'\b%s\b'% decl, line[1:]):
4154 results.append(
4155 output_api.PresubmitPromptWarning(
4156'%s: %s forward declaration is no longer needed'
4157%(f.LocalPath(), decl)))
4158 useless_fwd_decls.remove(decl)
4159
4160return results
4161
4162
4163def_CheckAndroidDebuggableBuild(input_api, output_api):
4164"""Checks that code uses BuildInfo.isDebugAndroid() instead of
4165 Build.TYPE.equals('') or ''.equals(Build.TYPE) to check if
4166 this is a debuggable build of Android.
4167 """
4168 build_type_check_pattern= input_api.re.compile(
4169 r'\bBuild\.TYPE\.equals\(|\.equals\(\s*\bBuild\.TYPE\)')
4170
4171 errors=[]
4172
4173 sources=lambda affected_file: input_api.FilterSourceFile(
4174 affected_file,
4175 files_to_skip=(
4176 _EXCLUDED_PATHS+ _TEST_CODE_EXCLUDED_PATHS+ input_api.
4177 DEFAULT_FILES_TO_SKIP+(
Bruce Dawson40fece62022-09-16 19:58:31[diff] [blame]4178 r"^android_webview/support_library/boundary_interfaces/",
4179 r"^chrome/android/webapk/.*",
4180 r'^third_party/.*',
4181 r"tools/android/customtabs_benchmark/.*",
4182 r"webview/chromium/License.*",
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]4183)),
4184 files_to_check=[r'.*\.java$'])
4185
4186for fin input_api.AffectedSourceFiles(sources):
4187for line_num, linein f.ChangedContents():
4188if build_type_check_pattern.search(line):
4189 errors.append("%s:%d"%(f.LocalPath(), line_num))
4190
4191 results=[]
4192
4193if errors:
4194 results.append(
4195 output_api.PresubmitPromptWarning(
4196'Build.TYPE.equals or .equals(Build.TYPE) usage is detected.'
4197' Please use BuildInfo.isDebugAndroid() instead.', errors))
4198
4199return results
4200
4201# TODO: add unit tests
4202def_CheckAndroidToastUsage(input_api, output_api):
4203"""Checks that code uses org.chromium.ui.widget.Toast instead of
4204 android.widget.Toast (Chromium Toast doesn't force hardware
4205 acceleration on low-end devices, saving memory).
4206 """
4207 toast_import_pattern= input_api.re.compile(
4208 r'^import android\.widget\.Toast;$')
4209
4210 errors=[]
4211
4212 sources=lambda affected_file: input_api.FilterSourceFile(
4213 affected_file,
4214 files_to_skip=(_EXCLUDED_PATHS+ _TEST_CODE_EXCLUDED_PATHS+ input_api.
Bruce Dawson40fece62022-09-16 19:58:31[diff] [blame]4215 DEFAULT_FILES_TO_SKIP+(r'^chromecast/.*',
4216 r'^remoting/.*')),
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]4217 files_to_check=[r'.*\.java$'])
4218
4219for fin input_api.AffectedSourceFiles(sources):
4220for line_num, linein f.ChangedContents():
4221if toast_import_pattern.search(line):
4222 errors.append("%s:%d"%(f.LocalPath(), line_num))
4223
4224 results=[]
4225
4226if errors:
4227 results.append(
4228 output_api.PresubmitError(
4229'android.widget.Toast usage is detected. Android toasts use hardware'
4230' acceleration, and can be\ncostly on low-end devices. Please use'
4231' org.chromium.ui.widget.Toast instead.\n'
4232'Contact dskiba@chromium.org if you have any questions.',
4233 errors))
4234
4235return results
4236
4237
4238def_CheckAndroidCrLogUsage(input_api, output_api):
4239"""Checks that new logs using org.chromium.base.Log:
4240 - Are using 'TAG' as variable name for the tags (warn)
4241 - Are using a tag that is shorter than 20 characters (error)
4242 """
4243
4244# Do not check format of logs in the given files
4245 cr_log_check_excluded_paths=[
4246# //chrome/android/webapk cannot depend on //base
Bruce Dawson40fece62022-09-16 19:58:31[diff] [blame]4247 r"^chrome/android/webapk/.*",
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]4248# WebView license viewer code cannot depend on //base; used in stub APK.
Bruce Dawson40fece62022-09-16 19:58:31[diff] [blame]4249 r"^android_webview/glue/java/src/com/android/"
4250 r"webview/chromium/License.*",
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]4251# The customtabs_benchmark is a small app that does not depend on Chromium
4252# java pieces.
Bruce Dawson40fece62022-09-16 19:58:31[diff] [blame]4253 r"tools/android/customtabs_benchmark/.*",
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]4254]
4255
4256 cr_log_import_pattern= input_api.re.compile(
4257 r'^import org\.chromium\.base\.Log;$', input_api.re.MULTILINE)
4258 class_in_base_pattern= input_api.re.compile(
4259 r'^package org\.chromium\.base;$', input_api.re.MULTILINE)
4260 has_some_log_import_pattern= input_api.re.compile(r'^import .*\.Log;$',
4261 input_api.re.MULTILINE)
4262# Extract the tag from lines like `Log.d(TAG, "*");` or `Log.d("TAG", "*");`
4263 log_call_pattern= input_api.re.compile(r'\bLog\.\w\((?P<tag>\"?\w+)')
4264 log_decl_pattern= input_api.re.compile(
4265 r'static final String TAG = "(?P<name>(.*))"')
4266 rough_log_decl_pattern= input_api.re.compile(r'\bString TAG\s*=')
4267
4268 REF_MSG=('See docs/android_logging.md for more info.')
4269 sources=lambda x: input_api.FilterSourceFile(
4270 x,
4271 files_to_check=[r'.*\.java$'],
4272 files_to_skip=cr_log_check_excluded_paths)
4273
4274 tag_decl_errors=[]
4275 tag_length_errors=[]
4276 tag_errors=[]
4277 tag_with_dot_errors=[]
4278 util_log_errors=[]
4279
4280for fin input_api.AffectedSourceFiles(sources):
4281 file_content= input_api.ReadFile(f)
4282 has_modified_logs=False
4283# Per line checks
4284if(cr_log_import_pattern.search(file_content)
4285or(class_in_base_pattern.search(file_content)
4286andnot has_some_log_import_pattern.search(file_content))):
4287# Checks to run for files using cr log
4288for line_num, linein f.ChangedContents():
4289if rough_log_decl_pattern.search(line):
4290 has_modified_logs=True
4291
4292# Check if the new line is doing some logging
4293 match= log_call_pattern.search(line)
4294if match:
4295 has_modified_logs=True
4296
4297# Make sure it uses "TAG"
4298ifnot match.group('tag')=='TAG':
4299 tag_errors.append("%s:%d"%(f.LocalPath(), line_num))
4300else:
4301# Report non cr Log function calls in changed lines
4302for line_num, linein f.ChangedContents():
4303if log_call_pattern.search(line):
4304 util_log_errors.append("%s:%d"%(f.LocalPath(), line_num))
4305
4306# Per file checks
4307if has_modified_logs:
4308# Make sure the tag is using the "cr" prefix and is not too long
4309 match= log_decl_pattern.search(file_content)
4310 tag_name= match.group('name')if matchelseNone
4311ifnot tag_name:
4312 tag_decl_errors.append(f.LocalPath())
4313elif len(tag_name)>20:
4314 tag_length_errors.append(f.LocalPath())
4315elif'.'in tag_name:
4316 tag_with_dot_errors.append(f.LocalPath())
4317
4318 results=[]
4319if tag_decl_errors:
4320 results.append(
4321 output_api.PresubmitPromptWarning(
4322'Please define your tags using the suggested format: .\n'
4323'"private static final String TAG = "<package tag>".\n'
4324'They will be prepended with "cr_" automatically.\n'+ REF_MSG,
4325 tag_decl_errors))
4326
4327if tag_length_errors:
4328 results.append(
4329 output_api.PresubmitError(
4330'The tag length is restricted by the system to be at most '
4331'20 characters.\n'+ REF_MSG, tag_length_errors))
4332
4333if tag_errors:
4334 results.append(
4335 output_api.PresubmitPromptWarning(
4336'Please use a variable named "TAG" for your log tags.\n'+
4337 REF_MSG, tag_errors))
4338
4339if util_log_errors:
4340 results.append(
4341 output_api.PresubmitPromptWarning(
4342'Please use org.chromium.base.Log for new logs.\n'+ REF_MSG,
4343 util_log_errors))
4344
4345if tag_with_dot_errors:
4346 results.append(
4347 output_api.PresubmitPromptWarning(
4348'Dot in log tags cause them to be elided in crash reports.\n'+
4349 REF_MSG, tag_with_dot_errors))
4350
4351return results
4352
4353
4354def_CheckAndroidTestJUnitFrameworkImport(input_api, output_api):
4355"""Checks that junit.framework.* is no longer used."""
4356 deprecated_junit_framework_pattern= input_api.re.compile(
4357 r'^import junit\.framework\..*;', input_api.re.MULTILINE)
4358 sources=lambda x: input_api.FilterSourceFile(
4359 x, files_to_check=[r'.*\.java$'], files_to_skip=None)
4360 errors=[]
4361for fin input_api.AffectedFiles(file_filter=sources):
4362for line_num, linein f.ChangedContents():
4363if deprecated_junit_framework_pattern.search(line):
4364 errors.append("%s:%d"%(f.LocalPath(), line_num))
4365
4366 results=[]
4367if errors:
4368 results.append(
4369 output_api.PresubmitError(
4370'APIs from junit.framework.* are deprecated, please use JUnit4 framework'
4371'(org.junit.*) from //third_party/junit. Contact yolandyan@chromium.org'
4372' if you have any question.', errors))
4373return results
4374
4375
4376def_CheckAndroidTestJUnitInheritance(input_api, output_api):
4377"""Checks that if new Java test classes have inheritance.
4378 Either the new test class is JUnit3 test or it is a JUnit4 test class
4379 with a base class, either case is undesirable.
4380 """
4381 class_declaration_pattern= input_api.re.compile(r'^public class \w*Test ')
4382
4383 sources=lambda x: input_api.FilterSourceFile(
4384 x, files_to_check=[r'.*Test\.java$'], files_to_skip=None)
4385 errors=[]
4386for fin input_api.AffectedFiles(file_filter=sources):
4387ifnot f.OldContents():
4388 class_declaration_start_flag=False
4389for line_num, linein f.ChangedContents():
4390if class_declaration_pattern.search(line):
4391 class_declaration_start_flag=True
4392if class_declaration_start_flagand' extends 'in line:
4393 errors.append('%s:%d'%(f.LocalPath(), line_num))
4394if'{'in line:
4395 class_declaration_start_flag=False
4396
4397 results=[]
4398if errors:
4399 results.append(
4400 output_api.PresubmitPromptWarning(
4401'The newly created files include Test classes that inherits from base'
4402' class. Please do not use inheritance in JUnit4 tests or add new'
4403' JUnit3 tests. Contact yolandyan@chromium.org if you have any'
4404' questions.', errors))
4405return results
4406
4407
4408def_CheckAndroidTestAnnotationUsage(input_api, output_api):
4409"""Checks that android.test.suitebuilder.annotation.* is no longer used."""
4410 deprecated_annotation_import_pattern= input_api.re.compile(
4411 r'^import android\.test\.suitebuilder\.annotation\..*;',
4412 input_api.re.MULTILINE)
4413 sources=lambda x: input_api.FilterSourceFile(
4414 x, files_to_check=[r'.*\.java$'], files_to_skip=None)
4415 errors=[]
4416for fin input_api.AffectedFiles(file_filter=sources):
4417for line_num, linein f.ChangedContents():
4418if deprecated_annotation_import_pattern.search(line):
4419 errors.append("%s:%d"%(f.LocalPath(), line_num))
4420
4421 results=[]
4422if errors:
4423 results.append(
4424 output_api.PresubmitError(
4425'Annotations in android.test.suitebuilder.annotation have been'
Mohamed Heikal3d7a94c2023-03-28 16:55:24[diff] [blame]4426' deprecated since API level 24. Please use androidx.test.filters'
4427' from //third_party/androidx:androidx_test_runner_java instead.'
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]4428' Contact yolandyan@chromium.org if you have any questions.',
4429 errors))
4430return results
4431
4432
4433def_CheckAndroidNewMdpiAssetLocation(input_api, output_api):
4434"""Checks if MDPI assets are placed in a correct directory."""
Bruce Dawson6c05e852022-07-21 15:48:51[diff] [blame]4435 file_filter=lambda f:(f.LocalPath().endswith(
4436'.png')and('/res/drawable/'.replace('/', input_api.os_path.sep)in f.
4437LocalPath()or'/res/drawable-ldrtl/'.replace(
4438'/', input_api.os_path.sep)in f.LocalPath()))
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]4439 errors=[]
4440for fin input_api.AffectedFiles(include_deletes=False,
4441 file_filter=file_filter):
4442 errors.append(' %s'% f.LocalPath())
4443
4444 results=[]
4445if errors:
4446 results.append(
4447 output_api.PresubmitError(
4448'MDPI assets should be placed in /res/drawable-mdpi/ or '
4449'/res/drawable-ldrtl-mdpi/\ninstead of /res/drawable/ and'
4450'/res/drawable-ldrtl/.\n'
4451'Contact newt@chromium.org if you have questions.', errors))
4452return results
4453
4454
4455def_CheckAndroidWebkitImports(input_api, output_api):
4456"""Checks that code uses org.chromium.base.Callback instead of
4457 android.webview.ValueCallback except in the WebView glue layer
4458 and WebLayer.
4459 """
4460 valuecallback_import_pattern= input_api.re.compile(
4461 r'^import android\.webkit\.ValueCallback;$')
4462
4463 errors=[]
4464
4465 sources=lambda affected_file: input_api.FilterSourceFile(
4466 affected_file,
4467 files_to_skip=(_EXCLUDED_PATHS+ _TEST_CODE_EXCLUDED_PATHS+ input_api.
4468 DEFAULT_FILES_TO_SKIP+(
Bruce Dawson40fece62022-09-16 19:58:31[diff] [blame]4469 r'^android_webview/glue/.*',
4470 r'^weblayer/.*',
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]4471)),
4472 files_to_check=[r'.*\.java$'])
4473
4474for fin input_api.AffectedSourceFiles(sources):
4475for line_num, linein f.ChangedContents():
4476if valuecallback_import_pattern.search(line):
4477 errors.append("%s:%d"%(f.LocalPath(), line_num))
4478
4479 results=[]
4480
4481if errors:
4482 results.append(
4483 output_api.PresubmitError(
4484'android.webkit.ValueCallback usage is detected outside of the glue'
4485' layer. To stay compatible with the support library, android.webkit.*'
4486' classes should only be used inside the glue layer and'
4487' org.chromium.base.Callback should be used instead.', errors))
4488
4489return results
4490
4491
4492def_CheckAndroidXmlStyle(input_api, output_api, is_check_on_upload):
4493"""Checks Android XML styles """
4494
4495# Return early if no relevant files were modified.
4496ifnot any(
4497_IsXmlOrGrdFile(input_api, f.LocalPath())
4498for fin input_api.AffectedFiles(include_deletes=False)):
4499return[]
4500
4501import sys
4502 original_sys_path= sys.path
4503try:
4504 sys.path= sys.path+[
4505 input_api.os_path.join(input_api.PresubmitLocalPath(),'tools',
4506'android','checkxmlstyle')
4507]
4508import checkxmlstyle
4509finally:
4510# Restore sys.path to what it was before.
4511 sys.path= original_sys_path
4512
4513if is_check_on_upload:
4514return checkxmlstyle.CheckStyleOnUpload(input_api, output_api)
4515else:
4516return checkxmlstyle.CheckStyleOnCommit(input_api, output_api)
4517
4518
4519def_CheckAndroidInfoBarDeprecation(input_api, output_api):
4520"""Checks Android Infobar Deprecation """
4521
4522import sys
4523 original_sys_path= sys.path
4524try:
4525 sys.path= sys.path+[
4526 input_api.os_path.join(input_api.PresubmitLocalPath(),'tools',
4527'android','infobar_deprecation')
4528]
4529import infobar_deprecation
4530finally:
4531# Restore sys.path to what it was before.
4532 sys.path= original_sys_path
4533
4534return infobar_deprecation.CheckDeprecationOnUpload(input_api, output_api)
4535
4536
4537class_PydepsCheckerResult:
4538def __init__(self, cmd, pydeps_path, process, old_contents):
4539 self._cmd= cmd
4540 self._pydeps_path= pydeps_path
4541 self._process= process
4542 self._old_contents= old_contents
4543
4544defGetError(self):
4545"""Returns an error message, or None."""
4546import difflib
Andrew Grieved27620b62023-07-13 16:35:07[diff] [blame]4547 new_contents= self._process.stdout.read().splitlines()[2:]
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]4548if self._process.wait()!=0:
4549# STDERR should already be printed.
4550return'Command failed: '+ self._cmd
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]4551if self._old_contents!= new_contents:
4552 diff='\n'.join(
4553 difflib.context_diff(self._old_contents, new_contents))
4554return('File is stale: {}\n'
4555'Diff (apply to fix):\n'
4556'{}\n'
4557'To regenerate, run:\n\n'
4558' {}').format(self._pydeps_path, diff, self._cmd)
4559returnNone
4560
4561
4562classPydepsChecker:
4563def __init__(self, input_api, pydeps_files):
4564 self._file_cache={}
4565 self._input_api= input_api
4566 self._pydeps_files= pydeps_files
4567
4568def_LoadFile(self, path):
4569"""Returns the list of paths within a .pydeps file relative to //."""
4570if pathnotin self._file_cache:
4571with open(path, encoding='utf-8')as f:
4572 self._file_cache[path]= f.read()
4573return self._file_cache[path]
4574
4575def_ComputeNormalizedPydepsEntries(self, pydeps_path):
Gao Shenga79ebd42022-08-08 17:25:59[diff] [blame]4576"""Returns an iterable of paths within the .pydep, relativized to //."""
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]4577 pydeps_data= self._LoadFile(pydeps_path)
4578 uses_gn_paths='--gn-paths'in pydeps_data
4579 entries=(lfor lin pydeps_data.splitlines()
4580ifnot l.startswith('#'))
4581if uses_gn_paths:
4582# Paths look like: //foo/bar/baz
4583return(e[2:]for ein entries)
4584else:
4585# Paths look like: path/relative/to/file.pydeps
4586 os_path= self._input_api.os_path
4587 pydeps_dir= os_path.dirname(pydeps_path)
4588return(os_path.normpath(os_path.join(pydeps_dir, e))
4589for ein entries)
4590
4591def_CreateFilesToPydepsMap(self):
4592"""Returns a map of local_path -> list_of_pydeps."""
4593 ret={}
4594for pydep_local_pathin self._pydeps_files:
4595for pathin self._ComputeNormalizedPydepsEntries(pydep_local_path):
4596 ret.setdefault(path,[]).append(pydep_local_path)
4597return ret
4598
4599defComputeAffectedPydeps(self):
4600"""Returns an iterable of .pydeps files that might need regenerating."""
4601 affected_pydeps= set()
4602 file_to_pydeps_map=None
4603for fin self._input_api.AffectedFiles(include_deletes=True):
4604 local_path= f.LocalPath()
4605# Changes to DEPS can lead to .pydeps changes if any .py files are in
4606# subrepositories. We can't figure out which files change, so re-check
4607# all files.
4608# Changes to print_python_deps.py affect all .pydeps.
4609if local_pathin('DEPS','PRESUBMIT.py'
4610)or local_path.endswith('print_python_deps.py'):
4611return self._pydeps_files
4612elif local_path.endswith('.pydeps'):
4613if local_pathin self._pydeps_files:
4614 affected_pydeps.add(local_path)
4615elif local_path.endswith('.py'):
4616if file_to_pydeps_mapisNone:
4617 file_to_pydeps_map= self._CreateFilesToPydepsMap()
4618 affected_pydeps.update(file_to_pydeps_map.get(local_path,()))
4619return affected_pydeps
4620
4621defDetermineIfStaleAsync(self, pydeps_path):
4622"""Runs print_python_deps.py to see if the files is stale."""
4623import os
4624
4625 old_pydeps_data= self._LoadFile(pydeps_path).splitlines()
4626if old_pydeps_data:
4627 cmd= old_pydeps_data[1][1:].strip()
4628if'--output'notin cmd:
4629 cmd+=' --output '+ pydeps_path
4630 old_contents= old_pydeps_data[2:]
4631else:
4632# A default cmd that should work in most cases (as long as pydeps filename
4633# matches the script name) so that PRESUBMIT.py does not crash if pydeps
4634# file is empty/new.
4635 cmd='build/print_python_deps.py {} --root={} --output={}'.format(
4636 pydeps_path[:-4], os.path.dirname(pydeps_path), pydeps_path)
4637 old_contents=[]
4638 env= dict(os.environ)
4639 env['PYTHONDONTWRITEBYTECODE']='1'
4640 process= self._input_api.subprocess.Popen(
4641 cmd+' --output ""',
4642 shell=True,
4643 env=env,
4644 stdout=self._input_api.subprocess.PIPE,
4645 encoding='utf-8')
4646return_PydepsCheckerResult(cmd, pydeps_path, process, old_contents)
agrievef32bcc72016-04-04 14:57:40[diff] [blame]4647
4648
Tibor Goldschwendt360793f72019-06-25 18:23:49[diff] [blame]4649def_ParseGclientArgs():
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]4650 args={}
4651with open('build/config/gclient_args.gni','r')as f:
4652for linein f:
4653 line= line.strip()
4654ifnot lineor line.startswith('#'):
4655continue
4656 attribute, value= line.split('=')
4657 args[attribute.strip()]= value.strip()
4658return args
Tibor Goldschwendt360793f72019-06-25 18:23:49[diff] [blame]4659
4660
Saagar Sanghavifceeaae2020-08-12 16:40:36[diff] [blame]4661defCheckPydepsNeedsUpdating(input_api, output_api, checker_for_tests=None):
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]4662"""Checks if a .pydeps file needs to be regenerated."""
4663# This check is for Python dependency lists (.pydeps files), and involves
4664# paths not only in the PRESUBMIT.py, but also in the .pydeps files. It
4665# doesn't work on Windows and Mac, so skip it on other platforms.
4666ifnot input_api.platform.startswith('linux'):
4667return[]
Erik Staabc734cd7a2021-11-23 03:11:52[diff] [blame]4668
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]4669 results=[]
4670# First, check for new / deleted .pydeps.
4671for fin input_api.AffectedFiles(include_deletes=True):
4672# Check whether we are running the presubmit check for a file in src.
4673# f.LocalPath is relative to repo (src, or internal repo).
4674# os_path.exists is relative to src repo.
4675# Therefore if os_path.exists is true, it means f.LocalPath is relative
4676# to src and we can conclude that the pydeps is in src.
4677if f.LocalPath().endswith('.pydeps'):
4678if input_api.os_path.exists(f.LocalPath()):
4679if f.Action()=='D'and f.LocalPath()in _ALL_PYDEPS_FILES:
4680 results.append(
4681 output_api.PresubmitError(
4682'Please update _ALL_PYDEPS_FILES within //PRESUBMIT.py to '
4683'remove %s'% f.LocalPath()))
4684elif f.Action()!='D'and f.LocalPath(
4685)notin _ALL_PYDEPS_FILES:
4686 results.append(
4687 output_api.PresubmitError(
4688'Please update _ALL_PYDEPS_FILES within //PRESUBMIT.py to '
4689'include %s'% f.LocalPath()))
agrievef32bcc72016-04-04 14:57:40[diff] [blame]4690
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]4691if results:
4692return results
4693
4694 is_android=_ParseGclientArgs().get('checkout_android','false')=='true'
4695 checker= checker_for_testsorPydepsChecker(input_api, _ALL_PYDEPS_FILES)
4696 affected_pydeps= set(checker.ComputeAffectedPydeps())
4697 affected_android_pydeps= affected_pydeps.intersection(
4698 set(_ANDROID_SPECIFIC_PYDEPS_FILES))
4699if affected_android_pydepsandnot is_android:
4700 results.append(
4701 output_api.PresubmitPromptOrNotify(
4702'You have changed python files that may affect pydeps for android\n'
Gao Shenga79ebd42022-08-08 17:25:59[diff] [blame]4703'specific scripts. However, the relevant presubmit check cannot be\n'
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]4704'run because you are not using an Android checkout. To validate that\n'
4705'the .pydeps are correct, re-run presubmit in an Android checkout, or\n'
4706'use the android-internal-presubmit optional trybot.\n'
4707'Possibly stale pydeps files:\n{}'.format(
4708'\n'.join(affected_android_pydeps))))
4709
4710 all_pydeps= _ALL_PYDEPS_FILESif is_androidelse _GENERIC_PYDEPS_FILES
4711 pydeps_to_check= affected_pydeps.intersection(all_pydeps)
4712# Process these concurrently, as each one takes 1-2 seconds.
4713 pydep_results=[checker.DetermineIfStaleAsync(p)for pin pydeps_to_check]
4714for resultin pydep_results:
4715 error_msg= result.GetError()
4716if error_msg:
4717 results.append(output_api.PresubmitError(error_msg))
4718
agrievef32bcc72016-04-04 14:57:40[diff] [blame]4719return results
4720
agrievef32bcc72016-04-04 14:57:40[diff] [blame]4721
Saagar Sanghavifceeaae2020-08-12 16:40:36[diff] [blame]4722defCheckSingletonInHeaders(input_api, output_api):
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]4723"""Checks to make sure no header files have |Singleton<|."""
4724
4725defFileFilter(affected_file):
4726# It's ok for base/memory/singleton.h to have |Singleton<|.
4727 files_to_skip=(_EXCLUDED_PATHS+ input_api.DEFAULT_FILES_TO_SKIP+
Bruce Dawson40fece62022-09-16 19:58:31[diff] [blame]4728(r"^base/memory/singleton\.h$",
4729 r"^net/quic/platform/impl/quic_singleton_impl\.h$"))
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]4730return input_api.FilterSourceFile(affected_file,
4731 files_to_skip=files_to_skip)
glidere61efad2015-02-18 17:39:43[diff] [blame]4732
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]4733 pattern= input_api.re.compile(r'(?<!class\sbase::)Singleton\s*<')
4734 files=[]
4735for fin input_api.AffectedSourceFiles(FileFilter):
4736if(f.LocalPath().endswith('.h')or f.LocalPath().endswith('.hxx')
4737or f.LocalPath().endswith('.hpp')
4738or f.LocalPath().endswith('.inl')):
4739 contents= input_api.ReadFile(f)
4740for linein contents.splitlines(False):
4741if(not line.lstrip().startswith('//')
4742and# Strip C++ comment.
4743 pattern.search(line)):
4744 files.append(f)
4745break
glidere61efad2015-02-18 17:39:43[diff] [blame]4746
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]4747if files:
4748return[
4749 output_api.PresubmitError(
4750'Found base::Singleton<T> in the following header files.\n'+
4751'Please move them to an appropriate source file so that the '+
4752'template gets instantiated in a single compilation unit.',
4753 files)
4754]
4755return[]
glidere61efad2015-02-18 17:39:43[diff] [blame]4756
4757
jchaffraix@chromium.orgfd20b902014-05-09 02:14:53[diff] [blame]4758_DEPRECATED_CSS=[
4759# Values
4760("-webkit-box","flex"),
4761("-webkit-inline-box","inline-flex"),
4762("-webkit-flex","flex"),
4763("-webkit-inline-flex","inline-flex"),
4764("-webkit-min-content","min-content"),
4765("-webkit-max-content","max-content"),
4766
4767# Properties
4768("-webkit-background-clip","background-clip"),
4769("-webkit-background-origin","background-origin"),
4770("-webkit-background-size","background-size"),
4771("-webkit-box-shadow","box-shadow"),
dbeam6936c67f2017-01-19 01:51:44[diff] [blame]4772("-webkit-user-select","user-select"),
jchaffraix@chromium.orgfd20b902014-05-09 02:14:53[diff] [blame]4773
4774# Functions
4775("-webkit-gradient","gradient"),
4776("-webkit-repeating-gradient","repeating-gradient"),
4777("-webkit-linear-gradient","linear-gradient"),
4778("-webkit-repeating-linear-gradient","repeating-linear-gradient"),
4779("-webkit-radial-gradient","radial-gradient"),
4780("-webkit-repeating-radial-gradient","repeating-radial-gradient"),
4781]
4782
Wei-Yin Chen (陳威尹)f799d442018-07-31 02:20:20[diff] [blame]4783
Wei-Yin Chen (陳威尹)dca729a2018-07-31 21:35:49[diff] [blame]4784# TODO: add unit tests
Saagar Sanghavifceeaae2020-08-12 16:40:36[diff] [blame]4785defCheckNoDeprecatedCss(input_api, output_api):
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]4786""" Make sure that we don't use deprecated CSS
4787 properties, functions or values. Our external
4788 documentation and iOS CSS for dom distiller
4789 (reader mode) are ignored by the hooks as it
4790 needs to be consumed by WebKit. """
4791 results=[]
4792 file_inclusion_pattern=[r".+\.css$"]
4793 files_to_skip=(_EXCLUDED_PATHS+ _TEST_CODE_EXCLUDED_PATHS+
4794 input_api.DEFAULT_FILES_TO_SKIP+
4795(r"^chrome/common/extensions/docs", r"^chrome/docs",
4796 r"^native_client_sdk"))
4797 file_filter=lambda f: input_api.FilterSourceFile(
4798 f, files_to_check=file_inclusion_pattern, files_to_skip=files_to_skip)
4799for fpathin input_api.AffectedFiles(file_filter=file_filter):
4800for line_num, linein fpath.ChangedContents():
4801for(deprecated_value, value)in _DEPRECATED_CSS:
4802if deprecated_valuein line:
4803 results.append(
4804 output_api.PresubmitError(
4805"%s:%d: Use of deprecated CSS %s, use %s instead"%
4806(fpath.LocalPath(), line_num, deprecated_value,
4807 value)))
4808return results
jchaffraix@chromium.orgfd20b902014-05-09 02:14:53[diff] [blame]4809
mohan.reddyf21db962014-10-16 12:26:47[diff] [blame]4810
Saagar Sanghavifceeaae2020-08-12 16:40:36[diff] [blame]4811defCheckForRelativeIncludes(input_api, output_api):
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]4812 bad_files={}
4813for fin input_api.AffectedFiles(include_deletes=False):
4814if(f.LocalPath().startswith('third_party')
4815andnot f.LocalPath().startswith('third_party/blink')
4816andnot f.LocalPath().startswith('third_party\\blink')):
4817continue
rlanday6802cf632017-05-30 17:48:36[diff] [blame]4818
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]4819ifnot_IsCPlusPlusFile(input_api, f.LocalPath()):
4820continue
rlanday6802cf632017-05-30 17:48:36[diff] [blame]4821
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]4822 relative_includes=[
4823 linefor _, linein f.ChangedContents()
4824if"#include"in lineand"../"in line
4825]
4826ifnot relative_includes:
4827continue
4828 bad_files[f.LocalPath()]= relative_includes
rlanday6802cf632017-05-30 17:48:36[diff] [blame]4829
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]4830ifnot bad_files:
4831return[]
rlanday6802cf632017-05-30 17:48:36[diff] [blame]4832
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]4833 error_descriptions=[]
4834for file_path, bad_linesin bad_files.items():
4835 error_description= file_path
4836for linein bad_lines:
4837 error_description+='\n '+ line
4838 error_descriptions.append(error_description)
rlanday6802cf632017-05-30 17:48:36[diff] [blame]4839
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]4840 results=[]
4841 results.append(
4842 output_api.PresubmitError(
4843'You added one or more relative #include paths (including "../").\n'
4844'These shouldn\'t be used because they can be used to include headers\n'
4845'from code that\'s not correctly specified as a dependency in the\n'
4846'relevant BUILD.gn file(s).', error_descriptions))
rlanday6802cf632017-05-30 17:48:36[diff] [blame]4847
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]4848return results
rlanday6802cf632017-05-30 17:48:36[diff] [blame]4849
Takeshi Yoshinoe387aa32017-08-02 13:16:13[diff] [blame]4850
Saagar Sanghavifceeaae2020-08-12 16:40:36[diff] [blame]4851defCheckForCcIncludes(input_api, output_api):
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]4852"""Check that nobody tries to include a cc file. It's a relatively
4853 common error which results in duplicate symbols in object
4854 files. This may not always break the build until someone later gets
4855 very confusing linking errors."""
4856 results=[]
4857for fin input_api.AffectedFiles(include_deletes=False):
4858# We let third_party code do whatever it wants
4859if(f.LocalPath().startswith('third_party')
4860andnot f.LocalPath().startswith('third_party/blink')
4861andnot f.LocalPath().startswith('third_party\\blink')):
4862continue
Daniel Bratell65b033262019-04-23 08:17:06[diff] [blame]4863
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]4864ifnot_IsCPlusPlusFile(input_api, f.LocalPath()):
4865continue
Daniel Bratell65b033262019-04-23 08:17:06[diff] [blame]4866
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]4867for _, linein f.ChangedContents():
4868if line.startswith('#include "'):
4869 included_file= line.split('"')[1]
4870if_IsCPlusPlusFile(input_api, included_file):
4871# The most common naming for external files with C++ code,
4872# apart from standard headers, is to call them foo.inc, but
4873# Chromium sometimes uses foo-inc.cc so allow that as well.
4874ifnot included_file.endswith(('.h','-inc.cc')):
4875 results.append(
4876 output_api.PresubmitError(
4877'Only header files or .inc files should be included in other\n'
4878'C++ files. Compiling the contents of a cc file more than once\n'
4879'will cause duplicate information in the build which may later\n'
4880'result in strange link_errors.\n'+
4881 f.LocalPath()+':\n '+ line))
Daniel Bratell65b033262019-04-23 08:17:06[diff] [blame]4882
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]4883return results
Daniel Bratell65b033262019-04-23 08:17:06[diff] [blame]4884
4885
Takeshi Yoshino3a8f9cb52017-08-10 11:32:20[diff] [blame]4886def_CheckWatchlistDefinitionsEntrySyntax(key, value, ast):
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]4887ifnot isinstance(key, ast.Str):
4888return'Key at line %d must be a string literal'% key.lineno
4889ifnot isinstance(value, ast.Dict):
4890return'Value at line %d must be a dict'% value.lineno
4891if len(value.keys)!=1:
4892return'Dict at line %d must have single entry'% value.lineno
4893ifnot isinstance(value.keys[0], ast.Str)or value.keys[0].s!='filepath':
4894return(
4895'Entry at line %d must have a string literal \'filepath\' as key'%
4896 value.lineno)
4897returnNone
Takeshi Yoshinoe387aa32017-08-02 13:16:13[diff] [blame]4898
Takeshi Yoshinoe387aa32017-08-02 13:16:13[diff] [blame]4899
Sergey Ulanov4af16052018-11-08 02:41:46[diff] [blame]4900def_CheckWatchlistsEntrySyntax(key, value, ast, email_regex):
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]4901ifnot isinstance(key, ast.Str):
4902return'Key at line %d must be a string literal'% key.lineno
4903ifnot isinstance(value, ast.List):
4904return'Value at line %d must be a list'% value.lineno
4905for elementin value.elts:
4906ifnot isinstance(element, ast.Str):
4907return'Watchlist elements on line %d is not a string'% key.lineno
4908ifnot email_regex.match(element.s):
4909return('Watchlist element on line %d doesn\'t look like a valid '
4910+'email: %s')%(key.lineno, element.s)
4911returnNone
Takeshi Yoshinoe387aa32017-08-02 13:16:13[diff] [blame]4912
Takeshi Yoshinoe387aa32017-08-02 13:16:13[diff] [blame]4913
Sergey Ulanov4af16052018-11-08 02:41:46[diff] [blame]4914def_CheckWATCHLISTSEntries(wd_dict, w_dict, input_api):
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]4915 mismatch_template=(
4916'Mismatch between WATCHLIST_DEFINITIONS entry (%s) and WATCHLISTS '
4917'entry (%s)')
Takeshi Yoshinoe387aa32017-08-02 13:16:13[diff] [blame]4918
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]4919 email_regex= input_api.re.compile(
4920 r"^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]+$")
Sergey Ulanov4af16052018-11-08 02:41:46[diff] [blame]4921
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]4922 ast= input_api.ast
4923 i=0
4924 last_key=''
4925whileTrue:
4926if i>= len(wd_dict.keys):
4927if i>= len(w_dict.keys):
4928returnNone
4929return mismatch_template%('missing',
4930'line %d'% w_dict.keys[i].lineno)
4931elif i>= len(w_dict.keys):
4932return(mismatch_template%
4933('line %d'% wd_dict.keys[i].lineno,'missing'))
Takeshi Yoshinoe387aa32017-08-02 13:16:13[diff] [blame]4934
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]4935 wd_key= wd_dict.keys[i]
4936 w_key= w_dict.keys[i]
Takeshi Yoshinoe387aa32017-08-02 13:16:13[diff] [blame]4937
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]4938 result=_CheckWatchlistDefinitionsEntrySyntax(wd_key,
4939 wd_dict.values[i], ast)
4940if resultisnotNone:
4941return'Bad entry in WATCHLIST_DEFINITIONS dict: %s'% result
Takeshi Yoshinoe387aa32017-08-02 13:16:13[diff] [blame]4942
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]4943 result=_CheckWatchlistsEntrySyntax(w_key, w_dict.values[i], ast,
4944 email_regex)
4945if resultisnotNone:
4946return'Bad entry in WATCHLISTS dict: %s'% result
Takeshi Yoshino3a8f9cb52017-08-10 11:32:20[diff] [blame]4947
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]4948if wd_key.s!= w_key.s:
4949return mismatch_template%('%s at line %d'%
4950(wd_key.s, wd_key.lineno),
4951'%s at line %d'%
4952(w_key.s, w_key.lineno))
Takeshi Yoshino3a8f9cb52017-08-10 11:32:20[diff] [blame]4953
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]4954if wd_key.s< last_key:
4955return(
4956'WATCHLISTS dict is not sorted lexicographically at line %d and %d'
4957%(wd_key.lineno, w_key.lineno))
4958 last_key= wd_key.s
Takeshi Yoshino3a8f9cb52017-08-10 11:32:20[diff] [blame]4959
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]4960 i= i+1
Takeshi Yoshino3a8f9cb52017-08-10 11:32:20[diff] [blame]4961
4962
Sergey Ulanov4af16052018-11-08 02:41:46[diff] [blame]4963def_CheckWATCHLISTSSyntax(expression, input_api):
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]4964 ast= input_api.ast
4965ifnot isinstance(expression, ast.Expression):
4966return'WATCHLISTS file must contain a valid expression'
4967 dictionary= expression.body
4968ifnot isinstance(dictionary, ast.Dict)or len(dictionary.keys)!=2:
4969return'WATCHLISTS file must have single dict with exactly two entries'
Takeshi Yoshino3a8f9cb52017-08-10 11:32:20[diff] [blame]4970
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]4971 first_key= dictionary.keys[0]
4972 first_value= dictionary.values[0]
4973 second_key= dictionary.keys[1]
4974 second_value= dictionary.values[1]
Takeshi Yoshino3a8f9cb52017-08-10 11:32:20[diff] [blame]4975
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]4976if(not isinstance(first_key, ast.Str)
4977or first_key.s!='WATCHLIST_DEFINITIONS'
4978ornot isinstance(first_value, ast.Dict)):
4979return('The first entry of the dict in WATCHLISTS file must be '
4980'WATCHLIST_DEFINITIONS dict')
Takeshi Yoshino3a8f9cb52017-08-10 11:32:20[diff] [blame]4981
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]4982if(not isinstance(second_key, ast.Str)or second_key.s!='WATCHLISTS'
4983ornot isinstance(second_value, ast.Dict)):
4984return('The second entry of the dict in WATCHLISTS file must be '
4985'WATCHLISTS dict')
Takeshi Yoshino3a8f9cb52017-08-10 11:32:20[diff] [blame]4986
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]4987return_CheckWATCHLISTSEntries(first_value, second_value, input_api)
Takeshi Yoshinoe387aa32017-08-02 13:16:13[diff] [blame]4988
4989
Saagar Sanghavifceeaae2020-08-12 16:40:36[diff] [blame]4990defCheckWATCHLISTS(input_api, output_api):
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]4991for fin input_api.AffectedFiles(include_deletes=False):
4992if f.LocalPath()=='WATCHLISTS':
4993 contents= input_api.ReadFile(f,'r')
Takeshi Yoshinoe387aa32017-08-02 13:16:13[diff] [blame]4994
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]4995try:
4996# First, make sure that it can be evaluated.
4997 input_api.ast.literal_eval(contents)
4998# Get an AST tree for it and scan the tree for detailed style checking.
4999 expression= input_api.ast.parse(contents,
5000 filename='WATCHLISTS',
5001 mode='eval')
5002exceptValueErroras e:
5003return[
5004 output_api.PresubmitError('Cannot parse WATCHLISTS file',
5005 long_text=repr(e))
5006]
5007exceptSyntaxErroras e:
5008return[
5009 output_api.PresubmitError('Cannot parse WATCHLISTS file',
5010 long_text=repr(e))
5011]
5012exceptTypeErroras e:
5013return[
5014 output_api.PresubmitError('Cannot parse WATCHLISTS file',
5015 long_text=repr(e))
5016]
Takeshi Yoshinoe387aa32017-08-02 13:16:13[diff] [blame]5017
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5018 result=_CheckWATCHLISTSSyntax(expression, input_api)
5019if resultisnotNone:
5020return[output_api.PresubmitError(result)]
5021break
Takeshi Yoshinoe387aa32017-08-02 13:16:13[diff] [blame]5022
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5023return[]
Takeshi Yoshinoe387aa32017-08-02 13:16:13[diff] [blame]5024
Sean Kaucb7c9b32022-10-25 21:25:52[diff] [blame]5025defCheckGnRebasePath(input_api, output_api):
5026"""Checks that target_gen_dir is not used wtih "//" in rebase_path().
5027
5028 Developers should use root_build_dir instead of "//" when using target_gen_dir because
5029 Chromium is sometimes built outside of the source tree.
5030 """
5031
5032def gn_files(f):
5033return input_api.FilterSourceFile(f, files_to_check=(r'.+\.gn',))
5034
5035 rebase_path_regex= input_api.re.compile(r'rebase_path\(("\$target_gen_dir"|target_gen_dir), ("/"|"//")\)')
5036 problems=[]
5037for fin input_api.AffectedSourceFiles(gn_files):
5038for line_num, linein f.ChangedContents():
5039if rebase_path_regex.search(line):
5040 problems.append(
5041'Absolute path in rebase_path() in %s:%d'%
5042(f.LocalPath(), line_num))
5043
5044if problems:
5045return[
5046 output_api.PresubmitPromptWarning(
5047'Using an absolute path in rebase_path()',
5048 items=sorted(problems),
5049 long_text=(
5050'rebase_path() should use root_build_dir instead of "/" ',
5051'since builds can be initiated from outside of the source ',
5052'root.'))
5053]
5054return[]
Takeshi Yoshinoe387aa32017-08-02 13:16:13[diff] [blame]5055
Andrew Grieve1b290e4a22020-11-24 20:07:01[diff] [blame]5056defCheckGnGlobForward(input_api, output_api):
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5057"""Checks that forward_variables_from(invoker, "*") follows best practices.
Andrew Grieve1b290e4a22020-11-24 20:07:01[diff] [blame]5058
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5059 As documented at //build/docs/writing_gn_templates.md
5060 """
Andrew Grieve1b290e4a22020-11-24 20:07:01[diff] [blame]5061
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5062def gn_files(f):
5063return input_api.FilterSourceFile(f, files_to_check=(r'.+\.gni',))
Andrew Grieve1b290e4a22020-11-24 20:07:01[diff] [blame]5064
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5065 problems=[]
5066for fin input_api.AffectedSourceFiles(gn_files):
5067for line_num, linein f.ChangedContents():
5068if'forward_variables_from(invoker, "*")'in line:
5069 problems.append(
5070'Bare forward_variables_from(invoker, "*") in %s:%d'%
5071(f.LocalPath(), line_num))
5072
5073if problems:
5074return[
5075 output_api.PresubmitPromptWarning(
5076'forward_variables_from("*") without exclusions',
5077 items=sorted(problems),
5078 long_text=(
Gao Shenga79ebd42022-08-08 17:25:59[diff] [blame]5079'The variables "visibility" and "test_only" should be '
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5080'explicitly listed in forward_variables_from(). For more '
5081'details, see:\n'
5082'https://chromium.googlesource.com/chromium/src/+/HEAD/'
5083'build/docs/writing_gn_templates.md'
5084'#Using-forward_variables_from'))
5085]
5086return[]
Andrew Grieve1b290e4a22020-11-24 20:07:01[diff] [blame]5087
Saagar Sanghavifceeaae2020-08-12 16:40:36[diff] [blame]5088defCheckNewHeaderWithoutGnChangeOnUpload(input_api, output_api):
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5089"""Checks that newly added header files have corresponding GN changes.
5090 Note that this is only a heuristic. To be precise, run script:
5091 build/check_gn_headers.py.
5092 """
Wei-Yin Chen (陳威尹)c0624d002018-07-30 18:22:19[diff] [blame]5093
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5094def headers(f):
5095return input_api.FilterSourceFile(
5096 f, files_to_check=(r'.+%s'% _HEADER_EXTENSIONS,))
Wei-Yin Chen (陳威尹)c0624d002018-07-30 18:22:19[diff] [blame]5097
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5098 new_headers=[]
5099for fin input_api.AffectedSourceFiles(headers):
5100if f.Action()!='A':
5101continue
5102 new_headers.append(f.LocalPath())
Wei-Yin Chen (陳威尹)c0624d002018-07-30 18:22:19[diff] [blame]5103
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5104def gn_files(f):
5105return input_api.FilterSourceFile(f, files_to_check=(r'.+\.gn',))
Wei-Yin Chen (陳威尹)c0624d002018-07-30 18:22:19[diff] [blame]5106
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5107 all_gn_changed_contents=''
5108for fin input_api.AffectedSourceFiles(gn_files):
5109for _, linein f.ChangedContents():
5110 all_gn_changed_contents+= line
Wei-Yin Chen (陳威尹)c0624d002018-07-30 18:22:19[diff] [blame]5111
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5112 problems=[]
5113for headerin new_headers:
5114 basename= input_api.os_path.basename(header)
5115if basenamenotin all_gn_changed_contents:
5116 problems.append(header)
Wei-Yin Chen (陳威尹)c0624d002018-07-30 18:22:19[diff] [blame]5117
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5118if problems:
5119return[
5120 output_api.PresubmitPromptWarning(
5121'Missing GN changes for new header files',
5122 items=sorted(problems),
5123 long_text=
5124'Please double check whether newly added header files need '
5125'corresponding changes in gn or gni files.\nThis checking is only a '
5126'heuristic. Run build/check_gn_headers.py to be precise.\n'
5127'Read https://crbug.com/661774 for more info.')
5128]
5129return[]
Wei-Yin Chen (陳威尹)c0624d002018-07-30 18:22:19[diff] [blame]5130
5131
Saagar Sanghavifceeaae2020-08-12 16:40:36[diff] [blame]5132defCheckCorrectProductNameInMessages(input_api, output_api):
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5133"""Check that Chromium-branded strings don't include "Chrome" or vice versa.
Michael Giuffridad3bc8672018-10-25 22:48:02[diff] [blame]5134
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5135 This assumes we won't intentionally reference one product from the other
5136 product.
5137 """
5138 all_problems=[]
5139 test_cases=[{
5140"filename_postfix":"google_chrome_strings.grd",
5141"correct_name":"Chrome",
5142"incorrect_name":"Chromium",
5143},{
Thiago Perrotta099034f2023-06-05 18:10:20[diff] [blame]5144"filename_postfix":"google_chrome_strings.grd",
5145"correct_name":"Chrome",
5146"incorrect_name":"Chrome for Testing",
5147},{
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5148"filename_postfix":"chromium_strings.grd",
5149"correct_name":"Chromium",
5150"incorrect_name":"Chrome",
5151}]
Michael Giuffridad3bc8672018-10-25 22:48:02[diff] [blame]5152
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5153for test_casein test_cases:
5154 problems=[]
5155 filename_filter=lambda x: x.LocalPath().endswith(test_case[
5156"filename_postfix"])
Michael Giuffridad3bc8672018-10-25 22:48:02[diff] [blame]5157
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5158# Check each new line. Can yield false positives in multiline comments, but
5159# easier than trying to parse the XML because messages can have nested
5160# children, and associating message elements with affected lines is hard.
5161for fin input_api.AffectedSourceFiles(filename_filter):
5162for line_num, linein f.ChangedContents():
5163if"<message"in lineor"<!--"in lineor"-->"in line:
5164continue
5165if test_case["incorrect_name"]in line:
Thiago Perrotta099034f2023-06-05 18:10:20[diff] [blame]5166# Chrome for Testing is a special edge case: https://goo.gle/chrome-for-testing#bookmark=id.n1rat320av91
5167if(test_case["correct_name"]=="Chromium"and line.count("Chrome")== line.count("Chrome for Testing")):
5168continue
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5169 problems.append("Incorrect product name in %s:%d"%
5170(f.LocalPath(), line_num))
Michael Giuffridad3bc8672018-10-25 22:48:02[diff] [blame]5171
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5172if problems:
5173 message=(
5174"Strings in %s-branded string files should reference \"%s\", not \"%s\""
5175%(test_case["correct_name"], test_case["correct_name"],
5176 test_case["incorrect_name"]))
5177 all_problems.append(
5178 output_api.PresubmitPromptWarning(message, items=problems))
Michael Giuffridad3bc8672018-10-25 22:48:02[diff] [blame]5179
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5180return all_problems
Michael Giuffridad3bc8672018-10-25 22:48:02[diff] [blame]5181
5182
Saagar Sanghavifceeaae2020-08-12 16:40:36[diff] [blame]5183defCheckForTooLargeFiles(input_api, output_api):
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5184"""Avoid large files, especially binary files, in the repository since
5185 git doesn't scale well for those. They will be in everyone's repo
5186 clones forever, forever making Chromium slower to clone and work
5187 with."""
Daniel Bratell93eb6c62019-04-29 20:13:36[diff] [blame]5188
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5189# Uploading files to cloud storage is not trivial so we don't want
5190# to set the limit too low, but the upper limit for "normal" large
5191# files seems to be 1-2 MB, with a handful around 5-8 MB, so
5192# anything over 20 MB is exceptional.
Bruce Dawsonbb414db2022-12-27 20:21:25[diff] [blame]5193 TOO_LARGE_FILE_SIZE_LIMIT=20*1024*1024
Daniel Bratell93eb6c62019-04-29 20:13:36[diff] [blame]5194
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5195 too_large_files=[]
5196for fin input_api.AffectedFiles():
5197# Check both added and modified files (but not deleted files).
5198if f.Action()in('A','M'):
5199 size= input_api.os_path.getsize(f.AbsoluteLocalPath())
Joe DeBlasio10a832f2023-04-21 20:20:18[diff] [blame]5200if size> TOO_LARGE_FILE_SIZE_LIMIT:
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5201 too_large_files.append("%s: %d bytes"%(f.LocalPath(), size))
Daniel Bratell93eb6c62019-04-29 20:13:36[diff] [blame]5202
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5203if too_large_files:
5204 message=(
5205'Do not commit large files to git since git scales badly for those.\n'
5206+
5207'Instead put the large files in cloud storage and use DEPS to\n'+
5208'fetch them.\n'+'\n'.join(too_large_files))
5209return[
5210 output_api.PresubmitError('Too large files found in commit',
5211 long_text=message+'\n')
5212]
5213else:
5214return[]
Daniel Bratell93eb6c62019-04-29 20:13:36[diff] [blame]5215
Max Morozb47503b2019-08-08 21:03:27[diff] [blame]5216
Saagar Sanghavifceeaae2020-08-12 16:40:36[diff] [blame]5217defCheckFuzzTargetsOnUpload(input_api, output_api):
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5218"""Checks specific for fuzz target sources."""
5219 EXPORTED_SYMBOLS=[
5220'LLVMFuzzerInitialize',
5221'LLVMFuzzerCustomMutator',
5222'LLVMFuzzerCustomCrossOver',
5223'LLVMFuzzerMutate',
5224]
Max Morozb47503b2019-08-08 21:03:27[diff] [blame]5225
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5226 REQUIRED_HEADER='#include "testing/libfuzzer/libfuzzer_exports.h"'
Max Morozb47503b2019-08-08 21:03:27[diff] [blame]5227
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5228defFilterFile(affected_file):
5229"""Ignore libFuzzer source code."""
5230 files_to_check= r'.*fuzz.*\.(h|hpp|hcc|cc|cpp|cxx)$'
Bruce Dawson40fece62022-09-16 19:58:31[diff] [blame]5231 files_to_skip= r"^third_party/libFuzzer"
Max Morozb47503b2019-08-08 21:03:27[diff] [blame]5232
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5233return input_api.FilterSourceFile(affected_file,
5234 files_to_check=[files_to_check],
5235 files_to_skip=[files_to_skip])
Max Morozb47503b2019-08-08 21:03:27[diff] [blame]5236
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5237 files_with_missing_header=[]
5238for fin input_api.AffectedSourceFiles(FilterFile):
5239 contents= input_api.ReadFile(f,'r')
5240if REQUIRED_HEADERin contents:
5241continue
Max Morozb47503b2019-08-08 21:03:27[diff] [blame]5242
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5243if any(symbolin contentsfor symbolin EXPORTED_SYMBOLS):
5244 files_with_missing_header.append(f.LocalPath())
Max Morozb47503b2019-08-08 21:03:27[diff] [blame]5245
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5246ifnot files_with_missing_header:
5247return[]
Max Morozb47503b2019-08-08 21:03:27[diff] [blame]5248
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5249 long_text=(
5250'If you define any of the libFuzzer optional functions (%s), it is '
5251'recommended to add \'%s\' directive. Otherwise, the fuzz target may '
5252'work incorrectly on Mac (crbug.com/687076).\nNote that '
5253'LLVMFuzzerInitialize should not be used, unless your fuzz target needs '
5254'to access command line arguments passed to the fuzzer. Instead, prefer '
5255'static initialization and shared resources as documented in '
5256'https://chromium.googlesource.com/chromium/src/+/main/testing/'
5257'libfuzzer/efficient_fuzzing.md#simplifying-initialization_cleanup.\n'
5258%(', '.join(EXPORTED_SYMBOLS), REQUIRED_HEADER))
Max Morozb47503b2019-08-08 21:03:27[diff] [blame]5259
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5260return[
5261 output_api.PresubmitPromptWarning(message="Missing '%s' in:"%
5262 REQUIRED_HEADER,
5263 items=files_with_missing_header,
5264 long_text=long_text)
5265]
Max Morozb47503b2019-08-08 21:03:27[diff] [blame]5266
5267
Mohamed Heikald048240a2019-11-12 16:57:37[diff] [blame]5268def_CheckNewImagesWarning(input_api, output_api):
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5269"""
5270 Warns authors who add images into the repo to make sure their images are
5271 optimized before committing.
5272 """
5273 images_added=False
5274 image_paths=[]
5275 errors=[]
5276 filter_lambda=lambda x: input_api.FilterSourceFile(
5277 x,
5278 files_to_skip=(('(?i).*test', r'.*\/junit\/')+ input_api.
5279 DEFAULT_FILES_TO_SKIP),
5280 files_to_check=[r'.*\/(drawable|mipmap)'])
5281for fin input_api.AffectedFiles(include_deletes=False,
5282 file_filter=filter_lambda):
5283 local_path= f.LocalPath().lower()
5284if any(
5285 local_path.endswith(extension)
5286for extensionin _IMAGE_EXTENSIONS):
5287 images_added=True
5288 image_paths.append(f)
5289if images_added:
5290 errors.append(
5291 output_api.PresubmitPromptWarning(
5292'It looks like you are trying to commit some images. If these are '
5293'non-test-only images, please make sure to read and apply the tips in '
5294'https://chromium.googlesource.com/chromium/src/+/HEAD/docs/speed/'
5295'binary_size/optimization_advice.md#optimizing-images\nThis check is '
5296'FYI only and will not block your CL on the CQ.', image_paths))
5297return errors
Mohamed Heikald048240a2019-11-12 16:57:37[diff] [blame]5298
5299
Saagar Sanghavifceeaae2020-08-12 16:40:36[diff] [blame]5300defChecksAndroidSpecificOnUpload(input_api, output_api):
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5301"""Groups upload checks that target android code."""
5302 results=[]
5303 results.extend(_CheckAndroidCrLogUsage(input_api, output_api))
5304 results.extend(_CheckAndroidDebuggableBuild(input_api, output_api))
5305 results.extend(_CheckAndroidNewMdpiAssetLocation(input_api, output_api))
5306 results.extend(_CheckAndroidToastUsage(input_api, output_api))
5307 results.extend(_CheckAndroidTestJUnitInheritance(input_api, output_api))
5308 results.extend(_CheckAndroidTestJUnitFrameworkImport(
5309 input_api, output_api))
5310 results.extend(_CheckAndroidTestAnnotationUsage(input_api, output_api))
5311 results.extend(_CheckAndroidWebkitImports(input_api, output_api))
5312 results.extend(_CheckAndroidXmlStyle(input_api, output_api,True))
5313 results.extend(_CheckNewImagesWarning(input_api, output_api))
5314 results.extend(_CheckAndroidNoBannedImports(input_api, output_api))
5315 results.extend(_CheckAndroidInfoBarDeprecation(input_api, output_api))
5316return results
5317
Becky Zhou7c69b50992018-12-10 19:37:57[diff] [blame]5318
Saagar Sanghavifceeaae2020-08-12 16:40:36[diff] [blame]5319defChecksAndroidSpecificOnCommit(input_api, output_api):
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5320"""Groups commit checks that target android code."""
5321 results=[]
5322 results.extend(_CheckAndroidXmlStyle(input_api, output_api,False))
5323return results
dgnaa68d5e2015-06-10 10:08:22[diff] [blame]5324
Chris Hall59f8d0c72020-05-01 07:31:19[diff] [blame]5325# TODO(chrishall): could we additionally match on any path owned by
5326# ui/accessibility/OWNERS ?
5327_ACCESSIBILITY_PATHS=(
Bruce Dawson40fece62022-09-16 19:58:31[diff] [blame]5328 r"^chrome/browser.*/accessibility/",
5329 r"^chrome/browser/extensions/api/automation.*/",
5330 r"^chrome/renderer/extensions/accessibility_.*",
5331 r"^chrome/tests/data/accessibility/",
Katie Dektar58ef07b2022-09-27 13:19:17[diff] [blame]5332 r"^components/services/screen_ai/",
Bruce Dawson40fece62022-09-16 19:58:31[diff] [blame]5333 r"^content/browser/accessibility/",
5334 r"^content/renderer/accessibility/",
5335 r"^content/tests/data/accessibility/",
5336 r"^extensions/renderer/api/automation/",
Katie Dektar58ef07b2022-09-27 13:19:17[diff] [blame]5337 r"^services/accessibility/",
Bruce Dawson40fece62022-09-16 19:58:31[diff] [blame]5338 r"^ui/accessibility/",
5339 r"^ui/views/accessibility/",
Chris Hall59f8d0c72020-05-01 07:31:19[diff] [blame]5340)
5341
Saagar Sanghavifceeaae2020-08-12 16:40:36[diff] [blame]5342defCheckAccessibilityRelnotesField(input_api, output_api):
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5343"""Checks that commits to accessibility code contain an AX-Relnotes field in
5344 their commit message."""
Chris Hall59f8d0c72020-05-01 07:31:19[diff] [blame]5345
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5346defFileFilter(affected_file):
5347 paths= _ACCESSIBILITY_PATHS
5348return input_api.FilterSourceFile(affected_file, files_to_check=paths)
Chris Hall59f8d0c72020-05-01 07:31:19[diff] [blame]5349
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5350# Only consider changes affecting accessibility paths.
5351ifnot any(input_api.AffectedFiles(file_filter=FileFilter)):
5352return[]
Akihiro Ota08108e542020-05-20 15:30:53[diff] [blame]5353
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5354# AX-Relnotes can appear in either the description or the footer.
5355# When searching the description, require 'AX-Relnotes:' to appear at the
5356# beginning of a line.
5357 ax_regex= input_api.re.compile('ax-relnotes[:=]')
5358 description_has_relnotes= any(
5359 ax_regex.match(line)
5360for linein input_api.change.DescriptionText().lower().splitlines())
Chris Hall59f8d0c72020-05-01 07:31:19[diff] [blame]5361
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5362 footer_relnotes= input_api.change.GitFootersFromDescription().get(
5363'AX-Relnotes',[])
5364if description_has_relnotesor footer_relnotes:
5365return[]
Chris Hall59f8d0c72020-05-01 07:31:19[diff] [blame]5366
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5367# TODO(chrishall): link to Relnotes documentation in message.
5368 message=(
5369"Missing 'AX-Relnotes:' field required for accessibility changes"
5370"\n please add 'AX-Relnotes: [release notes].' to describe any "
5371"user-facing changes"
5372"\n otherwise add 'AX-Relnotes: n/a.' if this change has no "
5373"user-facing effects"
5374"\n if this is confusing or annoying then please contact members "
5375"of ui/accessibility/OWNERS.")
5376
5377return[output_api.PresubmitNotifyResult(message)]
dgnaa68d5e2015-06-10 10:08:22[diff] [blame]5378
Mark Schillacie5a0be22022-01-19 00:38:39[diff] [blame]5379
5380_ACCESSIBILITY_EVENTS_TEST_PATH=(
Bruce Dawson40fece62022-09-16 19:58:31[diff] [blame]5381 r"^content/test/data/accessibility/event/.*\.html",
Mark Schillacie5a0be22022-01-19 00:38:39[diff] [blame]5382)
5383
5384_ACCESSIBILITY_TREE_TEST_PATH=(
Aaron Leventhal267119f2023-08-18 22:45:34[diff] [blame]5385 r"^content/test/data/accessibility/accname/"
5386".*-expected-(mac|win|uia-win|auralinux).txt",
5387 r"^content/test/data/accessibility/aria/"
5388".*-expected-(mac|win|uia-win|auralinux).txt",
5389 r"^content/test/data/accessibility/css/"
5390".*-expected-(mac|win|uia-win|auralinux).txt",
5391 r"^content/test/data/accessibility/event/"
5392".*-expected-(mac|win|uia-win|auralinux).txt",
5393 r"^content/test/data/accessibility/html/"
5394".*-expected-(mac|win|uia-win|auralinux).txt",
Mark Schillacie5a0be22022-01-19 00:38:39[diff] [blame]5395)
5396
5397_ACCESSIBILITY_ANDROID_EVENTS_TEST_PATH=(
Bruce Dawson40fece62022-09-16 19:58:31[diff] [blame]5398 r"^.*/WebContentsAccessibilityEventsTest\.java",
Mark Schillacie5a0be22022-01-19 00:38:39[diff] [blame]5399)
5400
5401_ACCESSIBILITY_ANDROID_TREE_TEST_PATH=(
Bruce Dawson40fece62022-09-16 19:58:31[diff] [blame]5402 r"^.*/WebContentsAccessibilityTreeTest\.java",
Mark Schillacie5a0be22022-01-19 00:38:39[diff] [blame]5403)
5404
5405defCheckAccessibilityEventsTestsAreIncludedForAndroid(input_api, output_api):
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5406"""Checks that commits that include a newly added, renamed/moved, or deleted
5407 test in the DumpAccessibilityEventsTest suite also includes a corresponding
5408 change to the Android test."""
Mark Schillacie5a0be22022-01-19 00:38:39[diff] [blame]5409
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5410defFilePathFilter(affected_file):
5411 paths= _ACCESSIBILITY_EVENTS_TEST_PATH
5412return input_api.FilterSourceFile(affected_file, files_to_check=paths)
Mark Schillacie5a0be22022-01-19 00:38:39[diff] [blame]5413
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5414defAndroidFilePathFilter(affected_file):
5415 paths= _ACCESSIBILITY_ANDROID_EVENTS_TEST_PATH
5416return input_api.FilterSourceFile(affected_file, files_to_check=paths)
Mark Schillacie5a0be22022-01-19 00:38:39[diff] [blame]5417
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5418# Only consider changes in the events test data path with html type.
5419ifnot any(
5420 input_api.AffectedFiles(include_deletes=True,
5421 file_filter=FilePathFilter)):
5422return[]
Mark Schillacie5a0be22022-01-19 00:38:39[diff] [blame]5423
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5424# If the commit contains any change to the Android test file, ignore.
5425if any(
5426 input_api.AffectedFiles(include_deletes=True,
5427 file_filter=AndroidFilePathFilter)):
5428return[]
Mark Schillacie5a0be22022-01-19 00:38:39[diff] [blame]5429
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5430# Only consider changes that are adding/renaming or deleting a file
5431 message=[]
5432for fin input_api.AffectedFiles(include_deletes=True,
5433 file_filter=FilePathFilter):
Aaron Leventhal267119f2023-08-18 22:45:34[diff] [blame]5434if f.Action()=='A':
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5435 message=(
Aaron Leventhal267119f2023-08-18 22:45:34[diff] [blame]5436"It appears that you are adding platform expectations for a"
Aaron Leventhal0de81072023-08-21 21:26:52[diff] [blame]5437"\ndump_accessibility_events* test, but have not included"
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5438"\na corresponding change for Android."
Aaron Leventhal267119f2023-08-18 22:45:34[diff] [blame]5439"\nPlease include the test from:"
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5440"\n content/public/android/javatests/src/org/chromium/"
5441"content/browser/accessibility/"
5442"WebContentsAccessibilityEventsTest.java"
5443"\nIf this message is confusing or annoying, please contact"
5444"\nmembers of ui/accessibility/OWNERS.")
Mark Schillacie5a0be22022-01-19 00:38:39[diff] [blame]5445
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5446# If no message was set, return empty.
5447ifnot len(message):
5448return[]
5449
5450return[output_api.PresubmitPromptWarning(message)]
5451
Mark Schillacie5a0be22022-01-19 00:38:39[diff] [blame]5452
5453defCheckAccessibilityTreeTestsAreIncludedForAndroid(input_api, output_api):
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5454"""Checks that commits that include a newly added, renamed/moved, or deleted
5455 test in the DumpAccessibilityTreeTest suite also includes a corresponding
5456 change to the Android test."""
Mark Schillacie5a0be22022-01-19 00:38:39[diff] [blame]5457
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5458defFilePathFilter(affected_file):
5459 paths= _ACCESSIBILITY_TREE_TEST_PATH
5460return input_api.FilterSourceFile(affected_file, files_to_check=paths)
Mark Schillacie5a0be22022-01-19 00:38:39[diff] [blame]5461
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5462defAndroidFilePathFilter(affected_file):
5463 paths= _ACCESSIBILITY_ANDROID_TREE_TEST_PATH
5464return input_api.FilterSourceFile(affected_file, files_to_check=paths)
Mark Schillacie5a0be22022-01-19 00:38:39[diff] [blame]5465
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5466# Only consider changes in the various tree test data paths with html type.
5467ifnot any(
5468 input_api.AffectedFiles(include_deletes=True,
5469 file_filter=FilePathFilter)):
5470return[]
Mark Schillacie5a0be22022-01-19 00:38:39[diff] [blame]5471
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5472# If the commit contains any change to the Android test file, ignore.
5473if any(
5474 input_api.AffectedFiles(include_deletes=True,
5475 file_filter=AndroidFilePathFilter)):
5476return[]
Mark Schillacie5a0be22022-01-19 00:38:39[diff] [blame]5477
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5478# Only consider changes that are adding/renaming or deleting a file
5479 message=[]
5480for fin input_api.AffectedFiles(include_deletes=True,
5481 file_filter=FilePathFilter):
Aaron Leventhal0de81072023-08-21 21:26:52[diff] [blame]5482if f.Action()=='A':
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5483 message=(
Aaron Leventhal0de81072023-08-21 21:26:52[diff] [blame]5484"It appears that you are adding platform expectations for a"
5485"\ndump_accessibility_tree* test, but have not included"
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5486"\na corresponding change for Android."
5487"\nPlease include (or remove) the test from:"
5488"\n content/public/android/javatests/src/org/chromium/"
5489"content/browser/accessibility/"
5490"WebContentsAccessibilityTreeTest.java"
5491"\nIf this message is confusing or annoying, please contact"
5492"\nmembers of ui/accessibility/OWNERS.")
Mark Schillacie5a0be22022-01-19 00:38:39[diff] [blame]5493
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5494# If no message was set, return empty.
5495ifnot len(message):
5496return[]
5497
5498return[output_api.PresubmitPromptWarning(message)]
Mark Schillacie5a0be22022-01-19 00:38:39[diff] [blame]5499
5500
Bruce Dawson33806592022-11-16 01:44:51[diff] [blame]5501defCheckEsLintConfigChanges(input_api, output_api):
5502"""Suggest using "git cl presubmit --files" when .eslintrc.js files are
5503 modified. This is important because enabling an error in .eslintrc.js can
5504 trigger errors in any .js or .ts files in its directory, leading to hidden
5505 presubmit errors."""
5506 results=[]
5507 eslint_filter=lambda f: input_api.FilterSourceFile(
5508 f, files_to_check=[r'.*\.eslintrc\.js$'])
5509for fin input_api.AffectedFiles(include_deletes=False,
5510 file_filter=eslint_filter):
5511 local_dir= input_api.os_path.dirname(f.LocalPath())
5512# Use / characters so that the commands printed work on any OS.
5513 local_dir= local_dir.replace(input_api.os_path.sep,'/')
5514if local_dir:
5515 local_dir+='/'
5516 results.append(
5517 output_api.PresubmitNotifyResult(
5518'%(file)s modified. Consider running \'git cl presubmit --files '
5519'"%(dir)s*.js;%(dir)s*.ts"\' in order to check and fix the affected '
5520'files before landing this change.'%
5521{'file': f.LocalPath(),'dir': local_dir}))
5522return results
5523
5524
seanmccullough4a9356252021-04-08 19:54:09[diff] [blame]5525# string pattern, sequence of strings to show when pattern matches,
5526# error flag. True if match is a presubmit error, otherwise it's a warning.
5527_NON_INCLUSIVE_TERMS=(
5528(
5529# Note that \b pattern in python re is pretty particular. In this
5530# regexp, 'class WhiteList ...' will match, but 'class FooWhiteList
5531# ...' will not. This may require some tweaking to catch these cases
5532# without triggering a lot of false positives. Leaving it naive and
5533# less matchy for now.
seanmccullough56d1e3cf2021-12-03 18:18:32[diff] [blame]5534 r'/\b(?i)((black|white)list|master|slave)\b',# nocheck
seanmccullough4a9356252021-04-08 19:54:09[diff] [blame]5535(
5536'Please don\'t use blacklist, whitelist, '# nocheck
5537'or slave in your',# nocheck
5538'code and make every effort to use other terms. Using "// nocheck"',
5539'"# nocheck" or "<!-- nocheck -->"',
5540'at the end of the offending line will bypass this PRESUBMIT error',
5541'but avoid using this whenever possible. Reach out to',
5542'community@chromium.org if you have questions'),
5543True),)
5544
Saagar Sanghavifceeaae2020-08-12 16:40:36[diff] [blame]5545defChecksCommon(input_api, output_api):
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5546"""Checks common to both upload and commit."""
5547 results=[]
Eric Boren6fd2b932018-01-25 15:05:08[diff] [blame]5548 results.extend(
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5549 input_api.canned_checks.PanProjectChecks(
5550 input_api, output_api, excluded_paths=_EXCLUDED_PATHS))
Eric Boren6fd2b932018-01-25 15:05:08[diff] [blame]5551
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5552 author= input_api.change.author_email
5553if authorand authornotin _KNOWN_ROBOTS:
5554 results.extend(
5555 input_api.canned_checks.CheckAuthorizedAuthor(
5556 input_api, output_api))
marja@chromium.org2299dcf2012-11-15 19:56:24[diff] [blame]5557
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5558 results.extend(
5559 input_api.canned_checks.CheckChangeHasNoTabs(
5560 input_api,
5561 output_api,
5562 source_file_filter=lambda x: x.LocalPath().endswith('.grd')))
5563 results.extend(
5564 input_api.RunTests(
5565 input_api.canned_checks.CheckVPythonSpec(input_api, output_api)))
Edward Lesmesce51df52020-08-04 22:10:17[diff] [blame]5566
Bruce Dawsonc8054482022-03-28 15:33:37[diff] [blame]5567 dirmd='dirmd.bat'if input_api.is_windowselse'dirmd'
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5568 dirmd_bin= input_api.os_path.join(input_api.PresubmitLocalPath(),
Bruce Dawsonc8054482022-03-28 15:33:37[diff] [blame]5569'third_party','depot_tools', dirmd)
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5570 results.extend(
5571 input_api.RunTests(
5572 input_api.canned_checks.CheckDirMetadataFormat(
5573 input_api, output_api, dirmd_bin)))
5574 results.extend(
5575 input_api.canned_checks.CheckOwnersDirMetadataExclusive(
5576 input_api, output_api))
5577 results.extend(
5578 input_api.canned_checks.CheckNoNewMetadataInOwners(
5579 input_api, output_api))
5580 results.extend(
5581 input_api.canned_checks.CheckInclusiveLanguage(
5582 input_api,
5583 output_api,
5584 excluded_directories_relative_path=[
5585'infra','inclusive_language_presubmit_exempt_dirs.txt'
5586],
5587 non_inclusive_terms=_NON_INCLUSIVE_TERMS))
Dirk Prankee3c9c62d2021-05-18 18:35:59[diff] [blame]5588
Aleksey Khoroshilov2978c942022-06-13 16:14:12[diff] [blame]5589 presubmit_py_filter=lambda f: input_api.FilterSourceFile(
Bruce Dawson696963f2022-09-13 01:15:47[diff] [blame]5590 f, files_to_check=[r'.*PRESUBMIT\.py$'])
Aleksey Khoroshilov2978c942022-06-13 16:14:12[diff] [blame]5591for fin input_api.AffectedFiles(include_deletes=False,
5592 file_filter=presubmit_py_filter):
5593 full_path= input_api.os_path.dirname(f.AbsoluteLocalPath())
5594 test_file= input_api.os_path.join(full_path,'PRESUBMIT_test.py')
5595# The PRESUBMIT.py file (and the directory containing it) might have
5596# been affected by being moved or removed, so only try to run the tests
5597# if they still exist.
5598ifnot input_api.os_path.exists(test_file):
5599continue
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5600
Aleksey Khoroshilov2978c942022-06-13 16:14:12[diff] [blame]5601 results.extend(
5602 input_api.canned_checks.RunUnitTestsInDirectory(
5603 input_api,
5604 output_api,
5605 full_path,
Takuto Ikuta40def482023-06-02 02:23:49[diff] [blame]5606 files_to_check=[r'^PRESUBMIT_test\.py$']))
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5607return results
maruel@chromium.org1f7b4172010-01-28 01:17:34[diff] [blame]5608
maruel@chromium.orgb337cb5b2011-01-23 21:24:05[diff] [blame]5609
Saagar Sanghavifceeaae2020-08-12 16:40:36[diff] [blame]5610defCheckPatchFiles(input_api, output_api):
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5611 problems=[
5612 f.LocalPath()for fin input_api.AffectedFiles()
5613if f.LocalPath().endswith(('.orig','.rej'))
5614]
5615# Cargo.toml.orig files are part of third-party crates downloaded from
5616# crates.io and should be included.
5617 problems=[ffor fin problemsifnot f.endswith('Cargo.toml.orig')]
5618if problems:
5619return[
5620 output_api.PresubmitError("Don't commit .rej and .orig files.",
5621 problems)
5622]
5623else:
5624return[]
enne@chromium.orgb8079ae4a2012-12-05 19:56:49[diff] [blame]5625
5626
Saagar Sanghavifceeaae2020-08-12 16:40:36[diff] [blame]5627defCheckBuildConfigMacrosWithoutInclude(input_api, output_api):
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5628# Excludes OS_CHROMEOS, which is not defined in build_config.h.
5629 macro_re= input_api.re.compile(
5630 r'^\s*#(el)?if.*\bdefined\(((COMPILER_|ARCH_CPU_|WCHAR_T_IS_)[^)]*)')
5631 include_re= input_api.re.compile(r'^#include\s+"build/build_config.h"',
5632 input_api.re.MULTILINE)
5633 extension_re= input_api.re.compile(r'\.[a-z]+$')
5634 errors=[]
Bruce Dawsonf7679202022-08-09 20:24:00[diff] [blame]5635 config_h_file= input_api.os_path.join('build','build_config.h')
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5636for fin input_api.AffectedFiles(include_deletes=False):
Bruce Dawsonf7679202022-08-09 20:24:00[diff] [blame]5637# The build-config macros are allowed to be used in build_config.h
5638# without including itself.
5639if f.LocalPath()== config_h_file:
5640continue
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5641ifnot f.LocalPath().endswith(
5642('.h','.c','.cc','.cpp','.m','.mm')):
5643continue
5644 found_line_number=None
5645 found_macro=None
5646 all_lines= input_api.ReadFile(f,'r').splitlines()
5647for line_num, linein enumerate(all_lines):
5648 match= macro_re.search(line)
5649if match:
5650 found_line_number= line_num
5651 found_macro= match.group(2)
5652break
5653ifnot found_line_number:
5654continue
Kent Tamura5a8755d2017-06-29 23:37:07[diff] [blame]5655
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5656 found_include_line=-1
5657for line_num, linein enumerate(all_lines):
5658if include_re.search(line):
5659 found_include_line= line_num
5660break
5661if found_include_line>=0and found_include_line< found_line_number:
5662continue
Kent Tamura5a8755d2017-06-29 23:37:07[diff] [blame]5663
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5664ifnot f.LocalPath().endswith('.h'):
5665 primary_header_path= extension_re.sub('.h', f.AbsoluteLocalPath())
5666try:
5667 content= input_api.ReadFile(primary_header_path,'r')
5668if include_re.search(content):
5669continue
5670exceptIOError:
5671pass
5672 errors.append('%s:%d %s macro is used without first including build/'
5673'build_config.h.'%
5674(f.LocalPath(), found_line_number, found_macro))
5675if errors:
5676return[output_api.PresubmitPromptWarning('\n'.join(errors))]
5677return[]
Kent Tamura5a8755d2017-06-29 23:37:07[diff] [blame]5678
5679
Lei Zhang1c12a22f2021-05-12 11:28:45[diff] [blame]5680defCheckForSuperfluousStlIncludesInHeaders(input_api, output_api):
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5681 stl_include_re= input_api.re.compile(r'^#include\s+<('
5682 r'algorithm|'
5683 r'array|'
5684 r'limits|'
5685 r'list|'
5686 r'map|'
5687 r'memory|'
5688 r'queue|'
5689 r'set|'
5690 r'string|'
5691 r'unordered_map|'
5692 r'unordered_set|'
5693 r'utility|'
5694 r'vector)>')
5695 std_namespace_re= input_api.re.compile(r'std::')
5696 errors=[]
5697for fin input_api.AffectedFiles():
5698ifnot_IsCPlusPlusHeaderFile(input_api, f.LocalPath()):
5699continue
Lei Zhang1c12a22f2021-05-12 11:28:45[diff] [blame]5700
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5701 uses_std_namespace=False
5702 has_stl_include=False
5703for linein f.NewContents():
5704if has_stl_includeand uses_std_namespace:
5705break
Lei Zhang1c12a22f2021-05-12 11:28:45[diff] [blame]5706
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5707ifnot has_stl_includeand stl_include_re.search(line):
5708 has_stl_include=True
5709continue
Lei Zhang1c12a22f2021-05-12 11:28:45[diff] [blame]5710
Bruce Dawson4a5579a2022-04-08 17:11:36[diff] [blame]5711ifnot uses_std_namespaceand(std_namespace_re.search(line)
5712or'no-std-usage-because-pch-file'in line):
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5713 uses_std_namespace=True
5714continue
Lei Zhang1c12a22f2021-05-12 11:28:45[diff] [blame]5715
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5716if has_stl_includeandnot uses_std_namespace:
5717 errors.append(
5718'%s: Includes STL header(s) but does not reference std::'%
5719 f.LocalPath())
5720if errors:
5721return[output_api.PresubmitPromptWarning('\n'.join(errors))]
5722return[]
Lei Zhang1c12a22f2021-05-12 11:28:45[diff] [blame]5723
5724
Xiaohan Wang42d96c22022-01-20 17:23:11[diff] [blame]5725def_CheckForDeprecatedOSMacrosInFile(input_api, f):
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5726"""Check for sensible looking, totally invalid OS macros."""
5727 preprocessor_statement= input_api.re.compile(r'^\s*#')
5728 os_macro= input_api.re.compile(r'defined\(OS_([^)]+)\)')
5729 results=[]
5730for lnum, linein f.ChangedContents():
5731if preprocessor_statement.search(line):
5732for matchin os_macro.finditer(line):
5733 results.append(
5734' %s:%d: %s'%
5735(f.LocalPath(), lnum,'defined(OS_'+ match.group(1)+
5736') -> BUILDFLAG(IS_'+ match.group(1)+')'))
5737return results
dbeam@chromium.orgb00342e7f2013-03-26 16:21:54[diff] [blame]5738
5739
Xiaohan Wang42d96c22022-01-20 17:23:11[diff] [blame]5740defCheckForDeprecatedOSMacros(input_api, output_api):
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5741"""Check all affected files for invalid OS macros."""
5742 bad_macros=[]
Bruce Dawsonf7679202022-08-09 20:24:00[diff] [blame]5743# The OS_ macros are allowed to be used in build/build_config.h.
5744 config_h_file= input_api.os_path.join('build','build_config.h')
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5745for fin input_api.AffectedSourceFiles(None):
Bruce Dawsonf7679202022-08-09 20:24:00[diff] [blame]5746ifnot f.LocalPath().endswith(('.py','.js','.html','.css','.md')) \
5747and f.LocalPath()!= config_h_file:
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5748 bad_macros.extend(_CheckForDeprecatedOSMacrosInFile(input_api, f))
dbeam@chromium.orgb00342e7f2013-03-26 16:21:54[diff] [blame]5749
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5750ifnot bad_macros:
5751return[]
dbeam@chromium.orgb00342e7f2013-03-26 16:21:54[diff] [blame]5752
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5753return[
5754 output_api.PresubmitError(
5755'OS macros have been deprecated. Please use BUILDFLAGs instead (still '
5756'defined in build_config.h):', bad_macros)
5757]
dbeam@chromium.orgb00342e7f2013-03-26 16:21:54[diff] [blame]5758
lliabraa35bab3932014-10-01 12:16:44[diff] [blame]5759
5760def_CheckForInvalidIfDefinedMacrosInFile(input_api, f):
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5761"""Check all affected files for invalid "if defined" macros."""
5762 ALWAYS_DEFINED_MACROS=(
5763"TARGET_CPU_PPC",
5764"TARGET_CPU_PPC64",
5765"TARGET_CPU_68K",
5766"TARGET_CPU_X86",
5767"TARGET_CPU_ARM",
5768"TARGET_CPU_MIPS",
5769"TARGET_CPU_SPARC",
5770"TARGET_CPU_ALPHA",
5771"TARGET_IPHONE_SIMULATOR",
5772"TARGET_OS_EMBEDDED",
5773"TARGET_OS_IPHONE",
5774"TARGET_OS_MAC",
5775"TARGET_OS_UNIX",
5776"TARGET_OS_WIN32",
5777)
5778 ifdef_macro= input_api.re.compile(
5779 r'^\s*#.*(?:ifdef\s|defined\()([^\s\)]+)')
5780 results=[]
5781for lnum, linein f.ChangedContents():
5782for matchin ifdef_macro.finditer(line):
5783if match.group(1)in ALWAYS_DEFINED_MACROS:
5784 always_defined=' %s is always defined. '% match.group(1)
5785 did_you_mean='Did you mean \'#if %s\'?'% match.group(1)
5786 results.append(
5787' %s:%d %s\n\t%s'%
5788(f.LocalPath(), lnum, always_defined, did_you_mean))
5789return results
lliabraa35bab3932014-10-01 12:16:44[diff] [blame]5790
5791
Saagar Sanghavifceeaae2020-08-12 16:40:36[diff] [blame]5792defCheckForInvalidIfDefinedMacros(input_api, output_api):
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5793"""Check all affected files for invalid "if defined" macros."""
5794 bad_macros=[]
5795 skipped_paths=['third_party/sqlite/','third_party/abseil-cpp/']
5796for fin input_api.AffectedFiles():
5797if any([f.LocalPath().startswith(path)for pathin skipped_paths]):
5798continue
5799if f.LocalPath().endswith(('.h','.c','.cc','.m','.mm')):
5800 bad_macros.extend(
5801_CheckForInvalidIfDefinedMacrosInFile(input_api, f))
lliabraa35bab3932014-10-01 12:16:44[diff] [blame]5802
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5803ifnot bad_macros:
5804return[]
lliabraa35bab3932014-10-01 12:16:44[diff] [blame]5805
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5806return[
5807 output_api.PresubmitError(
5808'Found ifdef check on always-defined macro[s]. Please fix your code\n'
5809'or check the list of ALWAYS_DEFINED_MACROS in src/PRESUBMIT.py.',
5810 bad_macros)
5811]
lliabraa35bab3932014-10-01 12:16:44[diff] [blame]5812
5813
Saagar Sanghavifceeaae2020-08-12 16:40:36[diff] [blame]5814defCheckForIPCRules(input_api, output_api):
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5815"""Check for same IPC rules described in
5816 http://www.chromium.org/Home/chromium-security/education/security-tips-for-ipc
5817 """
5818 base_pattern= r'IPC_ENUM_TRAITS\('
5819 inclusion_pattern= input_api.re.compile(r'(%s)'% base_pattern)
5820 comment_pattern= input_api.re.compile(r'//.*(%s)'% base_pattern)
mlamouria82272622014-09-16 18:45:04[diff] [blame]5821
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5822 problems=[]
5823for fin input_api.AffectedSourceFiles(None):
5824 local_path= f.LocalPath()
5825ifnot local_path.endswith('.h'):
5826continue
5827for line_number, linein f.ChangedContents():
5828if inclusion_pattern.search(
5829 line)andnot comment_pattern.search(line):
5830 problems.append('%s:%d\n %s'%
5831(local_path, line_number, line.strip()))
mlamouria82272622014-09-16 18:45:04[diff] [blame]5832
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5833if problems:
5834return[
5835 output_api.PresubmitPromptWarning(_IPC_ENUM_TRAITS_DEPRECATED,
5836 problems)
5837]
5838else:
5839return[]
mlamouria82272622014-09-16 18:45:04[diff] [blame]5840
dbeam@chromium.orgb00342e7f2013-03-26 16:21:54[diff] [blame]5841
Saagar Sanghavifceeaae2020-08-12 16:40:36[diff] [blame]5842defCheckForLongPathnames(input_api, output_api):
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5843"""Check to make sure no files being submitted have long paths.
5844 This causes issues on Windows.
5845 """
5846 problems=[]
5847for fin input_api.AffectedTestableFiles():
5848 local_path= f.LocalPath()
5849# Windows has a path limit of 260 characters. Limit path length to 200 so
5850# that we have some extra for the prefix on dev machines and the bots.
5851if len(local_path)>200:
5852 problems.append(local_path)
Stephen Martinis97a394142018-06-07 23:06:05[diff] [blame]5853
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5854if problems:
5855return[output_api.PresubmitError(_LONG_PATH_ERROR, problems)]
5856else:
5857return[]
Stephen Martinis97a394142018-06-07 23:06:05[diff] [blame]5858
5859
Saagar Sanghavifceeaae2020-08-12 16:40:36[diff] [blame]5860defCheckForIncludeGuards(input_api, output_api):
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5861"""Check that header files have proper guards against multiple inclusion.
5862 If a file should not have such guards (and it probably should) then it
Bruce Dawson4a5579a2022-04-08 17:11:36[diff] [blame]5863 should include the string "no-include-guard-because-multiply-included" or
5864 "no-include-guard-because-pch-file".
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5865 """
Daniel Bratell8ba52722018-03-02 16:06:14[diff] [blame]5866
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5867def is_chromium_header_file(f):
5868# We only check header files under the control of the Chromium
5869# project. That is, those outside third_party apart from
5870# third_party/blink.
5871# We also exclude *_message_generator.h headers as they use
5872# include guards in a special, non-typical way.
5873 file_with_path= input_api.os_path.normpath(f.LocalPath())
5874return(file_with_path.endswith('.h')
5875andnot file_with_path.endswith('_message_generator.h')
Bruce Dawson4c4c2922022-05-02 18:07:33[diff] [blame]5876andnot file_with_path.endswith('com_imported_mstscax.h')
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5877and(not file_with_path.startswith('third_party')
5878or file_with_path.startswith(
5879 input_api.os_path.join('third_party','blink'))))
Daniel Bratell8ba52722018-03-02 16:06:14[diff] [blame]5880
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5881def replace_special_with_underscore(string):
5882return input_api.re.sub(r'[+\\/.-]','_', string)
Daniel Bratell8ba52722018-03-02 16:06:14[diff] [blame]5883
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5884 errors=[]
Daniel Bratell8ba52722018-03-02 16:06:14[diff] [blame]5885
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5886for fin input_api.AffectedSourceFiles(is_chromium_header_file):
5887 guard_name=None
5888 guard_line_number=None
5889 seen_guard_end=False
Daniel Bratell8ba52722018-03-02 16:06:14[diff] [blame]5890
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5891 file_with_path= input_api.os_path.normpath(f.LocalPath())
5892 base_file_name= input_api.os_path.splitext(
5893 input_api.os_path.basename(file_with_path))[0]
5894 upper_base_file_name= base_file_name.upper()
Daniel Bratell8ba52722018-03-02 16:06:14[diff] [blame]5895
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5896 expected_guard= replace_special_with_underscore(
5897 file_with_path.upper()+'_')
Daniel Bratell8ba52722018-03-02 16:06:14[diff] [blame]5898
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5899# For "path/elem/file_name.h" we should really only accept
5900# PATH_ELEM_FILE_NAME_H_ per coding style. Unfortunately there
5901# are too many (1000+) files with slight deviations from the
5902# coding style. The most important part is that the include guard
5903# is there, and that it's unique, not the name so this check is
5904# forgiving for existing files.
5905#
5906# As code becomes more uniform, this could be made stricter.
Daniel Bratell8ba52722018-03-02 16:06:14[diff] [blame]5907
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5908 guard_name_pattern_list=[
5909# Anything with the right suffix (maybe with an extra _).
5910 r'\w+_H__?',
Daniel Bratell8ba52722018-03-02 16:06:14[diff] [blame]5911
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5912# To cover include guards with old Blink style.
5913 r'\w+_h',
Daniel Bratell8ba52722018-03-02 16:06:14[diff] [blame]5914
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5915# Anything including the uppercase name of the file.
5916 r'\w*'+ input_api.re.escape(
5917 replace_special_with_underscore(upper_base_file_name))+
5918 r'\w*',
5919]
5920 guard_name_pattern='|'.join(guard_name_pattern_list)
5921 guard_pattern= input_api.re.compile(r'#ifndef\s+('+
5922 guard_name_pattern+')')
Daniel Bratell8ba52722018-03-02 16:06:14[diff] [blame]5923
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5924for line_number, linein enumerate(f.NewContents()):
Bruce Dawson4a5579a2022-04-08 17:11:36[diff] [blame]5925if('no-include-guard-because-multiply-included'in line
5926or'no-include-guard-because-pch-file'in line):
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5927 guard_name='DUMMY'# To not trigger check outside the loop.
5928break
Daniel Bratell8ba52722018-03-02 16:06:14[diff] [blame]5929
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5930if guard_nameisNone:
5931 match= guard_pattern.match(line)
5932if match:
5933 guard_name= match.group(1)
5934 guard_line_number= line_number
Daniel Bratell8ba52722018-03-02 16:06:14[diff] [blame]5935
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5936# We allow existing files to use include guards whose names
5937# don't match the chromium style guide, but new files should
5938# get it right.
Bruce Dawson6cc154e2022-04-12 20:39:49[diff] [blame]5939if guard_name!= expected_guard:
Bruce Dawson95eb7562022-09-14 15:27:16[diff] [blame]5940if f.Action()=='A':# If file was just 'A'dded
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5941 errors.append(
5942 output_api.PresubmitPromptWarning(
5943'Header using the wrong include guard name %s'
5944% guard_name,[
5945'%s:%d'%
5946(f.LocalPath(), line_number+1)
5947],'Expected: %r\nFound: %r'%
5948(expected_guard, guard_name)))
5949else:
5950# The line after #ifndef should have a #define of the same name.
5951if line_number== guard_line_number+1:
5952 expected_line='#define %s'% guard_name
5953if line!= expected_line:
5954 errors.append(
5955 output_api.PresubmitPromptWarning(
5956'Missing "%s" for include guard'%
5957 expected_line,
5958['%s:%d'%(f.LocalPath(), line_number+1)],
5959'Expected: %r\nGot: %r'%
5960(expected_line, line)))
Daniel Bratell8ba52722018-03-02 16:06:14[diff] [blame]5961
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5962ifnot seen_guard_endand line=='#endif // %s'% guard_name:
5963 seen_guard_end=True
5964elif seen_guard_end:
5965if line.strip()!='':
5966 errors.append(
5967 output_api.PresubmitPromptWarning(
5968'Include guard %s not covering the whole file'
5969%(guard_name),[f.LocalPath()]))
5970break# Nothing else to check and enough to warn once.
Daniel Bratell8ba52722018-03-02 16:06:14[diff] [blame]5971
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5972if guard_nameisNone:
5973 errors.append(
5974 output_api.PresubmitPromptWarning(
Bruce Dawson32114b62022-04-11 16:45:49[diff] [blame]5975'Missing include guard in %s\n'
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5976'Recommended name: %s\n'
5977'This check can be disabled by having the string\n'
Bruce Dawson4a5579a2022-04-08 17:11:36[diff] [blame]5978'"no-include-guard-because-multiply-included" or\n'
5979'"no-include-guard-because-pch-file" in the header.'
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5980%(f.LocalPath(), expected_guard)))
5981
5982return errors
Daniel Bratell8ba52722018-03-02 16:06:14[diff] [blame]5983
5984
Saagar Sanghavifceeaae2020-08-12 16:40:36[diff] [blame]5985defCheckForWindowsLineEndings(input_api, output_api):
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5986"""Check source code and known ascii text files for Windows style line
5987 endings.
5988 """
Bruce Dawson5efbdc652022-04-11 19:29:51[diff] [blame]5989 known_text_files= r'.*\.(txt|html|htm|py|gyp|gypi|gn|isolate|icon)$'
mostynbb639aca52015-01-07 20:31:23[diff] [blame]5990
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5991 file_inclusion_pattern=(known_text_files,
5992 r'.+%s'% _IMPLEMENTATION_EXTENSIONS,
5993 r'.+%s'% _HEADER_EXTENSIONS)
mostynbb639aca52015-01-07 20:31:23[diff] [blame]5994
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]5995 problems=[]
5996 source_file_filter=lambda f: input_api.FilterSourceFile(
5997 f, files_to_check=file_inclusion_pattern, files_to_skip=None)
5998for fin input_api.AffectedSourceFiles(source_file_filter):
Bruce Dawson5efbdc652022-04-11 19:29:51[diff] [blame]5999# Ignore test files that contain crlf intentionally.
6000if f.LocalPath().endswith('crlf.txt'):
Daniel Chenga37c03db2022-05-12 17:20:34[diff] [blame]6001continue
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]6002 include_file=False
6003for linein input_api.ReadFile(f,'r').splitlines(True):
6004if line.endswith('\r\n'):
6005 include_file=True
6006if include_file:
6007 problems.append(f.LocalPath())
mostynbb639aca52015-01-07 20:31:23[diff] [blame]6008
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]6009if problems:
6010return[
6011 output_api.PresubmitPromptWarning(
6012'Are you sure that you want '
6013'these files to contain Windows style line endings?\n'+
6014'\n'.join(problems))
6015]
mostynbb639aca52015-01-07 20:31:23[diff] [blame]6016
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]6017return[]
6018
mostynbb639aca52015-01-07 20:31:23[diff] [blame]6019
Evan Stade6cfc964c12021-05-18 20:21:16[diff] [blame]6020defCheckIconFilesForLicenseHeaders(input_api, output_api):
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]6021"""Check that .icon files (which are fragments of C++) have license headers.
6022 """
Evan Stade6cfc964c12021-05-18 20:21:16[diff] [blame]6023
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]6024 icon_files=(r'.*\.icon$',)
Evan Stade6cfc964c12021-05-18 20:21:16[diff] [blame]6025
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]6026 icons=lambda x: input_api.FilterSourceFile(x, files_to_check=icon_files)
6027return input_api.canned_checks.CheckLicense(input_api,
6028 output_api,
6029 source_file_filter=icons)
6030
Evan Stade6cfc964c12021-05-18 20:21:16[diff] [blame]6031
Jose Magana2b456f22021-03-09 23:26:40[diff] [blame]6032defCheckForUseOfChromeAppsDeprecations(input_api, output_api):
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]6033"""Check source code for use of Chrome App technologies being
6034 deprecated.
6035 """
Jose Magana2b456f22021-03-09 23:26:40[diff] [blame]6036
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]6037def_CheckForDeprecatedTech(input_api,
6038 output_api,
6039 detection_list,
6040 files_to_check=None,
6041 files_to_skip=None):
Jose Magana2b456f22021-03-09 23:26:40[diff] [blame]6042
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]6043if(files_to_checkor files_to_skip):
6044 source_file_filter=lambda f: input_api.FilterSourceFile(
6045 f, files_to_check=files_to_check, files_to_skip=files_to_skip)
6046else:
6047 source_file_filter=None
6048
6049 problems=[]
6050
6051for fin input_api.AffectedSourceFiles(source_file_filter):
6052if f.Action()=='D':
6053continue
6054for _, linein f.ChangedContents():
6055if any(detectin linefor detectin detection_list):
6056 problems.append(f.LocalPath())
6057
6058return problems
6059
6060# to avoid this presubmit script triggering warnings
6061 files_to_skip=['PRESUBMIT.py','PRESUBMIT_test.py']
Jose Magana2b456f22021-03-09 23:26:40[diff] [blame]6062
6063 problems=[]
6064
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]6065# NMF: any files with extensions .nmf or NMF
6066 _NMF_FILES= r'\.(nmf|NMF)$'
6067 problems+=_CheckForDeprecatedTech(
6068 input_api,
6069 output_api,
6070 detection_list=[''],# any change to the file will trigger warning
6071 files_to_check=[r'.+%s'% _NMF_FILES])
Jose Magana2b456f22021-03-09 23:26:40[diff] [blame]6072
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]6073# MANIFEST: any manifest.json that in its diff includes "app":
6074 _MANIFEST_FILES= r'(manifest\.json)$'
6075 problems+=_CheckForDeprecatedTech(
6076 input_api,
6077 output_api,
6078 detection_list=['"app":'],
6079 files_to_check=[r'.*%s'% _MANIFEST_FILES])
Jose Magana2b456f22021-03-09 23:26:40[diff] [blame]6080
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]6081# NaCl / PNaCl: any file that in its diff contains the strings in the list
6082 problems+=_CheckForDeprecatedTech(
6083 input_api,
6084 output_api,
6085 detection_list=['config=nacl','enable-nacl','cpu=pnacl','nacl_io'],
Bruce Dawson40fece62022-09-16 19:58:31[diff] [blame]6086 files_to_skip=files_to_skip+[r"^native_client_sdk/"])
Jose Magana2b456f22021-03-09 23:26:40[diff] [blame]6087
Gao Shenga79ebd42022-08-08 17:25:59[diff] [blame]6088# PPAPI: any C/C++ file that in its diff includes a ppapi library
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]6089 problems+=_CheckForDeprecatedTech(
6090 input_api,
6091 output_api,
6092 detection_list=['#include "ppapi','#include <ppapi'],
6093 files_to_check=(r'.+%s'% _HEADER_EXTENSIONS,
6094 r'.+%s'% _IMPLEMENTATION_EXTENSIONS),
Bruce Dawson40fece62022-09-16 19:58:31[diff] [blame]6095 files_to_skip=[r"^ppapi/"])
Jose Magana2b456f22021-03-09 23:26:40[diff] [blame]6096
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]6097if problems:
6098return[
6099 output_api.PresubmitPromptWarning(
6100'You are adding/modifying code'
6101'related to technologies which will soon be deprecated (Chrome Apps, NaCl,'
6102' PNaCl, PPAPI). See this blog post for more details:\n'
6103'https://blog.chromium.org/2020/08/changes-to-chrome-app-support-timeline.html\n'
6104'and this documentation for options to replace these technologies:\n'
6105'https://developer.chrome.com/docs/apps/migration/\n'+
6106'\n'.join(problems))
6107]
Jose Magana2b456f22021-03-09 23:26:40[diff] [blame]6108
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]6109return[]
Jose Magana2b456f22021-03-09 23:26:40[diff] [blame]6110
mostynbb639aca52015-01-07 20:31:23[diff] [blame]6111
Saagar Sanghavifceeaae2020-08-12 16:40:36[diff] [blame]6112defCheckSyslogUseWarningOnUpload(input_api, output_api, src_file_filter=None):
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]6113"""Checks that all source files use SYSLOG properly."""
6114 syslog_files=[]
6115for fin input_api.AffectedSourceFiles(src_file_filter):
6116for line_number, linein f.ChangedContents():
6117if'SYSLOG'in line:
6118 syslog_files.append(f.LocalPath()+':'+ str(line_number))
pastarmovj032ba5bc2017-01-12 10:41:56[diff] [blame]6119
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]6120if syslog_files:
6121return[
6122 output_api.PresubmitPromptWarning(
6123'Please make sure there are no privacy sensitive bits of data in SYSLOG'
6124' calls.\nFiles to check:\n',
6125 items=syslog_files)
6126]
6127return[]
pastarmovj89f7ee12016-09-20 14:58:13[diff] [blame]6128
6129
maruel@chromium.org1f7b4172010-01-28 01:17:34[diff] [blame]6130defCheckChangeOnUpload(input_api, output_api):
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]6131if input_api.version<[2,0,0]:
6132return[
6133 output_api.PresubmitError(
6134"Your depot_tools is out of date. "
6135"This PRESUBMIT.py requires at least presubmit_support version 2.0.0, "
6136"but your version is %d.%d.%d"% tuple(input_api.version))
6137]
6138 results=[]
6139 results.extend(
6140 input_api.canned_checks.CheckPatchFormatted(input_api, output_api))
6141return results
maruel@chromium.orgca8d19842009-02-19 16:33:12[diff] [blame]6142
6143
6144defCheckChangeOnCommit(input_api, output_api):
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]6145if input_api.version<[2,0,0]:
6146return[
6147 output_api.PresubmitError(
6148"Your depot_tools is out of date. "
6149"This PRESUBMIT.py requires at least presubmit_support version 2.0.0, "
6150"but your version is %d.%d.%d"% tuple(input_api.version))
6151]
Saagar Sanghavifceeaae2020-08-12 16:40:36[diff] [blame]6152
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]6153 results=[]
6154# Make sure the tree is 'open'.
6155 results.extend(
6156 input_api.canned_checks.CheckTreeIsOpen(
6157 input_api,
6158 output_api,
6159 json_url='http://chromium-status.appspot.com/current?format=json'))
maruel@chromium.org806e98e2010-03-19 17:49:27[diff] [blame]6160
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]6161 results.extend(
6162 input_api.canned_checks.CheckPatchFormatted(input_api, output_api))
6163 results.extend(
6164 input_api.canned_checks.CheckChangeHasBugField(input_api, output_api))
6165 results.extend(
6166 input_api.canned_checks.CheckChangeHasNoUnwantedTags(
6167 input_api, output_api))
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]6168return results
Mustafa Emre Acer29bf6ac92018-07-30 21:42:14[diff] [blame]6169
6170
Saagar Sanghavifceeaae2020-08-12 16:40:36[diff] [blame]6171defCheckStrings(input_api, output_api):
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]6172"""Check string ICU syntax validity and if translation screenshots exist."""
6173# Skip translation screenshots check if a SkipTranslationScreenshotsCheck
6174# footer is set to true.
6175 git_footers= input_api.change.GitFootersFromDescription()
6176 skip_screenshot_check_footer=[
6177 footer.lower()for footerin git_footers.get(
6178 u'Skip-Translation-Screenshots-Check',[])
6179]
6180 run_screenshot_check= u'true'notin skip_screenshot_check_footer
Edward Lesmesf7c5c6d2020-05-14 23:30:02[diff] [blame]6181
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]6182import os
6183import re
6184import sys
6185from ioimportStringIO
Mustafa Emre Acer29bf6ac92018-07-30 21:42:14[diff] [blame]6186
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]6187 new_or_added_paths= set(f.LocalPath()for fin input_api.AffectedFiles()
6188if(f.Action()=='A'or f.Action()=='M'))
6189 removed_paths= set(f.LocalPath()
6190for fin input_api.AffectedFiles(include_deletes=True)
6191if f.Action()=='D')
Mustafa Emre Acer29bf6ac92018-07-30 21:42:14[diff] [blame]6192
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]6193 affected_grds=[
6194 ffor fin input_api.AffectedFiles()
6195if f.LocalPath().endswith(('.grd','.grdp'))
6196]
6197 affected_grds=[
6198 ffor fin affected_grdsifnot'testdata'in f.LocalPath()
6199]
6200ifnot affected_grds:
6201return[]
meacer8c0d3832019-12-26 21:46:16[diff] [blame]6202
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]6203 affected_png_paths=[
6204 f.AbsoluteLocalPath()for fin input_api.AffectedFiles()
6205if(f.LocalPath().endswith('.png'))
6206]
Mustafa Emre Acer29bf6ac92018-07-30 21:42:14[diff] [blame]6207
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]6208# Check for screenshots. Developers can upload screenshots using
6209# tools/translation/upload_screenshots.py which finds and uploads
6210# images associated with .grd files (e.g. test_grd/IDS_STRING.png for the
6211# message named IDS_STRING in test.grd) and produces a .sha1 file (e.g.
6212# test_grd/IDS_STRING.png.sha1) for each png when the upload is successful.
6213#
6214# The logic here is as follows:
6215#
6216# - If the CL has a .png file under the screenshots directory for a grd
6217# file, warn the developer. Actual images should never be checked into the
6218# Chrome repo.
6219#
6220# - If the CL contains modified or new messages in grd files and doesn't
6221# contain the corresponding .sha1 files, warn the developer to add images
6222# and upload them via tools/translation/upload_screenshots.py.
6223#
6224# - If the CL contains modified or new messages in grd files and the
6225# corresponding .sha1 files, everything looks good.
6226#
6227# - If the CL contains removed messages in grd files but the corresponding
6228# .sha1 files aren't removed, warn the developer to remove them.
6229 unnecessary_screenshots=[]
Jens Mueller054652c2023-05-10 15:12:30[diff] [blame]6230 invalid_sha1=[]
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]6231 missing_sha1=[]
Bruce Dawson55776c42022-12-09 17:23:47[diff] [blame]6232 missing_sha1_modified=[]
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]6233 unnecessary_sha1_files=[]
Mustafa Emre Acer29bf6ac92018-07-30 21:42:14[diff] [blame]6234
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]6235# This checks verifies that the ICU syntax of messages this CL touched is
6236# valid, and reports any found syntax errors.
6237# Without this presubmit check, ICU syntax errors in Chromium strings can land
6238# without developers being aware of them. Later on, such ICU syntax errors
6239# break message extraction for translation, hence would block Chromium
6240# translations until they are fixed.
6241 icu_syntax_errors=[]
Jens Mueller054652c2023-05-10 15:12:30[diff] [blame]6242 sha1_pattern= input_api.re.compile(r'^[a-fA-F0-9]{40}$',
6243 input_api.re.MULTILINE)
Mustafa Emre Acer29bf6ac92018-07-30 21:42:14[diff] [blame]6244
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]6245def_CheckScreenshotAdded(screenshots_dir, message_id):
6246 sha1_path= input_api.os_path.join(screenshots_dir,
6247 message_id+'.png.sha1')
6248if sha1_pathnotin new_or_added_paths:
6249 missing_sha1.append(sha1_path)
Jens Mueller054652c2023-05-10 15:12:30[diff] [blame]6250elifnot_CheckValidSha1(sha1_path):
Sam Maierb926c58c2023-08-08 19:58:25[diff] [blame]6251 invalid_sha1.append(sha1_path)
Mustafa Emre Acer29bf6ac92018-07-30 21:42:14[diff] [blame]6252
Bruce Dawson55776c42022-12-09 17:23:47[diff] [blame]6253def_CheckScreenshotModified(screenshots_dir, message_id):
6254 sha1_path= input_api.os_path.join(screenshots_dir,
6255 message_id+'.png.sha1')
6256if sha1_pathnotin new_or_added_paths:
6257 missing_sha1_modified.append(sha1_path)
Jens Mueller054652c2023-05-10 15:12:30[diff] [blame]6258elifnot_CheckValidSha1(sha1_path):
Sam Maierb926c58c2023-08-08 19:58:25[diff] [blame]6259 invalid_sha1.append(sha1_path)
Jens Mueller054652c2023-05-10 15:12:30[diff] [blame]6260
6261def_CheckValidSha1(sha1_path):
Sam Maierb926c58c2023-08-08 19:58:25[diff] [blame]6262return sha1_pattern.search(
6263 next("\n".join(f.NewContents())for fin input_api.AffectedFiles()
6264if f.LocalPath()== sha1_path))
Bruce Dawson55776c42022-12-09 17:23:47[diff] [blame]6265
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]6266def_CheckScreenshotRemoved(screenshots_dir, message_id):
6267 sha1_path= input_api.os_path.join(screenshots_dir,
6268 message_id+'.png.sha1')
6269if input_api.os_path.exists(
6270 sha1_path)and sha1_pathnotin removed_paths:
6271 unnecessary_sha1_files.append(sha1_path)
Mustafa Emre Acer29bf6ac92018-07-30 21:42:14[diff] [blame]6272
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]6273def_ValidateIcuSyntax(text, level, signatures):
6274"""Validates ICU syntax of a text string.
Mustafa Emre Acer29bf6ac92018-07-30 21:42:14[diff] [blame]6275
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]6276 Check if text looks similar to ICU and checks for ICU syntax correctness
6277 in this case. Reports various issues with ICU syntax and values of
6278 variants. Supports checking of nested messages. Accumulate information of
6279 each ICU messages found in the text for further checking.
Rainhard Findlingfc31844c52020-05-15 09:58:26[diff] [blame]6280
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]6281 Args:
6282 text: a string to check.
6283 level: a number of current nesting level.
6284 signatures: an accumulator, a list of tuple of (level, variable,
6285 kind, variants).
Rainhard Findlingfc31844c52020-05-15 09:58:26[diff] [blame]6286
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]6287 Returns:
6288 None if a string is not ICU or no issue detected.
6289 A tuple of (message, start index, end index) if an issue detected.
6290 """
6291 valid_types={
6292'plural':(frozenset(
6293['=0','=1','zero','one','two','few','many',
6294'other']), frozenset(['=1','other'])),
6295'selectordinal':(frozenset(
6296['=0','=1','zero','one','two','few','many',
6297'other']), frozenset(['one','other'])),
6298'select':(frozenset(), frozenset(['other'])),
6299}
Rainhard Findlingfc31844c52020-05-15 09:58:26[diff] [blame]6300
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]6301# Check if the message looks like an attempt to use ICU
6302# plural. If yes - check if its syntax strictly matches ICU format.
6303 like= re.match(r'^[^{]*\{[^{]*\b(plural|selectordinal|select)\b',
6304 text)
6305ifnot like:
6306 signatures.append((level,None,None,None))
6307return
Rainhard Findlingfc31844c52020-05-15 09:58:26[diff] [blame]6308
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]6309# Check for valid prefix and suffix
6310 m= re.match(
6311 r'^([^{]*\{)([a-zA-Z0-9_]+),\s*'
6312 r'(plural|selectordinal|select),\s*'
6313 r'(?:offset:\d+)?\s*(.*)', text, re.DOTALL)
6314ifnot m:
6315return(('This message looks like an ICU plural, '
6316'but does not follow ICU syntax.'), like.start(),
6317 like.end())
6318 starting, variable, kind, variant_pairs= m.groups()
6319 variants, depth, last_pos=_ParseIcuVariants(variant_pairs,
6320 m.start(4))
6321if depth:
6322return('Invalid ICU format. Unbalanced opening bracket', last_pos,
6323 len(text))
6324 first= text[0]
6325 ending= text[last_pos:]
6326ifnot starting:
6327return('Invalid ICU format. No initial opening bracket',
6328 last_pos-1, last_pos)
6329ifnot endingor'}'notin ending:
6330return('Invalid ICU format. No final closing bracket',
6331 last_pos-1, last_pos)
6332elif first!='{':
6333return((
6334'Invalid ICU format. Extra characters at the start of a complex '
6335'message (go/icu-message-migration): "%s"')% starting,0,
6336 len(starting))
6337elif ending!='}':
6338return((
6339'Invalid ICU format. Extra characters at the end of a complex '
6340'message (go/icu-message-migration): "%s"')% ending,
6341 last_pos-1, len(text)-1)
6342if kindnotin valid_types:
6343return(('Unknown ICU message type %s. '
6344'Valid types are: plural, select, selectordinal')% kind,
63450,0)
6346 known, required= valid_types[kind]
6347 defined_variants= set()
6348for variant, variant_range, value, value_rangein variants:
6349 start, end= variant_range
6350if variantin defined_variants:
6351return('Variant "%s" is defined more than once'% variant,
6352 start, end)
6353elif knownand variantnotin known:
6354return('Variant "%s" is not valid for %s message'%
6355(variant, kind), start, end)
6356 defined_variants.add(variant)
6357# Check for nested structure
6358 res=_ValidateIcuSyntax(value[1:-1], level+1, signatures)
6359if res:
6360return(res[0], res[1]+ value_range[0]+1,
6361 res[2]+ value_range[0]+1)
6362 missing= required- defined_variants
6363if missing:
6364return('Required variants missing: %s'%', '.join(missing),0,
6365 len(text))
6366 signatures.append((level, variable, kind, defined_variants))
Rainhard Findlingfc31844c52020-05-15 09:58:26[diff] [blame]6367
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]6368def_ParseIcuVariants(text, offset=0):
6369"""Parse variants part of ICU complex message.
Rainhard Findlingfc31844c52020-05-15 09:58:26[diff] [blame]6370
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]6371 Builds a tuple of variant names and values, as well as
6372 their offsets in the input string.
Rainhard Findlingfc31844c52020-05-15 09:58:26[diff] [blame]6373
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]6374 Args:
6375 text: a string to parse
6376 offset: additional offset to add to positions in the text to get correct
6377 position in the complete ICU string.
Rainhard Findlingfc31844c52020-05-15 09:58:26[diff] [blame]6378
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]6379 Returns:
6380 List of tuples, each tuple consist of four fields: variant name,
6381 variant name span (tuple of two integers), variant value, value
6382 span (tuple of two integers).
6383 """
6384 depth, start, end=0,-1,-1
6385 variants=[]
6386 key=None
6387for idx, charin enumerate(text):
6388if char=='{':
6389ifnot depth:
6390 start= idx
6391 chunk= text[end+1:start]
6392 key= chunk.strip()
6393 pos= offset+ end+1+ chunk.find(key)
6394 span=(pos, pos+ len(key))
6395 depth+=1
6396elif char=='}':
6397ifnot depth:
6398return variants, depth, offset+ idx
6399 depth-=1
6400ifnot depth:
6401 end= idx
6402 variants.append((key, span, text[start:end+1],
6403(offset+ start, offset+ end+1)))
6404return variants, depth, offset+ end+1
Rainhard Findlingfc31844c52020-05-15 09:58:26[diff] [blame]6405
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]6406try:
6407 old_sys_path= sys.path
6408 sys.path= sys.path+[
6409 input_api.os_path.join(input_api.PresubmitLocalPath(),'tools',
6410'translation')
6411]
6412from helperimport grd_helper
6413finally:
6414 sys.path= old_sys_path
Rainhard Findlingfc31844c52020-05-15 09:58:26[diff] [blame]6415
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]6416for fin affected_grds:
6417 file_path= f.LocalPath()
6418 old_id_to_msg_map={}
6419 new_id_to_msg_map={}
6420# Note that this code doesn't check if the file has been deleted. This is
6421# OK because it only uses the old and new file contents and doesn't load
6422# the file via its path.
6423# It's also possible that a file's content refers to a renamed or deleted
6424# file via a <part> tag, such as <part file="now-deleted-file.grdp">. This
6425# is OK as well, because grd_helper ignores <part> tags when loading .grd or
6426# .grdp files.
6427if file_path.endswith('.grdp'):
6428if f.OldContents():
6429 old_id_to_msg_map= grd_helper.GetGrdpMessagesFromString(
6430'\n'.join(f.OldContents()))
6431if f.NewContents():
6432 new_id_to_msg_map= grd_helper.GetGrdpMessagesFromString(
6433'\n'.join(f.NewContents()))
6434else:
6435 file_dir= input_api.os_path.dirname(file_path)or'.'
6436if f.OldContents():
6437 old_id_to_msg_map= grd_helper.GetGrdMessages(
6438StringIO('\n'.join(f.OldContents())), file_dir)
6439if f.NewContents():
6440 new_id_to_msg_map= grd_helper.GetGrdMessages(
6441StringIO('\n'.join(f.NewContents())), file_dir)
Rainhard Findlingfc31844c52020-05-15 09:58:26[diff] [blame]6442
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]6443 grd_name, ext= input_api.os_path.splitext(
6444 input_api.os_path.basename(file_path))
6445 screenshots_dir= input_api.os_path.join(
6446 input_api.os_path.dirname(file_path),
6447 grd_name+ ext.replace('.','_'))
Rainhard Findlingfc31844c52020-05-15 09:58:26[diff] [blame]6448
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]6449# Compute added, removed and modified message IDs.
6450 old_ids= set(old_id_to_msg_map)
6451 new_ids= set(new_id_to_msg_map)
6452 added_ids= new_ids- old_ids
6453 removed_ids= old_ids- new_ids
6454 modified_ids= set([])
6455for keyin old_ids.intersection(new_ids):
6456if(old_id_to_msg_map[key].ContentsAsXml('',True)!=
6457 new_id_to_msg_map[key].ContentsAsXml('',True)):
6458# The message content itself changed. Require an updated screenshot.
6459 modified_ids.add(key)
6460elif old_id_to_msg_map[key].attrs['meaning']!= \
6461 new_id_to_msg_map[key].attrs['meaning']:
Jens Mueller054652c2023-05-10 15:12:30[diff] [blame]6462# The message meaning changed. We later check for a screenshot.
6463 modified_ids.add(key)
Mustafa Emre Acer29bf6ac92018-07-30 21:42:14[diff] [blame]6464
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]6465if run_screenshot_check:
6466# Check the screenshot directory for .png files. Warn if there is any.
6467for png_pathin affected_png_paths:
6468if png_path.startswith(screenshots_dir):
6469 unnecessary_screenshots.append(png_path)
Mustafa Emre Acer29bf6ac92018-07-30 21:42:14[diff] [blame]6470
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]6471for added_idin added_ids:
6472_CheckScreenshotAdded(screenshots_dir, added_id)
Rainhard Findlingd8d04372020-08-13 13:30:09[diff] [blame]6473
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]6474for modified_idin modified_ids:
Bruce Dawson55776c42022-12-09 17:23:47[diff] [blame]6475_CheckScreenshotModified(screenshots_dir, modified_id)
Mustafa Emre Acer29bf6ac92018-07-30 21:42:14[diff] [blame]6476
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]6477for removed_idin removed_ids:
6478_CheckScreenshotRemoved(screenshots_dir, removed_id)
6479
6480# Check new and changed strings for ICU syntax errors.
6481for keyin added_ids.union(modified_ids):
6482 msg= new_id_to_msg_map[key].ContentsAsXml('',True)
6483 err=_ValidateIcuSyntax(msg,0,[])
6484if errisnotNone:
6485 icu_syntax_errors.append(str(key)+': '+ str(err[0]))
6486
6487 results=[]
Rainhard Findlingfc31844c52020-05-15 09:58:26[diff] [blame]6488if run_screenshot_check:
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]6489if unnecessary_screenshots:
6490 results.append(
6491 output_api.PresubmitError(
6492'Do not include actual screenshots in the changelist. Run '
6493'tools/translate/upload_screenshots.py to upload them instead:',
6494 sorted(unnecessary_screenshots)))
Mustafa Emre Acer29bf6ac92018-07-30 21:42:14[diff] [blame]6495
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]6496if missing_sha1:
6497 results.append(
6498 output_api.PresubmitError(
Bruce Dawson55776c42022-12-09 17:23:47[diff] [blame]6499'You are adding UI strings.\n'
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]6500'To ensure the best translations, take screenshots of the relevant UI '
6501'(https://g.co/chrome/translation) and add these files to your '
6502'changelist:', sorted(missing_sha1)))
Mustafa Emre Acer29bf6ac92018-07-30 21:42:14[diff] [blame]6503
Jens Mueller054652c2023-05-10 15:12:30[diff] [blame]6504if invalid_sha1:
6505 results.append(
6506 output_api.PresubmitError(
6507'The following files do not seem to contain valid sha1 hashes. '
6508'Make sure they contain hashes created by '
6509'tools/translate/upload_screenshots.py:', sorted(invalid_sha1)))
6510
Bruce Dawson55776c42022-12-09 17:23:47[diff] [blame]6511if missing_sha1_modified:
6512 results.append(
6513 output_api.PresubmitError(
6514'You are modifying UI strings or their meanings.\n'
6515'To ensure the best translations, take screenshots of the relevant UI '
6516'(https://g.co/chrome/translation) and add these files to your '
6517'changelist:', sorted(missing_sha1_modified)))
6518
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]6519if unnecessary_sha1_files:
6520 results.append(
6521 output_api.PresubmitError(
6522'You removed strings associated with these files. Remove:',
6523 sorted(unnecessary_sha1_files)))
6524else:
6525 results.append(
6526 output_api.PresubmitPromptOrNotify('Skipping translation '
6527'screenshots check.'))
Mustafa Emre Acer29bf6ac92018-07-30 21:42:14[diff] [blame]6528
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]6529if icu_syntax_errors:
6530 results.append(
6531 output_api.PresubmitPromptWarning(
6532'ICU syntax errors were found in the following strings (problems or '
6533'feedback? Contact rainhard@chromium.org):',
6534 items=icu_syntax_errors))
Rainhard Findlingfc31844c52020-05-15 09:58:26[diff] [blame]6535
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]6536return results
Mustafa Emre Acer51f2f742020-03-09 19:41:12[diff] [blame]6537
6538
Saagar Sanghavifceeaae2020-08-12 16:40:36[diff] [blame]6539defCheckTranslationExpectations(input_api, output_api,
Mustafa Emre Acer51f2f742020-03-09 19:41:12[diff] [blame]6540 repo_root=None,
6541 translation_expectations_path=None,
6542 grd_files=None):
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]6543import sys
6544 affected_grds=[
6545 ffor fin input_api.AffectedFiles()
6546if(f.LocalPath().endswith('.grd')or f.LocalPath().endswith('.grdp'))
6547]
6548ifnot affected_grds:
6549return[]
6550
6551try:
6552 old_sys_path= sys.path
6553 sys.path= sys.path+[
6554 input_api.os_path.join(input_api.PresubmitLocalPath(),'tools',
6555'translation')
6556]
6557from helperimport git_helper
6558from helperimport translation_helper
6559finally:
6560 sys.path= old_sys_path
6561
6562# Check that translation expectations can be parsed and we can get a list of
6563# translatable grd files. |repo_root| and |translation_expectations_path| are
6564# only passed by tests.
6565ifnot repo_root:
6566 repo_root= input_api.PresubmitLocalPath()
6567ifnot translation_expectations_path:
6568 translation_expectations_path= input_api.os_path.join(
6569 repo_root,'tools','gritsettings','translation_expectations.pyl')
6570ifnot grd_files:
6571 grd_files= git_helper.list_grds_in_repository(repo_root)
6572
6573# Ignore bogus grd files used only for testing
Gao Shenga79ebd42022-08-08 17:25:59[diff] [blame]6574# ui/webui/resources/tools/generate_grd.py.
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]6575 ignore_path= input_api.os_path.join('ui','webui','resources','tools',
6576'tests')
6577 grd_files=[pfor pin grd_filesif ignore_pathnotin p]
6578
6579try:
6580 translation_helper.get_translatable_grds(
6581 repo_root, grd_files, translation_expectations_path)
6582exceptExceptionas e:
6583return[
6584 output_api.PresubmitNotifyResult(
6585'Failed to get a list of translatable grd files. This happens when:\n'
6586' - One of the modified grd or grdp files cannot be parsed or\n'
6587' - %s is not updated.\n'
6588'Stack:\n%s'%(translation_expectations_path, str(e)))
6589]
Mustafa Emre Acer51f2f742020-03-09 19:41:12[diff] [blame]6590return[]
6591
Ken Rockotc31f4832020-05-29 18:58:51[diff] [blame]6592
Saagar Sanghavifceeaae2020-08-12 16:40:36[diff] [blame]6593defCheckStableMojomChanges(input_api, output_api):
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]6594"""Changes to [Stable] mojom types must preserve backward-compatibility."""
6595 changed_mojoms= input_api.AffectedFiles(
6596 include_deletes=True,
6597 file_filter=lambda f: f.LocalPath().endswith(('.mojom')))
Erik Staabc734cd7a2021-11-23 03:11:52[diff] [blame]6598
Bruce Dawson344ab262022-06-04 11:35:10[diff] [blame]6599ifnot changed_mojomsor input_api.no_diffs:
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]6600return[]
6601
6602 delta=[]
6603for mojomin changed_mojoms:
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]6604 delta.append({
6605'filename': mojom.LocalPath(),
6606'old':'\n'.join(mojom.OldContents())orNone,
6607'new':'\n'.join(mojom.NewContents())orNone,
6608})
6609
6610 process= input_api.subprocess.Popen([
Takuto Ikutadca10222022-04-13 02:51:21[diff] [blame]6611 input_api.python3_executable,
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]6612 input_api.os_path.join(
6613 input_api.PresubmitLocalPath(),'mojo','public','tools','mojom',
6614'check_stable_mojom_compatibility.py'),'--src-root',
6615 input_api.PresubmitLocalPath()
6616],
6617 stdin=input_api.subprocess.PIPE,
6618 stdout=input_api.subprocess.PIPE,
6619 stderr=input_api.subprocess.PIPE,
6620 universal_newlines=True)
6621(x, error)= process.communicate(input=input_api.json.dumps(delta))
6622if process.returncode:
6623return[
6624 output_api.PresubmitError(
6625'One or more [Stable] mojom definitions appears to have been changed '
6626'in a way that is not backward-compatible.',
6627 long_text=error)
6628]
Erik Staabc734cd7a2021-11-23 03:11:52[diff] [blame]6629return[]
6630
Dominic Battre645d42342020-12-04 16:14:10[diff] [blame]6631defCheckDeprecationOfPreferences(input_api, output_api):
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]6632"""Removing a preference should come with a deprecation."""
Dominic Battre645d42342020-12-04 16:14:10[diff] [blame]6633
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]6634defFilterFile(affected_file):
6635"""Accept only .cc files and the like."""
6636 file_inclusion_pattern=[r'.+%s'% _IMPLEMENTATION_EXTENSIONS]
6637 files_to_skip=(_EXCLUDED_PATHS+ _TEST_CODE_EXCLUDED_PATHS+
6638 input_api.DEFAULT_FILES_TO_SKIP)
6639return input_api.FilterSourceFile(
6640 affected_file,
6641 files_to_check=file_inclusion_pattern,
6642 files_to_skip=files_to_skip)
Dominic Battre645d42342020-12-04 16:14:10[diff] [blame]6643
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]6644defModifiedLines(affected_file):
6645"""Returns a list of tuples (line number, line text) of added and removed
6646 lines.
Dominic Battre645d42342020-12-04 16:14:10[diff] [blame]6647
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]6648 Deleted lines share the same line number as the previous line.
Dominic Battre645d42342020-12-04 16:14:10[diff] [blame]6649
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]6650 This relies on the scm diff output describing each changed code section
6651 with a line of the form
Dominic Battre645d42342020-12-04 16:14:10[diff] [blame]6652
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]6653 ^@@ <old line num>,<old size> <new line num>,<new size> @@$
6654 """
6655 line_num=0
6656 modified_lines=[]
6657for linein affected_file.GenerateScmDiff().splitlines():
6658# Extract <new line num> of the patch fragment (see format above).
6659 m= input_api.re.match(r'^@@ [0-9\,\+\-]+ \+([0-9]+)\,[0-9]+ @@',
6660 line)
6661if m:
6662 line_num= int(m.groups(1)[0])
6663continue
6664if((line.startswith('+')andnot line.startswith('++'))
6665or(line.startswith('-')andnot line.startswith('--'))):
6666 modified_lines.append((line_num, line))
Dominic Battre645d42342020-12-04 16:14:10[diff] [blame]6667
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]6668ifnot line.startswith('-'):
6669 line_num+=1
6670return modified_lines
Dominic Battre645d42342020-12-04 16:14:10[diff] [blame]6671
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]6672defFindLineWith(lines, needle):
6673"""Returns the line number (i.e. index + 1) in `lines` containing `needle`.
Dominic Battre645d42342020-12-04 16:14:10[diff] [blame]6674
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]6675 If 0 or >1 lines contain `needle`, -1 is returned.
6676 """
6677 matching_line_numbers=[
6678# + 1 for 1-based counting of line numbers.
6679 i+1for i, linein enumerate(lines)if needlein line
6680]
6681return matching_line_numbers[0]if len(
6682 matching_line_numbers)==1else-1
Dominic Battre645d42342020-12-04 16:14:10[diff] [blame]6683
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]6684defModifiedPrefMigration(affected_file):
6685"""Returns whether the MigrateObsolete.*Pref functions were modified."""
6686# Determine first and last lines of MigrateObsolete.*Pref functions.
6687 new_contents= affected_file.NewContents()
6688 range_1=(FindLineWith(new_contents,
6689'BEGIN_MIGRATE_OBSOLETE_LOCAL_STATE_PREFS'),
6690FindLineWith(new_contents,
6691'END_MIGRATE_OBSOLETE_LOCAL_STATE_PREFS'))
6692 range_2=(FindLineWith(new_contents,
6693'BEGIN_MIGRATE_OBSOLETE_PROFILE_PREFS'),
6694FindLineWith(new_contents,
6695'END_MIGRATE_OBSOLETE_PROFILE_PREFS'))
6696if(-1in range_1+ range_2):
6697raiseException(
6698'Broken .*MIGRATE_OBSOLETE_.*_PREFS markers in browser_prefs.cc.'
6699)
Dominic Battre645d42342020-12-04 16:14:10[diff] [blame]6700
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]6701# Check whether any of the modified lines are part of the
6702# MigrateObsolete.*Pref functions.
6703for line_nr, lineinModifiedLines(affected_file):
6704if(range_1[0]<= line_nr<= range_1[1]
6705or range_2[0]<= line_nr<= range_2[1]):
6706returnTrue
6707returnFalse
Dominic Battre645d42342020-12-04 16:14:10[diff] [blame]6708
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]6709 register_pref_pattern= input_api.re.compile(r'Register.+Pref')
6710 browser_prefs_file_pattern= input_api.re.compile(
6711 r'chrome/browser/prefs/browser_prefs.cc')
Dominic Battre645d42342020-12-04 16:14:10[diff] [blame]6712
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]6713 changes= input_api.AffectedFiles(include_deletes=True,
6714 file_filter=FilterFile)
6715 potential_problems=[]
6716for fin changes:
6717for linein f.GenerateScmDiff().splitlines():
6718# Check deleted lines for pref registrations.
6719if(line.startswith('-')andnot line.startswith('--')
6720and register_pref_pattern.search(line)):
6721 potential_problems.append('%s: %s'%(f.LocalPath(), line))
Dominic Battre645d42342020-12-04 16:14:10[diff] [blame]6722
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]6723if browser_prefs_file_pattern.search(f.LocalPath()):
6724# If the developer modified the MigrateObsolete.*Prefs() functions, we
6725# assume that they knew that they have to deprecate preferences and don't
6726# warn.
6727try:
6728ifModifiedPrefMigration(f):
6729return[]
6730exceptExceptionas e:
6731return[output_api.PresubmitError(str(e))]
Dominic Battre645d42342020-12-04 16:14:10[diff] [blame]6732
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]6733if potential_problems:
6734return[
6735 output_api.PresubmitPromptWarning(
6736'Discovered possible removal of preference registrations.\n\n'
6737'Please make sure to properly deprecate preferences by clearing their\n'
6738'value for a couple of milestones before finally removing the code.\n'
6739'Otherwise data may stay in the preferences files forever. See\n'
6740'Migrate*Prefs() in chrome/browser/prefs/browser_prefs.cc and\n'
6741'chrome/browser/prefs/README.md for examples.\n'
6742'This may be a false positive warning (e.g. if you move preference\n'
6743'registrations to a different place).\n', potential_problems)
6744]
6745return[]
6746
Matt Stark6ef08872021-07-29 01:21:46[diff] [blame]6747
6748defCheckConsistentGrdChanges(input_api, output_api):
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]6749"""Changes to GRD files must be consistent for tools to read them."""
6750 changed_grds= input_api.AffectedFiles(
6751 include_deletes=False,
6752 file_filter=lambda f: f.LocalPath().endswith(('.grd')))
6753 errors=[]
6754 invalid_file_regexes=[(input_api.re.compile(matcher), msg)
6755for matcher, msgin _INVALID_GRD_FILE_LINE]
6756for grdin changed_grds:
6757for i, linein enumerate(grd.NewContents()):
6758for matcher, msgin invalid_file_regexes:
6759if matcher.search(line):
6760 errors.append(
6761 output_api.PresubmitError(
6762'Problem on {grd}:{i} - {msg}'.format(
6763 grd=grd.LocalPath(), i=i+1, msg=msg)))
6764return errors
6765
Kevin McNee967dd2d22021-11-15 16:09:29[diff] [blame]6766
Henrique Ferreiro2a4b55942021-11-29 23:45:36[diff] [blame]6767defCheckAssertAshOnlyCode(input_api, output_api):
6768"""Errors if a BUILD.gn file in an ash/ directory doesn't include
6769 assert(is_chromeos_ash).
6770 """
6771
6772defFileFilter(affected_file):
6773"""Includes directories known to be Ash only."""
6774return input_api.FilterSourceFile(
6775 affected_file,
6776 files_to_check=(
6777 r'^ash/.*BUILD\.gn',# Top-level src/ash/.
6778 r'.*/ash/.*BUILD\.gn'),# Any path component.
6779 files_to_skip=(input_api.DEFAULT_FILES_TO_SKIP))
6780
6781 errors=[]
6782 pattern= input_api.re.compile(r'assert\(is_chromeos_ash')
Jameson Thies0ce669f2021-12-09 15:56:56[diff] [blame]6783for fin input_api.AffectedFiles(include_deletes=False,
6784 file_filter=FileFilter):
Henrique Ferreiro2a4b55942021-11-29 23:45:36[diff] [blame]6785if(not pattern.search(input_api.ReadFile(f))):
6786 errors.append(
6787 output_api.PresubmitError(
6788'Please add assert(is_chromeos_ash) to %s. If that\'s not '
6789'possible, please create and issue and add a comment such '
6790'as:\n # TODO(https://crbug.com/XXX): add '
6791'assert(is_chromeos_ash) when ...'% f.LocalPath()))
6792return errors
Lukasz Anforowicz7016d05e2021-11-30 03:56:27[diff] [blame]6793
6794
Kalvin Lee84ad17a2023-09-25 11:14:41[diff] [blame]6795def_IsMiraclePtrDisallowed(input_api, affected_file):
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]6796 path= affected_file.LocalPath()
6797ifnot_IsCPlusPlusFile(input_api, path):
6798returnFalse
6799
Kalvin Lee84ad17a2023-09-25 11:14:41[diff] [blame]6800# Renderer code is generally allowed to use MiraclePtr.
6801# These directories, however, are specifically disallowed.
6802if("third_party/blink/renderer/core/"in path
6803or"third_party/blink/renderer/platform/heap/"in path
6804or"third_party/blink/renderer/platform/wtf/"in path):
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]6805returnTrue
6806
6807# Blink's public/web API is only used/included by Renderer-only code. Note
6808# that public/platform API may be used in non-Renderer processes (e.g. there
6809# are some includes in code used by Utility, PDF, or Plugin processes).
6810if"/blink/public/web/"in path:
6811returnTrue
6812
6813# We assume that everything else may be used outside of Renderer processes.
Lukasz Anforowicz7016d05e2021-11-30 03:56:27[diff] [blame]6814returnFalse
6815
Lukasz Anforowicz7016d05e2021-11-30 03:56:27[diff] [blame]6816# TODO(https://crbug.com/1273182): Remove these checks, once they are replaced
6817# by the Chromium Clang Plugin (which will be preferable because it will
6818# 1) report errors earlier - at compile-time and 2) cover more rules).
6819defCheckRawPtrUsage(input_api, output_api):
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]6820"""Rough checks that raw_ptr<T> usage guidelines are followed."""
6821 errors=[]
6822# The regex below matches "raw_ptr<" following a word boundary, but not in a
6823# C++ comment.
6824 raw_ptr_matcher= input_api.re.compile(r'^((?!//).)*\braw_ptr<')
Kalvin Lee84ad17a2023-09-25 11:14:41[diff] [blame]6825 file_filter=lambda f:_IsMiraclePtrDisallowed(input_api, f)
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]6826for f, line_num, linein input_api.RightHandSideLines(file_filter):
6827if raw_ptr_matcher.search(line):
6828 errors.append(
6829 output_api.PresubmitError(
6830'Problem on {path}:{line} - '\
Kalvin Lee84ad17a2023-09-25 11:14:41[diff] [blame]6831'raw_ptr<T> should not be used in this renderer code '\
Sam Maiera6e76d72022-02-11 21:43:50[diff] [blame]6832'(as documented in the "Pointers to unprotected memory" '\
6833'section in //base/memory/raw_ptr.md)'.format(
6834 path=f.LocalPath(), line=line_num)))
6835return errors
Henrique Ferreirof9819f2e32021-11-30 13:31:56[diff] [blame]6836
mikt9337567c2023-09-08 18:38:17[diff] [blame]6837defCheckAdvancedMemorySafetyChecksUsage(input_api, output_api):
6838"""Checks that ADVANCED_MEMORY_SAFETY_CHECKS() macro is neither added nor
6839 removed as it is managed by the memory safety team internally.
6840 Do not add / remove it manually."""
6841 paths= set([])
6842# The regex below matches "ADVANCED_MEMORY_SAFETY_CHECKS(" following a word
6843# boundary, but not in a C++ comment.
6844 macro_matcher= input_api.re.compile(
6845 r'^((?!//).)*\bADVANCED_MEMORY_SAFETY_CHECKS\(', input_api.re.MULTILINE)
6846for fin input_api.AffectedFiles():
6847ifnot_IsCPlusPlusFile(input_api, f.LocalPath()):
6848continue
6849if macro_matcher.search(f.GenerateScmDiff()):
6850 paths.add(f.LocalPath())
6851ifnot paths:
6852return[]
6853return[output_api.PresubmitPromptWarning(
6854'ADVANCED_MEMORY_SAFETY_CHECKS() macro is managed by ' \
6855'the memory safety team (chrome-memory-safety@). ' \
6856'Please contact us to add/delete the uses of the macro.',
6857 paths)]
Henrique Ferreirof9819f2e32021-11-30 13:31:56[diff] [blame]6858
6859defCheckPythonShebang(input_api, output_api):
6860"""Checks that python scripts use #!/usr/bin/env instead of hardcoding a
6861 system-wide python.
6862 """
6863 errors=[]
6864 sources=lambda affected_file: input_api.FilterSourceFile(
6865 affected_file,
6866 files_to_skip=((_THIRD_PARTY_EXCEPT_BLINK,
6867 r'third_party/blink/web_tests/external/')+ input_api.
6868 DEFAULT_FILES_TO_SKIP),
6869 files_to_check=[r'.*\.py$'])
6870for fin input_api.AffectedSourceFiles(sources):
Takuto Ikuta36976512021-11-30 23:15:27[diff] [blame]6871for line_num, linein f.ChangedContents():
6872if line_num==1and line.startswith('#!/usr/bin/python'):
6873 errors.append(f.LocalPath())
6874break
Henrique Ferreirof9819f2e32021-11-30 13:31:56[diff] [blame]6875
6876 result=[]
6877for filein errors:
6878 result.append(
6879 output_api.PresubmitError(
6880"Please use '#!/usr/bin/env python/2/3' as the shebang of %s"%
6881 file))
6882return result
James Shen81cc0e22022-06-15 21:10:45[diff] [blame]6883
6884
6885defCheckBatchAnnotation(input_api, output_api):
6886"""Checks that tests have either @Batch or @DoNotBatch annotation. If this
6887 is not an instrumentation test, disregard."""
6888
6889 batch_annotation= input_api.re.compile(r'^\s*@Batch')
6890 do_not_batch_annotation= input_api.re.compile(r'^\s*@DoNotBatch')
6891 robolectric_test= input_api.re.compile(r'[rR]obolectric')
6892 test_class_declaration= input_api.re.compile(r'^\s*public\sclass.*Test')
6893 uiautomator_test= input_api.re.compile(r'[uU]i[aA]utomator')
Mark Schillaci8ef0d872023-07-18 22:07:59[diff] [blame]6894 test_annotation_declaration= input_api.re.compile(r'^\s*public\s@interface\s.*{')
James Shen81cc0e22022-06-15 21:10:45[diff] [blame]6895
ckitagawae8fd23b2022-06-17 15:29:38[diff] [blame]6896 missing_annotation_errors=[]
6897 extra_annotation_errors=[]
James Shen81cc0e22022-06-15 21:10:45[diff] [blame]6898
6899def_FilterFile(affected_file):
6900return input_api.FilterSourceFile(
6901 affected_file,
6902 files_to_skip=input_api.DEFAULT_FILES_TO_SKIP,
6903 files_to_check=[r'.*Test\.java$'])
6904
6905for fin input_api.AffectedSourceFiles(_FilterFile):
6906 batch_matched=None
6907 do_not_batch_matched=None
6908 is_instrumentation_test=True
Mark Schillaci8ef0d872023-07-18 22:07:59[diff] [blame]6909 test_annotation_declaration_matched=None
James Shen81cc0e22022-06-15 21:10:45[diff] [blame]6910for linein f.NewContents():
6911if robolectric_test.search(line)or uiautomator_test.search(line):
6912# Skip Robolectric and UiAutomator tests.
6913 is_instrumentation_test=False
6914break
6915ifnot batch_matched:
6916 batch_matched= batch_annotation.search(line)
6917ifnot do_not_batch_matched:
6918 do_not_batch_matched= do_not_batch_annotation.search(line)
6919 test_class_declaration_matched= test_class_declaration.search(
6920 line)
Mark Schillaci8ef0d872023-07-18 22:07:59[diff] [blame]6921 test_annotation_declaration_matched= test_annotation_declaration.search(line)
6922if test_class_declaration_matchedor test_annotation_declaration_matched:
James Shen81cc0e22022-06-15 21:10:45[diff] [blame]6923break
Mark Schillaci8ef0d872023-07-18 22:07:59[diff] [blame]6924if test_annotation_declaration_matched:
6925continue
James Shen81cc0e22022-06-15 21:10:45[diff] [blame]6926if(is_instrumentation_testand
6927not batch_matchedand
6928not do_not_batch_matched):
Sam Maier4cef9242022-10-03 14:21:24[diff] [blame]6929 missing_annotation_errors.append(str(f.LocalPath()))
ckitagawae8fd23b2022-06-17 15:29:38[diff] [blame]6930if(not is_instrumentation_testand
6931(batch_matchedor
6932 do_not_batch_matched)):
Sam Maier4cef9242022-10-03 14:21:24[diff] [blame]6933 extra_annotation_errors.append(str(f.LocalPath()))
James Shen81cc0e22022-06-15 21:10:45[diff] [blame]6934
6935 results=[]
6936
ckitagawae8fd23b2022-06-17 15:29:38[diff] [blame]6937if missing_annotation_errors:
James Shen81cc0e22022-06-15 21:10:45[diff] [blame]6938 results.append(
6939 output_api.PresubmitPromptWarning(
6940"""
Andrew Grieve43a5cf82023-09-08 15:09:46[diff] [blame]6941A change was made to an on-device test that has neither been annotated with
6942@Batch nor @DoNotBatch. If this is a new test, please add the annotation. If
6943this is an existing test, please consider adding it if you are sufficiently
6944familiar with the test (but do so as a separate change).
6945
Jens Mueller2085ff82023-02-27 11:54:49[diff] [blame]6946See https://source.chromium.org/chromium/chromium/src/+/main:docs/testing/batching_instrumentation_tests.md
ckitagawae8fd23b2022-06-17 15:29:38[diff] [blame]6947""", missing_annotation_errors))
6948if extra_annotation_errors:
6949 results.append(
6950 output_api.PresubmitPromptWarning(
6951"""
6952Robolectric tests do not need a @Batch or @DoNotBatch annotations.
6953""", extra_annotation_errors))
James Shen81cc0e22022-06-15 21:10:45[diff] [blame]6954
6955return results
Sam Maier4cef9242022-10-03 14:21:24[diff] [blame]6956
6957
6958defCheckMockAnnotation(input_api, output_api):
6959"""Checks that we have annotated all Mockito.mock()-ed or Mockito.spy()-ed
6960 classes with @Mock or @Spy. If this is not an instrumentation test,
6961 disregard."""
6962
6963# This is just trying to be approximately correct. We are not writing a
6964# Java parser, so special cases like statically importing mock() then
6965# calling an unrelated non-mockito spy() function will cause a false
6966# positive.
6967 package_name= input_api.re.compile(r'^package\s+(\w+(?:\.\w+)+);')
6968 mock_static_import= input_api.re.compile(
6969 r'^import\s+static\s+org.mockito.Mockito.(?:mock|spy);')
6970 import_class= input_api.re.compile(r'import\s+((?:\w+\.)+)(\w+);')
6971 mock_annotation= input_api.re.compile(r'^\s*@(?:Mock|Spy)')
6972 field_type= input_api.re.compile(r'(\w+)(?:<\w+>)?\s+\w+\s*(?:;|=)')
6973 mock_or_spy_function_call= r'(?:mock|spy)\(\s*(?:new\s*)?(\w+)(?:\.class|\()'
6974 fully_qualified_mock_function= input_api.re.compile(
6975 r'Mockito\.'+ mock_or_spy_function_call)
6976 statically_imported_mock_function= input_api.re.compile(
6977 r'\W'+ mock_or_spy_function_call)
6978 robolectric_test= input_api.re.compile(r'[rR]obolectric')
6979 uiautomator_test= input_api.re.compile(r'[uU]i[aA]utomator')
6980
6981def_DoClassLookup(class_name, class_name_map, package):
6982 found= class_name_map.get(class_name)
6983if foundisnotNone:
6984return found
6985else:
6986return package+'.'+ class_name
6987
6988def_FilterFile(affected_file):
6989return input_api.FilterSourceFile(
6990 affected_file,
6991 files_to_skip=input_api.DEFAULT_FILES_TO_SKIP,
6992 files_to_check=[r'.*Test\.java$'])
6993
6994 mocked_by_function_classes= set()
6995 mocked_by_annotation_classes= set()
6996 class_to_filename={}
6997for fin input_api.AffectedSourceFiles(_FilterFile):
6998 mock_function_regex= fully_qualified_mock_function
6999 next_line_is_annotated=False
7000 fully_qualified_class_map={}
7001 package=None
7002
7003for linein f.NewContents():
7004if robolectric_test.search(line)or uiautomator_test.search(line):
7005# Skip Robolectric and UiAutomator tests.
7006break
7007
7008 m= package_name.search(line)
7009if m:
7010 package= m.group(1)
7011continue
7012
7013if mock_static_import.search(line):
7014 mock_function_regex= statically_imported_mock_function
7015continue
7016
7017 m= import_class.search(line)
7018if m:
7019 fully_qualified_class_map[m.group(2)]= m.group(1)+ m.group(2)
7020continue
7021
7022if next_line_is_annotated:
7023 next_line_is_annotated=False
7024 fully_qualified_class=_DoClassLookup(
7025 field_type.search(line).group(1), fully_qualified_class_map,
7026 package)
7027 mocked_by_annotation_classes.add(fully_qualified_class)
7028continue
7029
7030if mock_annotation.search(line):
Sam Maierb8a66a02023-10-10 13:50:55[diff] [blame]7031 field_type_search= field_type.search(line)
7032if field_type_search:
7033 fully_qualified_class=_DoClassLookup(
7034 field_type_search.group(1), fully_qualified_class_map,
7035 package)
7036 mocked_by_annotation_classes.add(fully_qualified_class)
7037else:
7038 next_line_is_annotated=True
Sam Maier4cef9242022-10-03 14:21:24[diff] [blame]7039continue
7040
7041 m= mock_function_regex.search(line)
7042if m:
7043 fully_qualified_class=_DoClassLookup(m.group(1),
7044 fully_qualified_class_map, package)
7045# Skipping builtin classes, since they don't get optimized.
7046if fully_qualified_class.startswith(
7047'android.')or fully_qualified_class.startswith(
7048'java.'):
7049continue
7050 class_to_filename[fully_qualified_class]= str(f.LocalPath())
7051 mocked_by_function_classes.add(fully_qualified_class)
7052
7053 results=[]
7054 missed_classes= mocked_by_function_classes- mocked_by_annotation_classes
7055if missed_classes:
7056 error_locations=[]
7057for cin missed_classes:
7058 error_locations.append(c+' in '+ class_to_filename[c])
7059 results.append(
7060 output_api.PresubmitPromptWarning(
7061"""
7062Mockito.mock()/spy() cause issues with our Java optimizer. You have 3 options:
70631) If the mocked variable can be a class member, annotate the member with
7064 @Mock/@Spy.
70652) If the mocked variable cannot be a class member, create a dummy member
7066 variable of that type, annotated with @Mock/@Spy. This dummy does not need
7067 to be used or initialized in any way.
70683) If the mocked type is definitely not going to be optimized, whether it's a
7069 builtin type which we don't ship, or a class you know R8 will treat
7070 specially, you can ignore this warning.
7071""", error_locations))
7072
7073return results
Mike Dougherty1b8be712022-10-20 00:15:13[diff] [blame]7074
7075defCheckNoJsInIos(input_api, output_api):
7076"""Checks to make sure that JavaScript files are not used on iOS."""
7077
7078def_FilterFile(affected_file):
7079return input_api.FilterSourceFile(
7080 affected_file,
7081 files_to_skip=input_api.DEFAULT_FILES_TO_SKIP+
Daniel White44b8bd02023-08-22 16:20:36[diff] [blame]7082(r'^ios/third_party/*', r'^ios/tools/*', r'^third_party/*',
7083 r'^components/autofill/ios/form_util/resources/*'),
Mike Dougherty1b8be712022-10-20 00:15:13[diff] [blame]7084 files_to_check=[r'^ios/.*\.js$', r'.*/ios/.*\.js$'])
7085
Mike Dougherty4d1050b2023-03-14 15:59:53[diff] [blame]7086 deleted_files=[]
7087
7088# Collect filenames of all removed JS files.
7089for fin input_api.AffectedSourceFiles(_FilterFile):
7090 local_path= f.LocalPath()
7091
7092if input_api.os_path.splitext(local_path)[1]=='.js'and f.Action()=='D':
7093 deleted_files.append(input_api.os_path.basename(local_path))
7094
Mike Dougherty1b8be712022-10-20 00:15:13[diff] [blame]7095 error_paths=[]
Mike Dougherty4d1050b2023-03-14 15:59:53[diff] [blame]7096 moved_paths=[]
Mike Dougherty1b8be712022-10-20 00:15:13[diff] [blame]7097 warning_paths=[]
7098
7099for fin input_api.AffectedSourceFiles(_FilterFile):
7100 local_path= f.LocalPath()
7101
7102if input_api.os_path.splitext(local_path)[1]=='.js':
7103if f.Action()=='A':
Mike Dougherty4d1050b2023-03-14 15:59:53[diff] [blame]7104if input_api.os_path.basename(local_path)in deleted_files:
7105# This script was probably moved rather than newly created.
7106# Present a warning instead of an error for these cases.
7107 moved_paths.append(local_path)
7108else:
7109 error_paths.append(local_path)
Mike Dougherty1b8be712022-10-20 00:15:13[diff] [blame]7110elif f.Action()!='D':
7111 warning_paths.append(local_path)
7112
7113 results=[]
7114
7115if warning_paths:
7116 results.append(output_api.PresubmitPromptWarning(
7117'TypeScript is now fully supported for iOS feature scripts. '
7118'Consider converting JavaScript files to TypeScript. See '
7119'//ios/web/public/js_messaging/README.md for more details.',
7120 warning_paths))
7121
Mike Dougherty4d1050b2023-03-14 15:59:53[diff] [blame]7122if moved_paths:
7123 results.append(output_api.PresubmitPromptWarning(
7124'Do not use JavaScript on iOS for new files as TypeScript is '
7125'fully supported. (If this is a moved file, you may leave the '
7126'script unconverted.) See //ios/web/public/js_messaging/README.md '
7127'for help using scripts on iOS.', moved_paths))
7128
Mike Dougherty1b8be712022-10-20 00:15:13[diff] [blame]7129if error_paths:
7130 results.append(output_api.PresubmitError(
7131'Do not use JavaScript on iOS as TypeScript is fully supported. '
7132'See //ios/web/public/js_messaging/README.md for help using '
7133'scripts on iOS.', error_paths))
7134
7135return results
Hans Wennborg23a81d52023-03-24 16:38:13[diff] [blame]7136
7137defCheckLibcxxRevisionsMatch(input_api, output_api):
7138"""Check to make sure the libc++ version matches across deps files."""
Andrew Grieve21bb6792023-03-27 19:06:48[diff] [blame]7139# Disable check for changes to sub-repositories.
7140if input_api.PresubmitLocalPath()!= input_api.change.RepositoryRoot():
Sam Maierb926c58c2023-08-08 19:58:25[diff] [blame]7141return[]
Hans Wennborg23a81d52023-03-24 16:38:13[diff] [blame]7142
7143 DEPS_FILES=['DEPS','buildtools/deps_revisions.gni']
7144
7145 file_filter=lambda f: f.LocalPath().replace(
7146 input_api.os_path.sep,'/')in DEPS_FILES
7147 changed_deps_files= input_api.AffectedFiles(file_filter=file_filter)
7148ifnot changed_deps_files:
7149return[]
7150
7151defLibcxxRevision(file):
7152 file= input_api.os_path.join(input_api.PresubmitLocalPath(),
7153*file.split('/'))
7154return input_api.re.search(
7155 r'libcxx_revision.*[:=].*[\'"](\w+)[\'"]',
7156 input_api.ReadFile(file)).group(1)
7157
7158if len(set([LibcxxRevision(f)for fin DEPS_FILES]))==1:
7159return[]
7160
7161return[output_api.PresubmitError(
7162'libcxx_revision not equal across %s'%', '.join(DEPS_FILES),
7163 changed_deps_files)]
Arthur Sonzogni7109bd32023-10-03 10:34:42[diff] [blame]7164
7165
7166defCheckDanglingUntriaged(input_api, output_api):
7167"""Warn developers adding DanglingUntriaged raw_ptr."""
7168
7169# Ignore during git presubmit --all.
7170#
7171# This would be too costly, because this would check every lines of every
7172# C++ files. Check from _BANNED_CPP_FUNCTIONS are also reading the whole
7173# source code, but only once to apply every checks. It seems the bots like
7174# `win-presubmit` are particularly sensitive to reading the files. Adding
7175# this check caused the bot to run 2x longer. See https://crbug.com/1486612.
7176if input_api.no_diffs:
Arthur Sonzogni9eafd222023-11-10 08:50:39[diff] [blame]7177return[]
Arthur Sonzogni7109bd32023-10-03 10:34:42[diff] [blame]7178
7179defFilterFile(file):
7180return input_api.FilterSourceFile(
7181 file,
7182 files_to_check=[r".*\.(h|cc|cpp|cxx|m|mm)$"],
7183 files_to_skip=[r"^base/allocator.*"],
7184)
7185
7186 count=0
7187for fin input_api.AffectedSourceFiles(FilterFile):
Arthur Sonzogni9eafd222023-11-10 08:50:39[diff] [blame]7188 count-= sum([l.count("DanglingUntriaged")for lin f.OldContents()])
7189 count+= sum([l.count("DanglingUntriaged")for lin f.NewContents()])
Arthur Sonzogni7109bd32023-10-03 10:34:42[diff] [blame]7190
7191# Most likely, nothing changed:
7192if count==0:
7193return[]
7194
7195# Congrats developers for improving it:
7196if count<0:
Arthur Sonzogni9eafd222023-11-10 08:50:39[diff] [blame]7197 message= f"DanglingUntriaged pointers removed: {-count}\nThank you!"
Arthur Sonzogni7109bd32023-10-03 10:34:42[diff] [blame]7198return[output_api.PresubmitNotifyResult(message)]
7199
7200# Check for 'DanglingUntriaged-notes' in the description:
7201 notes_regex= input_api.re.compile("DanglingUntriaged-notes[:=]")
7202if any(
7203 notes_regex.match(line)
7204for linein input_api.change.DescriptionText().splitlines()):
7205return[]
7206
7207# Check for DanglingUntriaged-notes in the git footer:
7208if input_api.change.GitFootersFromDescription().get(
7209"DanglingUntriaged-notes",[]):
7210return[]
7211
7212 message=(
Arthur Sonzogni9eafd222023-11-10 08:50:39[diff] [blame]7213"Unexpected new occurrences of `DanglingUntriaged` detected. Please\n"+
7214"avoid adding new ones\n"+
7215"\n"+
7216"See documentation:\n"+
7217"https://chromium.googlesource.com/chromium/src/+/main/docs/dangling_ptr.md\n"+
7218"\n"+
7219"See also the guide to fix dangling pointers:\n"+
7220"https://chromium.googlesource.com/chromium/src/+/main/docs/dangling_ptr_guide.md\n"+
7221"\n"+
7222"To disable this warning, please add in the commit description:\n"+
7223"DanglingUntriaged-notes: <rational for new untriaged dangling "+
7224"pointers>"
Arthur Sonzogni7109bd32023-10-03 10:34:42[diff] [blame]7225)
7226return[output_api.PresubmitPromptWarning(message)]
Jan Keitel77be7522023-10-12 20:40:49[diff] [blame]7227
7228defCheckInlineConstexprDefinitionsInHeaders(input_api, output_api):
7229"""Checks that non-static constexpr definitions in headers are inline."""
7230# In a properly formatted file, constexpr definitions inside classes or
7231# structs will have additional whitespace at the beginning of the line.
7232# The pattern looks for variables initialized as constexpr kVar = ...; or
7233# constexpr kVar{...};
7234# The pattern does not match expressions that have braces in kVar to avoid
7235# matching constexpr functions.
7236 pattern= input_api.re.compile(r'^constexpr (?!inline )[^\(\)]*[={]')
7237 attribute_pattern= input_api.re.compile(r'(\[\[[a-zA-Z_:]+\]\]|[A-Z]+[A-Z_]+) ')
7238 problems=[]
7239for fin input_api.AffectedFiles():
7240ifnot_IsCPlusPlusHeaderFile(input_api, f.LocalPath()):
7241continue
7242
7243for line_number, linein f.ChangedContents():
7244 line= attribute_pattern.sub('', line)
7245if pattern.search(line):
7246 problems.append(
7247 f"{f.LocalPath()}: {line_number}\n {line}")
7248
7249if problems:
7250return[
7251 output_api.PresubmitPromptWarning(
7252'Consider inlining constexpr variable definitions in headers '
7253'outside of classes to avoid unnecessary copies of the '
7254'constant. See https://abseil.io/tips/168 for more details.',
7255 problems)
7256]
7257else:
7258return[]

[8]ページ先頭

©2009-2025 Movatter.jp