|
#!/usr/bin/env python3 |
|
import re |
|
import subprocess |
|
import sys |
|
|
|
import pycodestyle |
|
import pyflakes.api |
|
import pyflakes.reporter |
|
|
|
|
|
MAX_LINE_LENGTH = 120 |
|
|
|
|
|
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() |