Being nice to colleagues with git pre-commit hooks
For my current contract I'm doing a huge amount of testing on a system that is very fun to hack on. I've also been given a lot of
rope leeway in how I test. Thus, I use Test::Most quite heavily, but I've a tiny problem:
use Test::Most 'die';
That should halt the test file at first failure, a feature I use quite a bit when developing to ensure that test failures don't scroll past when I'm actively hacking on code. However, when I added subtests to
Test::Builder a few years ago, I made sure that a fatal failure in a subtest would cause the subtest to fail, but not the entire test program. Well, darn. That means
use Test::Most 'die' doesn't quite do what I want it to do in this case.
Being pragmatic, I did the simplest thing which can possibly work. I used the testing equivalent of weapons of mass destruction:
use Test::Most 'bail';
Thus, any test failure will cause the test suite to bail out, immediately, no questions asked! I don't mind this behavior at all when I'm hacking on a single test program, but I don't want to commit that, so I must remember to remove that before I commit.
Well, of course I committed that; the more manual steps you make anyone take, the more likely they are to forget one. Time to make sure I don't do that again.
One of the lovely features of
git is how easy it is to modify its behavior at various stages. In this case, I didn't want to commit my 'bail' hack, so I wrote the following and saved it as
#!/bin/bash RESULT=$(git grep -l 'Test::Most.*bail' t | wc -l) if [ $RESULT -ne 0 ]; then echo -e "\e[01;31m$0 failed. Cannot commit:\e[0m" >&2 git grep 'Test::Most.*bail' t exit 1 fi exit 0
For this tiny hack, I check to see if I've committed my nuclear option and if I have, I get output similar to this:
$ git commit .git/hooks/pre-commit failed. Cannot commit: t/import/merger.t:use Test::Most 'bail'; t/import/parser_errors.t:use Test::Most 'bail';
I knew about
parser_errors.t having 'bail' because I added that for testing my pre-commit hook, but I didn't know that
merger.t had the same problem!
I'm sure my colleagues would have been most unhappy had I merged this to integration.
Next up is stopping myself from committing
$DB::single = 1;.