Introducing grunt-githooks

— An article about: - Uncategorized

Git hooks allow you to run scripts when certain Git commands are executed. Grunt allows you to run Javascript tasks. Sounded to me like these two things are clearly meant to work together, so say hi to grunt-githooks!

grunt-githooks is a Grunt plugin that generates Git hooks which will run specified Grunt task(s). It is available via NPM (npm install grunt-githooks --save-dev) and provides a githooks task that will generate the hooks.

Defining hooks

Hooks are defined using simple "name-of-the-hook": "space separated list of grunt tasks to run" pairs in the githooks task configuration. Say you want to run jshint and your project's unit tests before each commit, you'd have something like this:

grunt.initConfig({
  githooks: {
    all: {
      // Will run the jshint and test:unit tasks at every commit
      'pre-commit': 'jshint test:unit',
    }
  }
  // Rest of the Grunt configuration
});

This means the Gruntfile now centralises hooks definitions. This makes it easier to share than developers each having their own sets of scripts in their .git\hooks folder.

Generated scripts

With the above configuration, running grunt githooks will create the following pre-commit file in the .git\hooks folder of your project:

#!/usr/bin/env node

// GRUNT-GITHOOKS START
var exec = require('child_process').exec;

exec('grunt jshint test:unit', {
       cwd: '/path/to/project'
     }, function (err, stdout, stderr) {

  console.log(stdout);

  var exitCode = 0;
  if (err) {

    console.log(stderr);
    exitCode = -1;
  }

  process.exit(exitCode);
});
// GRUNT-GITHOOKS END

As you notice, this is a NodeJS script. NodeJS runs on both Windows, Mac and Linux, and if you're using Grunt, it'll be there already, so it made sense to go for it. If you fancy another language, the plugin provides options to configure the output to anything else, using a system of templates.

The // GRUNT-GITHOOKS ... comments mark where grunt-githooks should insert its script if a hook already exists. If they're not present, the script will simply be appended to any existing code, so any existing hook you have won't be lost.

Wrapping it up!

This was just a quick description of the grunt-githooks plugin (the project's README contains more details about the different config options). Hopefully enough to let you create hooks running Grunt tasks 🙂

Note: If you need to go futher and customise the output of the hooks, this article presenting the use of the template option by Chris Manning is definitely worth a read!

The project is open source, by the way. So feel free to raise issues, submit pull requests… It's hosted on Github.