blob: a45c497d0f744058dde03c08bd47e6ff11b29730 [file] [log] [blame]
Anush Elangovane2408fc2010-12-10 10:42:16 -08001# Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5"""Top-level presubmit script for Chromium OS.
6
7See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts
8for more details about the presubmit API built into gcl and git cl.
9"""
10
11import re
12
13_EXCLUDED_PATHS = (
14 r"^inherit-review-settings-ok$",
15 r".*[\\\/]debian[\\\/]rules$",
16)
17
18# These match files that should contain tabs as indentation.
19_TAB_OK_PATHS = (
20 r"/src/third_party/kernel/",
21 r"/src/third_party/kernel-next/",
22 r"/src/third_party/u-boot/",
23 r"/src/third_party/u-boot-next/",
24 r".*\.ebuild$",
25 r".*\.eclass$",
26)
27
28# These match files that are part of out "next" developemnt flow and as such
29# do not require a valid BUG= field to commit, but it's still a good idea.
30_NEXT_PATHS = (
31 r"/src/third_party/kernel-next",
32 r"/src/third_party/u-boot-next",
33)
34
35_LICENSE_HEADER = (
36 r".*? Copyright \(c\) 20[-0-9]{2,7} The Chromium OS Authors\. All rights "
37 r"reserved\." "\n"
38 r".*? Use of this source code is governed by a BSD-style license that can "
39 "be\n"
40 r".*? found in the LICENSE file\."
41 "\n"
42)
43
44
45def CheckAndShowLicense(input_api, output_api, source_file_filter=None):
46 """Check that the source files have a valid License header.
47
48 The license header must matches our template. If not also show the
49 header that should have been used.
50
51 """
52 results = []
53 license_check = input_api.canned_checks.CheckLicense(
54 input_api, output_api, _LICENSE_HEADER, source_file_filter)
55 results.extend(license_check)
56 if license_check:
57 results.extend([output_api.PresubmitNotifyResult(
58 "License header should match the following:",
59 long_text=_LICENSE_HEADER)])
60 return results
61
62
63def CheckChangeHasMandatoryBugField(input_api,
64 output_api,
65 source_file_filter=None):
66 """Check that the commit contains a valid BUG= field."""
67 msg = ('Changelist must reference a bug number using BUG=\n'
68 'For example, BUG=chromium-os:8205\n'
Anton Staafdecc2872011-02-11 13:33:00 -080069 'BUG=none is allowed.')
Anush Elangovane2408fc2010-12-10 10:42:16 -080070
71 if (not input_api.AffectedSourceFiles(source_file_filter) or
Anton Staafdecc2872011-02-11 13:33:00 -080072 input_api.change.BUG):
Anush Elangovane2408fc2010-12-10 10:42:16 -080073 return []
74 else:
75 return [output_api.PresubmitError(msg)]
76
77
78def CheckChangeHasBugField(input_api, output_api, source_file_filter=None):
79 # This function is required because the canned BugField check doesn't
80 # take a source filter.
81 return input_api.canned_checks.CheckChangeHasBugField(input_api,
82 output_api)
83
84
85def CheckChangeHasTestField(input_api, output_api, source_file_filter=None):
86 # This function is required because the canned TestField check doesn't
87 # take a source filter.
88 return input_api.canned_checks.CheckChangeHasTestField(input_api,
89 output_api)
90
91
92def CheckTreeIsOpen(input_api, output_api, source_file_filter=None):
93 """Make sure the tree is 'open'. If not, don't submit."""
94 return input_api.canned_checks.CheckTreeIsOpen(
95 input_api,
96 output_api,
David James81180e72011-01-31 16:40:51 -080097 json_url='http://chromiumos-status.appspot.com/current?format=json')
Anush Elangovane2408fc2010-12-10 10:42:16 -080098
99
100def CheckBuildbotPendingBuilds(input_api, output_api, source_file_filter=None):
101 """Check to see if there's a backlog on the pending CL queue"""
102 return input_api.canned_checks.CheckBuildbotPendingBuilds(
103 input_api,
104 output_api,
bradnelson54843152010-12-15 15:25:39 -0800105 'http://build.chromium.org/p/chromiumos/json/builders?filter=1',
Anush Elangovane2408fc2010-12-10 10:42:16 -0800106 6,
107 [])
108
109
110def FilterAbsoluteSourceFile(input_api, affected_file, white_list, black_list):
111 """Filters out files that aren't considered "source file".
112
113 The lists will be compiled as regular expression and
114 AffectedFile.AbsoluteLocalPath() needs to pass both list.
115
116 Note: This function was coppied from presubmit_support.py and modified to
117 check against (AbsoluteLocalPath - PresubmitLocalPath) instead of LocalPath
118 because LocalPath doesn't contain enough information to disambiguate kernel,
119 u-boot and -next files from the rest of ChromiumOS.
120
121 """
122 presubmit_local_path = input_api.PresubmitLocalPath()
123
124 def RelativePath(affected_file):
125 absolute_local_path = affected_file.AbsoluteLocalPath()
126
127 assert absolute_local_path.startswith(presubmit_local_path)
128 return absolute_local_path[len(presubmit_local_path):]
129
130 def Find(relative_path, items):
131 for item in items:
132 if re.match(item, relative_path):
133 return True
134
135 return False
136
137 relative_path = RelativePath(affected_file)
138
139 return (Find(relative_path, white_list) and
140 not Find(relative_path, black_list))
141
142def RunChecklist(input_api, output_api, checklist):
143 """Run through a set of checks provided in a checklist.
144
145 The checklist is a list of tuples, each of which contains the check to run
146 and a list of regular expressions of paths to ignore for this check
147
148 """
149 results = []
150
151 for check, paths in checklist:
152 white_list = input_api.DEFAULT_WHITE_LIST
153
154 # Construct a black list from the DEFAULT_BLACK_LIST supplied by
155 # depot_tools and the paths that this check should not be applied to.
156 #
157 # We also remove the third_party rule here because our paterns are
158 # matching against the entire path from the root of the ChromiumOS
159 # project. We use the rooted paths because we want to be able to apply
160 # some of the presubmit checks to things like the kernel and u-boot that
161 # live in the third_party directory.
162 black_list = list(input_api.DEFAULT_BLACK_LIST)
163 black_list.remove(r".*\bthird_party[\\\/].*")
164 black_list.extend(paths)
165 sources = lambda path: FilterAbsoluteSourceFile(input_api,
166 path,
167 white_list,
168 black_list)
169 results.extend(check(input_api, output_api, source_file_filter=sources))
170
171 return results
172
173
174def MakeCommonChecklist(input_api):
175 return [(input_api.canned_checks.CheckLongLines, _EXCLUDED_PATHS),
176 (input_api.canned_checks.CheckChangeHasNoStrayWhitespace,
177 _EXCLUDED_PATHS),
178 (CheckChangeHasTestField, _EXCLUDED_PATHS),
179 (CheckAndShowLicense, _EXCLUDED_PATHS),
180 (input_api.canned_checks.CheckChangeHasNoTabs,
181 _EXCLUDED_PATHS + _TAB_OK_PATHS)]
182
183
184def MakeUploadChecklist(input_api):
185 return [(CheckChangeHasBugField, _EXCLUDED_PATHS)]
186
187
188def MakeCommitChecklist(input_api):
Anton Staafdecc2872011-02-11 13:33:00 -0800189 return [(CheckChangeHasMandatoryBugField, _EXCLUDED_PATHS),
Anush Elangovane2408fc2010-12-10 10:42:16 -0800190 (CheckTreeIsOpen, _EXCLUDED_PATHS),
191 (CheckBuildbotPendingBuilds, _EXCLUDED_PATHS)]
192
193
194def CheckChangeOnUpload(input_api, output_api):
195 """On upload we check against the common and upload lists."""
196 return RunChecklist(input_api,
197 output_api,
198 MakeCommonChecklist(input_api) +
199 MakeUploadChecklist(input_api))
200
201
202def CheckChangeOnCommit(input_api, output_api):
203 """On commit we check against the common and commit lists."""
204 return RunChecklist(input_api,
205 output_api,
206 MakeCommonChecklist(input_api) +
207 MakeCommitChecklist(input_api))
208
209
210def GetPreferredTrySlaves():
211 return ['ChromiumOS x86']