Created
December 20, 2009 09:08
-
-
Save anonymous/260411 to your computer and use it in GitHub Desktop.
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 | |
"""A Python git pre-commit script for Go programming language projects. | |
Install the script by putting it in .git/hooks/ directory in your project | |
directory. The script file must be called "pre-commit". Make sure the | |
executable flag in the script file is set. The script assumes you are building | |
your project with make. | |
The script makes sure that all go source files in the project have valid | |
formatting and that the project unit tests pass before allowing the commit to | |
proceed. The script checks out the git index of the project into a temporary | |
directory. It checks gofmt validity by running gofmt on each *.go file and | |
checking that the output is identical to the original file with diff. It runs | |
unit tests by doing "make test" at the project root and checking the return | |
value. Gofmt check is done before "make test" so that generated .go files | |
won't be involved in the format check. | |
You can bypass the check with the "--no-verify" flag to git commit.""" | |
import os | |
import os.path | |
import tempfile | |
import shutil | |
import sys | |
from subprocess import * | |
def git_checkout_index(path): | |
call("git checkout-index --prefix=%s/ -a" % path, shell=True) | |
def file_needs_gofmt(filepath): | |
p1 = Popen(["gofmt", filepath], stdout=PIPE) | |
p2 = Popen(["diff", "-", filepath], stdin=p1.stdout, stdout=open(os.devnull, 'w')) | |
return os.waitpid(p2.pid, 0)[1] | |
def files_needing_gofmt(path): | |
need_gofmt = [] | |
for root, dirs, files in os.walk(path): | |
for gofile in [x for x in files if x.endswith('.go')]: | |
if file_needs_gofmt(os.path.join(root, gofile)): | |
need_gofmt.append(gofile) | |
return need_gofmt | |
def gofmt_check(path): | |
need_gofmt = files_needing_gofmt(path) | |
if need_gofmt: | |
for gofile in need_gofmt: | |
print gofile, "needs gofmt." | |
sys.exit(1) | |
def unittest_check(path): | |
status = call("make test", shell=True, cwd=path) | |
if status: | |
print "Unit test(s) failed." | |
sys.exit(1) | |
def main(): | |
tmpdir = tempfile.mkdtemp() | |
try: | |
git_checkout_index(tmpdir) | |
gofmt_check(tmpdir) | |
unittest_check(tmpdir) | |
finally: | |
shutil.rmtree(tmpdir) | |
if __name__=='__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment