Skip to content

Instantly share code, notes, and snippets.

@jalp
Created January 27, 2014 07:52
Show Gist options
  • Save jalp/8644578 to your computer and use it in GitHub Desktop.
Save jalp/8644578 to your computer and use it in GitHub Desktop.
Precommit python files testing and running PEP8 control after commit into git
#!/usr/bin/env python
import os
import re
import subprocess
import sys
modified_re = re.compile('^[AM]+\s+(?P<name>.*\.py)', re.MULTILINE)
def get_staged_files():
"""Get all files staged for the current commit.
"""
git = subprocess.Popen(['git', 'status', '--porcelain'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out,error = git.communicate()
staged_files = modified_re.findall(out)
return staged_files
def get_test_apps():
"""Return apps with tests folder
"""
tests = []
for root, subFolders, files in os.walk('.'):
if 'tests' in subFolders:
val = root.split('/')
# Exclude apps to test
if val[-1] != '<app_name_to_exclude>':
tests.append(val[-1])
return tests
def main():
abort = False
# Getting stage files
staged_files = get_staged_files()
# Staging changed files
subprocess.call(['git', 'stash', '-u', '-q', '--keep-index'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
# staged_files is empty, nothing to do
if len(staged_files) == 0:
print 'No python files to evaluate'
sys.exit(0)
print '========== Checking PEP8 =========='
for filename in staged_files:
proc = subprocess.Popen(['pep8', '--max-line-length=119', '--show-source', filename], stdout=subprocess.PIPE)
output, _ = proc.communicate()
# If pep8 still reports problems then abort this commit.
if output:
abort = True
print '========= Found PEP8 ERROR =========='
print output
else:
print 'PEP8 correct'
# Run unit test
cwd = os.getcwd() + '/<project_folder>/'
print '========== Running unit tests =========='
data = ['python', 'manage.py', 'test', '--noinput', '--settings=settings.test'] + get_test_apps()
proc = subprocess.Popen(data, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=cwd)
out, error = proc.communicate()
if 'FAILED' in error:
print 'There are errors in unit tests: {0}'.format(error)
abort = True
else:
print 'tests PASSED'
print '========== =========='
# Un-staging previously files
subprocess.call(['git', 'stash', 'pop', '-q'], stdout=subprocess.PIPE)
# Final result
if abort:
print '========== ABORTING commit =========='
sys.exit(1)
else:
sys.exit(0)
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment