1 | #!/usr/bin/env node
|
2 |
|
3 | // requires
|
4 | var exec = require('child_process').exec;
|
5 | var path = require('path');
|
6 | var fs = require('fs');
|
7 |
|
8 | // some status strings
|
9 | var fail = '\x1B[31mfailed!\x1B[39m';
|
10 | var ok = '\x1B[32mok\x1B[39m';
|
11 | var notfound = '\x1B[33mn/a\x1B[39m (no script found)';
|
12 | var skipped = '\x1B[33mn/a\x1B[39m (skipped)';
|
13 |
|
14 | // config
|
15 | var projectRoot = '{{projectRoot}}'; // lame templating so this gets populated correctly
|
16 | var config = require(path.join(projectRoot, 'package.json'));
|
17 | var myconfig = config.config && config.config.precommit ? config.config.precommit : undefined;
|
18 |
|
19 | // set up environment
|
20 | var pathKey;
|
21 | var pathSep = process.platform === 'win32' ? ';' : ':';
|
22 | var env = {};
|
23 | for (var key in process.env) {
|
24 | if (key.toLowerCase() === 'path') {
|
25 | pathKey = key;
|
26 | }
|
27 |
|
28 | env[key] = process.env[key];
|
29 | }
|
30 | env[pathKey] = path.join(projectRoot, 'node_modules', '.bin') + pathSep + env[pathKey];
|
31 |
|
32 | // run the command for the given property
|
33 | function runCmd(prop, done) {
|
34 | var skip = myconfig ? !myconfig[prop] : false;
|
35 | var cmd = config.scripts && config.scripts[prop] ? config.scripts[prop] : prop === 'lint' ? 'jshint .' : undefined;
|
36 | var pad = '';
|
37 | for (var i = 0; i < (8 - prop.length); i++) {
|
38 | pad += ' ';
|
39 | }
|
40 |
|
41 | process.stdout.write('running ' + prop + ': ' + pad);
|
42 |
|
43 | if (skip) {
|
44 | console.log(skipped);
|
45 | return done();
|
46 | }
|
47 |
|
48 | if (!cmd) {
|
49 | console.log(notfound);
|
50 | return done();
|
51 | }
|
52 |
|
53 | cmd = (process.platform === 'win32' ? 'cmd /c ' : 'sh -c ') + '\"' + cmd + '\"';
|
54 |
|
55 | exec(cmd, { cwd: projectRoot, env: env }, function (err, stdout, stderr) {
|
56 | if (err) {
|
57 | console.log(fail);
|
58 | console.log(stdout);
|
59 | console.log(stderr);
|
60 | exit(err.code, process.exit);
|
61 | } else {
|
62 | console.log(ok);
|
63 | exit(0, done);
|
64 | }
|
65 | });
|
66 | }
|
67 |
|
68 | // this method shamelessly adapted from https://github.com/cowbody/node-exit
|
69 | function exit(code, callback) {
|
70 | var streams = [process.stdout, process.stderr];
|
71 | var drainCount = 0;
|
72 |
|
73 | function tryToExit() {
|
74 | if (drainCount === streams.length) {
|
75 | callback(code);
|
76 | }
|
77 | }
|
78 |
|
79 | streams.forEach(function (stream) {
|
80 | if (stream.bufferSize === 0) {
|
81 | drainCount++;
|
82 | } else {
|
83 | stream.write('', 'utf-8', function () {
|
84 | drainCount++;
|
85 | tryToExit();
|
86 | });
|
87 |
|
88 | stream.write = function () {};
|
89 | }
|
90 | });
|
91 |
|
92 | tryToExit();
|
93 | }
|
94 |
|
95 | console.log('running pre-commit checks...');
|
96 | runCmd('lint', function () {
|
97 | runCmd('validate', function () {
|
98 | runCmd('test', process.exit);
|
99 | });
|
100 | });
|