Coverage

79%
707
559
148

NullStream.js

94%
19
18
1
LineHitsSource
1// Generated by CoffeeScript 1.4.0
21var NullStream, events,
3 __hasProp = {}.hasOwnProperty,
47 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
5
61events = require('events');
7
81module.exports = NullStream = (function(_super) {
9
101 __extends(NullStream, _super);
11
121 function NullStream() {
1330 return NullStream.__super__.constructor.apply(this, arguments);
14 }
15
161 NullStream.prototype.readable = true;
17
181 NullStream.prototype.pause = function() {};
19
201 NullStream.prototype.resume = function() {};
21
221 NullStream.prototype.pipe = function() {};
23
241 NullStream.prototype.writable = true;
25
261 NullStream.prototype.write = function(data) {
2756 return this.emit('data', data);
28 };
29
301 NullStream.prototype.end = function() {
310 return this.emit('close');
32 };
33
341 NullStream.prototype.destroy = function() {};
35
361 NullStream.prototype.destroySoon = function() {};
37
381 return NullStream;
39
40})(events.EventEmitter);

Request.js

98%
68
67
1
LineHitsSource
1// Generated by CoffeeScript 1.4.0
21var Request, each;
3
41each = require('each');
5
61module.exports = Request = (function() {
7
81 function Request(shell, command) {
914 this.shell = shell;
1014 this.command = command;
11 }
12
13 /*
14 Ask one or more questions
15 */
16
17
181 Request.prototype.question = function(questions, callback) {
193 var answers, isObject, multiple, q, v,
20 _this = this;
213 isObject = function(v) {
226 return typeof v === 'object' && (v != null) && !Array.isArray(v);
23 };
243 multiple = true;
253 answers = {};
263 if (isObject(questions)) {
271 questions = (function() {
281 var _results;
291 _results = [];
301 for (q in questions) {
313 v = questions[q];
323 if (v == null) {
331 v = {};
34 }
353 if (!isObject(v)) {
361 v = {
37 value: v
38 };
39 }
403 v.name = q;
413 _results.push(v);
42 }
431 return _results;
44 })();
452 } else if (typeof questions === 'string') {
461 multiple = false;
471 questions = [
48 {
49 name: questions,
50 value: ''
51 }
52 ];
53 }
543 return each(questions).on('item', function(next, question) {
556 q = "" + question.name + " ";
566 if (question.value) {
573 q += "[" + question.value + "] ";
58 }
596 return _this.shell["interface"]().question(q, function(answer) {
606 if (answer.substr(-1, 1) === '\n') {
616 answer = answer.substr(0, answer.length - 1);
62 }
636 answers[question.name] = answer === '' ? question.value : answer;
646 return next();
65 });
66 }).on('end', function() {
673 if (!multiple) {
681 answers = answers[questions[0].name];
69 }
703 return callback(answers);
71 });
72 };
73
74 /*
75 Ask a question expecting a boolean answer
76 */
77
78
791 Request.prototype.confirm = function(msg, defaultTrue, callback) {
802 var args, keyFalse, keyTrue, key_false, key_true, question, _base, _base1, _ref, _ref1,
81 _this = this;
822 args = arguments;
832 if (!callback) {
842 callback = defaultTrue;
852 defaultTrue = true;
86 }
872 if ((_ref = (_base = this.shell.settings).key_true) == null) {
881 _base.key_true = 'y';
89 }
902 if ((_ref1 = (_base1 = this.shell.settings).key_false) == null) {
911 _base1.key_false = 'n';
92 }
932 key_true = this.shell.settings.key_true.toLowerCase();
942 key_false = this.shell.settings.key_false.toLowerCase();
952 keyTrue = defaultTrue ? key_true.toUpperCase() : key_true;
962 keyFalse = defaultTrue ? key_false : key_false.toUpperCase();
972 msg += ' ';
982 msg += "[" + keyTrue + keyFalse + "] ";
992 question = this.shell.styles.raw(msg, {
100 color: 'green'
101 });
1022 return this.shell["interface"]().question(question, function(answer) {
1032 var accepted, valid;
1042 accepted = ['', key_true, key_false];
1052 if (answer.substr(-1, 1) === '\n') {
1062 answer = answer.substr(0, answer.length - 1);
107 }
1082 answer = answer.toLowerCase();
1092 valid = accepted.indexOf(answer) !== -1;
1102 if (!valid) {
1110 return _this.confirm.apply(_this, args);
112 }
1132 return callback(answer === key_true || (defaultTrue && answer === ''));
114 });
115 };
116
1171 return Request;
118
119})();

Response.js

