#!/usr/bin/env node // requires var exec = require('child_process').exec; var path = require('path'); // some status strings var fail = '\x1B[31mfailed!\x1B[39m'; var ok = '\x1B[32mok\x1B[39m'; var notfound = '\x1B[31mfailed\x1B[31m (no script found)'; var notfoundDefault = '\x1B[33mn/a\x1B[39m (no script found)'; // longest name, for padding var longest = 0; // config var projectRoot = '{{projectRoot}}'; // lame templating so this gets populated correctly var package = require(path.join(projectRoot, 'package.json')); var scripts = package.scripts; var config = package.precommit; // set up environment var pathKey; var pathSep = process.platform === 'win32' ? ';' : ':'; var env = {}; for (var key in process.env) { if (key.toLowerCase() === 'path') { pathKey = key; } env[key] = process.env[key]; } env[pathKey] = path.join(projectRoot, 'node_modules', '.bin') + pathSep + env[pathKey]; // run the command for the given property function runCmd(name, done) { done = done || process.exit; var pad = ''; for (var i = 0, il = longest - name.length; i < il; ++i) { pad += ' '; } process.stdout.write('running ' + name + ': ' + pad); if (!scripts[name]) { console.log(notfound); exit(1, process.exit); } var cmd = (process.platform === 'win32' ? 'cmd /c ' : 'sh -c ') + JSON.stringify(scripts[name]); exec(cmd, { cwd: projectRoot, env: env }, function (err, stdout, stderr) { if (err) { console.log(fail); console.log(stdout); console.log(stderr); exit(err.code, process.exit); } else { console.log(ok); exit(0, done); } }); } // this method shamelessly adapted from https://github.com/cowboy/node-exit function exit(code, callback) { var streams = [process.stdout, process.stderr]; var drainCount = 0; function tryToExit() { if (drainCount === streams.length) { callback(code); } } streams.forEach(function (stream) { if (stream.bufferSize === 0) { drainCount++; } else { stream.write('', 'utf-8', function () { drainCount++; tryToExit(); }); stream.write = function () {}; } }); tryToExit(); } if (!config || !config.length) { config = ['lint']; scripts = scripts || {}; scripts.lint = scripts.lint || 'jshint .'; ['validate', 'test'].forEach(function (elem) { if (scripts[elem]) { config.push(elem); } else { console.log(elem + ': ' + notfoundDefault); } }); } var tasks = []; config.forEach(function (cmd, i) { longest = (longest < cmd.length) ? cmd.length : longest; var task = runCmd.bind(null, cmd); tasks[i] = function () { task.call(null, tasks[i + 1]); }; }); console.log('running pre-commit checks...'); tasks[0]();