summaryrefslogtreecommitdiff
path: root/hooks/pre-commit-python.hook
blob: ba33113e13c899f89fcfb47d59e73fce509ae8b5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
#!/usr/bin/env python3
import os
import subprocess
import sys
import tempfile

NOT_PYCODESTYLE_COMPLIANT_MESSAGE_PRE = \
    "Your code is not fully pycodestyle compliant and contains"\
    " the following coding style issues:\n\n"

NOT_PYCODESTYLE_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_PYCODESTYLE_MESSAGE = \
    "You should install the pycodestyle style checker to be able"\
    " to commit in this repo.\nIt allows us to garantee that "\
    "anything that is commited respects the pycodestyle coding style "\
    "standard.\nYou can install it:\n"\
    "  * on ubuntu, debian: $sudo apt-get install pycodestyle \n"\
    "  * on fedora: #yum install python3-pycodestyle \n"\
    "  * on arch: #pacman -S python-pycodestyle \n"\
    "  * or `pip install --user pycodestyle`"


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:
            if not modified_file.endswith(".py"):
                continue
            pycodestyle_errors = system('pycodestyle', '--repeat', '--ignore', 'E501,E128,W605', modified_file)
            if pycodestyle_errors:
                if output_message is None:
                    output_message = NOT_PYCODESTYLE_COMPLIANT_MESSAGE_PRE
                output_message += pycodestyle_errors
                non_compliant_files.append(modified_file)
        except OSError as e:
            output_message = NO_PYCODESTYLE_MESSAGE
            break

    if output_message:
        print(output_message)
        if non_compliant_files:
            print(NOT_PYCODESTYLE_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()