100%
13
13
0
LineHitsSource
1// Generated by CoffeeScript 1.4.0
21var Response, pad, styles,
3 __hasProp = {}.hasOwnProperty,
49 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
5
61styles = require('./Styles');
7
81pad = require('pad');
9
101module.exports = Response = (function(_super) {
11
121 __extends(Response, _super);
13
141 function Response(settings) {
1514 this.shell = settings.shell;
1614 Response.__super__.constructor.call(this, settings);
17 }
18
191 Response.prototype.pad = pad;
20
211 Response.prototype.prompt = function() {
224 return this.shell.prompt();
23 };
24
251 return Response;
26
27})(styles);

Shell.js

76%
141
108
33
LineHitsSource
1// Generated by CoffeeScript 1.4.0
21var EventEmitter, Interface, Request, Response, Shell, each, events, readline, styles, util, utils,
3 __hasProp = {}.hasOwnProperty,
47 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
5
61util = require('util');
7
81readline = require('readline');
9
101events = require('events');
11
121EventEmitter = events.EventEmitter;
13
141each = require('each');
15
161utils = require('./utils');
17
181styles = require('./Styles');
19
201Request = require('./Request');
21
221Response = require('./Response');
23
241Interface = require('readline').Interface;
25
261Interface.prototype.setPrompt = (function(parent) {
271 return function(prompt, length) {
2825 var args;
2925 args = Array.prototype.slice.call(arguments);
3025 if (!args[1]) {
3125 args[1] = styles.unstyle(args[0]).length;
32 }
3325 return parent.apply(this, args);
34 };
35})(Interface.prototype.setPrompt);
36
371module.exports = Shell = (function(_super) {
38
391 __extends(Shell, _super);
40
411 function Shell(settings) {
4229 var _base, _base1, _base2, _ref, _ref1, _ref2, _ref3, _ref4, _ref5, _ref6,
43 _this = this;
4429 if (settings == null) {
450 settings = {};
46 }
4729 if (!(this instanceof Shell)) {
4814 return new Shell(settings);
49 }
5015 EventEmitter.call(this);
5115 this.tmp = {};
5215 this.settings = settings;
5315 if ((_ref = (_base = this.settings).prompt) == null) {
5415 _base.prompt = '>> ';
55 }
5615 if ((_ref1 = (_base1 = this.settings).stdin) == null) {
570 _base1.stdin = process.stdin;
58 }
5915 if ((_ref2 = (_base2 = this.settings).stdout) == null) {
600 _base2.stdout = process.stdout;
61 }
6215 this.set('env', (_ref3 = (_ref4 = this.settings.env) != null ? _ref4 : process.env.NODE_ENV) != null ? _ref3 : 'development');
6315 this.set('command', typeof settings.command !== 'undefined' ? settings.command : process.argv.slice(2).join(' '));
6415 this.stack = [];
6515 this.styles = styles({
66 stdout: this.settings.stdout
67 });
6815 process.on('beforeExit', function() {
690 return _this.emit('exit');
70 });
7115 process.on('uncaughtException', function(e) {
720 _this.emit('exit', [e]);
730 _this.styles.red('Internal error, closing...').ln();
740 console.error(e.message);
750 console.error(e.stack);
760 return process.exit();
77 });
7815 this.isShell = (_ref5 = this.settings.isShell) != null ? _ref5 : process.argv.length === 2;
7915 if (this.isShell) {
800 this["interface"]();
81 }
8215 if ((_ref6 = settings.workspace) == null) {
8310 settings.workspace = utils.workspace();
84 }
8515 if (settings.chdir === true) {
860 process.chdir(settings.workspace);
87 }
8815 if (typeof settings.chdir === 'string') {
890 process.chdir(settings.chdir);
90 }
9115 process.nextTick(function() {
9215 var command, noPrompt;
9315 if (_this.isShell) {
940 command = _this.set('command');
950 noPrompt = _this.set('noPrompt');
960 if (command) {
970 return _this.run(command);
980 } else if (!noPrompt) {
990 return _this.prompt();
100 }
101 } else {
10215 command = _this.set('command');
10315 if (command) {
10412 return _this.run(command);
105 }
106 }
107 });
10815 return this;
109 }
110
1111 Shell.prototype["interface"] = function() {
11214 if (this._interface != null) {
1135 return this._interface;
114 }
1159 return this._interface = readline.createInterface(this.settings.stdin, this.settings.stdout);
116 };
117
1181 Shell.prototype.configure = function(env, fn) {
11913 if (typeof env === 'function') {
12013 fn = env;
12113 env = 'all';
122 }
12313 if (env === 'all' || env === this.settings.env) {
12413 fn.call(this);
125 }
12613 return this;
127 };
128
1291 Shell.prototype.use = function(handle) {
13016 if (handle) {
13116 this.stack.push({
132 route: null,
133 handle: handle
134 });
135 }
13616 return this;
137 };
138
1391 Shell.prototype.cmds = {};
140
1411 Shell.prototype.run = function(command) {
14214 var index, next, req, res, self;
14314 command = command.trim();
14414 this.emit('command', [command]);
14514 this.emit(command, []);
14614 self = this;
14714 req = new Request(this, command);
14814 res = new Response({
149 shell: this,
150 stdout: this.settings.stdout
151 });
15214 index = 0;
15314 next = function(err) {
15419 var arity, layer, text;
15519 layer = self.stack[index++];
15619 if (!layer) {
1571 if (err) {
1581 return self.emit('error', err);
159 }
1600 if (command !== '') {
1610 text = "Command failed to execute " + command;
1620 if (err) {
1630 text += ": " + (err.message || err.name);
164 }
1650 res.red(text);
166 }
1670 return res.prompt();
168 }
16918 arity = layer.handle.length;
17018 if (err) {
1712 if (arity === 4) {
1722 self.emit('error', err);
1732 return layer.handle(err, req, res, next);
174 } else {
1750 return next(err);
176 }
17716 } else if (arity < 4) {
17816 return layer.handle(req, res, next);
179 } else {
1800 return next();
181 }
182 };
18314 return next();
184 };
185
1861 Shell.prototype.set = function(setting, val) {
18746 if (!(val != null)) {
18817 if (this.settings.hasOwnProperty(setting)) {
18917 return this.settings[setting];
1900 } else if (this.parent) {
1910 return this.parent.set(setting);
192 }
193 } else {
19429 this.settings[setting] = val;
19529 return this;
196 }
197 };
198
1991 Shell.prototype.prompt = function() {
2004 var text;
2014 if (this.isShell) {
2020 text = this.styles.raw(this.settings.prompt, {
203 color: 'green'
204 });
2050 return this["interface"]().question(text, this.run.bind(this));
206 } else {
2074 this.styles.ln();
2084 if (process.versions) {
2094 return this.quit();
210 } else {
2110 this.settings.stdout.destroySoon();
2120 return this.settings.stdout.on('close', function() {
2130 return process.exit();
214 });
215 }
216 }
217 };
218
2191 Shell.prototype.quit = function(params) {
2206 this.emit('quit');
2216 this["interface"]().close();
2226 return this.settings.stdin.destroy();
223 };
224
2251 return Shell;
226
227})(EventEmitter);

Styles.js

92%
76
70
6
LineHitsSource
1// Generated by CoffeeScript 1.4.0
22var Styles, bgcolors, code, color, colors, _fn;
3
42colors = {
5 black: 30,
6 red: 31,
7 green: 32,
8 yellow: 33,
9 blue: 34,
10 magenta: 35,
11 cyan: 36,
12 white: 37
13};
14
152bgcolors = {
16 black: 40,
17 red: 41,
18 green: 42,
19 yellow: 43,
20 blue: 44,
21 magenta: 45,
22 cyan: 46,
23 white: 47
24};
25
262module.exports = Styles = function(settings) {
2754 var _ref;
2854 if (settings == null) {
290 settings = {};
30 }
3154 if (!(this instanceof Styles)) {
3220 return new Styles(settings);
33 }
3434 this.settings = settings;
3534 this.settings.stdout = (_ref = settings.stdout) != null ? _ref : process.stdout;
3634 this.current = {
37 weight: 'regular'
38 };
3934 this.colors = colors;
4034 this.bgcolors = bgcolors;
4134 return this;
42};
43
442Styles.prototype.color = function(color, text) {
4540 this.print(text, {
46 color: color
47 });
4840 if (!text) {
499 this.current.color = color;
50 }
5140 return this;
52};
53
542_fn = function(color) {
5516 return Styles.prototype[color] = function(text) {
5638 return this.color(color, text);
57 };
58};
592for (color in colors) {
6016 code = colors[color];
6116 _fn(color);
62}
63
642Styles.prototype.nocolor = function(text) {
652 return this.color(null, text);
66};
67
682Styles.prototype.bgcolor = function(bgcolor) {
690 if (bgcolor == null) {
700 bgcolor = 0;
71 }
720 this.print('\x1B[' + bgcolor + ';m39');
730 return this;
74};
75
762Styles.prototype.weight = function(weight, text) {
779 this.print(text, {
78 weight: weight
79 });
809 if (!text) {
814 this.current.weight = weight;
82 }
839 return this;
84};
85
862Styles.prototype.bold = function(text) {
875 return this.weight('bold', text);
88};
89
902Styles.prototype.regular = function(text) {
914 return this.weight('regular', text);
92};
93
942Styles.prototype.print = function(text, settings) {
9572 this.settings.stdout.write(this.raw(text, settings));
9672 return this;
97};
98
992Styles.prototype.println = function(text) {
1001 this.settings.stdout.write(text + '\n');
1011 return this;
102};
103
1042Styles.prototype.ln = function() {
10522 this.settings.stdout.write('\n');
10622 return this;
107};
108
1092Styles.prototype.raw = function(text, settings) {
110148 var raw;
111148 raw = '';
112148 if (settings == null) {
11322 settings = {};
114 }
115148 if (settings.color !== null && (settings.color || this.current.color)) {
11678 raw += '\x1b[' + this.colors[settings.color || this.current.color] + 'm';
117 } else {
11870 raw += '\x1b[39m';
119 }
120148 switch (settings.weight || this.current.weight) {
121 case 'bold':
12213 raw += '\x1b[1m';
12313 break;
124 case 'regular':
125135 raw += '\x1b[22m';
126135 break;
127 default:
1280 throw new Error('Invalid weight "' + weight + '" (expect "bold" or "regular")');
129 }
130148 if (text) {
13160 raw += text;
13260 if (this.current.color && this.current.color !== settings.color) {
13316 raw += this.raw(null, this.current.color);
134 }
13560 if (this.current.weight && this.current.weight !== settings.weight) {
13658 raw += this.raw(null, this.current.weight);
137 }
138 }
139148 return raw;
140};
141
1422Styles.prototype.reset = function(text) {
1431 return this.print(null, {
144 color: null,
145 weight: 'regular'
146 });
147};
148
1492Styles.unstyle = function(text) {
15027 return text.replace(/\x1b.*?m/g, '');
151};

plugins/error.js

90%
22
20
2
LineHitsSource
1// Generated by CoffeeScript 1.4.0
2
31module.exports = function(settings) {
42 var shell;
52 if (!settings.shell) {
60 throw new Error('No shell provided');
7 }
82 shell = settings.shell;
92 shell.on('error', function() {});
102 return function(err, req, res, next) {
112 var k, v;
122 if (err.message) {
132 res.red(err.message).ln();
14 }
152 if (err.stack) {
162 res.red(err.stack).ln();
17 }
182 for (k in err) {
1912 v = err[k];
2012 if (k === 'message') {
212 continue;
22 }
2310 if (k === 'stack') {
240 continue;
25 }
2610 if (typeof v === 'function') {
272 continue;
28 }
298 res.magenta(k).white(': ').red(v).ln();
30 }
312 return res.prompt();
32 };
33};

plugins/http.js

83%
59
49
10
LineHitsSource
1// Generated by CoffeeScript 1.4.0
21var existsSync, fs, path, start_stop;
3
41fs = require('fs');
5
61path = require('path');
7
81existsSync = fs.existsSync || path.existsSync;
9
101start_stop = require('../start_stop');
11
12/*
13
14HTTP server
15===========
16
17Register two commands, `http start` and `http stop`. The start command will
18search for "./server.js" and "./app.js" (and additionnaly their CoffeeScript
19alternatives) to run by `node`.
20
21The following properties may be provided as settings:
22
23- `message_start` Message to display once the server is started
24- `message_stop` Message to display once the server is stoped
25- `workspace` Project directory used to resolve relative paths and search for "server" and "app" scripts.
26- `cmd` Command to start the server, not required if path is provided or if the script is discoverable
27- `path` Path to the js/coffee script starting the process, may be relative to the workspace, extension isn't required.
28
29Properties derived from the start_stop utility:
30
31- `detached` Wether the HTTP process should be attached to the current process. If not defined, default to `false` (the server doesn't run as a daemon).
32- `pidfile` Path to the file storing the daemon process id. Defaults to `"/.node_shell/#{md5}.pid"`
33- `stdout` Writable stream or file path to redirect the server stdout.
34- `stderr` Writable stream or file path to redirect the server stderr.
35
36Example:
37
38```javascript
39var app = new shell();
40app.configure(function() {
41 app.use(shell.router({
42 shell: app
43 }));
44 app.use(shell.http({
45 shell: app
46 }));
47 app.use(shell.help({
48 shell: app,
49 introduction: true
50 }));
51});
52```
53*/
54
55
561module.exports = function() {
571 var cmd, http, route, settings;
581 settings = {};
591 cmd = function() {
601 var search, searchs, _i, _len;
611 searchs = settings.path ? [settings.path] : ['app', 'server', 'lib/app', 'lib/server'];
621 for (_i = 0, _len = searchs.length; _i < _len; _i++) {
631 search = searchs[_i];
641 search = path.resolve(settings.workspace, search);
651 if (existsSync("" + search)) {
660 if (search.substr(-4) === '.coffee') {
670 return "coffee " + search;
68 } else {
690 return "node " + search;
70 }
71 }
721 if (existsSync("" + search + ".js")) {
730 return "node " + search + ".js";
741 } else if (existsSync("" + search + ".coffee")) {
751 return "coffee " + search + ".coffee";
76 }
77 }
780 throw new Error('Failed to discover a "server.js" or "app.js" file');
79 };
801 http = null;
811 route = function(req, res, next) {
822 var app, _ref, _ref1, _ref2;
832 app = req.shell;
842 if (app.tmp.http) {
851 return next();
86 }
871 app.tmp.http = true;
881 if ((_ref = settings.workspace) == null) {
891 settings.workspace = app.set('workspace');
90 }
911 if (!settings.workspace) {
920 throw new Error('No workspace provided');
93 }
941 if ((_ref1 = settings.message_start) == null) {
951 settings.message_start = 'HTTP server successfully started';
96 }
971 if ((_ref2 = settings.message_stop) == null) {
981 settings.message_stop = 'HTTP server successfully stopped';
99 }
1001 if (!settings.cmd) {
1011 settings.cmd = cmd();
102 }
1031 app.cmd('http start', 'Start HTTP server', function(req, res, next) {
1041 return http = start_stop.start(settings, function(err, pid) {
1051 if (err) {
1060 return next(err);
107 }
1081 if (!pid) {
1090 return res.cyan('HTTP server already started').ln() && res.prompt();
110 }
1111 res.cyan(settings.message_start).ln();
1121 return res.prompt();
113 });
114 });
1151 app.cmd('http stop', 'Stop HTTP server', function(req, res, next) {
1161 return start_stop.stop(settings, function(err, success) {
1171 if (success) {
1181 res.cyan(settings.message_stop).ln();
119 } else {
1200 res.magenta('HTTP server was not started').ln();
121 }
1221 return res.prompt();
123 });
124 });
1251 return next();
126 };
1271 if (arguments.length === 1) {
1281 settings = arguments[0];
1291 return route;
130 } else {
1310 return route.apply(null, arguments);
132 }
133};

