#!/usr/bin/env python3 import subprocess import urllib.request import os import re import tempfile import collections import copy import sys base = os.environ["SYSTEM_PULLREQUEST_TARGETBRANCH"] if not re.match("^[0-9a-fA-F]{40}$", base): base = "refs/remotes/origin/" + base with tempfile.TemporaryDirectory() as dfn: patches = subprocess.check_output( [ "git", "format-patch", "--output-directory", dfn, os.environ["SYSTEM_PULLREQUEST_SOURCECOMMITID"], "^" + base ], universal_newlines=True).splitlines() if len(patches) == 0: sys.exit(0) ckp = os.path.join(dfn, "checkpatch.pl") urllib.request.urlretrieve( "https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/plain/scripts/checkpatch.pl", ckp) urllib.request.urlretrieve( "https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/plain/scripts/spelling.txt", os.path.join(dfn, "spelling.txt")) os.symlink( os.path.join(os.getcwd(), "buildlib/const_structs.checkpatch"), os.path.join(dfn, "const_structs.checkpatch")) checkpatch = [ "perl", ckp, "--no-tree", "--show-types", "--ignore", "PREFER_KERNEL_TYPES,FILE_PATH_CHANGES,EXECUTE_PERMISSIONS,USE_NEGATIVE_ERRNO,CONST_STRUCT", "--emacs", "--mailback", "--quiet", "--no-summary" ] environ = copy.copy(os.environ) environ["GIT_DIR"] = subprocess.check_output(["git","rev-parse","--absolute-git-dir"]).decode().strip() warnings = False errors = False for fn in patches: proc = subprocess.run( checkpatch + [os.path.basename(fn)], cwd=dfn, stdout=subprocess.PIPE, universal_newlines=True, env=environ, stderr=subprocess.STDOUT) if proc.returncode == 0: assert (not proc.stdout) continue sys.stdout.write(proc.stdout) warnings = True for g in re.finditer( r"^\d+-.*:\d+: (\S+):(\S+): (.*)(?:\n#(\d+): (?:FILE: (.*):(\d+):)?)?$", proc.stdout, flags=re.MULTILINE): itms = {} if g.group(1) == "WARNING": itms["type"] = "warning" else: itms["type"] = "error" itms["code"]=g.group(2) if g.group(4): itms["sourcepath"] = g.group(5) itms["linenumber"] = g.group(6) # Bump some warnings to errors if itms["code"] == "UNKNOWN_COMMIT_ID": itms["type"] = "error" if itms["type"] == "error": errors = True print("##vso[task.logissue %s]%s" % (";".join( "%s=%s" % (k, v) for k, v in sorted(itms.items())), g.group(3))) if errors: print("##vso[task.complete result=Failed]azp-checkpatch") elif warnings: print("##vso[task.complete result=SucceededWithIssues]azp-checkpatch")