diff --git a/validate/autogen.sh b/validate/autogen.sh index b3db050cf0..4df9fbf6a8 100755 --- a/validate/autogen.sh +++ b/validate/autogen.sh @@ -25,11 +25,9 @@ fi . common/gst-autogen.sh # install pre-commit hook for doing clean commits -if test ! \( -x ../.git/hooks/pre-commit -a -L ../.git/hooks/pre-commit \); -then - rm -f ../.git/hooks/pre-commit - ln -s ../../validate/common/hooks/pre-commit.hook ../.git/hooks/pre-commit -fi +echo "installing pre-commit hooks" +rm -f ../.git/hooks/pre-commit +ln -s ../../validate/multi-pre-commit.hook ../.git/hooks/pre-commit # GNU gettext automake support doesn't get along with git. # https://bugzilla.gnome.org/show_bug.cgi?id=661128 diff --git a/validate/multi-pre-commit.hook b/validate/multi-pre-commit.hook new file mode 100755 index 0000000000..4a1e8e0f79 --- /dev/null +++ b/validate/multi-pre-commit.hook @@ -0,0 +1,43 @@ +#!/bin/sh +# Git pre-commit hook that runs multiple hooks specified in $HOOKS. +# Make sure this script is executable. Bypass hooks with git commit --no-verify. + +# This file is inspired by a set of unofficial pre-commit hooks available +# at github. +# Link: https://github.com/githubbrowser/Pre-commit-hooks +# Contact: David Martin, david.martin.mailbox@googlemail.com + + +########################################################### +# SETTINGS: +# pre-commit hooks to be executed. They should be in the same .git/hooks/ folder +# as this script. Hooks should return 0 if successful and nonzero to cancel the +# commit. They are executed in the order in which they are listed. +########################################################### + +HOOKS="validate/common/hooks/pre-commit.hook validate/pre-commit-python.hook" + +# exit on error +set -e + +echo $PWD + +for hook in $HOOKS +do + echo "Running hook: $hook" + # run hook if it exists + # if it returns with nonzero exit with 1 and thus abort the commit + if [ -f "$PWD/$hook" ]; then + "$PWD/$hook" + if [ $? != 0 ]; then + exit 1 + fi + else + echo "Error: file $hook not found." + echo "Aborting commit. Make sure the hook is at $PWD/$hook and executable." + echo "You can disable it by removing it from the list" + echo "You can skip all pre-commit hooks with --no-verify (not recommended)." + exit 1 + fi +done + diff --git a/validate/pre-commit-python.hook b/validate/pre-commit-python.hook new file mode 100755 index 0000000000..a3b324f897 --- /dev/null +++ b/validate/pre-commit-python.hook @@ -0,0 +1,80 @@ +#!/usr/bin/env python2 +import os +import subprocess +import sys +import tempfile + +NOT_PEP8_COMPLIANT_MESSAGE_PRE = \ + "Your code is not fully pep8 compliant and contains"\ + " the following coding style issues:\n\n" + +NOT_PEP8_COMPLIANT_MESSAGE_POST = \ + "Please fix these errors and commit again, you can do so "\ + "from the root directory automatically like this, assuming the whole "\ + "file is to be commited:" + +NO_PEP8_MESSAGE = \ + "You should install the pep8 style checker to be able"\ + " to commit in this repo.\nIt allows us to garantee that "\ + "anything that is commited respects the pep8 coding style "\ + "standard.\nYou can install it:\n"\ + " * on ubuntu, debian: $sudo apt-get install pep8 \n"\ + " * on fedora: #yum install python-pep8 \n"\ + " * on arch: #pacman -S pep8-python3 \n"\ + " * or add the official pep8 from http://www.python.org/dev/peps/pep-0008/"\ + " in your $PATH" + + +def system(*args, **kwargs): + kwargs.setdefault('stdout', subprocess.PIPE) + proc = subprocess.Popen(args, **kwargs) + out, err = proc.communicate() + if type(out) == bytes: + out = out.decode() + return out + + +def copy_files_to_tmp_dir(files): + tempdir = tempfile.mkdtemp() + for name in files: + filename = os.path.join(tempdir, name) + filepath = os.path.dirname(filename) + if not os.path.exists(filepath): + os.makedirs(filepath) + with open(filename, 'w') as f: + system('git', 'show', ':' + name, stdout=f) + + return tempdir + + +def main(): + modified_files = system('git', 'diff-index', '--cached', + '--name-only', 'HEAD', '--diff-filter=ACMR').split("\n")[:-1] + non_compliant_files = [] + output_message = None + + for modified_file in modified_files: + try: + pep8_errors = system('pep8', '--repeat', '--ignore', 'E501,E128', modified_file) + if pep8_errors: + if output_message is None: + output_message = NOT_PEP8_COMPLIANT_MESSAGE_PRE + output_message += pep8_errors + non_compliant_files.append(modified_file) + except OSError: + output_message = NO_PEP8_MESSAGE + break + + if output_message: + print output_message + if non_compliant_files: + print NOT_PEP8_COMPLIANT_MESSAGE_POST + for non_compliant_file in non_compliant_files: + print "autopep8 -i ", non_compliant_file, "; git add ", \ + non_compliant_file + print "git commit" + sys.exit(1) + + +if __name__ == '__main__': + main()