Skip to content

Instantly share code, notes, and snippets.

@sgen
Last active November 1, 2015 19:29
Show Gist options
  • Save sgen/2d3ee9f7dfa94b935f8b to your computer and use it in GitHub Desktop.
Save sgen/2d3ee9f7dfa94b935f8b to your computer and use it in GitHub Desktop.
Gulpfile.js for a Node.js module

The Ultimate Gulpfile

The ultimate gulpfile watches for changes to your .jsfiles and runs jshint, mocha tests and istanbul test coverage before launching 2 file servers serving jshint results and istanbul coverage respectively.

Usage

  1. Copy this gist (or just gulpfile.js and server.js) to your project

  2. Install the dependencies (assumes you already have gulp installed):

npm install --save-dev gulp-plumber gulp-cat gulp-watch gulp-jshint gulp-jshint-html-reporter gulp-istanbul gulp-mocha sinon chai sinon-chai node-static del ps-node run-sequence mkdirp

Tasks

Default

By default gulp will run the jshint, mocha and istanbul once then start the file servers.

gulp

Watch

Watch will run the default command once, then watch for changes, linting, testing, generating test coverage and restarting the file servers whenever a file changes.

gulp watch

Kill

Kill will kill any running file servers

gulp kill

Clean

Clean will kill any running file servers and clean up the generated linter, coverage and logs files.

gulp clean

Logs

Logs will output the contents of all of the file server logs. Useful for troubleshooting.

gulp logs
'use strict';
var gulp = require('gulp');
var plumber = require('gulp-plumber');
var jshint = require('gulp-jshint');
var istanbul = require('gulp-istanbul');
var mocha = require('gulp-mocha');
var srv = require('node-static');
var http = require('http');
var del = require('del');
var fs = require('fs');
var mkdirp = require('mkdirp');
var getDirName = require('path').dirname;
var ps = require('ps-node');
var spawn = require('child_process').spawn;
var sequence = require('run-sequence');
var cat = require('gulp-cat');
var watch = require('gulp-watch');
var istDir = 'coverage';
var istSrvName = 'Istanbul.js Coverage Server';
var istSrvPort = 8000;
var istSrvPidFile = '.istanbul-coverage-server.pid';
var istSrvOutFile = 'log/istanbul/out.log';
var istSrvErrFile = 'log/istanbul/err.log';
var lintDir = 'linter';
var lintSrvName = 'JSHint Server';
var lintSrvPort = 8001;
var lintSrvPidFile = '.lint-server.pid';
var lintSrvOutFile = 'log/linter/out.log';
var lintSrvErrFile = 'log/linter/err.log';
function openSync(path, flags, mode) {
mkdirp.sync(getDirName(path));
return fs.openSync(path, flags, mode);
}
function writeFile(path, contents, cb) {
mkdirp(getDirName(path), function(e) {
if (e) {
return cb(e);
}
fs.writeFile(path, contents, cb);
});
}
function kill(name, pidFile, cb) {
fs.readFile(pidFile, {
encoding: 'utf8'
}, function(e, data) {
var exists = true;
if (e) {
if (e.code === 'ENOENT') {
exists = false;
} else {
throw e;
}
}
if (!exists) {
console.log('%s is not running', name);
if (cb) {
cb();
}
return;
}
var pid = parseInt(data);
ps.kill(pid, function() {
console.log('Killed %s (%s)', name, pid);
del(pidFile).then(function() {
console.log('Deleted %s', pidFile);
if (cb) {
cb();
}
});
});
});
}
function serve(name, dir, port, outFile, errFile, pidFile) {
var srv = function(name, dir, port, outFile, errFile, pidFile) {
var out = openSync(outFile, 'a');
var err = openSync(errFile, 'a');
var child = spawn('node', ['./server.js', dir, port], {
detached: true,
stdio: ['ignore', out, err]
});
var pid = child.pid;
console.log('Launching %s (%s)', name, pid);
child.unref();
writeFile(pidFile, pid);
console.log('Created %s', pidFile);
};
kill(name, pidFile, function() {
srv(name, dir, port, outFile, errFile, pidFile);
});
}
function lint() {
return gulp.src(['!node_modules/**', '!server.js', '!coverage/**', '!linter/**', '!.jshintrc', '**/*.js'])
.pipe(plumber())
.pipe(jshint({linter: 'jshint'}))
.pipe(jshint.reporter('gulp-jshint-html-reporter', {
filename: lintDir + '/index.html',
createMissingFolders: true
})).on('end', function() {
serve(lintSrvName, lintDir, lintSrvPort, lintSrvOutFile, lintSrvErrFile, lintSrvPidFile);
});
}
gulp.task('lint', lint);
function test() {
return gulp.src(['!node_modules/**', '!server.js', '!coverage/**', '!linter/**', '!.jshintrc', '!test/**', '**/*.js'])
.pipe(plumber())
.pipe(istanbul())
.pipe(istanbul.hookRequire())
.on('finish', function() {
gulp.src(['test/*.js'])
.pipe(plumber())
.pipe(mocha())
.pipe(istanbul.writeReports({
dir: istDir,
reporters: [
'text',
'html'
],
reportOpts: {
dir: istDir
}
}))
.on('end', function() {
serve(istSrvName, istDir, istSrvPort, istSrvOutFile, istSrvErrFile, istSrvPidFile);
});
});
}
gulp.task('test', test);
function lintAndTest() {
sequence(
'lint',
'test'
);
}
function logs() {
return gulp.src(['log/**/*.log'])
.pipe(cat());
}
gulp.task('logs', logs);
gulp.task('watch', function() {
lintAndTest();
watch(['!node_modules/**', '!server.js', '!coverage/**', '!linter/**', '.jshintrc', 'test/**', '**/*.js'], lintAndTest);
})
gulp.task('clean', function() {
del(['coverage', 'log']).then(function(paths) {
paths.forEach(function(e) {
console.log('Deleted %s', e);
});
});
kill(istSrvName, istSrvPidFile);
kill(lintSrvName, lintSrvPidFile);
});
gulp.task('kill', function() {
kill(istSrvName, istSrvPidFile);
kill(lintSrvName, lintSrvPidFile);
});
gulp.task('default', lintAndTest);
'use strict';
var srv = require('node-static');
var http = require('http');
var dir = process.argv[2];
if (dir === undefined) {
throw new Error('dir was not specified');
}
var port = parseInt(process.argv[3]);
if (port === undefined || isNaN(port)) {
port = 8000;
}
var cfs = new srv.Server(dir, {cache: false});
http.createServer(function(req, resp) {
req.addListener('end', function() {
cfs.serve(req, resp);
}).resume();
}).listen(port);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment