Index: ROOT_PRESUBMIT.py |
diff --git a/ROOT_PRESUBMIT.py b/ROOT_PRESUBMIT.py |
new file mode 100644 |
index 0000000000000000000000000000000000000000..f59b7f5fe08c5e147cccccf2b96d35858b23c074 |
--- /dev/null |
+++ b/ROOT_PRESUBMIT.py |
@@ -0,0 +1,212 @@ |
+# Copyright (c) 2010 The Chromium OS Authors. All rights reserved. |
+# Use of this source code is governed by a BSD-style license that can be |
+# found in the LICENSE file. |
+ |
+"""Top-level presubmit script for Chromium OS. |
+ |
+See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts |
+for more details about the presubmit API built into gcl and git cl. |
+""" |
+ |
+import re |
+ |
+_EXCLUDED_PATHS = ( |
+ r"^inherit-review-settings-ok$", |
+ r".*[\\\/]debian[\\\/]rules$", |
+) |
+ |
+# These match files that should contain tabs as indentation. |
+_TAB_OK_PATHS = ( |
+ r"/src/third_party/kernel/", |
+ r"/src/third_party/kernel-next/", |
+ r"/src/third_party/u-boot/", |
+ r"/src/third_party/u-boot-next/", |
+ r".*\.ebuild$", |
+ r".*\.eclass$", |
+) |
+ |
+# These match files that are part of out "next" developemnt flow and as such |
+# do not require a valid BUG= field to commit, but it's still a good idea. |
+_NEXT_PATHS = ( |
+ r"/src/third_party/kernel-next", |
+ r"/src/third_party/u-boot-next", |
+) |
+ |
+_LICENSE_HEADER = ( |
+ r".*? Copyright \(c\) 20[-0-9]{2,7} The Chromium OS Authors\. All rights " |
+ r"reserved\." "\n" |
+ r".*? Use of this source code is governed by a BSD-style license that can " |
+ "be\n" |
+ r".*? found in the LICENSE file\." |
+ "\n" |
+) |
+ |
+ |
+def CheckAndShowLicense(input_api, output_api, source_file_filter=None): |
+ """Check that the source files have a valid License header. |
+ |
+ The license header must matches our template. If not also show the |
+ header that should have been used. |
+ |
+ """ |
+ results = [] |
+ license_check = input_api.canned_checks.CheckLicense( |
+ input_api, output_api, _LICENSE_HEADER, source_file_filter) |
+ results.extend(license_check) |
+ if license_check: |
+ results.extend([output_api.PresubmitNotifyResult( |
+ "License header should match the following:", |
+ long_text=_LICENSE_HEADER)]) |
+ return results |
+ |
+ |
+def CheckChangeHasMandatoryBugField(input_api, |
+ output_api, |
+ source_file_filter=None): |
+ """Check that the commit contains a valid BUG= field.""" |
+ msg = ('Changelist must reference a bug number using BUG=\n' |
+ 'For example, BUG=chromium-os:8205\n' |
+ 'BUG=none is not allowed.') |
+ |
+ if (not input_api.AffectedSourceFiles(source_file_filter) or |
+ (input_api.change.BUG and re.search(r"\d", input_api.change.BUG))): |
+ return [] |
+ else: |
+ return [output_api.PresubmitError(msg)] |
+ |
+ |
+def CheckChangeHasBugField(input_api, output_api, source_file_filter=None): |
+ # This function is required because the canned BugField check doesn't |
+ # take a source filter. |
+ return input_api.canned_checks.CheckChangeHasBugField(input_api, |
+ output_api) |
+ |
+ |
+def CheckChangeHasTestField(input_api, output_api, source_file_filter=None): |
+ # This function is required because the canned TestField check doesn't |
+ # take a source filter. |
+ return input_api.canned_checks.CheckChangeHasTestField(input_api, |
+ output_api) |
+ |
+ |
+def CheckTreeIsOpen(input_api, output_api, source_file_filter=None): |
+ """Make sure the tree is 'open'. If not, don't submit.""" |
+ return input_api.canned_checks.CheckTreeIsOpen( |
+ input_api, |
+ output_api, |
+ 'http://chromiumos-status.appspot.com/current?format=raw', |
+ '.*closed.*') |
+ |
+ |
+def CheckBuildbotPendingBuilds(input_api, output_api, source_file_filter=None): |
+ """Check to see if there's a backlog on the pending CL queue""" |
+ return input_api.canned_checks.CheckBuildbotPendingBuilds( |
+ input_api, |
+ output_api, |
+ 'http://build.chromium.org/buildbot/chromiumos/json/builders?filter=1', |
+ 6, |
+ []) |
+ |
+ |
+def FilterAbsoluteSourceFile(input_api, affected_file, white_list, black_list): |
+ """Filters out files that aren't considered "source file". |
+ |
+ The lists will be compiled as regular expression and |
+ AffectedFile.AbsoluteLocalPath() needs to pass both list. |
+ |
+ Note: This function was coppied from presubmit_support.py and modified to |
+ check against (AbsoluteLocalPath - PresubmitLocalPath) instead of LocalPath |
+ because LocalPath doesn't contain enough information to disambiguate kernel, |
+ u-boot and -next files from the rest of ChromiumOS. |
+ |
+ """ |
+ presubmit_local_path = input_api.PresubmitLocalPath() |
+ |
+ def RelativePath(affected_file): |
+ absolute_local_path = affected_file.AbsoluteLocalPath() |
+ |
+ assert absolute_local_path.startswith(presubmit_local_path) |
+ return absolute_local_path[len(presubmit_local_path):] |
+ |
+ def Find(relative_path, items): |
+ for item in items: |
+ if re.match(item, relative_path): |
+ return True |
+ |
+ return False |
+ |
+ relative_path = RelativePath(affected_file) |
+ |
+ return (Find(relative_path, white_list) and |
+ not Find(relative_path, black_list)) |
+ |
+def RunChecklist(input_api, output_api, checklist): |
+ """Run through a set of checks provided in a checklist. |
+ |
+ The checklist is a list of tuples, each of which contains the check to run |
+ and a list of regular expressions of paths to ignore for this check |
+ |
+ """ |
+ results = [] |
+ |
+ for check, paths in checklist: |
+ white_list = input_api.DEFAULT_WHITE_LIST |
+ |
+ # Construct a black list from the DEFAULT_BLACK_LIST supplied by |
+ # depot_tools and the paths that this check should not be applied to. |
+ # |
+ # We also remove the third_party rule here because our paterns are |
+ # matching against the entire path from the root of the ChromiumOS |
+ # project. We use the rooted paths because we want to be able to apply |
+ # some of the presubmit checks to things like the kernel and u-boot that |
+ # live in the third_party directory. |
+ black_list = list(input_api.DEFAULT_BLACK_LIST) |
+ black_list.remove(r".*\bthird_party[\\\/].*") |
+ black_list.extend(paths) |
+ sources = lambda path: FilterAbsoluteSourceFile(input_api, |
+ path, |
+ white_list, |
+ black_list) |
+ results.extend(check(input_api, output_api, source_file_filter=sources)) |
+ |
+ return results |
+ |
+ |
+def MakeCommonChecklist(input_api): |
+ return [(input_api.canned_checks.CheckLongLines, _EXCLUDED_PATHS), |
+ (input_api.canned_checks.CheckChangeHasNoStrayWhitespace, |
+ _EXCLUDED_PATHS), |
+ (CheckChangeHasTestField, _EXCLUDED_PATHS), |
+ (CheckAndShowLicense, _EXCLUDED_PATHS), |
+ (input_api.canned_checks.CheckChangeHasNoTabs, |
+ _EXCLUDED_PATHS + _TAB_OK_PATHS)] |
+ |
+ |
+def MakeUploadChecklist(input_api): |
+ return [(CheckChangeHasBugField, _EXCLUDED_PATHS)] |
+ |
+ |
+def MakeCommitChecklist(input_api): |
+ return [(CheckChangeHasMandatoryBugField, _EXCLUDED_PATHS + _NEXT_PATHS), |
+ (CheckTreeIsOpen, _EXCLUDED_PATHS), |
+ (CheckBuildbotPendingBuilds, _EXCLUDED_PATHS)] |
+ |
+ |
+def CheckChangeOnUpload(input_api, output_api): |
+ """On upload we check against the common and upload lists.""" |
+ return RunChecklist(input_api, |
+ output_api, |
+ MakeCommonChecklist(input_api) + |
+ MakeUploadChecklist(input_api)) |
+ |
+ |
+def CheckChangeOnCommit(input_api, output_api): |
+ """On commit we check against the common and commit lists.""" |
+ return RunChecklist(input_api, |
+ output_api, |
+ MakeCommonChecklist(input_api) + |
+ MakeCommitChecklist(input_api)) |
+ |
+ |
+def GetPreferredTrySlaves(): |
+ return ['ChromiumOS x86'] |