Index: source/libvpx/tools/lint-hunks.py |
=================================================================== |
--- source/libvpx/tools/lint-hunks.py (revision 0) |
+++ source/libvpx/tools/lint-hunks.py (revision 0) |
@@ -0,0 +1,144 @@ |
+#!/usr/bin/python |
+## Copyright (c) 2012 The WebM project authors. All Rights Reserved. |
+## |
+## Use of this source code is governed by a BSD-style license |
+## that can be found in the LICENSE file in the root of the source |
+## tree. An additional intellectual property rights grant can be found |
+## in the file PATENTS. All contributing project authors may |
+## be found in the AUTHORS file in the root of the source tree. |
+## |
+"""Performs style checking on each diff hunk.""" |
+import getopt |
+import os |
+import StringIO |
+import subprocess |
+import sys |
+ |
+import diff |
+ |
+ |
+SHORT_OPTIONS = "h" |
+LONG_OPTIONS = ["help"] |
+ |
+TOPLEVEL_CMD = ["git", "rev-parse", "--show-toplevel"] |
+DIFF_CMD = ["git", "diff"] |
+DIFF_INDEX_CMD = ["git", "diff-index", "-u", "HEAD", "--"] |
+SHOW_CMD = ["git", "show"] |
+CPPLINT_FILTERS = ["-readability/casting", "-runtime/int"] |
+ |
+ |
+class Usage(Exception): |
+ pass |
+ |
+ |
+class SubprocessException(Exception): |
+ def __init__(self, args): |
+ msg = "Failed to execute '%s'"%(" ".join(args)) |
+ super(SubprocessException, self).__init__(msg) |
+ |
+ |
+class Subprocess(subprocess.Popen): |
+ """Adds the notion of an expected returncode to Popen.""" |
+ |
+ def __init__(self, args, expected_returncode=0, **kwargs): |
+ self._args = args |
+ self._expected_returncode = expected_returncode |
+ super(Subprocess, self).__init__(args, **kwargs) |
+ |
+ def communicate(self, *args, **kwargs): |
+ result = super(Subprocess, self).communicate(*args, **kwargs) |
+ if self._expected_returncode is not None: |
+ try: |
+ ok = self.returncode in self._expected_returncode |
+ except TypeError: |
+ ok = self.returncode == self._expected_returncode |
+ if not ok: |
+ raise SubprocessException(self._args) |
+ return result |
+ |
+ |
+def main(argv=None): |
+ if argv is None: |
+ argv = sys.argv |
+ try: |
+ try: |
+ opts, args = getopt.getopt(argv[1:], SHORT_OPTIONS, LONG_OPTIONS) |
+ except getopt.error, msg: |
+ raise Usage(msg) |
+ |
+ # process options |
+ for o, _ in opts: |
+ if o in ("-h", "--help"): |
+ print __doc__ |
+ sys.exit(0) |
+ |
+ if args and len(args) > 1: |
+ print __doc__ |
+ sys.exit(0) |
+ |
+ # Find the fully qualified path to the root of the tree |
+ tl = Subprocess(TOPLEVEL_CMD, stdout=subprocess.PIPE) |
+ tl = tl.communicate()[0].strip() |
+ |
+ # See if we're working on the index or not. |
+ if args: |
+ diff_cmd = DIFF_CMD + [args[0] + "^!"] |
+ else: |
+ diff_cmd = DIFF_INDEX_CMD |
+ |
+ # Build the command line to execute cpplint |
+ cpplint_cmd = [os.path.join(tl, "tools", "cpplint.py"), |
+ "--filter=" + ",".join(CPPLINT_FILTERS), |
+ "-"] |
+ |
+ # Get a list of all affected lines |
+ file_affected_line_map = {} |
+ p = Subprocess(diff_cmd, stdout=subprocess.PIPE) |
+ stdout = p.communicate()[0] |
+ for hunk in diff.ParseDiffHunks(StringIO.StringIO(stdout)): |
+ filename = hunk.right.filename[2:] |
+ if filename not in file_affected_line_map: |
+ file_affected_line_map[filename] = set() |
+ file_affected_line_map[filename].update(hunk.right.delta_line_nums) |
+ |
+ # Run each affected file through cpplint |
+ lint_failed = False |
+ for filename, affected_lines in file_affected_line_map.iteritems(): |
+ if filename.split(".")[-1] not in ("c", "h", "cc"): |
+ continue |
+ |
+ if args: |
+ # File contents come from git |
+ show_cmd = SHOW_CMD + [args[0] + ":" + filename] |
+ show = Subprocess(show_cmd, stdout=subprocess.PIPE) |
+ lint = Subprocess(cpplint_cmd, expected_returncode=(0, 1), |
+ stdin=show.stdout, stderr=subprocess.PIPE) |
+ lint_out = lint.communicate()[1] |
+ else: |
+ # File contents come from the working tree |
+ lint = Subprocess(cpplint_cmd, expected_returncode=(0, 1), |
+ stdin=subprocess.PIPE, stderr=subprocess.PIPE) |
+ stdin = open(os.path.join(tl, filename)).read() |
+ lint_out = lint.communicate(stdin)[1] |
+ |
+ for line in lint_out.split("\n"): |
+ fields = line.split(":") |
+ if fields[0] != "-": |
+ continue |
+ warning_line_num = int(fields[1]) |
+ if warning_line_num in affected_lines: |
+ print "%s:%d:%s"%(filename, warning_line_num, |
+ ":".join(fields[2:])) |
+ lint_failed = True |
+ |
+ # Set exit code if any relevant lint errors seen |
+ if lint_failed: |
+ return 1 |
+ |
+ except Usage, err: |
+ print >>sys.stderr, err |
+ print >>sys.stderr, "for help use --help" |
+ return 2 |
+ |
+if __name__ == "__main__": |
+ sys.exit(main()) |
Property changes on: source/libvpx/tools/lint-hunks.py |
___________________________________________________________________ |
Added: svn:eol-style |
+ LF |