plugins/router.js

70%
130
91
39
LineHitsSource
1// Generated by CoffeeScript 1.4.0
21var match, normalize, querystring, utils,
30 __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
4
51utils = require('../utils');
6
71querystring = {
8 unescape: function(str) {
94 return decodeURIComponent(str);
10 },
11 parse: function(qs, sep, eq) {
120 var k, kvp, obj, v, vkps, x, _i, _len, _ref;
130 sep = sep || '&';
140 eq = eq || '=';
150 obj = {};
160 if (typeof qs !== 'string') {
170 return obj;
18 }
190 vkps = qs.split(sep);
200 for (_i = 0, _len = vkps.length; _i < _len; _i++) {
210 kvp = vkps[_i];
220 x = kvp.split(eq);
230 k = querystring.unescape(x[0], true);
240 v = querystring.unescape(x.slice(1).join(eq), true);
250 if (_ref = !k, __indexOf.call(obj, _ref) >= 0) {
260 obj[k] = v;
270 } else if (!Array.isArray(obj[k])) {
280 obj[k] = [obj[k], v];
29 } else {
300 obj[k].push(v);
31 }
32 }
330 return obj;
34 }
35};
36
371normalize = function(command, keys, sensitive) {
3829 command = command.concat('/?').replace(/\/\(/g, '(?:/').replace(/:(\w+)(\(.*\))?(\?)?/g, function(_, key, format, optional) {
396 keys.push(key);
406 format = format || '([^ ]+)';
416 optional = optional || '';
426 return format + optional;
43 }).replace(/([\/.])/g, '\\$1').replace(/\*/g, '(.+)');
4429 return new RegExp('^' + command + '$', (sensitive != null ? 'i' : void 0));
45};
46
471match = function(req, routes, i) {
4814 var captures, index, j, key, keys, regexp, route, val;
4914 if (i == null) {
5014 i = 0;
51 }
5214 while (i < routes.length) {
5330 route = routes[i];
5430 regexp = route.regexp;
5530 keys = route.keys;
5630 captures = regexp.exec(req.command);
5730 if (captures) {
5814 route.params = {};
5914 index = 0;
6014 j = 1;
6114 while (j < captures.length) {
624 key = keys[j - 1];
634 val = typeof captures[j] === 'string' ? querystring.unescape(captures[j]) : captures[j];
644 if (key) {
654 route.params[key] = val;
66 } else {
670 route.params['' + index] = val;
680 index++;
69 }
704 j++;
71 }
7214 req._route_index = i;
7314 return route;
74 }
7516 i++;
76 }
770 return null;
78};
79
801module.exports = function(settings) {
8113 var params, routes, shell, _ref;
8213 if (!settings.shell) {
830 throw new Error('No shell provided');
84 }
8513 shell = settings.shell;
8613 if ((_ref = settings.sensitive) == null) {
8713 settings.sensitive = true;
88 }
8913 routes = shell.routes = [];
9013 params = {};
9113 shell.param = function(name, fn) {
920 if (Array.isArray(name)) {
930 name.forEach(function(name) {
940 return this.param(name, fn);
95 }, this);
96 } else {
970 if (':' === name[0]) {
980 name = name.substr(1);
99 }
1000 params[name] = fn;
101 }
1020 return this;
103 };
10413 shell.cmd = function(command, description, middleware1, middleware2, fn) {
10529 var args, keys, route;
10629 args = Array.prototype.slice.call(arguments);
10729 route = {};
10829 route.command = args.shift();
10929 if (typeof args[0] === 'string') {
11015 route.description = args.shift();
111 }
11229 route.middlewares = utils.flatten(args);
11329 keys = [];
11429 route.regexp = route.command instanceof RegExp ? route.command : normalize(route.command, keys, settings.sensitive);
11529 route.keys = keys;
11629 routes.push(route);
11729 return this;
118 };
11913 shell.cmd('quit', 'Exit this shell', shell.quit.bind(shell));
12013 return function(req, res, next) {
12114 var i, pass, route, self;
12214 route = null;
12314 self = this;
12414 i = 0;
12514 pass = function(i) {
12614 var keys, param;
12714 route = match(req, routes, i);
12814 if (!route) {
1290 return next();
130 }
13114 i = 0;
13214 keys = route.keys;
13314 req.params = route.params;
13414 param = function(err) {
13518 var fn, key, nextMiddleware, val;
13618 try {
13718 key = keys[i++];
13818 val = req.params[key];
13918 fn = params[key];
14018 if ('route' === err) {
1410 return pass(req._route_index + 1);
14218 } else if (err) {
1430 return next(err);
14418 } else if (fn) {
1450 if (1 === fn.length) {
1460 req.params[key] = fn(val);
1470 return param();
148 } else {
1490 return fn(req, res, param, val);
150 }
15118 } else if (!key) {
15214 i = 0;
15314 nextMiddleware = function(err) {
15415 fn = route.middlewares[i++];
15515 if ('route' === err) {
1560 return pass(req._route_index + 1);
15715 } else if (err) {
1581 return next(err);
15914 } else if (fn) {
16014 return fn(req, res, nextMiddleware);
161 } else {
1620 return pass(req._route_index + 1);
163 }
164 };
16514 return nextMiddleware();
166 } else {
1674 return param();
168 }
169 } catch (err) {
1702 return next(err);
171 }
172 };
17314 return param();
174 };
17514 return pass();
176 };
177};

start_stop.js

69%
152
105
47
LineHitsSource
1// Generated by CoffeeScript 1.4.0
21var crypto, exec, exists, fs, md5, path, spawn, start_stop, _ref;
3
41crypto = require('crypto');
5
61_ref = require('child_process'), exec = _ref.exec, spawn = _ref.spawn;
7
81fs = require('fs');
9
101path = require('path');
11
121exists = fs.exists || path.exists;
13
141md5 = function(cmd) {
153 return crypto.createHash('md5').update(cmd).digest('hex');
16};
17
18/*
19`start_stop`: Unix process management
20-------------------------------------
21
22The library start and stop unix child process. Process are by default
23daemonized and will keep running even if your current process exit. For
24conveniency, they may also be attached to the current process by
25providing the `attach` option.
26*/
27
28
291module.exports = start_stop = {
30 /*
31
32 `start(options, callback)`
33 --------------------------
34 Start a prcess as a daemon (default) or as a child of the current process. Options includes
35 all the options of the "child_process.exec" function plus a few specific ones.
36
37 `options` , Object with the following properties:
38 * `cmd` , Command to run
39 * `cwd` , Current working directory of the child process
40 * `detached` , Detached the child process from the current process
41 * `pidfile` , Path to the file storing the child pid
42 * `stdout` , Path to the file where standard output is redirected
43 * `stderr` , Path to the file where standard error is redirected
44 * `strict` , Send an error when a pid file exists and reference
45 an unrunning pid.
46 * `watch` , Watch for file changes
47 * `watchIgnore` , List of ignore files
48
49 `callback` , Received arguments are:
50 * `err` , Error if any
51 * `pid` , Process id of the new child
52 */
53
54 start: function(options, callback) {
554 var c, check_pid, child, cmdStderr, cmdStdout, start, stderr, stdout, watch;
564 if (options.attach != null) {
570 console.log('Option attach was renamed to attached to be consistent with the new spawn option');
580 options.detached = !options.attach;
59 }
604 if (options.detached) {
612 child = null;
622 cmdStdout = typeof options.stdout === 'string' ? options.stdout : '/dev/null';
632 cmdStderr = typeof options.stderr === 'string' ? options.stderr : '/dev/null';
642 check_pid = function() {
652 return start_stop.pid(options, function(err, pid) {
662 if (!pid) {
672 return watch();
68 }
690 return start_stop.running(pid, function(err, pid) {
700 if (pid) {
710 return callback(new Error("Pid " + pid + " already running"));
72 }
730 if (options.strict) {
740 return callback(new Error("Pid file reference a dead process"));
75 } else {
760 return watch();
77 }
78 });
79 });
80 };
812 watch = function() {
822 var ignore, ioptions;
832 if (!options.watch) {
842 return start();
85 }
860 if (typeof options.watch !== 'string') {
870 options.watch = options.cwd || process.cwd;
88 }
890 ioptions = {
90 path: options.watch,
91 ignoreFiles: [".startstopignore"] || options.watchIgnoreFiles
92 };
930 console.log('ioptions', ioptions);
940 ignore = require('fstream-ignore');
950 ignore(ioptions).on('child', function(c) {
960 console.log(c.path);
970 return fs.watchFile(c.path, function(curr, prev) {
980 console.log(c.path);
990 return start_stop.stop(options, function(e) {
1000 return start_stop.start(options, function(e) {
1010 return console.log('restarted', e);
102 });
103 });
104 });
105 });
1060 return start();
107 };
1082 start = function() {
1092 var cmd, info, pipe;
1102 pipe = "</dev/null >" + cmdStdout + " 2>" + cmdStdout;
1112 info = 'echo $? $!';
1122 cmd = "" + options.cmd + " " + pipe + " & " + info;
1132 return child = exec(cmd, options, function(err, stdout, stderr) {
1142 var code, msg, pid, _ref1;
1152 _ref1 = stdout.split(' '), code = _ref1[0], pid = _ref1[1];
1162 code = parseInt(code, 10);
1172 pid = parseInt(pid, 10);
1182 if (code !== 0) {
1190 msg = "Process exit with code " + code;
1200 return callback(new Error(msg));
121 }
1222 return exists(path.dirname(options.pidfile), function(exists) {
1232 if (!exists) {
1241 return callback(new Error("Pid directory does not exist"));
125 }
1261 return fs.writeFile(options.pidfile, '' + pid, function(err) {
1271 return callback(null, pid);
128 });
129 });
130 });
131 };
1322 return check_pid();
133 } else {
1342 c = exec(options.cmd);
1352 if (typeof options.stdout === 'string') {
1360 stdout = fs.createWriteStream(options.stdout);
1372 } else if (options.stdout !== null && typeof options.stdout === 'object') {
1380 stdout = options.stdout;
139 } else {
1402 stdout = null;
141 }
1422 if (typeof options.stderr === 'string') {
1430 stdout = fs.createWriteStream(options.stderr);
1442 } else if (options.stderr !== null && typeof options.stderr === 'object') {
1450 stderr = options.stderr;
146 } else {
1472 stderr = null;
148 }
1492 return process.nextTick(function() {
1502 options.pid = c.pid;
1512 return callback(null, c.pid);
152 });
153 }
154 },
155 /*
156
157 `stop(options, callback)`
158 -------------------------
159 Stop a process. In daemon mode, the pid is obtained from the `pidfile` option which, if
160 not provided, can be guessed from the `cmd` option used to start the process.
161
162 `options` , Object with the following properties:
163 * `detached` , Detach the child process to the current process
164 * `cmd` , Command used to run the process, in case no pidfile is provided
165 * `pid` , Pid to kill in attach mode
166 * `pidfile` , Path to the file storing the child pid
167 * `strict` , Send an error when a pid file exists and reference
168 an unrunning pid.
169
170 `callback` , Received arguments are:
171 * `err` , Error if any
172 * `stoped` , True if the process was stoped
173 */
174
175 stop: function(options, callback) {
1766 var kill;
1776 if (options.attach != null) {
1780 console.log('Option attach was renamed to attached to be consistent with the new spawn option');
1790 options.detached = !options.attach;
180 }
1816 if (typeof options === 'string' || typeof options === 'number') {
1821 options = {
183 pid: parseInt(options, 10),
184 detached: false
185 };
186 }
1876 kill = function(pid) {
1883 var cmds;
1893 cmds = "for i in `ps -ef | awk '$3 == '" + pid + "' { print $2 }'`\ndo\n kill $i\ndone\nkill " + pid;
1903 return exec(cmds, function(err, stdout, stderr) {
1913 if (err) {
1920 return callback(new Error("Unexpected exit code " + err.code));
193 }
1943 options.pid = null;
1953 return callback(null, true);
196 });
197 };
1986 if (options.detached) {
1994 return start_stop.pid(options, function(err, pid) {
2004 if (err) {
2010 return callback(err);
202 }
2034 if (!pid) {
2041 return callback(null, false);
205 }
2063 return fs.unlink(options.pidfile, function(err) {
2073 if (err) {
2080 return callback(err);
209 }
2103 return start_stop.running(pid, function(err, running) {
2113 if (!running) {
2122 if (options.strict) {
2131 return callback(new Error("Pid file reference a dead process"));
214 } else {
2151 return callback(null, false);
216 }
217 }
2181 return kill(pid);
219 });
220 });
221 });
222 } else {
2232 return kill(options.pid);
224 }
225 },
226 /*
227
228 `pid(options, callback)`
229 ------------------------
230 Retrieve a process pid. The pid value is return only if the command is running
231 otherwise it is set to false.
232
233 `options` , Object with the following properties:
234 * `detached` , True if the child process is not attached to the current process
235 * `cmd` , Command used to run the process, in case no pidfile is provided
236 * `pid` , Pid to kill if not running in detached mode
237 * `pidfile` , Path to the file storing the child pid
238
239
240 `callback` , Received arguments are:
241 * `err` , Error if any
242 * `pid` , Process pid. Pid is null if there are no pid file or
243 if the process isn't running.
244 */
245
246 pid: function(options, callback) {
2476 if (options.attach != null) {
2480 console.log('Option attach was renamed to attached to be consistent with the new spawn option');
2490 options.detached = !options.attach;
250 }
2516 if (!options.detached) {
2520 if (options.pid == null) {
2530 return new Error('Expect a pid property in attached mode');
254 }
2550 return callback(null, options.pid);
256 }
2576 return start_stop.file(options, function(err, file, exists) {
2586 if (!exists) {
2593 return callback(null, false);
260 }
2613 return fs.readFile(options.pidfile, 'ascii', function(err, pid) {
2623 if (err) {
2630 return callback(err);
264 }
2653 pid = pid.trim();
2663 return callback(null, pid);
267 });
268 });
269 },
270 /*
271
272 `file(options, callback)`
273 -------------------------
274 Retrieve information relative to the file storing the pid. Retrieve
275 the path to the file storing the pid number and whether
276 it exists or not. Note, it will additionnaly enrich the `options`
277 argument with a pidfile property unless already present.
278
279 `options` , Object with the following properties:
280 * `detached` , True if the child process is not attached to the current process
281 * `cmd` , Command used to run the process, in case no pidfile is provided
282 * `pid` , Pid to kill in attach mode
283 * `pidfile` , Path to the file storing the child pid
284
285 `callback` , Received arguments are:
286 * `err` , Error if any
287 * `path` , Path to the file storing the pid, null in attach mode
288 * `exists` , True if the file is created
289 */
290
291 file: function(options, callback) {
2926 var createDir, pidFileExists, start;
2936 if (options.attach != null) {
2940 console.log('Option attach was renamed to detached to be consistent with the spawn API');
2950 options.detached = !options.attach;
296 }
2976 if (!options.detached) {
2980 return callback(null, null, false);
299 }
3006 start = function() {
3016 var dir, file;
3026 if (options.pidfile) {
3033 return pidFileExists();
304 }
3053 dir = path.resolve(process.env['HOME'], '.node_shell');
3063 file = md5(options.cmd);
3073 options.pidfile = "" + dir + "/" + file + ".pid";
3083 return exists(dir, function(dirExists) {
3093 if (!dirExists) {
3100 return createDir();
311 }
3123 return pidFileExists();
313 });
314 };
3156 createDir = function() {
3160 return fs.mkdir(dir, 0x1c0, function(err) {
3170 if (err) {
3180 return callback(err);
319 }
3200 return pidFileExists();
321 });
322 };
3236 pidFileExists = function() {
3246 return exists(options.pidfile, function(pidFileExists) {
3256 return callback(null, options.pidfile, pidFileExists);
326 });
327 };
3286 return start();
329 },
330 /*
331
332 `running(pid, callback)`
333 ------------------------
334
335 Test if a pid match a running process.
336
337 `pid` , Process id to test
338
339 `callback` , Received arguments are:
340 * `err` , Error if any
341 * `running` , True if pid match a running process
342 */
343
344 running: function(pid, callback) {
3459 return exec("ps -ef " + pid + " | grep -v PID", function(err, stdout, stderr) {
3469 if (err && err.code !== 1) {
3470 return callback(err);
348 }
3499 return callback(null, !err);
350 });
351 }
352};

utils.js

66%
27
18
9
LineHitsSource
1// Generated by CoffeeScript 1.4.0
21var existsSync, fs, path;
3
41fs = require('fs');
5
61path = require('path');
7
81existsSync = fs.existsSync || path.existsSync;
9
101module.exports = {
11 flatten: function(arr, ret) {
1229 var i, _i, _ref;
1329 if (ret == null) {
1429 ret = [];
15 }
1629 for (i = _i = 0, _ref = arr.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {
1729 if (Array.isArray(arr[i])) {
180 this.flatten(arr[i], ret);
19 } else {
2029 ret.push(arr[i]);
21 }
22 }
2329 return ret;
24 },
25 workspace: function() {
2610 var dir, dirs, _i, _len;
2710 dirs = require('module')._nodeModulePaths(process.argv[1]);
2810 for (_i = 0, _len = dirs.length; _i < _len; _i++) {
2930 dir = dirs[_i];
3030 if (existsSync(dir) || existsSync(path.normalize(dir + '/../package.json'))) {
3110 return path.normalize(dir + '/..');
32 }
33 }
34 },
35 checkPort: function(port, host, callback) {
360 var cmd;
370 cmd = exec("nc " + host + " " + port + " < /dev/null");
380 return cmd.on('exit', function(code) {
390 if (code === 0) {
400 return callback(true);
41 }
420 if (code === 1) {
430 return callback(false);
44 }
450 return callback(new Error('The nc (or netcat) utility is required'));
46 });
47 }
48};