Problem: I want to automatically run unit tests, lint the application code, and check it’s state against team standards every time I try to commit my changes to a project. It would be nice if the commit aborts if any of the existing tests fails or if I did not follow a particular standard that the team agrees to uphold. The commit pushes through if there are no errors. If possible, I don’t have to change anything in my software development workflow.
Solution: Use a Git pre-commit hook. Under the .git/hooks hidden folder in the project directory, create a new file called pre-commit (without any file extension) containing something like the following bash script (for testing PHP code):
#!/bin/sh
stagedFiles=$(git diff-index --cached HEAD | grep ".php" | grep "^:" | sed 's:.*[DAM][ \\''t]*\([^ \\''t]*\):\1:g');
errorMessage="Please correct the errors above. Commit aborted."
printf "Linting and checking code standards ..."
for file in $stagedFiles
do
php -l $file
LINTVAL=$?
if [[ $LINTVAL != 0 ]]
then
printf $errorMessage
exit 1
fi
php core/phpcs.phar --colors --standard=phpcs.xml $file
STANDVAL=$?
if [[ $STANDVAL != 0 ]]
then
printf $errorMessage
exit 1
fi
done
printf "Running unit tests ..."
core/vendor/bin/phpunit --colors="always" [TESTS_DIRECTORY]
TESTSVAL=$?
if [[ $TESTSVAL != 0 ]]
then
printf $errorMessage
exit 1
fi
where
- linting and code standard checks only runs for the files you want to commit changes to
- code standard checks are based on a certain phpcs.xml file
- unit tests inside a particular TESTS_DIRECTORY will run
- the commit will abort whenever any of the lints, code standard checks, or unit tests fails