26 de marzo de 2014

Create a global GIT hook to check Flake8 before each commit

First, let's install Flake8:


$ sudo pip install flake8==2.0
view raw gistfile1.sh hosted with ❤ by GitHub


Note It is important to set the right version when installing Flake8, as there there are some versions that are bugged and will prevent the GIT hook to work (like the 2.1.0 version).

Now, let's setup global git commit hooks:

1. Enable git templates:

$ git config --global init.templatedir '~/.git-templates'
view raw gistfile1.ps1 hosted with ❤ by GitHub


This tells git to copy everything in ~/.git-templates to your per-project .git/ directory when you run git init

2. Create a directory to hold the global hooks:

$ mkdir -p ~/.git-templates/hooks
view raw gistfile1.ps1 hosted with ❤ by GitHub


3. Write your hooks in ~/.git-templates/hooks.

For example, here's a post-commit hook (located in ~/.git-templates/hooks/post-commit):

#!/bin/sh
# Copy last commit hash to clipboard on commit
git log -1 --format=format:%h | pbcopy
# Add other post-commit hooks
view raw gistfile1.ps1 hosted with ❤ by GitHub


4. Make sure the hook is executable.

chmod a+x ~/.git-templates/hooks/post-commit
view raw gistfile1.ps1 hosted with ❤ by GitHub


5. Re-initialize git in each existing repo you'd like to use this in:

$ git init
view raw gistfile1.ps1 hosted with ❤ by GitHub



NOTE if you already have a hook defined in your local git repo, this will not overwrite it.

Now, let's create a global git pre-commit hook:

#!/usr/bin/env python
import glob
import os
import sys
# git usurbs your bin path for hooks and will always run system python
site_packages = glob.glob('%s/lib/*/site-packages' % os.environ['VIRTUAL_ENV'])[0]
sys.path.insert(0, site_packages)
from flake8.run import git_hook
COMPLEXITY = 10
STRICT = True
if __name__ == '__main__':
sys.exit(git_hook(complexity=COMPLEXITY, strict=STRICT))
view raw gistfile1.py hosted with ❤ by GitHub

Finally, let's take it for a spin!

Go to some of your repos and re-initialize it to take the pre-commit hook:

$ git init
view raw gistfile1.ps1 hosted with ❤ by GitHub

Now edit some of your Python files, introducing some violation (like a >80 columns line, only one blank line between function/class definitions, etc.) and try to commit it:

$ git commit setup.py
setup.py:4:1: E302 expected 2 blank lines, found 0
setup.py:8:1: E302 expected 2 blank lines, found 0
view raw gistfile1.sh hosted with ❤ by GitHub

Voilà!