blob: de83d12ea70daeac16abc7ca9dcb7a8d9d6292a5 [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
10from subprocess import call
11
Jamie Madill73397e82019-01-09 10:33:16 -050012# Fragment of a regular expression that matches C++ and Objective-C++ implementation files.
13_IMPLEMENTATION_EXTENSIONS = r'\.(cc|cpp|cxx|mm)$'
14
Jamie Madill73397e82019-01-09 10:33:16 -050015# Fragment of a regular expression that matches C++ and Objective-C++ header files.
16_HEADER_EXTENSIONS = r'\.(h|hpp|hxx)$'
17
18
Jamie Madill9e438ee2019-07-05 08:44:23 -040019def _CheckChangeHasBugField(input_api, output_api):
20 """Requires that the changelist have a Bug: field."""
21 bugs = input_api.change.BugsFromDescription()
22 if not bugs:
23 return [
24 output_api.PresubmitError(
25 'If this change has an associated bug, add Bug: angleproject:[bug number].')
26 ]
27 elif not all([' ' not in bug for bug in bugs]):
28 return [
29 output_api.PresubmitError(
30 'Check bug tag formatting. Ensure there are no spaces after the colon.')
31 ]
32 else:
33 return []
34
35
Jamie Madill73397e82019-01-09 10:33:16 -050036def _CheckCodeGeneration(input_api, output_api):
Jamie Madill04e9e552019-04-01 14:40:21 -040037
38 class Msg(output_api.PresubmitError):
Geoff Langd7d42392019-05-06 13:15:35 -040039 """Specialized error message"""
40
41 def __init__(self, message):
42 super(output_api.PresubmitError, self).__init__(
43 message,
Jamie Madill9e438ee2019-07-05 08:44:23 -040044 long_text='Please run scripts/run_code_generation.py to refresh generated hashes.\n'
45 '\n'
46 'If that fails, ensure your ANGLE repositiory is synced to tip-of-tree\n'
47 'and all ANGLE DEPS are fully up-to-date by running gclient sync.\n'
48 '\n'
49 'If you are building ANGLE inside Chromium you must bootstrap ANGLE\n'
50 'before gclient sync. See the DevSetup documentation for more details.\n')
Jamie Madill04e9e552019-04-01 14:40:21 -040051
Shahbaz Youssefi98a35502019-01-08 22:09:39 -050052 code_gen_path = input_api.os_path.join(input_api.PresubmitLocalPath(),
53 'scripts/run_code_generation.py')
54 cmd_name = 'run_code_generation'
55 cmd = [input_api.python_executable, code_gen_path, '--verify-no-dirty']
Geoff Langd7d42392019-05-06 13:15:35 -040056 test_cmd = input_api.Command(name=cmd_name, cmd=cmd, kwargs={}, message=Msg)
Shahbaz Youssefi98a35502019-01-08 22:09:39 -050057 if input_api.verbose:
58 print('Running ' + cmd_name)
59 return input_api.RunTests([test_cmd])
60
Shahbaz Youssefi98a35502019-01-08 22:09:39 -050061
Jamie Madill73397e82019-01-09 10:33:16 -050062# Taken directly from Chromium's PRESUBMIT.py
63def _CheckNewHeaderWithoutGnChange(input_api, output_api):
Geoff Langd7d42392019-05-06 13:15:35 -040064 """Checks that newly added header files have corresponding GN changes.
Jamie Madill73397e82019-01-09 10:33:16 -050065 Note that this is only a heuristic. To be precise, run script:
66 build/check_gn_headers.py.
67 """
68
Geoff Langd7d42392019-05-06 13:15:35 -040069 def headers(f):
70 return input_api.FilterSourceFile(f, white_list=(r'.+%s' % _HEADER_EXTENSIONS,))
Jamie Madill73397e82019-01-09 10:33:16 -050071
Geoff Langd7d42392019-05-06 13:15:35 -040072 new_headers = []
73 for f in input_api.AffectedSourceFiles(headers):
74 if f.Action() != 'A':
75 continue
76 new_headers.append(f.LocalPath())
Jamie Madill73397e82019-01-09 10:33:16 -050077
Geoff Langd7d42392019-05-06 13:15:35 -040078 def gn_files(f):
79 return input_api.FilterSourceFile(f, white_list=(r'.+\.gn',))
Jamie Madill73397e82019-01-09 10:33:16 -050080
Geoff Langd7d42392019-05-06 13:15:35 -040081 all_gn_changed_contents = ''
82 for f in input_api.AffectedSourceFiles(gn_files):
83 for _, line in f.ChangedContents():
84 all_gn_changed_contents += line
Jamie Madill73397e82019-01-09 10:33:16 -050085
Geoff Langd7d42392019-05-06 13:15:35 -040086 problems = []
87 for header in new_headers:
88 basename = input_api.os_path.basename(header)
89 if basename not in all_gn_changed_contents:
90 problems.append(header)
Jamie Madill73397e82019-01-09 10:33:16 -050091
Geoff Langd7d42392019-05-06 13:15:35 -040092 if problems:
93 return [
94 output_api.PresubmitPromptWarning(
95 'Missing GN changes for new header files',
96 items=sorted(problems),
97 long_text='Please double check whether newly added header files need '
98 'corresponding changes in gn or gni files.\nThis checking is only a '
99 'heuristic. Run build/check_gn_headers.py to be precise.\n'
100 'Read https://crbug.com/661774 for more info.')
101 ]
102 return []
Jamie Madill73397e82019-01-09 10:33:16 -0500103
104
105def CheckChangeOnUpload(input_api, output_api):
106 results = []
107 results.extend(_CheckCodeGeneration(input_api, output_api))
Jamie Madill9e438ee2019-07-05 08:44:23 -0400108 results.extend(_CheckChangeHasBugField(input_api, output_api))
Geoff Langd7d42392019-05-06 13:15:35 -0400109 results.extend(input_api.canned_checks.CheckChangeHasDescription(input_api, output_api))
Jamie Madill73397e82019-01-09 10:33:16 -0500110 results.extend(_CheckNewHeaderWithoutGnChange(input_api, output_api))
Jamie Madill9e438ee2019-07-05 08:44:23 -0400111 results.extend(
112 input_api.canned_checks.CheckPatchFormatted(
113 input_api, output_api, result_factory=output_api.PresubmitError))
Jamie Madill73397e82019-01-09 10:33:16 -0500114 return results
115
Shahbaz Youssefi98a35502019-01-08 22:09:39 -0500116
117def CheckChangeOnCommit(input_api, output_api):
Jamie Madill73397e82019-01-09 10:33:16 -0500118 results = []
Jamie Madill04e9e552019-04-01 14:40:21 -0400119 results.extend(_CheckCodeGeneration(input_api, output_api))
Jamie Madill9e438ee2019-07-05 08:44:23 -0400120 results.extend(
121 input_api.canned_checks.CheckPatchFormatted(
122 input_api, output_api, result_factory=output_api.PresubmitError))
123 results.extend(_CheckChangeHasBugField(input_api, output_api))
Geoff Langd7d42392019-05-06 13:15:35 -0400124 results.extend(input_api.canned_checks.CheckChangeHasDescription(input_api, output_api))
Jamie Madill73397e82019-01-09 10:33:16 -0500125 return results