Created
August 21, 2011 23:55
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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