blob: 13547a448be11d0501f4699333fcddb8ca8d845b [file] [log] [blame]
Shahbaz Youssefi98a35502019-01-08 22:09:39 -05001# Copyright 2019 The ANGLE Project Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
Shahbaz Youssefi98a35502019-01-08 22:09:39 -05004"""Top-level presubmit script for code generation.
5
6See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts
7for more details on the presubmit API built into depot_tools.
8"""
9
Brian Sheedycc4d8332019-09-11 17:26:00 -070010import os
11import shutil
12import subprocess
13import sys
14import tempfile
Shahbaz Youssefi98a35502019-01-08 22:09:39 -050015
Jamie Madill73397e82019-01-09 10:33:16 -050016# Fragment of a regular expression that matches C++ and Objective-C++ implementation files.
17_IMPLEMENTATION_EXTENSIONS = r'\.(cc|cpp|cxx|mm)$'
18
Jamie Madill73397e82019-01-09 10:33:16 -050019# Fragment of a regular expression that matches C++ and Objective-C++ header files.
20_HEADER_EXTENSIONS = r'\.(h|hpp|hxx)$'
21
Brian Sheedycc4d8332019-09-11 17:26:00 -070022_PRIMARY_EXPORT_TARGETS = [
23 '//:libEGL',
24 '//:libGLESv1_CM',
25 '//:libGLESv2',
26 '//:translator',
27]
28
Jamie Madill73397e82019-01-09 10:33:16 -050029
Jamie Madill9e438ee2019-07-05 08:44:23 -040030def _CheckChangeHasBugField(input_api, output_api):
31 """Requires that the changelist have a Bug: field."""
32 bugs = input_api.change.BugsFromDescription()
33 if not bugs:
34 return [
Alexis Hetu4210e492019-10-10 14:22:03 -040035 output_api.PresubmitError('Please ensure that your description contains:\n'
36 '"Bug: angleproject:[bug number]"\n'
37 'directly above the Change-Id tag.')
Jamie Madill9e438ee2019-07-05 08:44:23 -040038 ]
39 elif not all([' ' not in bug for bug in bugs]):
40 return [
41 output_api.PresubmitError(
42 'Check bug tag formatting. Ensure there are no spaces after the colon.')
43 ]
44 else:
45 return []
46
47
Jamie Madill73397e82019-01-09 10:33:16 -050048def _CheckCodeGeneration(input_api, output_api):
Jamie Madill04e9e552019-04-01 14:40:21 -040049
50 class Msg(output_api.PresubmitError):
Geoff Langd7d42392019-05-06 13:15:35 -040051 """Specialized error message"""
52
53 def __init__(self, message):
54 super(output_api.PresubmitError, self).__init__(
55 message,
Jamie Madill8dfc2b02019-11-25 15:12:58 -050056 long_text='Please ensure your ANGLE repositiory is synced to tip-of-tree\n'
Jamie Madill9e438ee2019-07-05 08:44:23 -040057 'and all ANGLE DEPS are fully up-to-date by running gclient sync.\n'
58 '\n'
Jamie Madill8dfc2b02019-11-25 15:12:58 -050059 'If that fails, run scripts/run_code_generation.py to refresh generated hashes.\n'
60 '\n'
Jamie Madill9e438ee2019-07-05 08:44:23 -040061 'If you are building ANGLE inside Chromium you must bootstrap ANGLE\n'
62 'before gclient sync. See the DevSetup documentation for more details.\n')
Jamie Madill04e9e552019-04-01 14:40:21 -040063
Shahbaz Youssefi98a35502019-01-08 22:09:39 -050064 code_gen_path = input_api.os_path.join(input_api.PresubmitLocalPath(),
65 'scripts/run_code_generation.py')
66 cmd_name = 'run_code_generation'
67 cmd = [input_api.python_executable, code_gen_path, '--verify-no-dirty']
Geoff Langd7d42392019-05-06 13:15:35 -040068 test_cmd = input_api.Command(name=cmd_name, cmd=cmd, kwargs={}, message=Msg)
Shahbaz Youssefi98a35502019-01-08 22:09:39 -050069 if input_api.verbose:
70 print('Running ' + cmd_name)
71 return input_api.RunTests([test_cmd])
72
Shahbaz Youssefi98a35502019-01-08 22:09:39 -050073
Jamie Madill73397e82019-01-09 10:33:16 -050074# Taken directly from Chromium's PRESUBMIT.py
75def _CheckNewHeaderWithoutGnChange(input_api, output_api):
Geoff Langd7d42392019-05-06 13:15:35 -040076 """Checks that newly added header files have corresponding GN changes.
Jamie Madill73397e82019-01-09 10:33:16 -050077 Note that this is only a heuristic. To be precise, run script:
78 build/check_gn_headers.py.
79 """
80
Geoff Langd7d42392019-05-06 13:15:35 -040081 def headers(f):
82 return input_api.FilterSourceFile(f, white_list=(r'.+%s' % _HEADER_EXTENSIONS,))
Jamie Madill73397e82019-01-09 10:33:16 -050083
Geoff Langd7d42392019-05-06 13:15:35 -040084 new_headers = []
85 for f in input_api.AffectedSourceFiles(headers):
86 if f.Action() != 'A':
87 continue
88 new_headers.append(f.LocalPath())
Jamie Madill73397e82019-01-09 10:33:16 -050089
Geoff Langd7d42392019-05-06 13:15:35 -040090 def gn_files(f):
91 return input_api.FilterSourceFile(f, white_list=(r'.+\.gn',))
Jamie Madill73397e82019-01-09 10:33:16 -050092
Geoff Langd7d42392019-05-06 13:15:35 -040093 all_gn_changed_contents = ''
94 for f in input_api.AffectedSourceFiles(gn_files):
95 for _, line in f.ChangedContents():
96 all_gn_changed_contents += line
Jamie Madill73397e82019-01-09 10:33:16 -050097
Geoff Langd7d42392019-05-06 13:15:35 -040098 problems = []
99 for header in new_headers:
100 basename = input_api.os_path.basename(header)
101 if basename not in all_gn_changed_contents:
102 problems.append(header)
Jamie Madill73397e82019-01-09 10:33:16 -0500103
Geoff Langd7d42392019-05-06 13:15:35 -0400104 if problems:
105 return [
106 output_api.PresubmitPromptWarning(
107 'Missing GN changes for new header files',
108 items=sorted(problems),
109 long_text='Please double check whether newly added header files need '
110 'corresponding changes in gn or gni files.\nThis checking is only a '
111 'heuristic. Run build/check_gn_headers.py to be precise.\n'
112 'Read https://crbug.com/661774 for more info.')
113 ]
114 return []
Jamie Madill73397e82019-01-09 10:33:16 -0500115
116
Brian Sheedycc4d8332019-09-11 17:26:00 -0700117def _CheckExportValidity(input_api, output_api):
118 outdir = tempfile.mkdtemp()
119 # shell=True is necessary on Windows, as otherwise subprocess fails to find
120 # either 'gn' or 'vpython3' even if they are findable via PATH.
121 use_shell = input_api.is_windows
122 try:
123 try:
124 subprocess.check_output(['gn', 'gen', outdir], shell=use_shell)
125 except subprocess.CalledProcessError as e:
126 return [
127 output_api.PresubmitError(
128 'Unable to run gn gen for export_targets.py: %s' % e.output)
129 ]
130 export_target_script = os.path.join(input_api.PresubmitLocalPath(), 'scripts',
131 'export_targets.py')
132 try:
133 subprocess.check_output(
134 ['vpython3', export_target_script, outdir] + _PRIMARY_EXPORT_TARGETS,
135 stderr=subprocess.STDOUT,
136 shell=use_shell)
137 except subprocess.CalledProcessError as e:
138 if input_api.is_committing:
139 return [output_api.PresubmitError('export_targets.py failed: %s' % e.output)]
140 return [
141 output_api.PresubmitPromptWarning(
142 'export_targets.py failed, this may just be due to your local checkout: %s' %
143 e.output)
144 ]
145 return []
146 finally:
147 shutil.rmtree(outdir)
148
149
Jamie Madill73397e82019-01-09 10:33:16 -0500150def CheckChangeOnUpload(input_api, output_api):
151 results = []
152 results.extend(_CheckCodeGeneration(input_api, output_api))
Jamie Madill9e438ee2019-07-05 08:44:23 -0400153 results.extend(_CheckChangeHasBugField(input_api, output_api))
Geoff Langd7d42392019-05-06 13:15:35 -0400154 results.extend(input_api.canned_checks.CheckChangeHasDescription(input_api, output_api))
Jamie Madill73397e82019-01-09 10:33:16 -0500155 results.extend(_CheckNewHeaderWithoutGnChange(input_api, output_api))
Brian Sheedycc4d8332019-09-11 17:26:00 -0700156 results.extend(_CheckExportValidity(input_api, output_api))
Jamie Madill9e438ee2019-07-05 08:44:23 -0400157 results.extend(
158 input_api.canned_checks.CheckPatchFormatted(
159 input_api, output_api, result_factory=output_api.PresubmitError))
Jamie Madill73397e82019-01-09 10:33:16 -0500160 return results
161
Shahbaz Youssefi98a35502019-01-08 22:09:39 -0500162
163def CheckChangeOnCommit(input_api, output_api):
Jamie Madill73397e82019-01-09 10:33:16 -0500164 results = []
Jamie Madill04e9e552019-04-01 14:40:21 -0400165 results.extend(_CheckCodeGeneration(input_api, output_api))
Jamie Madill9e438ee2019-07-05 08:44:23 -0400166 results.extend(
167 input_api.canned_checks.CheckPatchFormatted(
168 input_api, output_api, result_factory=output_api.PresubmitError))
169 results.extend(_CheckChangeHasBugField(input_api, output_api))
Brian Sheedycc4d8332019-09-11 17:26:00 -0700170 results.extend(_CheckExportValidity(input_api, output_api))
Geoff Langd7d42392019-05-06 13:15:35 -0400171 results.extend(input_api.canned_checks.CheckChangeHasDescription(input_api, output_api))
Jamie Madill73397e82019-01-09 10:33:16 -0500172 return results