#!/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)