Skip to content

Instantly share code, notes, and snippets.

@vpetro
Created August 21, 2011 23:55
Show Gist options
  • Save vpetro/1161360 to your computer and use it in GitHub Desktop.
Save vpetro/1161360 to your computer and use it in GitHub Desktop.
git pre-commit hook for preventing commits that contain untested lines with python/nose
#!/usr/bin/env python
import os
import re
import sys
temp_filename = '/tmp/hook_file'
def _read_test_output():
total_output = {}
command = "nosetests --with-coverage"
os.system('%s &> %s' % (command, temp_filename))
output_lines = open(temp_filename, 'r')
for line in output_lines:
split_line = line.split()
if not split_line:
continue
name = split_line[0]
lines = []
for line_range in split_line[4:]:
line_range = line_range.replace(',', '')
if '-' in line_range:
values = map(int, line_range.split('-'))
values[1] += 1
split_line_range = list(range(*values))
lines.extend(split_line_range)
elif line_range.isdigit():
lines.append(int(line_range))
if name and lines:
total_output[ name.replace('.', '/') + ".py"] = lines
#sys.stdout.write('nose length: %d' % len(total_output))
return total_output
def _read_diff():
total_output = {}
os.system('git diff --cached > %s' % temp_filename)
current_filename = None
lineno = 0
for line in open(temp_filename).readlines():
line = line.strip()
if line.startswith('+++ b/'):
current_filename = line[6:]
total_output[current_filename] = []
elif line.startswith('@@'):
lineno = int(re.findall('\+([0-9]+),',line)[0]) - 1
elif line.startswith('+'):
total_output[current_filename].append(lineno)
elif line.startswith('-'):
lineno -= 1
lineno += 1
#sys.stdout.write('diff length: %d' % len(total_output))
return total_output
def main():
can_commit = True
diff_output_dict = _read_diff()
test_output_dict = _read_test_output()
for filename, linenos in diff_output_dict.iteritems():
if filename not in test_output_dict:
sys.stdout.write('you should really test this file -> %s\n' % filename)
can_commit = False
continue
if set(linenos).intersection(test_output_dict[filename]):
sys.stdout.write("%s %s\n" % (filename, sorted(set(linenos).intersection(test_output_dict[filename]))))
can_commit = False
if not can_commit:
sys.exit(1)
if __name__ == '__main__':
sys.stdout.write('petro! the stuff is working!\n')
main()
sys.exit(1)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment