Using Gulp.js to check your code quality

Gulp.jsIn this blog post I want to show you how you can use Gulp.js to automate some tasks to check the quality of your code. Before we deep dive into the subject and the coding examples I first want to
give you a short introduction on what Gulp.js actually is. So if you already know what Gulp.js is about you can move on to the next chapter.

Easy to use
By preferring code over configuration, gulp keeps things simple and makes complex tasks manageable.
Efficient
Using the power of node streams, gulp gives you fast builds that don’t write intermediary files to disk.
Previous statements are quoted from the Gulp.js homepage. Gulp.js is just like Grunt.js a task runner build on Node.js aka io.js. Where you define your tasks in Grunt.js in a configuration based style, you will be defining your tasks in Gulp.js more in a code based style. For both task runner there is a wide variety of plugins available.

So what is the real power of Gulp.js?

In my opinion that is the utilization of the Node.js streams, which makes Gulp.js a very fast and memory efficient task runner. The difference between Gulp.js and Grunt.js can especially be noticed when working on larger projects, with huge amounts of files.

In many cases developers are limiting the usage of both task runners to only their javascript projects. As I showed you last time Grunt.js can also be used to automate some of your .Net/c# tasks I want to show you today you can also use it on php projects. So here is my call for action. Stop limiting yourself and try to apply it on any project you’re working on, no matter the language!

In one of my previous blogposts I showed you how to use Grunt.js to automate some of your development tasks. Today we gonna have a look at Gulp.js, so lets get started. The minimum requirement to have Gulp.js is to have the node package installed and having the gulpfile.js in place in the root of your project folder.

1
2
npm install -g gulp
npm install --save-dev gulp

gulpfile.js

1
2
3
'use strict';
var gulp = require('gulp');

Similar as Grunt.js, Gulp.js also has a lot of plugins available. Lets zoom in on some of the plugins you can apply on php.

Some of the tasks I will be showing you may look a little bit silly at first sight, but keep on reading, in the Gulp-watch paragraph you will understand.

Php lint

1
npm install --save-dev phplint

In your gulpfile.js you can add the following lines of code to use it. As you can see you can use a globbing pattern to match the files you want to have phplint executed on and you can also ignore folders from being included.

1
2
3
4
5
6
7
8
9
10
11
var phplint = require('phplint').lint;
gulp.task('phplint', function (cb) {
phplint(['./**/*.php', '!node_modules/**/*', '!vendor/**/*'], { limit: 10 }, function (err, stdout, stderr) {
if (err) {
cb(err);
} else {
cb();
}
});
});

Above task executes all phplint on all files matching your globbing pattern.

Php Unit

1
2
npm install --save-dev gulp-phpunit
composer require --dev "phpunit/phpunit"

In your gulpfile.js you can add the following lines of code to use it.

1
2
3
4
5
6
7
8
var phpunit = require('gulp-phpunit');
gulp.task('phpunit', function () {
return gulp.src('phpunit.xml')
.pipe(phpunit('vendor/bin/phpunit'))
.on('error', console.error('TESTS FAILED:\nYou killed someones baby!'))
.pipe(function () { console.log('TESTS PASSED:\nAwesome you rock!'); });
});

Based on the settings defined in your phpunit.xml file you will execute phpunit using those settings.

Php CS

1
2
npm install --save-dev gulp-phpcs gulp-shell
composer require --dev "squizlabs/php_codesniffer"

In your gulpfile.js you can add the following lines of code to use it.

1
2
3
4
5
6
7
8
9
10
11
12
13
var phpcs = require('gulp-phpcs');
gulp.task('phpcs', function () {
return gulp.src(['./**/*.php', '!node_modules/', '!vendor/**/*'])
.pipe(phpcs({
bin: 'vendor/bin/phpcs',
standard: 'PSR2',
warningSeverity: 0
}))
.pipe(phpcs.reporter('log'));
});
gulp.task('phpcbf', shell.task(['vendor/bin/phpcbf --standard=PSR2 --ignore=vendor/,some/other/folder folder/to/include another/folder/to/include somefiletoinclude.php server.php']));

As you may see phpcs also ships with a tool phpcbf which can be used to autofix many of those phpcs issues. Unfortunatily there is no Gulp.js plugin for this tool, but we can leverage from the gulp-shell plugin to execute phpcbf. As you can see we are using the PSR2 standard for both tools.

Php Doc

1
2
npm install --save-dev gulp-shell
composer require --dev "phpdocumentor/phpdocumentor"

In your gulpfile.js you can add the following lines of code to use it.

1
2
3
var shell = require('gulp-shell');
gulp.task('phpdoc', shell.task(['vendor/bin/phpdoc -d . -t docs/phpdoc -i vendor/,node_modules/,server.php']));

Also for phpdoc it’s a similar story. We have the gulp-shell plugin execute phpdoc on the root folder of our project and we exclude the vendor, node_modules and server.php from being included in the docs.

Php MD

1
2
npm install --save-dev gulp-shell
composer require --dev "phpmd/phpmd"

In your gulpfile.js you can add the following lines of code to use it.

1
2
3
var shell = require('gulp-shell');
gulp.task('phpmd', shell.task(['vendor/bin/phpmd . codesize,unusedcode,naming,design,cleancode,controversial --reportfile docs/phpmd.html --exclude vendor/,node_modules/ --suffixes php']));

Also for PhpMD there is no Gulp.js plugin available, however no worries also here we just leverage from the gulp-shell plugin. We configured phpmd to make checks on codesize, unusedcode, naming, design, cleancode and some controversial checks.

Php depend

1
2
npm install --save-dev gulp-shell
composer require --dev "pdepend/pdepend"

In your gulpfile.js you can add the following lines of code to use it.

1
2
3
4
5
6
7
var shell = require('gulp-shell'),
pdependDocs = 'docs/pdepend';
gulp.task('pdepend', shell.task([
'mkdir -p ' + pdependDocs,
'vendor/bin/pdepend --summary-xml=' + pdependDocs + '/summary.xml --jdepend-chart=' + pdependDocs + '/chart.svg --overview-pyramid=' + pdependDocs + '/pyramid.svg --ignore=vendor,node_modules --suffix=php .'
]));

For pdepend we also use the shell plugin. As you can see we define multiple elements in the array. So the first command we execute is to create a folder to store the output of pdepend. The second command executes pdepend and writes the summary.xml, chart.svg and pyramid.svg to the docs/pdepend folder.

Gulp.js Watch

Unlike Grunt.js you don’t have to install another plugin to watch your directories/files for changes. Gulp.js has this feature builtin.

Using Gulp.js watch we will be continuously watching our project files for changes, and based on which files have changed we can have Gulp.js automatically execute our tasks. So lets use gulp watch to have some of our tasks being executed automatically on changes to files matching the globbing patterns.

1
2
3
4
5
6
7
8
9
gulp.task('watch', function () {
gulp.watch(['composer.json', 'phpunit.xml', './**/*.php', '!vendor/**/*', !node_modules/**/*'], function (event) {
console.log('File ' + event.path + ' was ' + event.type + ', running tasks...');
});
gulp.watch('composer.json', ['dump-autoload']);
gulp.watch(['phpunit.xml', './**/*.php', '!vendor/**/*', !node_modules/**/*'], ['phplint', 'phpcs', 'phpunit']);
});
gulp.task('default', ['phplint', 'phpcs', 'phpunit', 'watch']);

The above task shows a small message in the console that something has changed and that the configured tasks will be executed. We also defined the default tasks which initially runs all our “quality” tasks and then starts the watch task. Now each time you change a php file the tasks phplint, phpcs and phpunit will be executed and give you immediate feedback on the changes you made.

The things I showed you in this blogpost are just the beginning of what you can achieve with this. You could also be using git hooks to have some of these tasks being executed prior to a push. I would love to get your feedback on how you are applying it on your projects.

Share