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