- Python >= 3.x
- pycodestyle
- pyflakes
cd path/to/repository/
wget https://gist.githubusercontent.com/Kilte/a4a9973ccc239136404fb70564c9d72b/raw/9374954a78ec00365ea1c040e0f8a4c03e877b3b/pre-commit -O .git/hooks/pre-commit
chmod +x .git/hooks/pre-commit
#!/usr/bin/env python3 | |
import re | |
import subprocess | |
import sys | |
import pycodestyle | |
import pyflakes.api | |
import pyflakes.reporter | |
MAX_LINE_LENGTH = 100 | |
def subprocess_call(cmd, cwd=None): | |
p = subprocess.Popen(cmd.split(), stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=cwd) | |
out, err = p.communicate() | |
return out.decode('utf-8'), err.decode('utf-8'), p.returncode | |
def find_modified_files(ext): | |
modified = re.compile('^(?:M|A).(?P<name>.*\.%s)' % ext) | |
out, _, _ = subprocess_call('git status --porcelain') | |
result = [] | |
for line in out.splitlines(): | |
match = modified.match(line.strip()) | |
if match: | |
result.append(match.group('name').strip()) | |
return result | |
class PEP8Report(pycodestyle.BaseReport): | |
def __init__(self, *args, **kwargs): | |
super().__init__(*args, **kwargs) | |
self._deferred_output = [] | |
def error(self, line_number, offset, text, check): | |
self._deferred_output.append('{0}:{1}: {2}'.format(self.filename, line_number, text)) | |
return super().error(line_number, offset, text, check) | |
def get_results(self): | |
return self._deferred_output | |
def run_pycodestype(paths): | |
style_guide = pycodestyle.StyleGuide( | |
parse_argv=False, | |
config_file=False, | |
max_line_length=MAX_LINE_LENGTH, | |
reporter=PEP8Report | |
) | |
return style_guide.check_files(paths).get_results() | |
def run_pyflakes(paths): | |
reporter = pyflakes.reporter._makeDefaultReporter() | |
return pyflakes.api.checkRecursive(paths, reporter) | |
def main(): | |
paths = find_modified_files('py') | |
if not paths: | |
return | |
exitcode = 0 | |
results = run_pycodestype(paths) | |
if results: | |
print('PEP8 style violations have been detected.') | |
for i in results: | |
print(i) | |
exitcode = 1 | |
if run_pyflakes(paths): | |
print('^' * 20) | |
print('Pyflakes violations have been detected.') | |
exitcode = 1 | |
if exitcode != 0: | |
print('Please fix them or force the commit with "git commit --no-verify".') | |
sys.exit(exitcode) | |
if __name__ == '__main__': | |
main() |