def git_hook(complexity=-1, strict=False, ignore=None, lazy=False): """This is the function used by the git hook. :param int complexity: (optional), any value > 0 enables complexity checking with mccabe :param bool strict: (optional), if True, this returns the total number of errors which will cause the hook to fail :param str ignore: (optional), a comma-separated list of errors and warnings to ignore :param bool lazy: (optional), allows for the instances where you don't add the files to the index before running a commit, e.g., git commit -a :returns: total number of errors if strict is True, otherwise 0 """ gitcmd = "git diff-index --cached --name-only --diff-filter=ACMRTUXB HEAD" if lazy: # Catch all files, including those not added to the index gitcmd = gitcmd.replace('--cached ', '') if hasattr(ignore, 'split'): ignore = ignore.split(',') # Returns the exit code, list of files modified, list of error messages _, files_modified, _ = run(gitcmd) # We only want to pass ignore and max_complexity if they differ from the # defaults so that we don't override a local configuration file options = {} if ignore: options['ignore'] = ignore if complexity > -1: options['max_complexity'] = complexity tmpdir = tempfile.mkdtemp() flake8_style = get_style_guide(config_file=DEFAULT_CONFIG, paths=['.'], **options) filepatterns = flake8_style.options.filename # Copy staged versions to temporary directory files_to_check = [] try: for file_ in files_modified: # get the staged version of the file gitcmd_getstaged = "git show :%s" % file_ _, out, _ = run(gitcmd_getstaged, raw_output=True, decode=False) # write the staged version to temp dir with its full path to # avoid overwriting files with the same name dirname, filename = os.path.split(os.path.abspath(file_)) prefix = os.path.commonprefix([dirname, tmpdir]) dirname = compat.relpath(dirname, start=prefix) dirname = os.path.join(tmpdir, dirname) if not os.path.isdir(dirname): os.makedirs(dirname) # check_files() only does this check if passed a dir; so we do it if ((pep8.filename_match(file_, filepatterns) and not flake8_style.excluded(file_))): filename = os.path.join(dirname, filename) files_to_check.append(filename) # write staged version of file to temporary directory with open(filename, "wb") as fh: fh.write(out) # Run the checks report = flake8_style.check_files(files_to_check) # remove temporary directory finally: shutil.rmtree(tmpdir, ignore_errors=True) if strict: return report.total_errors return 0
# -*- coding: utf-8 -*-