summaryrefslogtreecommitdiff
path: root/PRESUBMIT.py
diff options
context:
space:
mode:
Diffstat (limited to 'PRESUBMIT.py')
-rw-r--r--PRESUBMIT.py202
1 files changed, 202 insertions, 0 deletions
diff --git a/PRESUBMIT.py b/PRESUBMIT.py
new file mode 100644
index 0000000..58be26d
--- /dev/null
+++ b/PRESUBMIT.py
@@ -0,0 +1,202 @@
+# Copyright (c) 2021, Google Inc. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+#
+# * Neither the name of Google nor the names of its contributors may
+# be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+"""Top-level presubmit script for libwebm.
+
+See https://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts for
+details on the presubmit API built into depot_tools.
+"""
+import re
+import subprocess2
+
+USE_PYTHON3 = True
+_BASH_INDENTATION = "2"
+_GIT_COMMIT_SUBJECT_LENGTH = 65
+_INCLUDE_BASH_FILES_ONLY = [r".*\.sh$"]
+_INCLUDE_SOURCE_FILES_ONLY = [r".*\.(c|cc|[hc]pp|h)$"]
+_LIBWEBM_MAX_LINE_LENGTH = 80
+
+
+def _CheckCommitSubjectLength(input_api, output_api):
+ """Ensures commit's subject length is no longer than 65 chars."""
+ name = "git-commit subject"
+ cmd = ["git", "log", "-1", "--pretty=%s"]
+ start = input_api.time.time()
+ proc = subprocess2.Popen(
+ cmd,
+ stderr=subprocess2.PIPE,
+ stdout=subprocess2.PIPE,
+ universal_newlines=True)
+
+ stdout, _ = proc.communicate()
+ duration = input_api.time.time() - start
+
+ if not re.match(r"^Revert",
+ stdout) and (len(stdout) - 1) > _GIT_COMMIT_SUBJECT_LENGTH:
+ failure_msg = (
+ "The commit subject: %s is too long (%d chars)\n"
+ "Try to keep this to 50 or less (up to 65 is permitted for "
+ "non-reverts).\n"
+ "https://www.git-scm.com/book/en/v2/Distributed-Git-Contributing-to-a-"
+ "Project#_commit_guidelines") % (stdout, len(stdout) - 1)
+ return output_api.PresubmitError("%s\n (%4.2fs) failed\n%s" %
+ (name, duration, failure_msg))
+
+ return output_api.PresubmitResult("%s\n (%4.2fs) success" % (name, duration))
+
+
+def _GetFilesToSkip(input_api):
+ """Skips libwebm-specific files."""
+ return list(input_api.DEFAULT_FILES_TO_SKIP) + [
+ r"\.pylintrc$",
+ ]
+
+
+def _CheckChangeLintsClean(input_api, output_api):
+ """Makes sure that libwebm/ code is cpplint clean."""
+ sources = lambda x: input_api.FilterSourceFile(
+ x, files_to_check=_INCLUDE_SOURCE_FILES_ONLY, files_to_skip=None)
+ return input_api.canned_checks.CheckChangeLintsClean(input_api, output_api,
+ sources)
+
+
+def _RunShellCheckCmd(input_api, output_api, bash_file):
+ """shellcheck command wrapper."""
+ cmd = ["shellcheck", "-x", "-oall", "-sbash", bash_file]
+ name = "Check %s file." % bash_file
+ start = input_api.time.time()
+ output, rc = subprocess2.communicate(
+ cmd, stdout=None, stderr=subprocess2.PIPE, universal_newlines=True)
+ duration = input_api.time.time() - start
+ if rc == 0:
+ return output_api.PresubmitResult("%s\n%s (%4.2fs)\n" %
+ (name, " ".join(cmd), duration))
+ return output_api.PresubmitError("%s\n%s (%4.2fs) failed\n%s" %
+ (name, " ".join(cmd), duration, output[1]))
+
+
+def _RunShfmtCheckCmd(input_api, output_api, bash_file):
+ """shfmt command wrapper."""
+ cmd = [
+ "shfmt", "-i", _BASH_INDENTATION, "-bn", "-ci", "-sr", "-kp", "-d",
+ bash_file
+ ]
+ name = "Check %s file." % bash_file
+ start = input_api.time.time()
+ output, rc = subprocess2.communicate(
+ cmd, stdout=None, stderr=subprocess2.PIPE, universal_newlines=True)
+ duration = input_api.time.time() - start
+ if rc == 0:
+ return output_api.PresubmitResult("%s\n%s (%4.2fs)\n" %
+ (name, " ".join(cmd), duration))
+ return output_api.PresubmitError("%s\n%s (%4.2fs) failed\n%s" %
+ (name, " ".join(cmd), duration, output[1]))
+
+
+def _RunCmdOnCheckedFiles(input_api, output_api, run_cmd, files_to_check):
+ """Ensure that libwebm/ files are clean."""
+ file_filter = lambda x: input_api.FilterSourceFile(
+ x, files_to_check=files_to_check, files_to_skip=None)
+
+ affected_files = input_api.change.AffectedFiles(file_filter=file_filter)
+ results = [
+ run_cmd(input_api, output_api, f.AbsoluteLocalPath())
+ for f in affected_files
+ ]
+ return results
+
+
+def _CommonChecks(input_api, output_api):
+ results = []
+ results.extend(
+ input_api.canned_checks.CheckChangeHasNoCrAndHasOnlyOneEol(
+ input_api, output_api))
+ results.extend(
+ input_api.canned_checks.CheckChangeHasNoTabs(input_api, output_api))
+ results.extend(
+ input_api.canned_checks.CheckChangeHasNoStrayWhitespace(
+ input_api, output_api))
+ results.append(_CheckCommitSubjectLength(input_api, output_api))
+
+ source_file_filter = lambda x: input_api.FilterSourceFile(
+ x, files_to_skip=_GetFilesToSkip(input_api))
+ results.extend(
+ input_api.canned_checks.CheckLongLines(
+ input_api,
+ output_api,
+ maxlen=_LIBWEBM_MAX_LINE_LENGTH,
+ source_file_filter=source_file_filter))
+
+ results.extend(
+ input_api.canned_checks.CheckPatchFormatted(
+ input_api,
+ output_api,
+ check_clang_format=True,
+ check_python=True,
+ result_factory=output_api.PresubmitError))
+ results.extend(_CheckChangeLintsClean(input_api, output_api))
+
+ # Run pylint.
+ results.extend(
+ input_api.canned_checks.RunPylint(
+ input_api,
+ output_api,
+ files_to_skip=_GetFilesToSkip(input_api),
+ pylintrc=".pylintrc",
+ version="2.7"))
+
+ # Binaries shellcheck and shfmt are not installed in depot_tools.
+ # Installation is needed
+ try:
+ subprocess2.communicate(["shellcheck", "--version"])
+ results.extend(
+ _RunCmdOnCheckedFiles(input_api, output_api, _RunShellCheckCmd,
+ _INCLUDE_BASH_FILES_ONLY))
+ print("shfmt")
+ subprocess2.communicate(["shfmt", "-version"])
+ results.extend(
+ _RunCmdOnCheckedFiles(input_api, output_api, _RunShfmtCheckCmd,
+ _INCLUDE_BASH_FILES_ONLY))
+ except OSError as os_error:
+ results.append(
+ output_api.PresubmitPromptWarning(
+ "%s\nPlease install missing binaries locally." % os_error.args[0]))
+ return results
+
+
+def CheckChangeOnUpload(input_api, output_api):
+ results = []
+ results.extend(_CommonChecks(input_api, output_api))
+ return results
+
+
+def CheckChangeOnCommit(input_api, output_api):
+ results = []
+ results.extend(_CommonChecks(input_api, output_api))
+ return results