November 15, 2016

Gilp: A node tool to implement pre-commit and other git hooks over gulp

Git has a lot of hooks for client and server side but the most used and known hook is pre-commit, where you can run some validations (like linters) and cancel a commit if something fails. Gilp is a tool to define (using gulp tasks), install and run hooks.

Why gilp over gulp?

There are 2 main reasons:

  • The regular pre-commit hook managers run using the local file's content instead of git staged content. Gulp comes with vinyl, a virtual file format where we can create an in-memory version of a file to use as content for the tasks. Like gulp.src, we created a new stream provider for that: srcFromStaged. If we need to run the same tools but over a commit, branch or tag instead (e.g. in a CI), you can do it using srcFromCommit without a checkout.

  • Gulp has plenty of plugins ready to use, check here.

Yarn, please.

We recommend to use yarn instead of npm because the error report is less verbose when gulp returns a non-zero code (on error) so we can focus on the "real" error.

Installation

1
yarn add --dev gilp

Usage

You can use any gulp or gilp plugin.

How to define a hook

1
2
3
4
5
6
7
8
9
var gulp = require('gulp');
var eslint = require('gulp-eslint');
var gilp = require('gilp')(gulp);

gilp.hook('pre-commit', function () {
  return gilp.srcFromStaged(['**/*.js']) 
    .pipe(eslint())
    .pipe(eslint.failAfterError());
});

Get a stream of files to be committed (staged content):

1
gilp.srcFromStaged();

Get a stream of files from a commit:

1
gilp.srcFromCommit('e3bca34');

Install defined hooks (.git/hooks)

Gilp auto define a gulp task to install the git hooks properly because each hook should be defined under the .git/hooks folder.

1
yarn run gulp gilp-install

To auto-install the hooks after yarn [install], add in your package.json the following postinstall command:

1
2
3
4
5
6
7
8
9
{
  // ...
  "scripts": {
    // ...
    "gulp": "gulp",
    "postinstall": "gulp gilp-install"
  },
  // ...
}

Run a task on the CI to check the commit

1
2
3
4
5
6
7
8
9
var gulp = require('gulp');
var eslint = require('gulp-eslint');
var gilp = require('gilp')(gulp);

gulp.task('check-commit', function () {
  return gilp.srcFromCommit('e3bca34', ['**/*.js']) 
    .pipe(eslint())
    .pipe(eslint.failAfterError());
});

Final notes

This is a open source project under MIT license and can be found in our github organization: https://github.com/sophilabs/gilp