Automatically adding Git pre-commit linting with Grunt
Using the Git pre-commit hook along with Grunt.js allows you to perform linting on your code before it is committed. This can help your team stick to a particular coding style.
It's worth reading up on Git commit hooks and Grunt.js if you haven't already.
A pre-commit hook normally has to be manually copied/written in to .git/hooks on developers' machines. Instead Grunt with a little help from npm can help automate the process.
Your lint pre-commit hook would look something like this
#!/bin/sh
#
# Pre-commit hooks
# Lint stuff before committing
grunt jshint
You'll need to npm install
grunt-contrib-clean and grunt-shell. The following Grunt tasks will remove the current pre-commit hook executable (if there is one) then copy the pre-commit executable from the project in to .git/hooks.
// Clean stuff up
clean: {
// Clean any pre-commit hooks in .git/hooks directory
hooks: ['.git/hooks/pre-commit']
},
// Run shell commands
shell: {
hooks: {
// Copy the project's pre-commit hook into .git/hooks
command: 'cp git-hooks/pre-commit .git/hooks/'
}
}
You'll need to include the tasks and then they can be tied up with a single task, in this case called hookmeup
.
grunt.loadNpmTasks('grunt-contrib-clean');
grunt.loadNpmTasks('grunt-shell');
// Clean the .git/hooks/pre-commit file then copy in the latest version
grunt.registerTask('hookmeup', ['clean:hooks', 'shell:hooks']);
You can now run grunt hookmeup
and the pre-commit hook will be copied to your .git/hooks directory.
Lastly you can automate this by running grunt hookmeup
when an npm install
is completed, using a postinstall
script in your package.json file.
"scripts": {
"postinstall": "grunt hookmeup"
}
When you or another developer on your project runs npm install
the pre-commit hook will be added to the .git/hooks directory. When you git commit
your code will be linter. Should the linting fail the commit will fail too.
The same setup can also be used to run tests, concatenation, minifying etc. Nathan LaFreniere's precommit-hook npm module provides nice set up for linting and testing with the pre-commit Git hook.
Thanks to codeinthhole and Andreas Köberle for providing great articles on how to work with Git hooks.
Written by Tom Loudon
Related protips
6 Responses
Hi, I think the link to Nathan's precommit npm module should be https://github.com/nlf/precommit-hook
Thanks for letting me know. I think the author has updated their account name. I've changed it now.
Awesome! FYI You can get rid of grunt-shell by using grunt-githooks: https://github.com/rhumaric/grunt-githooks
Made it a bit cleaner
This is great, thanks for sharing.
Was wondering, have you done much in the way of callbacks? For example, how to stop the commit if the jslint fails? Or, if I want to run a build script to minify scripts, how to wait for it to be done?
I used copy instead of shell:
copy: {
githooks: {
files: [{
flatten: true,
src: ['git-hooks/pre-commit'],
dest: '.git/hooks/pre-commit'
}]
}
}