#!/usr/bin/python3 """ Run the Anaconda pylint tests on the files changed in this commit Set NOPYLINT env variable to skip this. eg. NOPYLINT= git commit """ # Ignore any interruptible calls # pylint: disable=interruptible-system-call import os import sys from subprocess import check_output, CalledProcessError import tempfile def is_python(filename): if filename.endswith(".py"): return True try: with open(filename) as testfile: if testfile.readline().startswith("#!/usr/bin/python"): return True except IOError: pass return False OTHER_MODULES_PATH = ".:../blivet/:../pykickstart/" if "NOPYLINT" in os.environ: print("Skipping pre-commit pylint run") sys.exit(0) # run pylint on all the python files changed by this commit try: git_files = check_output(["git", "status", "--porcelain", "-z"]) except CalledProcessError: sys.exit(1) # If git status returned nothing, return if not git_files: sys.exit(0) git_files = git_files.decode('utf-8').strip('\0').split('\0') pylint_names = [] pylint_files = [] # Lines look like: MM tests/pylint/runpylint.sh # The first character is the status in the index (or our side of a merge), # the second character is the status in the tree (or their side of a merge). # Use an iterator so we can skip lines in the case of renames git_iter = iter(git_files) for gf in git_iter: # If the file is being removed, or is not in git, or is not part of this # commit, ignore it if gf[0] in ('D', '?', ' '): continue # If the file is being renamed, the target filename (which we want) is on # the current line, and the next line is the source, which we want to skip if gf[0] == 'R': git_iter.next() if is_python(gf[3:]): pylint_names.append(gf[3:]) # If the file is unmerged, changed, or deleted locally, create a # temporary file with the actual content that will be committed if gf[0] == 'U' or gf[1] in ('U', 'M', 'D'): tmpfile = tempfile.NamedTemporaryFile(prefix=gf[3:].replace('/', '.')) tmpfile.write(check_output(["git", "show", ":%s" % gf[3:]])) tmpfile.flush() pylint_files.append(tmpfile.name) else: pylint_files.append(gf[3:]) if not pylint_files: sys.exit(0) # Make sure pykickstart and blivet can be found # Note that if the checked out versions are too far off pylint may fail env = os.environ.copy() env["PYTHONPATH"] = OTHER_MODULES_PATH print("Running pylint on %s" % " ".join(pylint_names)) try: check_output(["./tests/pylint/runpylint.py"] + pylint_files, env=env) except CalledProcessError as e: print(e.output.decode('utf-8')) sys.exit(1) sys.exit(0)