xref: /aosp_15_r20/external/perfetto/PRESUBMIT.py (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
1*6dbdd20aSAndroid Build Coastguard Worker# Copyright (C) 2017 The Android Open Source Project
2*6dbdd20aSAndroid Build Coastguard Worker#
3*6dbdd20aSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License");
4*6dbdd20aSAndroid Build Coastguard Worker# you may not use this file except in compliance with the License.
5*6dbdd20aSAndroid Build Coastguard Worker# You may obtain a copy of the License at
6*6dbdd20aSAndroid Build Coastguard Worker#
7*6dbdd20aSAndroid Build Coastguard Worker#      http://www.apache.org/licenses/LICENSE-2.0
8*6dbdd20aSAndroid Build Coastguard Worker#
9*6dbdd20aSAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software
10*6dbdd20aSAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS,
11*6dbdd20aSAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*6dbdd20aSAndroid Build Coastguard Worker# See the License for the specific language governing permissions and
13*6dbdd20aSAndroid Build Coastguard Worker# limitations under the License.
14*6dbdd20aSAndroid Build Coastguard Worker
15*6dbdd20aSAndroid Build Coastguard Workerfrom __future__ import print_function
16*6dbdd20aSAndroid Build Coastguard Workerimport itertools
17*6dbdd20aSAndroid Build Coastguard Workerimport subprocess
18*6dbdd20aSAndroid Build Coastguard Workerimport time
19*6dbdd20aSAndroid Build Coastguard Worker
20*6dbdd20aSAndroid Build Coastguard WorkerUSE_PYTHON3 = True
21*6dbdd20aSAndroid Build Coastguard Worker
22*6dbdd20aSAndroid Build Coastguard Worker
23*6dbdd20aSAndroid Build Coastguard Workerdef RunAndReportIfLong(func, *args, **kargs):
24*6dbdd20aSAndroid Build Coastguard Worker  start = time.time()
25*6dbdd20aSAndroid Build Coastguard Worker  results = func(*args, **kargs)
26*6dbdd20aSAndroid Build Coastguard Worker  end = time.time()
27*6dbdd20aSAndroid Build Coastguard Worker  limit = 3.0  # seconds
28*6dbdd20aSAndroid Build Coastguard Worker  name = func.__name__
29*6dbdd20aSAndroid Build Coastguard Worker  runtime = end - start
30*6dbdd20aSAndroid Build Coastguard Worker  if runtime > limit:
31*6dbdd20aSAndroid Build Coastguard Worker    print("{} took >{:.2}s ({:.2}s)".format(name, limit, runtime))
32*6dbdd20aSAndroid Build Coastguard Worker  return results
33*6dbdd20aSAndroid Build Coastguard Worker
34*6dbdd20aSAndroid Build Coastguard Worker
35*6dbdd20aSAndroid Build Coastguard Workerdef CheckChange(input, output):
36*6dbdd20aSAndroid Build Coastguard Worker  # There apparently is no way to wrap strings in blueprints, so ignore long
37*6dbdd20aSAndroid Build Coastguard Worker  # lines in them.
38*6dbdd20aSAndroid Build Coastguard Worker  def long_line_sources(x):
39*6dbdd20aSAndroid Build Coastguard Worker    return input.FilterSourceFile(
40*6dbdd20aSAndroid Build Coastguard Worker        x,
41*6dbdd20aSAndroid Build Coastguard Worker        files_to_check='.*',
42*6dbdd20aSAndroid Build Coastguard Worker        files_to_skip=[
43*6dbdd20aSAndroid Build Coastguard Worker            'Android[.]bp',
44*6dbdd20aSAndroid Build Coastguard Worker            "buildtools/grpc/BUILD.gn",
45*6dbdd20aSAndroid Build Coastguard Worker            '.*[.]json$',
46*6dbdd20aSAndroid Build Coastguard Worker            '.*[.]sql$',
47*6dbdd20aSAndroid Build Coastguard Worker            '.*[.]out$',
48*6dbdd20aSAndroid Build Coastguard Worker            'test/trace_processor/.*/tests.*$',
49*6dbdd20aSAndroid Build Coastguard Worker            '(.*/)?BUILD$',
50*6dbdd20aSAndroid Build Coastguard Worker            'WORKSPACE',
51*6dbdd20aSAndroid Build Coastguard Worker            '.*/Makefile$',
52*6dbdd20aSAndroid Build Coastguard Worker            '/perfetto_build_flags.h$',
53*6dbdd20aSAndroid Build Coastguard Worker            "infra/luci/.*",
54*6dbdd20aSAndroid Build Coastguard Worker            "^ui/.*\.[jt]s$",  # TS/JS handled by eslint
55*6dbdd20aSAndroid Build Coastguard Worker            "^ui/pnpm-lock.yaml$",
56*6dbdd20aSAndroid Build Coastguard Worker        ])
57*6dbdd20aSAndroid Build Coastguard Worker
58*6dbdd20aSAndroid Build Coastguard Worker  results = []
59*6dbdd20aSAndroid Build Coastguard Worker  results += RunAndReportIfLong(input.canned_checks.CheckDoNotSubmit, input,
60*6dbdd20aSAndroid Build Coastguard Worker                                output)
61*6dbdd20aSAndroid Build Coastguard Worker  results += RunAndReportIfLong(input.canned_checks.CheckChangeHasNoTabs, input,
62*6dbdd20aSAndroid Build Coastguard Worker                                output)
63*6dbdd20aSAndroid Build Coastguard Worker  results += RunAndReportIfLong(
64*6dbdd20aSAndroid Build Coastguard Worker      input.canned_checks.CheckLongLines,
65*6dbdd20aSAndroid Build Coastguard Worker      input,
66*6dbdd20aSAndroid Build Coastguard Worker      output,
67*6dbdd20aSAndroid Build Coastguard Worker      80,
68*6dbdd20aSAndroid Build Coastguard Worker      source_file_filter=long_line_sources)
69*6dbdd20aSAndroid Build Coastguard Worker  # TS/JS handled by eslint
70*6dbdd20aSAndroid Build Coastguard Worker  results += RunAndReportIfLong(
71*6dbdd20aSAndroid Build Coastguard Worker      input.canned_checks.CheckPatchFormatted, input, output, check_js=False)
72*6dbdd20aSAndroid Build Coastguard Worker  results += RunAndReportIfLong(input.canned_checks.CheckGNFormatted, input,
73*6dbdd20aSAndroid Build Coastguard Worker                                output)
74*6dbdd20aSAndroid Build Coastguard Worker  results += RunAndReportIfLong(CheckIncludeGuards, input, output)
75*6dbdd20aSAndroid Build Coastguard Worker  results += RunAndReportIfLong(CheckIncludeViolations, input, output)
76*6dbdd20aSAndroid Build Coastguard Worker  results += RunAndReportIfLong(CheckIncludePaths, input, output)
77*6dbdd20aSAndroid Build Coastguard Worker  results += RunAndReportIfLong(CheckProtoComments, input, output)
78*6dbdd20aSAndroid Build Coastguard Worker  results += RunAndReportIfLong(CheckBuild, input, output)
79*6dbdd20aSAndroid Build Coastguard Worker  results += RunAndReportIfLong(CheckAndroidBlueprint, input, output)
80*6dbdd20aSAndroid Build Coastguard Worker  results += RunAndReportIfLong(CheckBinaryDescriptors, input, output)
81*6dbdd20aSAndroid Build Coastguard Worker  results += RunAndReportIfLong(CheckMergedTraceConfigProto, input, output)
82*6dbdd20aSAndroid Build Coastguard Worker  results += RunAndReportIfLong(CheckProtoEventList, input, output)
83*6dbdd20aSAndroid Build Coastguard Worker  results += RunAndReportIfLong(CheckBannedCpp, input, output)
84*6dbdd20aSAndroid Build Coastguard Worker  results += RunAndReportIfLong(CheckBadCppPatterns, input, output)
85*6dbdd20aSAndroid Build Coastguard Worker  results += RunAndReportIfLong(CheckSqlModules, input, output)
86*6dbdd20aSAndroid Build Coastguard Worker  results += RunAndReportIfLong(CheckSqlMetrics, input, output)
87*6dbdd20aSAndroid Build Coastguard Worker  results += RunAndReportIfLong(CheckTestData, input, output)
88*6dbdd20aSAndroid Build Coastguard Worker  results += RunAndReportIfLong(CheckAmalgamatedPythonTools, input, output)
89*6dbdd20aSAndroid Build Coastguard Worker  results += RunAndReportIfLong(CheckChromeStdlib, input, output)
90*6dbdd20aSAndroid Build Coastguard Worker  results += RunAndReportIfLong(CheckAbsolutePathsInGn, input, output)
91*6dbdd20aSAndroid Build Coastguard Worker  return results
92*6dbdd20aSAndroid Build Coastguard Worker
93*6dbdd20aSAndroid Build Coastguard Worker
94*6dbdd20aSAndroid Build Coastguard Workerdef CheckChangeOnUpload(input_api, output_api):
95*6dbdd20aSAndroid Build Coastguard Worker  return CheckChange(input_api, output_api)
96*6dbdd20aSAndroid Build Coastguard Worker
97*6dbdd20aSAndroid Build Coastguard Worker
98*6dbdd20aSAndroid Build Coastguard Workerdef CheckChangeOnCommit(input_api, output_api):
99*6dbdd20aSAndroid Build Coastguard Worker  return CheckChange(input_api, output_api)
100*6dbdd20aSAndroid Build Coastguard Worker
101*6dbdd20aSAndroid Build Coastguard Worker
102*6dbdd20aSAndroid Build Coastguard Workerdef CheckBuild(input_api, output_api):
103*6dbdd20aSAndroid Build Coastguard Worker  # The script invocation doesn't work on Windows.
104*6dbdd20aSAndroid Build Coastguard Worker  if input_api.is_windows:
105*6dbdd20aSAndroid Build Coastguard Worker    return []
106*6dbdd20aSAndroid Build Coastguard Worker
107*6dbdd20aSAndroid Build Coastguard Worker  tool = 'tools/gen_bazel'
108*6dbdd20aSAndroid Build Coastguard Worker
109*6dbdd20aSAndroid Build Coastguard Worker  # If no GN files were modified, bail out.
110*6dbdd20aSAndroid Build Coastguard Worker  def build_file_filter(x):
111*6dbdd20aSAndroid Build Coastguard Worker    return input_api.FilterSourceFile(
112*6dbdd20aSAndroid Build Coastguard Worker        x, files_to_check=('.*BUILD[.]gn$', '.*[.]gni$', 'BUILD\.extras', tool))
113*6dbdd20aSAndroid Build Coastguard Worker
114*6dbdd20aSAndroid Build Coastguard Worker  if not input_api.AffectedSourceFiles(build_file_filter):
115*6dbdd20aSAndroid Build Coastguard Worker    return []
116*6dbdd20aSAndroid Build Coastguard Worker  if subprocess.call([tool, '--check-only']):
117*6dbdd20aSAndroid Build Coastguard Worker    return [
118*6dbdd20aSAndroid Build Coastguard Worker        output_api.PresubmitError('Bazel BUILD(s) are out of date. Run ' +
119*6dbdd20aSAndroid Build Coastguard Worker                                  tool + ' to update them.')
120*6dbdd20aSAndroid Build Coastguard Worker    ]
121*6dbdd20aSAndroid Build Coastguard Worker  return []
122*6dbdd20aSAndroid Build Coastguard Worker
123*6dbdd20aSAndroid Build Coastguard Worker
124*6dbdd20aSAndroid Build Coastguard Workerdef CheckAndroidBlueprint(input_api, output_api):
125*6dbdd20aSAndroid Build Coastguard Worker  # The script invocation doesn't work on Windows.
126*6dbdd20aSAndroid Build Coastguard Worker  if input_api.is_windows:
127*6dbdd20aSAndroid Build Coastguard Worker    return []
128*6dbdd20aSAndroid Build Coastguard Worker
129*6dbdd20aSAndroid Build Coastguard Worker  tool = 'tools/gen_android_bp'
130*6dbdd20aSAndroid Build Coastguard Worker
131*6dbdd20aSAndroid Build Coastguard Worker  # If no GN files were modified, bail out.
132*6dbdd20aSAndroid Build Coastguard Worker  def build_file_filter(x):
133*6dbdd20aSAndroid Build Coastguard Worker    return input_api.FilterSourceFile(
134*6dbdd20aSAndroid Build Coastguard Worker        x,
135*6dbdd20aSAndroid Build Coastguard Worker        files_to_check=('.*BUILD[.]gn$', '.*[.]gni$', tool),
136*6dbdd20aSAndroid Build Coastguard Worker        # Do not require Android.bp to be regenerated for chrome
137*6dbdd20aSAndroid Build Coastguard Worker        # stdlib changes.
138*6dbdd20aSAndroid Build Coastguard Worker        files_to_skip=(
139*6dbdd20aSAndroid Build Coastguard Worker            'src/trace_processor/perfetto_sql/stdlib/chrome/BUILD.gn'))
140*6dbdd20aSAndroid Build Coastguard Worker
141*6dbdd20aSAndroid Build Coastguard Worker  if not input_api.AffectedSourceFiles(build_file_filter):
142*6dbdd20aSAndroid Build Coastguard Worker    return []
143*6dbdd20aSAndroid Build Coastguard Worker  if subprocess.call([tool, '--check-only']):
144*6dbdd20aSAndroid Build Coastguard Worker    return [
145*6dbdd20aSAndroid Build Coastguard Worker        output_api.PresubmitError('Android build files are out of date. ' +
146*6dbdd20aSAndroid Build Coastguard Worker                                  'Run ' + tool + ' to update them.')
147*6dbdd20aSAndroid Build Coastguard Worker    ]
148*6dbdd20aSAndroid Build Coastguard Worker  return []
149*6dbdd20aSAndroid Build Coastguard Worker
150*6dbdd20aSAndroid Build Coastguard Worker
151*6dbdd20aSAndroid Build Coastguard Workerdef CheckIncludeGuards(input_api, output_api):
152*6dbdd20aSAndroid Build Coastguard Worker  # The script invocation doesn't work on Windows.
153*6dbdd20aSAndroid Build Coastguard Worker  if input_api.is_windows:
154*6dbdd20aSAndroid Build Coastguard Worker    return []
155*6dbdd20aSAndroid Build Coastguard Worker
156*6dbdd20aSAndroid Build Coastguard Worker  tool = 'tools/fix_include_guards'
157*6dbdd20aSAndroid Build Coastguard Worker
158*6dbdd20aSAndroid Build Coastguard Worker  def file_filter(x):
159*6dbdd20aSAndroid Build Coastguard Worker    return input_api.FilterSourceFile(
160*6dbdd20aSAndroid Build Coastguard Worker        x, files_to_check=['.*[.]cc$', '.*[.]h$', tool])
161*6dbdd20aSAndroid Build Coastguard Worker
162*6dbdd20aSAndroid Build Coastguard Worker  if not input_api.AffectedSourceFiles(file_filter):
163*6dbdd20aSAndroid Build Coastguard Worker    return []
164*6dbdd20aSAndroid Build Coastguard Worker  if subprocess.call([tool, '--check-only']):
165*6dbdd20aSAndroid Build Coastguard Worker    return [
166*6dbdd20aSAndroid Build Coastguard Worker        output_api.PresubmitError('Please run ' + tool +
167*6dbdd20aSAndroid Build Coastguard Worker                                  ' to fix include guards.')
168*6dbdd20aSAndroid Build Coastguard Worker    ]
169*6dbdd20aSAndroid Build Coastguard Worker  return []
170*6dbdd20aSAndroid Build Coastguard Worker
171*6dbdd20aSAndroid Build Coastguard Worker
172*6dbdd20aSAndroid Build Coastguard Workerdef CheckBannedCpp(input_api, output_api):
173*6dbdd20aSAndroid Build Coastguard Worker  bad_cpp = [
174*6dbdd20aSAndroid Build Coastguard Worker      (r'\bstd::stoi\b',
175*6dbdd20aSAndroid Build Coastguard Worker       'std::stoi throws exceptions prefer base::StringToInt32()'),
176*6dbdd20aSAndroid Build Coastguard Worker      (r'\bstd::stol\b',
177*6dbdd20aSAndroid Build Coastguard Worker       'std::stoull throws exceptions prefer base::StringToInt32()'),
178*6dbdd20aSAndroid Build Coastguard Worker      (r'\bstd::stoul\b',
179*6dbdd20aSAndroid Build Coastguard Worker       'std::stoull throws exceptions prefer base::StringToUint32()'),
180*6dbdd20aSAndroid Build Coastguard Worker      (r'\bstd::stoll\b',
181*6dbdd20aSAndroid Build Coastguard Worker       'std::stoull throws exceptions prefer base::StringToInt64()'),
182*6dbdd20aSAndroid Build Coastguard Worker      (r'\bstd::stoull\b',
183*6dbdd20aSAndroid Build Coastguard Worker       'std::stoull throws exceptions prefer base::StringToUint64()'),
184*6dbdd20aSAndroid Build Coastguard Worker      (r'\bstd::stof\b',
185*6dbdd20aSAndroid Build Coastguard Worker       'std::stof throws exceptions prefer base::StringToDouble()'),
186*6dbdd20aSAndroid Build Coastguard Worker      (r'\bstd::stod\b',
187*6dbdd20aSAndroid Build Coastguard Worker       'std::stod throws exceptions prefer base::StringToDouble()'),
188*6dbdd20aSAndroid Build Coastguard Worker      (r'\bstd::stold\b',
189*6dbdd20aSAndroid Build Coastguard Worker       'std::stold throws exceptions prefer base::StringToDouble()'),
190*6dbdd20aSAndroid Build Coastguard Worker      (r'\bstrncpy\b',
191*6dbdd20aSAndroid Build Coastguard Worker       'strncpy does not null-terminate if src > dst. Use base::StringCopy'),
192*6dbdd20aSAndroid Build Coastguard Worker      (r'[(=]\s*snprintf\(',
193*6dbdd20aSAndroid Build Coastguard Worker       'snprintf can return > dst_size. Use base::SprintfTrunc'),
194*6dbdd20aSAndroid Build Coastguard Worker      (r'//.*\bDNS\b',
195*6dbdd20aSAndroid Build Coastguard Worker       '// DNS (Do Not Ship) found. Did you mean to remove some testing code?'),
196*6dbdd20aSAndroid Build Coastguard Worker      (r'\bPERFETTO_EINTR\(close\(',
197*6dbdd20aSAndroid Build Coastguard Worker       'close(2) must not be retried on EINTR on Linux and other OSes '
198*6dbdd20aSAndroid Build Coastguard Worker       'that we run on, as the fd will be closed.'),
199*6dbdd20aSAndroid Build Coastguard Worker      (r'^#include <inttypes.h>', 'Use <cinttypes> rather than <inttypes.h>. ' +
200*6dbdd20aSAndroid Build Coastguard Worker       'See https://github.com/google/perfetto/issues/146'),
201*6dbdd20aSAndroid Build Coastguard Worker  ]
202*6dbdd20aSAndroid Build Coastguard Worker
203*6dbdd20aSAndroid Build Coastguard Worker  def file_filter(x):
204*6dbdd20aSAndroid Build Coastguard Worker    return input_api.FilterSourceFile(x, files_to_check=[r'.*\.h$', r'.*\.cc$'])
205*6dbdd20aSAndroid Build Coastguard Worker
206*6dbdd20aSAndroid Build Coastguard Worker  errors = []
207*6dbdd20aSAndroid Build Coastguard Worker  for f in input_api.AffectedSourceFiles(file_filter):
208*6dbdd20aSAndroid Build Coastguard Worker    for line_number, line in f.ChangedContents():
209*6dbdd20aSAndroid Build Coastguard Worker      if input_api.re.search(r'^\s*//', line):
210*6dbdd20aSAndroid Build Coastguard Worker        continue  # Skip comments
211*6dbdd20aSAndroid Build Coastguard Worker      for regex, message in bad_cpp:
212*6dbdd20aSAndroid Build Coastguard Worker        if input_api.re.search(regex, line):
213*6dbdd20aSAndroid Build Coastguard Worker          errors.append(
214*6dbdd20aSAndroid Build Coastguard Worker              output_api.PresubmitError('Banned pattern:\n  {}:{} {}'.format(
215*6dbdd20aSAndroid Build Coastguard Worker                  f.LocalPath(), line_number, message)))
216*6dbdd20aSAndroid Build Coastguard Worker  return errors
217*6dbdd20aSAndroid Build Coastguard Worker
218*6dbdd20aSAndroid Build Coastguard Worker
219*6dbdd20aSAndroid Build Coastguard Workerdef CheckBadCppPatterns(input_api, output_api):
220*6dbdd20aSAndroid Build Coastguard Worker  bad_patterns = [
221*6dbdd20aSAndroid Build Coastguard Worker      (r'.*/tracing_service_impl[.]cc$', r'\btrigger_config\(\)',
222*6dbdd20aSAndroid Build Coastguard Worker       'Use GetTriggerMode(session->config) rather than .trigger_config()'),
223*6dbdd20aSAndroid Build Coastguard Worker  ]
224*6dbdd20aSAndroid Build Coastguard Worker  errors = []
225*6dbdd20aSAndroid Build Coastguard Worker  for file_regex, code_regex, message in bad_patterns:
226*6dbdd20aSAndroid Build Coastguard Worker    filt = lambda x: input_api.FilterSourceFile(x, files_to_check=[file_regex])
227*6dbdd20aSAndroid Build Coastguard Worker    for f in input_api.AffectedSourceFiles(filt):
228*6dbdd20aSAndroid Build Coastguard Worker      for line_number, line in f.ChangedContents():
229*6dbdd20aSAndroid Build Coastguard Worker        if input_api.re.search(r'^\s*//', line):
230*6dbdd20aSAndroid Build Coastguard Worker          continue  # Skip comments
231*6dbdd20aSAndroid Build Coastguard Worker        if input_api.re.search(code_regex, line):
232*6dbdd20aSAndroid Build Coastguard Worker          errors.append(
233*6dbdd20aSAndroid Build Coastguard Worker              output_api.PresubmitError('{}:{} {}'.format(
234*6dbdd20aSAndroid Build Coastguard Worker                  f.LocalPath(), line_number, message)))
235*6dbdd20aSAndroid Build Coastguard Worker  return errors
236*6dbdd20aSAndroid Build Coastguard Worker
237*6dbdd20aSAndroid Build Coastguard Worker
238*6dbdd20aSAndroid Build Coastguard Workerdef CheckIncludeViolations(input_api, output_api):
239*6dbdd20aSAndroid Build Coastguard Worker  # The script invocation doesn't work on Windows.
240*6dbdd20aSAndroid Build Coastguard Worker  if input_api.is_windows:
241*6dbdd20aSAndroid Build Coastguard Worker    return []
242*6dbdd20aSAndroid Build Coastguard Worker
243*6dbdd20aSAndroid Build Coastguard Worker  tool = 'tools/check_include_violations'
244*6dbdd20aSAndroid Build Coastguard Worker
245*6dbdd20aSAndroid Build Coastguard Worker  def file_filter(x):
246*6dbdd20aSAndroid Build Coastguard Worker    return input_api.FilterSourceFile(
247*6dbdd20aSAndroid Build Coastguard Worker        x, files_to_check=['include/.*[.]h$', tool])
248*6dbdd20aSAndroid Build Coastguard Worker
249*6dbdd20aSAndroid Build Coastguard Worker  if not input_api.AffectedSourceFiles(file_filter):
250*6dbdd20aSAndroid Build Coastguard Worker    return []
251*6dbdd20aSAndroid Build Coastguard Worker  if subprocess.call([tool]):
252*6dbdd20aSAndroid Build Coastguard Worker    return [output_api.PresubmitError(tool + ' failed.')]
253*6dbdd20aSAndroid Build Coastguard Worker  return []
254*6dbdd20aSAndroid Build Coastguard Worker
255*6dbdd20aSAndroid Build Coastguard Worker
256*6dbdd20aSAndroid Build Coastguard Workerdef CheckIncludePaths(input_api, output_api):
257*6dbdd20aSAndroid Build Coastguard Worker
258*6dbdd20aSAndroid Build Coastguard Worker  def file_filter(x):
259*6dbdd20aSAndroid Build Coastguard Worker    return input_api.FilterSourceFile(x, files_to_check=[r'.*\.h$', r'.*\.cc$'])
260*6dbdd20aSAndroid Build Coastguard Worker
261*6dbdd20aSAndroid Build Coastguard Worker  error_lines = []
262*6dbdd20aSAndroid Build Coastguard Worker  for f in input_api.AffectedSourceFiles(file_filter):
263*6dbdd20aSAndroid Build Coastguard Worker    for line_num, line in f.ChangedContents():
264*6dbdd20aSAndroid Build Coastguard Worker      m = input_api.re.search(r'^#include "(.*\.h)"', line)
265*6dbdd20aSAndroid Build Coastguard Worker      if not m:
266*6dbdd20aSAndroid Build Coastguard Worker        continue
267*6dbdd20aSAndroid Build Coastguard Worker      inc_hdr = m.group(1)
268*6dbdd20aSAndroid Build Coastguard Worker      if inc_hdr.startswith('include/perfetto'):
269*6dbdd20aSAndroid Build Coastguard Worker        error_lines.append('  %s:%s: Redundant "include/" in #include path"' %
270*6dbdd20aSAndroid Build Coastguard Worker                           (f.LocalPath(), line_num))
271*6dbdd20aSAndroid Build Coastguard Worker      if '/' not in inc_hdr:
272*6dbdd20aSAndroid Build Coastguard Worker        error_lines.append(
273*6dbdd20aSAndroid Build Coastguard Worker            '  %s:%s: relative #include not allowed, use full path' %
274*6dbdd20aSAndroid Build Coastguard Worker            (f.LocalPath(), line_num))
275*6dbdd20aSAndroid Build Coastguard Worker  return [] if len(error_lines) == 0 else [
276*6dbdd20aSAndroid Build Coastguard Worker      output_api.PresubmitError('Invalid #include paths detected:\n' +
277*6dbdd20aSAndroid Build Coastguard Worker                                '\n'.join(error_lines))
278*6dbdd20aSAndroid Build Coastguard Worker  ]
279*6dbdd20aSAndroid Build Coastguard Worker
280*6dbdd20aSAndroid Build Coastguard Worker
281*6dbdd20aSAndroid Build Coastguard Workerdef CheckBinaryDescriptors(input_api, output_api):
282*6dbdd20aSAndroid Build Coastguard Worker  # The script invocation doesn't work on Windows.
283*6dbdd20aSAndroid Build Coastguard Worker  if input_api.is_windows:
284*6dbdd20aSAndroid Build Coastguard Worker    return []
285*6dbdd20aSAndroid Build Coastguard Worker
286*6dbdd20aSAndroid Build Coastguard Worker  tool = 'tools/gen_binary_descriptors'
287*6dbdd20aSAndroid Build Coastguard Worker
288*6dbdd20aSAndroid Build Coastguard Worker  def file_filter(x):
289*6dbdd20aSAndroid Build Coastguard Worker    return input_api.FilterSourceFile(
290*6dbdd20aSAndroid Build Coastguard Worker        x, files_to_check=['protos/perfetto/.*[.]proto$', '.*[.]h', tool])
291*6dbdd20aSAndroid Build Coastguard Worker
292*6dbdd20aSAndroid Build Coastguard Worker  if not input_api.AffectedSourceFiles(file_filter):
293*6dbdd20aSAndroid Build Coastguard Worker    return []
294*6dbdd20aSAndroid Build Coastguard Worker  if subprocess.call([tool, '--check-only']):
295*6dbdd20aSAndroid Build Coastguard Worker    return [
296*6dbdd20aSAndroid Build Coastguard Worker        output_api.PresubmitError('Please run ' + tool +
297*6dbdd20aSAndroid Build Coastguard Worker                                  ' to update binary descriptors.')
298*6dbdd20aSAndroid Build Coastguard Worker    ]
299*6dbdd20aSAndroid Build Coastguard Worker  return []
300*6dbdd20aSAndroid Build Coastguard Worker
301*6dbdd20aSAndroid Build Coastguard Worker
302*6dbdd20aSAndroid Build Coastguard Workerdef CheckMergedTraceConfigProto(input_api, output_api):
303*6dbdd20aSAndroid Build Coastguard Worker  # The script invocation doesn't work on Windows.
304*6dbdd20aSAndroid Build Coastguard Worker  if input_api.is_windows:
305*6dbdd20aSAndroid Build Coastguard Worker    return []
306*6dbdd20aSAndroid Build Coastguard Worker
307*6dbdd20aSAndroid Build Coastguard Worker  tool = 'tools/gen_merged_protos'
308*6dbdd20aSAndroid Build Coastguard Worker
309*6dbdd20aSAndroid Build Coastguard Worker  def build_file_filter(x):
310*6dbdd20aSAndroid Build Coastguard Worker    return input_api.FilterSourceFile(
311*6dbdd20aSAndroid Build Coastguard Worker        x, files_to_check=['protos/perfetto/.*[.]proto$', tool])
312*6dbdd20aSAndroid Build Coastguard Worker
313*6dbdd20aSAndroid Build Coastguard Worker  if not input_api.AffectedSourceFiles(build_file_filter):
314*6dbdd20aSAndroid Build Coastguard Worker    return []
315*6dbdd20aSAndroid Build Coastguard Worker  if subprocess.call([tool, '--check-only']):
316*6dbdd20aSAndroid Build Coastguard Worker    return [
317*6dbdd20aSAndroid Build Coastguard Worker        output_api.PresubmitError(
318*6dbdd20aSAndroid Build Coastguard Worker            'perfetto_config.proto or perfetto_trace.proto is out of ' +
319*6dbdd20aSAndroid Build Coastguard Worker            'date. Please run ' + tool + ' to update it.')
320*6dbdd20aSAndroid Build Coastguard Worker    ]
321*6dbdd20aSAndroid Build Coastguard Worker  return []
322*6dbdd20aSAndroid Build Coastguard Worker
323*6dbdd20aSAndroid Build Coastguard Worker
324*6dbdd20aSAndroid Build Coastguard Worker# Prevent removing or changing lines in event_list.
325*6dbdd20aSAndroid Build Coastguard Workerdef CheckProtoEventList(input_api, output_api):
326*6dbdd20aSAndroid Build Coastguard Worker  for f in input_api.AffectedFiles():
327*6dbdd20aSAndroid Build Coastguard Worker    if f.LocalPath() != 'src/tools/ftrace_proto_gen/event_list':
328*6dbdd20aSAndroid Build Coastguard Worker      continue
329*6dbdd20aSAndroid Build Coastguard Worker    if any((not new_line.startswith('removed')) and new_line != old_line
330*6dbdd20aSAndroid Build Coastguard Worker           for old_line, new_line in zip(f.OldContents(), f.NewContents())):
331*6dbdd20aSAndroid Build Coastguard Worker      return [
332*6dbdd20aSAndroid Build Coastguard Worker          output_api.PresubmitError(
333*6dbdd20aSAndroid Build Coastguard Worker              'event_list only has two supported changes: '
334*6dbdd20aSAndroid Build Coastguard Worker              'appending a new line, and replacing a line with removed.')
335*6dbdd20aSAndroid Build Coastguard Worker      ]
336*6dbdd20aSAndroid Build Coastguard Worker  return []
337*6dbdd20aSAndroid Build Coastguard Worker
338*6dbdd20aSAndroid Build Coastguard Worker
339*6dbdd20aSAndroid Build Coastguard Workerdef CheckProtoComments(input_api, output_api):
340*6dbdd20aSAndroid Build Coastguard Worker  # The script invocation doesn't work on Windows.
341*6dbdd20aSAndroid Build Coastguard Worker  if input_api.is_windows:
342*6dbdd20aSAndroid Build Coastguard Worker    return []
343*6dbdd20aSAndroid Build Coastguard Worker
344*6dbdd20aSAndroid Build Coastguard Worker  tool = 'tools/check_proto_comments'
345*6dbdd20aSAndroid Build Coastguard Worker
346*6dbdd20aSAndroid Build Coastguard Worker  def file_filter(x):
347*6dbdd20aSAndroid Build Coastguard Worker    return input_api.FilterSourceFile(
348*6dbdd20aSAndroid Build Coastguard Worker        x, files_to_check=['protos/perfetto/.*[.]proto$', tool])
349*6dbdd20aSAndroid Build Coastguard Worker
350*6dbdd20aSAndroid Build Coastguard Worker  if not input_api.AffectedSourceFiles(file_filter):
351*6dbdd20aSAndroid Build Coastguard Worker    return []
352*6dbdd20aSAndroid Build Coastguard Worker  if subprocess.call([tool]):
353*6dbdd20aSAndroid Build Coastguard Worker    return [output_api.PresubmitError(tool + ' failed')]
354*6dbdd20aSAndroid Build Coastguard Worker  return []
355*6dbdd20aSAndroid Build Coastguard Worker
356*6dbdd20aSAndroid Build Coastguard Worker
357*6dbdd20aSAndroid Build Coastguard Workerdef CheckSqlModules(input_api, output_api):
358*6dbdd20aSAndroid Build Coastguard Worker  # The script invocation doesn't work on Windows.
359*6dbdd20aSAndroid Build Coastguard Worker  if input_api.is_windows:
360*6dbdd20aSAndroid Build Coastguard Worker    return []
361*6dbdd20aSAndroid Build Coastguard Worker
362*6dbdd20aSAndroid Build Coastguard Worker  tool = 'tools/check_sql_modules.py'
363*6dbdd20aSAndroid Build Coastguard Worker
364*6dbdd20aSAndroid Build Coastguard Worker  def file_filter(x):
365*6dbdd20aSAndroid Build Coastguard Worker    return input_api.FilterSourceFile(
366*6dbdd20aSAndroid Build Coastguard Worker        x,
367*6dbdd20aSAndroid Build Coastguard Worker        files_to_check=[
368*6dbdd20aSAndroid Build Coastguard Worker            'src/trace_processor/perfetto_sql/stdlib/.*[.]sql$', tool
369*6dbdd20aSAndroid Build Coastguard Worker        ])
370*6dbdd20aSAndroid Build Coastguard Worker
371*6dbdd20aSAndroid Build Coastguard Worker  if not input_api.AffectedSourceFiles(file_filter):
372*6dbdd20aSAndroid Build Coastguard Worker    return []
373*6dbdd20aSAndroid Build Coastguard Worker  if subprocess.call([tool]):
374*6dbdd20aSAndroid Build Coastguard Worker    return [output_api.PresubmitError(tool + ' failed')]
375*6dbdd20aSAndroid Build Coastguard Worker  return []
376*6dbdd20aSAndroid Build Coastguard Worker
377*6dbdd20aSAndroid Build Coastguard Worker
378*6dbdd20aSAndroid Build Coastguard Workerdef CheckSqlMetrics(input_api, output_api):
379*6dbdd20aSAndroid Build Coastguard Worker  # The script invocation doesn't work on Windows.
380*6dbdd20aSAndroid Build Coastguard Worker  if input_api.is_windows:
381*6dbdd20aSAndroid Build Coastguard Worker    return []
382*6dbdd20aSAndroid Build Coastguard Worker
383*6dbdd20aSAndroid Build Coastguard Worker  tool = 'tools/check_sql_metrics.py'
384*6dbdd20aSAndroid Build Coastguard Worker
385*6dbdd20aSAndroid Build Coastguard Worker  def file_filter(x):
386*6dbdd20aSAndroid Build Coastguard Worker    return input_api.FilterSourceFile(
387*6dbdd20aSAndroid Build Coastguard Worker        x, files_to_check=['src/trace_processor/metrics/.*[.]sql$', tool])
388*6dbdd20aSAndroid Build Coastguard Worker
389*6dbdd20aSAndroid Build Coastguard Worker  if not input_api.AffectedSourceFiles(file_filter):
390*6dbdd20aSAndroid Build Coastguard Worker    return []
391*6dbdd20aSAndroid Build Coastguard Worker  if subprocess.call([tool]):
392*6dbdd20aSAndroid Build Coastguard Worker    return [output_api.PresubmitError(tool + ' failed')]
393*6dbdd20aSAndroid Build Coastguard Worker  return []
394*6dbdd20aSAndroid Build Coastguard Worker
395*6dbdd20aSAndroid Build Coastguard Worker
396*6dbdd20aSAndroid Build Coastguard Workerdef CheckTestData(input_api, output_api):
397*6dbdd20aSAndroid Build Coastguard Worker  # The script invocation doesn't work on Windows.
398*6dbdd20aSAndroid Build Coastguard Worker  if input_api.is_windows:
399*6dbdd20aSAndroid Build Coastguard Worker    return []
400*6dbdd20aSAndroid Build Coastguard Worker
401*6dbdd20aSAndroid Build Coastguard Worker  tool = 'tools/test_data'
402*6dbdd20aSAndroid Build Coastguard Worker  if subprocess.call([tool, 'status', '--quiet']):
403*6dbdd20aSAndroid Build Coastguard Worker    return [
404*6dbdd20aSAndroid Build Coastguard Worker        output_api.PresubmitError(
405*6dbdd20aSAndroid Build Coastguard Worker            '//test/data is out of sync. Run ' + tool + ' status for more. \n'
406*6dbdd20aSAndroid Build Coastguard Worker            'If you rebaselined UI tests or added a new test trace, run:'
407*6dbdd20aSAndroid Build Coastguard Worker            '`tools/test_data upload`. Otherwise run `tools/install-build-deps`'
408*6dbdd20aSAndroid Build Coastguard Worker            ' or `tools/test_data download --overwrite` to sync local test_data'
409*6dbdd20aSAndroid Build Coastguard Worker        )
410*6dbdd20aSAndroid Build Coastguard Worker    ]
411*6dbdd20aSAndroid Build Coastguard Worker  return []
412*6dbdd20aSAndroid Build Coastguard Worker
413*6dbdd20aSAndroid Build Coastguard Worker
414*6dbdd20aSAndroid Build Coastguard Workerdef CheckChromeStdlib(input_api, output_api):
415*6dbdd20aSAndroid Build Coastguard Worker  stdlib_paths = ("src/trace_processor/perfetto_sql/stdlib/chrome/",
416*6dbdd20aSAndroid Build Coastguard Worker                  "test/data/chrome/",
417*6dbdd20aSAndroid Build Coastguard Worker                  "test/trace_processor/diff_tests/stdlib/chrome/")
418*6dbdd20aSAndroid Build Coastguard Worker
419*6dbdd20aSAndroid Build Coastguard Worker  def chrome_stdlib_file_filter(x):
420*6dbdd20aSAndroid Build Coastguard Worker    return input_api.FilterSourceFile(x, files_to_check=stdlib_paths)
421*6dbdd20aSAndroid Build Coastguard Worker
422*6dbdd20aSAndroid Build Coastguard Worker  # Only check chrome stdlib files
423*6dbdd20aSAndroid Build Coastguard Worker  if not any(input_api.AffectedFiles(file_filter=chrome_stdlib_file_filter)):
424*6dbdd20aSAndroid Build Coastguard Worker    return []
425*6dbdd20aSAndroid Build Coastguard Worker
426*6dbdd20aSAndroid Build Coastguard Worker  # Always allow Copybara service to make changes to chrome stdlib
427*6dbdd20aSAndroid Build Coastguard Worker  if input_api.change.COPYBARA_IMPORT:
428*6dbdd20aSAndroid Build Coastguard Worker    return []
429*6dbdd20aSAndroid Build Coastguard Worker
430*6dbdd20aSAndroid Build Coastguard Worker  if input_api.change.CHROME_STDLIB_MANUAL_ROLL:
431*6dbdd20aSAndroid Build Coastguard Worker    return []
432*6dbdd20aSAndroid Build Coastguard Worker
433*6dbdd20aSAndroid Build Coastguard Worker  message = (
434*6dbdd20aSAndroid Build Coastguard Worker      'Files under {0} and {1} '
435*6dbdd20aSAndroid Build Coastguard Worker      'are rolled from the Chromium repository by a '
436*6dbdd20aSAndroid Build Coastguard Worker      'Copybara service.\nYou should not modify these in '
437*6dbdd20aSAndroid Build Coastguard Worker      'the Perfetto repository, please make your changes '
438*6dbdd20aSAndroid Build Coastguard Worker      'in Chromium instead.\n'
439*6dbdd20aSAndroid Build Coastguard Worker      'If you want to do a manual roll, you must specify '
440*6dbdd20aSAndroid Build Coastguard Worker      'CHROME_STDLIB_MANUAL_ROLL=<reason> in the CL description.').format(
441*6dbdd20aSAndroid Build Coastguard Worker          *stdlib_paths)
442*6dbdd20aSAndroid Build Coastguard Worker  return [output_api.PresubmitError(message)]
443*6dbdd20aSAndroid Build Coastguard Worker
444*6dbdd20aSAndroid Build Coastguard Worker
445*6dbdd20aSAndroid Build Coastguard Workerdef CheckAmalgamatedPythonTools(input_api, output_api):
446*6dbdd20aSAndroid Build Coastguard Worker  # The script invocation doesn't work on Windows.
447*6dbdd20aSAndroid Build Coastguard Worker  if input_api.is_windows:
448*6dbdd20aSAndroid Build Coastguard Worker    return []
449*6dbdd20aSAndroid Build Coastguard Worker
450*6dbdd20aSAndroid Build Coastguard Worker  tool = 'tools/gen_amalgamated_python_tools'
451*6dbdd20aSAndroid Build Coastguard Worker
452*6dbdd20aSAndroid Build Coastguard Worker  # If no GN files were modified, bail out.
453*6dbdd20aSAndroid Build Coastguard Worker  def build_file_filter(x):
454*6dbdd20aSAndroid Build Coastguard Worker    return input_api.FilterSourceFile(x, files_to_check=('python/.*$', tool))
455*6dbdd20aSAndroid Build Coastguard Worker
456*6dbdd20aSAndroid Build Coastguard Worker  if not input_api.AffectedSourceFiles(build_file_filter):
457*6dbdd20aSAndroid Build Coastguard Worker    return []
458*6dbdd20aSAndroid Build Coastguard Worker  if subprocess.call([tool, '--check-only']):
459*6dbdd20aSAndroid Build Coastguard Worker    return [
460*6dbdd20aSAndroid Build Coastguard Worker        output_api.PresubmitError(
461*6dbdd20aSAndroid Build Coastguard Worker            'amalgamated python tools/ are out of date. ' + 'Run ' + tool +
462*6dbdd20aSAndroid Build Coastguard Worker            ' to update them.')
463*6dbdd20aSAndroid Build Coastguard Worker    ]
464*6dbdd20aSAndroid Build Coastguard Worker  return []
465*6dbdd20aSAndroid Build Coastguard Worker
466*6dbdd20aSAndroid Build Coastguard Worker
467*6dbdd20aSAndroid Build Coastguard Workerdef CheckAbsolutePathsInGn(input_api, output_api):
468*6dbdd20aSAndroid Build Coastguard Worker
469*6dbdd20aSAndroid Build Coastguard Worker  def file_filter(x):
470*6dbdd20aSAndroid Build Coastguard Worker    return input_api.FilterSourceFile(
471*6dbdd20aSAndroid Build Coastguard Worker        x,
472*6dbdd20aSAndroid Build Coastguard Worker        files_to_check=[r'.*\.gni?$'],
473*6dbdd20aSAndroid Build Coastguard Worker        files_to_skip=[
474*6dbdd20aSAndroid Build Coastguard Worker            '^.gn$',
475*6dbdd20aSAndroid Build Coastguard Worker            '^gn/.*',
476*6dbdd20aSAndroid Build Coastguard Worker            '^buildtools/.*',
477*6dbdd20aSAndroid Build Coastguard Worker        ])
478*6dbdd20aSAndroid Build Coastguard Worker
479*6dbdd20aSAndroid Build Coastguard Worker  error_lines = []
480*6dbdd20aSAndroid Build Coastguard Worker  for f in input_api.AffectedSourceFiles(file_filter):
481*6dbdd20aSAndroid Build Coastguard Worker    for line_number, line in f.ChangedContents():
482*6dbdd20aSAndroid Build Coastguard Worker      if input_api.re.search(r'(^\s*[#])|([#]\s*nogncheck)', line):
483*6dbdd20aSAndroid Build Coastguard Worker        continue  # Skip comments and '# nogncheck' lines
484*6dbdd20aSAndroid Build Coastguard Worker      if input_api.re.search(r'"//[^"]', line):
485*6dbdd20aSAndroid Build Coastguard Worker        error_lines.append('  %s:%s: %s' %
486*6dbdd20aSAndroid Build Coastguard Worker                           (f.LocalPath(), line_number, line.strip()))
487*6dbdd20aSAndroid Build Coastguard Worker
488*6dbdd20aSAndroid Build Coastguard Worker  if len(error_lines) == 0:
489*6dbdd20aSAndroid Build Coastguard Worker    return []
490*6dbdd20aSAndroid Build Coastguard Worker  return [
491*6dbdd20aSAndroid Build Coastguard Worker      output_api.PresubmitError(
492*6dbdd20aSAndroid Build Coastguard Worker          'Use relative paths in GN rather than absolute:\n' +
493*6dbdd20aSAndroid Build Coastguard Worker          '\n'.join(error_lines))
494*6dbdd20aSAndroid Build Coastguard Worker  ]
495