Gulp and commit hooks (gilp)
Rodrigo Lopez
August 28, 2017
This is part of Code quality enforcement series.
When creating a validation pipeline for your staged files, you don't have too many choices and usually end up with a huge bash script with countless functions for every linter, rule, or standard you want to automate.
This post presents gilp, a gulp plugin which takes care of installing pre-commit
, pre-push
, and commit-msg
hooks and running gulp tasks.
Validation pipeline
As gulp provides gulp.src
, gilp provides gilp.srcFromStaged
, a similar function that filters out unstaged files and returns a stream of vinyl File objects. Gilp also provides gilp.srcFromCommit
which takes a revision hash.
This example includes gulp-eslint
for javascript validation.
gilp.hook('pre-commit', ['check-eslint'], () =>
gilp.srcFromStaged(['**/*'.js])
.pipe(eslint())
.pipe(eslint.format())
.pipe(eslint.failAfterError())
gilp.hook
behaves similarly to gulp.task
, but it gets registered to ./git/hooks
and wraps the original gulp.task
.
Now let's take a look at a minimal working example.
Example
We usually first separate our checks in different functions.
const filter = require('gulp-filter');
const combiner = require('stream-combiner2').obj;
const print = require('gulp-print');
const flake8 = require('gulp-flake8');
const gulpIsort = require('gulp-isort');
const checkGrep = require('gulp-check-grep');
function py() {
const src = filter([
'**/*.py',
], {restore: true});
return combiner(
src,
print(),
flake8('.flake8'),
flake8.failOnError(),
gulpIsort(),
gulpIsort.failOnError(),
checkGrep(/print\+$/gm, {pass: (line, n, f) => line.endswith('# noqa')}),
checkGrep.failOnError(),
src.restore
);
}
This uses stream-combiner2 to make our py
function behave like a single-stream pipeline and gulp-filter to get only python files.
const filter = require('gulp-filter');
const combiner = require('stream-combiner2').obj;
const print = require('gulp-print');
const lintFilepath = require('gulp-lint-filepath');
function html() {
const src = filter(['**/*.html'], {restore: true});
return combiner(
src,
print(),
lintFilepath({'file-name': [/(^|\/)[a-z0-9_]+\.html$/]}),
lintFilepath.reporter(),
src.restore
);
}
This is more or less the same using a gulp file name validator for html files.
const gilp = require('gilp');
gilp.hook('pre-commit', () =>
gilp.srcFromStaged(['**/*'])
.pipe(py())
.pipe(html())
);
And here's the gilp hook defined, running gulp gilp-install
will put those tasks into the pre-commit
hooks file.
SQL Window Functions in Django
Window functions can be seen as close relatives to our well-known aggregate functions. They perform a calculation over a set of rows and return a single value.
Git Fundamentals
Git is a Distributed Version Control System (DVCS), a tool used to develop and maintain software. It allows you to develop software in incremental steps and gives you a view of the project's history.
Photo by Tommy Lisbin on Unsplash.
Categorized under research & learning.Join our team
If you're passionate about building quality software and our values resonate with you, get in touch with us!