2021-02-10 19:47:43 -04:00
|
|
|
#!/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
|
|
|
|
|
2022-08-24 16:56:49 -03:00
|
|
|
@staticmethod
|
|
|
|
def progress(message):
|
2021-02-10 19:47:43 -04:00
|
|
|
print("***** %s" % (message, ))
|
|
|
|
|
2022-08-24 16:56:49 -03:00
|
|
|
@staticmethod
|
|
|
|
def has_flake8_tag(filepath):
|
2021-02-10 19:47:43 -04:00
|
|
|
content = open(filepath).read()
|
2022-08-24 16:56:49 -03:00
|
|
|
return "AP_FLAKE8_CLEAN" in content
|
|
|
|
|
|
|
|
def files_are_flake8_clean(self, files_to_check):
|
|
|
|
if files_to_check:
|
|
|
|
for path in files_to_check:
|
|
|
|
self.progress("Checking (%s)" % path)
|
|
|
|
try:
|
|
|
|
subprocess.check_output(["flake8"] + files_to_check, stderr=subprocess.STDOUT)
|
|
|
|
except subprocess.CalledProcessError as e:
|
|
|
|
self.progress("Flake8 check failed: (%s)" % (e.output))
|
|
|
|
return False
|
2021-02-10 19:47:43 -04:00
|
|
|
return True
|
|
|
|
|
2022-08-24 16:56:49 -03:00
|
|
|
@staticmethod
|
|
|
|
def split_git_diff_output(output):
|
2021-02-10 19:47:43 -04:00
|
|
|
'''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)
|
2022-08-24 16:56:49 -03:00
|
|
|
files_to_check_flake8 = []
|
2021-02-10 19:47:43 -04:00
|
|
|
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)
|
2022-08-24 16:56:49 -03:00
|
|
|
if extension == ".py" and self.has_flake8_tag(filepath):
|
|
|
|
files_to_check_flake8.append(filepath)
|
|
|
|
if not self.files_are_flake8_clean(files_to_check_flake8):
|
|
|
|
return 1
|
|
|
|
return 0
|
2021-02-10 19:47:43 -04:00
|
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
precommit = PreCommitFlake8()
|
|
|
|
sys.exit(precommit.run())
|