#!/usr/bin/env python

'''
    Kivy Git Pre-Commit Hook to Enforce Styleguide
    ==============================================

    This script is not supposed to be run directly.
    Instead, copy it to your kivy/.git/hooks/ directory, call it 'pre-commit'
    and make it executable.

    If you attempt to commit, git will run this script, which in turn will run
    the styleguide checker over your code and abort the commit if there are any
    errors. If that happens, please fix & retry.

    To install::

        cp kivy/tools/pep8checker/pre-commit.githook .git/hooks/pre-commit
        chmod +x .git/hooks/pre-commit
'''

import sys, os
from os.path import dirname, abspath, sep, join
from subprocess import call, Popen, PIPE

curdir = dirname(abspath(__file__))
kivydir = sep.join(curdir.split(sep)[:-2])
srcdir = join(kivydir, 'kivy')
script = join(srcdir, 'tools', 'pep8checker', 'pep8kivy.py')
try:
    with open(script): pass
except IOError:
    # if this not the kivy project, find the script file in the kivy project
    os.environ['KIVY_NO_CONSOLELOG'] = '1'
    import kivy
    script = join(dirname(kivy.__file__), 'tools', 'pep8checker', 'pep8kivy.py')
    srcdir = ''

# Only check the files that were staged
#proc = Popen(['git', 'diff', '--cached', '--name-only', 'HEAD'], stdout=PIPE)
#targets = [join(kivydir, target) for target in proc.stdout]

# Correction: only check the files that were staged, but do not include
# deleted files.
proc = Popen(['git', 'diff', '--cached', '--name-status', 'HEAD'], stdout=PIPE)
proc.wait()

# This gives output like the following:
#
#    A       examples/widgets/lists/list_simple_in_kv.py
#    A       examples/widgets/lists/list_simple_in_kv_2.py
#    D       kivy/uix/observerview.py
#
# So check for D entries and remove them from targets.
#
targets = []
for target in proc.stdout:
    parts = [p.strip() for p in target.split()]
    if parts[0] != 'D':
        targets.append(join(kivydir, target.decode(encoding='UTF-8')))

# Untested possibility: After making the changes above for removing deleted
# files from targets, saw also where the git diff call could be:
#
#    git diff --cached --name-only --diff-filter=ACM
#                                                    (leaving off D)
#
# and we could then remove the special handling in python for targets above.

call(['git', 'stash', 'save', '--keep-index', '--quiet'])
retval = call([sys.executable, script, srcdir] + targets)
call(['git', 'stash', 'pop', '--quiet'])

if retval:
    # There are styleguide violations
    print("Error:", retval, "styleguide violation(s) encountered!")
    print("Your commit has been aborted. Please fix the violations and retry.")
    sys.exit(retval)

