You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
87 lines
2.7 KiB
87 lines
2.7 KiB
#!/usr/bin/env python |
|
|
|
''' |
|
A script suitable for use as a git pre-commit hook to ensure your |
|
files are flake8-compliant before committing them. |
|
|
|
Use this by copying it to a file called $ARDUPILOT_ROOT/.git/hooks/pre-commit |
|
|
|
AP_FLAKE8_CLEAN |
|
''' |
|
|
|
import os |
|
import re |
|
import sys |
|
import subprocess |
|
|
|
|
|
class PreCommitFlake8(object): |
|
|
|
def __init__(self): |
|
pass |
|
|
|
def progress(self, message): |
|
print("***** %s" % (message, )) |
|
|
|
def check_file(self, filepath): |
|
content = open(filepath).read() |
|
if "AP_FLAKE8_CLEAN" not in content: |
|
return True |
|
self.progress("Checking (%s)" % filepath) |
|
retcode = subprocess.call(["flake8", filepath]) |
|
if retcode != 0: |
|
self.progress("File (%s) failed with retcode (%s)" % |
|
(filepath, retcode)) |
|
return False |
|
return True |
|
|
|
def split_git_diff_output(self, output): |
|
'''split output from git-diff into a list of (status, filepath) tuples''' |
|
ret = [] |
|
if type(output) == bytes: |
|
output = output.decode('utf-8') |
|
for line in output.split("\n"): |
|
if len(line) == 0: |
|
continue |
|
ret.append(re.split(r"\s+", line)) |
|
return ret |
|
|
|
def run(self): |
|
# generate a list of files which have changes not marked for commit |
|
output = subprocess.check_output([ |
|
"git", "diff", "--name-status"]) |
|
dirty_list = self.split_git_diff_output(output) |
|
dirty = set() |
|
for (status, dirty_filepath) in dirty_list: |
|
dirty.add(dirty_filepath) |
|
|
|
# check files marked for commit: |
|
output = subprocess.check_output([ |
|
"git", "diff", "--cached", "--name-status"]) |
|
output_tuples = self.split_git_diff_output(output) |
|
self.retcode = 0 |
|
for output_tuple in output_tuples: |
|
if len(output_tuple) > 2: |
|
if output_tuple[0].startswith('R'): |
|
# rename, check destination |
|
(status, filepath) = (output_tuple[0], output_tuple[2]) |
|
else: |
|
raise ValueError("Unknown status %s" % str(output_tuple[0])) |
|
else: |
|
(status, filepath) = output_tuple |
|
if filepath in dirty: |
|
self.progress("WARNING: (%s) has unstaged changes" % filepath) |
|
if status == 'D': |
|
# don't check deleted files |
|
continue |
|
(base, extension) = os.path.splitext(filepath) |
|
if extension != ".py": |
|
continue |
|
if not self.check_file(filepath): |
|
self.retcode = 1 |
|
return self.retcode |
|
|
|
|
|
if __name__ == '__main__': |
|
precommit = PreCommitFlake8() |
|
sys.exit(precommit.run())
|
|
|