Line | Hits | Source |
---|---|---|
1 | // Generated by CoffeeScript 1.4.0 | |
2 | 1 | var NullStream, events, |
3 | __hasProp = {}.hasOwnProperty, | |
4 | 7 | __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 | ||
6 | 1 | events = require('events'); |
7 | ||
8 | 1 | module.exports = NullStream = (function(_super) { |
9 | ||
10 | 1 | __extends(NullStream, _super); |
11 | ||
12 | 1 | function NullStream() { |
13 | 30 | return NullStream.__super__.constructor.apply(this, arguments); |
14 | } | |
15 | ||
16 | 1 | NullStream.prototype.readable = true; |
17 | ||
18 | 1 | NullStream.prototype.pause = function() {}; |
19 | ||
20 | 1 | NullStream.prototype.resume = function() {}; |
21 | ||
22 | 1 | NullStream.prototype.pipe = function() {}; |
23 | ||
24 | 1 | NullStream.prototype.writable = true; |
25 | ||
26 | 1 | NullStream.prototype.write = function(data) { |
27 | 56 | return this.emit('data', data); |
28 | }; | |
29 | ||
30 | 1 | NullStream.prototype.end = function() { |
31 | 0 | return this.emit('close'); |
32 | }; | |
33 | ||
34 | 1 | NullStream.prototype.destroy = function() {}; |
35 | ||
36 | 1 | NullStream.prototype.destroySoon = function() {}; |
37 | ||
38 | 1 | return NullStream; |
39 | ||
40 | })(events.EventEmitter); |
Line | Hits | Source |
---|---|---|
1 | // Generated by CoffeeScript 1.4.0 | |
2 | 1 | var Request, each; |
3 | ||
4 | 1 | each = require('each'); |
5 | ||
6 | 1 | module.exports = Request = (function() { |
7 | ||
8 | 1 | function Request(shell, command) { |
9 | 14 | this.shell = shell; |
10 | 14 | this.command = command; |
11 | } | |
12 | ||
13 | /* | |
14 | Ask one or more questions | |
15 | */ | |
16 | ||
17 | ||
18 | 1 | Request.prototype.question = function(questions, callback) { |
19 | 3 | var answers, isObject, multiple, q, v, |
20 | _this = this; | |
21 | 3 | isObject = function(v) { |
22 | 6 | return typeof v === 'object' && (v != null) && !Array.isArray(v); |
23 | }; | |
24 | 3 | multiple = true; |
25 | 3 | answers = {}; |
26 | 3 | if (isObject(questions)) { |
27 | 1 | questions = (function() { |
28 | 1 | var _results; |
29 | 1 | _results = []; |
30 | 1 | for (q in questions) { |
31 | 3 | v = questions[q]; |
32 | 3 | if (v == null) { |
33 | 1 | v = {}; |
34 | } | |
35 | 3 | if (!isObject(v)) { |
36 | 1 | v = { |
37 | value: v | |
38 | }; | |
39 | } | |
40 | 3 | v.name = q; |
41 | 3 | _results.push(v); |
42 | } | |
43 | 1 | return _results; |
44 | })(); | |
45 | 2 | } else if (typeof questions === 'string') { |
46 | 1 | multiple = false; |
47 | 1 | questions = [ |
48 | { | |
49 | name: questions, | |
50 | value: '' | |
51 | } | |
52 | ]; | |
53 | } | |
54 | 3 | return each(questions).on('item', function(next, question) { |
55 | 6 | q = "" + question.name + " "; |
56 | 6 | if (question.value) { |
57 | 3 | q += "[" + question.value + "] "; |
58 | } | |
59 | 6 | return _this.shell["interface"]().question(q, function(answer) { |
60 | 6 | if (answer.substr(-1, 1) === '\n') { |
61 | 6 | answer = answer.substr(0, answer.length - 1); |
62 | } | |
63 | 6 | answers[question.name] = answer === '' ? question.value : answer; |
64 | 6 | return next(); |
65 | }); | |
66 | }).on('end', function() { | |
67 | 3 | if (!multiple) { |
68 | 1 | answers = answers[questions[0].name]; |
69 | } | |
70 | 3 | return callback(answers); |
71 | }); | |
72 | }; | |
73 | ||
74 | /* | |
75 | Ask a question expecting a boolean answer | |
76 | */ | |
77 | ||
78 | ||
79 | 1 | Request.prototype.confirm = function(msg, defaultTrue, callback) { |
80 | 2 | var args, keyFalse, keyTrue, key_false, key_true, question, _base, _base1, _ref, _ref1, |
81 | _this = this; | |
82 | 2 | args = arguments; |
83 | 2 | if (!callback) { |
84 | 2 | callback = defaultTrue; |
85 | 2 | defaultTrue = true; |
86 | } | |
87 | 2 | if ((_ref = (_base = this.shell.settings).key_true) == null) { |
88 | 1 | _base.key_true = 'y'; |
89 | } | |
90 | 2 | if ((_ref1 = (_base1 = this.shell.settings).key_false) == null) { |
91 | 1 | _base1.key_false = 'n'; |
92 | } | |
93 | 2 | key_true = this.shell.settings.key_true.toLowerCase(); |
94 | 2 | key_false = this.shell.settings.key_false.toLowerCase(); |
95 | 2 | keyTrue = defaultTrue ? key_true.toUpperCase() : key_true; |
96 | 2 | keyFalse = defaultTrue ? key_false : key_false.toUpperCase(); |
97 | 2 | msg += ' '; |
98 | 2 | msg += "[" + keyTrue + keyFalse + "] "; |
99 | 2 | question = this.shell.styles.raw(msg, { |
100 | color: 'green' | |
101 | }); | |
102 | 2 | return this.shell["interface"]().question(question, function(answer) { |
103 | 2 | var accepted, valid; |
104 | 2 | accepted = ['', key_true, key_false]; |
105 | 2 | if (answer.substr(-1, 1) === '\n') { |
106 | 2 | answer = answer.substr(0, answer.length - 1); |
107 | } | |
108 | 2 | answer = answer.toLowerCase(); |
109 | 2 | valid = accepted.indexOf(answer) !== -1; |
110 | 2 | if (!valid) { |
111 | 0 | return _this.confirm.apply(_this, args); |
112 | } | |
113 | 2 | return callback(answer === key_true || (defaultTrue && answer === '')); |
114 | }); | |
115 | }; | |
116 | ||
117 | 1 | return Request; |
118 | ||
119 | })(); |
Line | Hits | Source |
---|---|---|
1 | // Generated by CoffeeScript 1.4.0 | |
2 | 1 | var Response, pad, styles, |
3 | __hasProp = {}.hasOwnProperty, | |
4 | 9 | __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 | ||
6 | 1 | styles = require('./Styles'); |
7 | ||
8 | 1 | pad = require('pad'); |
9 | ||
10 | 1 | module.exports = Response = (function(_super) { |
11 | ||
12 | 1 | __extends(Response, _super); |
13 | ||
14 | 1 | function Response(settings) { |
15 | 14 | this.shell = settings.shell; |
16 | 14 | Response.__super__.constructor.call(this, settings); |
17 | } | |
18 | ||
19 | 1 | Response.prototype.pad = pad; |
20 | ||
21 | 1 | Response.prototype.prompt = function() { |
22 | 4 | return this.shell.prompt(); |
23 | }; | |
24 | ||
25 | 1 | return Response; |
26 | ||
27 | })(styles); |
Line | Hits | Source |
---|---|---|
1 | // Generated by CoffeeScript 1.4.0 | |
2 | 1 | var EventEmitter, Interface, Request, Response, Shell, each, events, readline, styles, util, utils, |
3 | __hasProp = {}.hasOwnProperty, | |
4 | 7 | __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 | ||
6 | 1 | util = require('util'); |
7 | ||
8 | 1 | readline = require('readline'); |
9 | ||
10 | 1 | events = require('events'); |
11 | ||
12 | 1 | EventEmitter = events.EventEmitter; |
13 | ||
14 | 1 | each = require('each'); |
15 | ||
16 | 1 | utils = require('./utils'); |
17 | ||
18 | 1 | styles = require('./Styles'); |
19 | ||
20 | 1 | Request = require('./Request'); |
21 | ||
22 | 1 | Response = require('./Response'); |
23 | ||
24 | 1 | Interface = require('readline').Interface; |
25 | ||
26 | 1 | Interface.prototype.setPrompt = (function(parent) { |
27 | 1 | return function(prompt, length) { |
28 | 25 | var args; |
29 | 25 | args = Array.prototype.slice.call(arguments); |
30 | 25 | if (!args[1]) { |
31 | 25 | args[1] = styles.unstyle(args[0]).length; |
32 | } | |
33 | 25 | return parent.apply(this, args); |
34 | }; | |
35 | })(Interface.prototype.setPrompt); | |
36 | ||
37 | 1 | module.exports = Shell = (function(_super) { |
38 | ||
39 | 1 | __extends(Shell, _super); |
40 | ||
41 | 1 | function Shell(settings) { |
42 | 29 | var _base, _base1, _base2, _ref, _ref1, _ref2, _ref3, _ref4, _ref5, _ref6, |
43 | _this = this; | |
44 | 29 | if (settings == null) { |
45 | 0 | settings = {}; |
46 | } | |
47 | 29 | if (!(this instanceof Shell)) { |
48 | 14 | return new Shell(settings); |
49 | } | |
50 | 15 | EventEmitter.call(this); |
51 | 15 | this.tmp = {}; |
52 | 15 | this.settings = settings; |
53 | 15 | if ((_ref = (_base = this.settings).prompt) == null) { |
54 | 15 | _base.prompt = '>> '; |
55 | } | |
56 | 15 | if ((_ref1 = (_base1 = this.settings).stdin) == null) { |
57 | 0 | _base1.stdin = process.stdin; |
58 | } | |
59 | 15 | if ((_ref2 = (_base2 = this.settings).stdout) == null) { |
60 | 0 | _base2.stdout = process.stdout; |
61 | } | |
62 | 15 | this.set('env', (_ref3 = (_ref4 = this.settings.env) != null ? _ref4 : process.env.NODE_ENV) != null ? _ref3 : 'development'); |
63 | 15 | this.set('command', typeof settings.command !== 'undefined' ? settings.command : process.argv.slice(2).join(' ')); |
64 | 15 | this.stack = []; |
65 | 15 | this.styles = styles({ |
66 | stdout: this.settings.stdout | |
67 | }); | |
68 | 15 | process.on('beforeExit', function() { |
69 | 0 | return _this.emit('exit'); |
70 | }); | |
71 | 15 | process.on('uncaughtException', function(e) { |
72 | 0 | _this.emit('exit', [e]); |
73 | 0 | _this.styles.red('Internal error, closing...').ln(); |
74 | 0 | console.error(e.message); |
75 | 0 | console.error(e.stack); |
76 | 0 | return process.exit(); |
77 | }); | |
78 | 15 | this.isShell = (_ref5 = this.settings.isShell) != null ? _ref5 : process.argv.length === 2; |
79 | 15 | if (this.isShell) { |
80 | 0 | this["interface"](); |
81 | } | |
82 | 15 | if ((_ref6 = settings.workspace) == null) { |
83 | 10 | settings.workspace = utils.workspace(); |
84 | } | |
85 | 15 | if (settings.chdir === true) { |
86 | 0 | process.chdir(settings.workspace); |
87 | } | |
88 | 15 | if (typeof settings.chdir === 'string') { |
89 | 0 | process.chdir(settings.chdir); |
90 | } | |
91 | 15 | process.nextTick(function() { |
92 | 15 | var command, noPrompt; |
93 | 15 | if (_this.isShell) { |
94 | 0 | command = _this.set('command'); |
95 | 0 | noPrompt = _this.set('noPrompt'); |
96 | 0 | if (command) { |
97 | 0 | return _this.run(command); |
98 | 0 | } else if (!noPrompt) { |
99 | 0 | return _this.prompt(); |
100 | } | |
101 | } else { | |
102 | 15 | command = _this.set('command'); |
103 | 15 | if (command) { |
104 | 12 | return _this.run(command); |
105 | } | |
106 | } | |
107 | }); | |
108 | 15 | return this; |
109 | } | |
110 | ||
111 | 1 | Shell.prototype["interface"] = function() { |
112 | 14 | if (this._interface != null) { |
113 | 5 | return this._interface; |
114 | } | |
115 | 9 | return this._interface = readline.createInterface(this.settings.stdin, this.settings.stdout); |
116 | }; | |
117 | ||
118 | 1 | Shell.prototype.configure = function(env, fn) { |
119 | 13 | if (typeof env === 'function') { |
120 | 13 | fn = env; |
121 | 13 | env = 'all'; |
122 | } | |
123 | 13 | if (env === 'all' || env === this.settings.env) { |
124 | 13 | fn.call(this); |
125 | } | |
126 | 13 | return this; |
127 | }; | |
128 | ||
129 | 1 | Shell.prototype.use = function(handle) { |
130 | 16 | if (handle) { |
131 | 16 | this.stack.push({ |
132 | route: null, | |
133 | handle: handle | |
134 | }); | |
135 | } | |
136 | 16 | return this; |
137 | }; | |
138 | ||
139 | 1 | Shell.prototype.cmds = {}; |
140 | ||
141 | 1 | Shell.prototype.run = function(command) { |
142 | 14 | var index, next, req, res, self; |
143 | 14 | command = command.trim(); |
144 | 14 | this.emit('command', [command]); |
145 | 14 | this.emit(command, []); |
146 | 14 | self = this; |
147 | 14 | req = new Request(this, command); |
148 | 14 | res = new Response({ |
149 | shell: this, | |
150 | stdout: this.settings.stdout | |
151 | }); | |
152 | 14 | index = 0; |
153 | 14 | next = function(err) { |
154 | 19 | var arity, layer, text; |
155 | 19 | layer = self.stack[index++]; |
156 | 19 | if (!layer) { |
157 | 1 | if (err) { |
158 | 1 | return self.emit('error', err); |
159 | } | |
160 | 0 | if (command !== '') { |
161 | 0 | text = "Command failed to execute " + command; |
162 | 0 | if (err) { |
163 | 0 | text += ": " + (err.message || err.name); |
164 | } | |
165 | 0 | res.red(text); |
166 | } | |
167 | 0 | return res.prompt(); |
168 | } | |
169 | 18 | arity = layer.handle.length; |
170 | 18 | if (err) { |
171 | 2 | if (arity === 4) { |
172 | 2 | self.emit('error', err); |
173 | 2 | return layer.handle(err, req, res, next); |
174 | } else { | |
175 | 0 | return next(err); |
176 | } | |
177 | 16 | } else if (arity < 4) { |
178 | 16 | return layer.handle(req, res, next); |
179 | } else { | |
180 | 0 | return next(); |
181 | } | |
182 | }; | |
183 | 14 | return next(); |
184 | }; | |
185 | ||
186 | 1 | Shell.prototype.set = function(setting, val) { |
187 | 46 | if (!(val != null)) { |
188 | 17 | if (this.settings.hasOwnProperty(setting)) { |
189 | 17 | return this.settings[setting]; |
190 | 0 | } else if (this.parent) { |
191 | 0 | return this.parent.set(setting); |
192 | } | |
193 | } else { | |
194 | 29 | this.settings[setting] = val; |
195 | 29 | return this; |
196 | } | |
197 | }; | |
198 | ||
199 | 1 | Shell.prototype.prompt = function() { |
200 | 4 | var text; |
201 | 4 | if (this.isShell) { |
202 | 0 | text = this.styles.raw(this.settings.prompt, { |
203 | color: 'green' | |
204 | }); | |
205 | 0 | return this["interface"]().question(text, this.run.bind(this)); |
206 | } else { | |
207 | 4 | this.styles.ln(); |
208 | 4 | if (process.versions) { |
209 | 4 | return this.quit(); |
210 | } else { | |
211 | 0 | this.settings.stdout.destroySoon(); |
212 | 0 | return this.settings.stdout.on('close', function() { |
213 | 0 | return process.exit(); |
214 | }); | |
215 | } | |
216 | } | |
217 | }; | |
218 | ||
219 | 1 | Shell.prototype.quit = function(params) { |
220 | 6 | this.emit('quit'); |
221 | 6 | this["interface"]().close(); |
222 | 6 | return this.settings.stdin.destroy(); |
223 | }; | |
224 | ||
225 | 1 | return Shell; |
226 | ||
227 | })(EventEmitter); |
Line | Hits | Source |
---|---|---|
1 | // Generated by CoffeeScript 1.4.0 | |
2 | 2 | var Styles, bgcolors, code, color, colors, _fn; |
3 | ||
4 | 2 | colors = { |
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 | ||
15 | 2 | bgcolors = { |
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 | ||
26 | 2 | module.exports = Styles = function(settings) { |
27 | 54 | var _ref; |
28 | 54 | if (settings == null) { |
29 | 0 | settings = {}; |
30 | } | |
31 | 54 | if (!(this instanceof Styles)) { |
32 | 20 | return new Styles(settings); |
33 | } | |
34 | 34 | this.settings = settings; |
35 | 34 | this.settings.stdout = (_ref = settings.stdout) != null ? _ref : process.stdout; |
36 | 34 | this.current = { |
37 | weight: 'regular' | |
38 | }; | |
39 | 34 | this.colors = colors; |
40 | 34 | this.bgcolors = bgcolors; |
41 | 34 | return this; |
42 | }; | |
43 | ||
44 | 2 | Styles.prototype.color = function(color, text) { |
45 | 40 | this.print(text, { |
46 | color: color | |
47 | }); | |
48 | 40 | if (!text) { |
49 | 9 | this.current.color = color; |
50 | } | |
51 | 40 | return this; |
52 | }; | |
53 | ||
54 | 2 | _fn = function(color) { |
55 | 16 | return Styles.prototype[color] = function(text) { |
56 | 38 | return this.color(color, text); |
57 | }; | |
58 | }; | |
59 | 2 | for (color in colors) { |
60 | 16 | code = colors[color]; |
61 | 16 | _fn(color); |
62 | } | |
63 | ||
64 | 2 | Styles.prototype.nocolor = function(text) { |
65 | 2 | return this.color(null, text); |
66 | }; | |
67 | ||
68 | 2 | Styles.prototype.bgcolor = function(bgcolor) { |
69 | 0 | if (bgcolor == null) { |
70 | 0 | bgcolor = 0; |
71 | } | |
72 | 0 | this.print('\x1B[' + bgcolor + ';m39'); |
73 | 0 | return this; |
74 | }; | |
75 | ||
76 | 2 | Styles.prototype.weight = function(weight, text) { |
77 | 9 | this.print(text, { |
78 | weight: weight | |
79 | }); | |
80 | 9 | if (!text) { |
81 | 4 | this.current.weight = weight; |
82 | } | |
83 | 9 | return this; |
84 | }; | |
85 | ||
86 | 2 | Styles.prototype.bold = function(text) { |
87 | 5 | return this.weight('bold', text); |
88 | }; | |
89 | ||
90 | 2 | Styles.prototype.regular = function(text) { |
91 | 4 | return this.weight('regular', text); |
92 | }; | |
93 | ||
94 | 2 | Styles.prototype.print = function(text, settings) { |
95 | 72 | this.settings.stdout.write(this.raw(text, settings)); |
96 | 72 | return this; |
97 | }; | |
98 | ||
99 | 2 | Styles.prototype.println = function(text) { |
100 | 1 | this.settings.stdout.write(text + '\n'); |
101 | 1 | return this; |
102 | }; | |
103 | ||
104 | 2 | Styles.prototype.ln = function() { |
105 | 22 | this.settings.stdout.write('\n'); |
106 | 22 | return this; |
107 | }; | |
108 | ||
109 | 2 | Styles.prototype.raw = function(text, settings) { |
110 | 148 | var raw; |
111 | 148 | raw = ''; |
112 | 148 | if (settings == null) { |
113 | 22 | settings = {}; |
114 | } | |
115 | 148 | if (settings.color !== null && (settings.color || this.current.color)) { |
116 | 78 | raw += '\x1b[' + this.colors[settings.color || this.current.color] + 'm'; |
117 | } else { | |
118 | 70 | raw += '\x1b[39m'; |
119 | } | |
120 | 148 | switch (settings.weight || this.current.weight) { |
121 | case 'bold': | |
122 | 13 | raw += '\x1b[1m'; |
123 | 13 | break; |
124 | case 'regular': | |
125 | 135 | raw += '\x1b[22m'; |
126 | 135 | break; |
127 | default: | |
128 | 0 | throw new Error('Invalid weight "' + weight + '" (expect "bold" or "regular")'); |
129 | } | |
130 | 148 | if (text) { |
131 | 60 | raw += text; |
132 | 60 | if (this.current.color && this.current.color !== settings.color) { |
133 | 16 | raw += this.raw(null, this.current.color); |
134 | } | |
135 | 60 | if (this.current.weight && this.current.weight !== settings.weight) { |
136 | 58 | raw += this.raw(null, this.current.weight); |
137 | } | |
138 | } | |
139 | 148 | return raw; |
140 | }; | |
141 | ||
142 | 2 | Styles.prototype.reset = function(text) { |
143 | 1 | return this.print(null, { |
144 | color: null, | |
145 | weight: 'regular' | |
146 | }); | |
147 | }; | |
148 | ||
149 | 2 | Styles.unstyle = function(text) { |
150 | 27 | return text.replace(/\x1b.*?m/g, ''); |
151 | }; |
Line | Hits | Source |
---|---|---|
1 | // Generated by CoffeeScript 1.4.0 | |
2 | ||
3 | 1 | module.exports = function(settings) { |
4 | 2 | var shell; |
5 | 2 | if (!settings.shell) { |
6 | 0 | throw new Error('No shell provided'); |
7 | } | |
8 | 2 | shell = settings.shell; |
9 | 2 | shell.on('error', function() {}); |
10 | 2 | return function(err, req, res, next) { |
11 | 2 | var k, v; |
12 | 2 | if (err.message) { |
13 | 2 | res.red(err.message).ln(); |
14 | } | |
15 | 2 | if (err.stack) { |
16 | 2 | res.red(err.stack).ln(); |
17 | } | |
18 | 2 | for (k in err) { |
19 | 12 | v = err[k]; |
20 | 12 | if (k === 'message') { |
21 | 2 | continue; |
22 | } | |
23 | 10 | if (k === 'stack') { |
24 | 0 | continue; |
25 | } | |
26 | 10 | if (typeof v === 'function') { |
27 | 2 | continue; |
28 | } | |
29 | 8 | res.magenta(k).white(': ').red(v).ln(); |
30 | } | |
31 | 2 | return res.prompt(); |
32 | }; | |
33 | }; |
Line | Hits | Source |
---|---|---|
1 | // Generated by CoffeeScript 1.4.0 | |
2 | 1 | var existsSync, fs, path, start_stop; |
3 | ||
4 | 1 | fs = require('fs'); |
5 | ||
6 | 1 | path = require('path'); |
7 | ||
8 | 1 | existsSync = fs.existsSync || path.existsSync; |
9 | ||
10 | 1 | start_stop = require('../start_stop'); |
11 | ||
12 | /* | |
13 | ||
14 | HTTP server | |
15 | =========== | |
16 | ||
17 | Register two commands, `http start` and `http stop`. The start command will | |
18 | search for "./server.js" and "./app.js" (and additionnaly their CoffeeScript | |
19 | alternatives) to run by `node`. | |
20 | ||
21 | The 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 | ||
29 | Properties 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 | ||
36 | Example: | |
37 | ||
38 | ```javascript | |
39 | var app = new shell(); | |
40 | app.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 | ||
56 | 1 | module.exports = function() { |
57 | 1 | var cmd, http, route, settings; |
58 | 1 | settings = {}; |
59 | 1 | cmd = function() { |
60 | 1 | var search, searchs, _i, _len; |
61 | 1 | searchs = settings.path ? [settings.path] : ['app', 'server', 'lib/app', 'lib/server']; |
62 | 1 | for (_i = 0, _len = searchs.length; _i < _len; _i++) { |
63 | 1 | search = searchs[_i]; |
64 | 1 | search = path.resolve(settings.workspace, search); |
65 | 1 | if (existsSync("" + search)) { |
66 | 0 | if (search.substr(-4) === '.coffee') { |
67 | 0 | return "coffee " + search; |
68 | } else { | |
69 | 0 | return "node " + search; |
70 | } | |
71 | } | |
72 | 1 | if (existsSync("" + search + ".js")) { |
73 | 0 | return "node " + search + ".js"; |
74 | 1 | } else if (existsSync("" + search + ".coffee")) { |
75 | 1 | return "coffee " + search + ".coffee"; |
76 | } | |
77 | } | |
78 | 0 | throw new Error('Failed to discover a "server.js" or "app.js" file'); |
79 | }; | |
80 | 1 | http = null; |
81 | 1 | route = function(req, res, next) { |
82 | 2 | var app, _ref, _ref1, _ref2; |
83 | 2 | app = req.shell; |
84 | 2 | if (app.tmp.http) { |
85 | 1 | return next(); |
86 | } | |
87 | 1 | app.tmp.http = true; |
88 | 1 | if ((_ref = settings.workspace) == null) { |
89 | 1 | settings.workspace = app.set('workspace'); |
90 | } | |
91 | 1 | if (!settings.workspace) { |
92 | 0 | throw new Error('No workspace provided'); |
93 | } | |
94 | 1 | if ((_ref1 = settings.message_start) == null) { |
95 | 1 | settings.message_start = 'HTTP server successfully started'; |
96 | } | |
97 | 1 | if ((_ref2 = settings.message_stop) == null) { |
98 | 1 | settings.message_stop = 'HTTP server successfully stopped'; |
99 | } | |
100 | 1 | if (!settings.cmd) { |
101 | 1 | settings.cmd = cmd(); |
102 | } | |
103 | 1 | app.cmd('http start', 'Start HTTP server', function(req, res, next) { |
104 | 1 | return http = start_stop.start(settings, function(err, pid) { |
105 | 1 | if (err) { |
106 | 0 | return next(err); |
107 | } | |
108 | 1 | if (!pid) { |
109 | 0 | return res.cyan('HTTP server already started').ln() && res.prompt(); |
110 | } | |
111 | 1 | res.cyan(settings.message_start).ln(); |
112 | 1 | return res.prompt(); |
113 | }); | |
114 | }); | |
115 | 1 | app.cmd('http stop', 'Stop HTTP server', function(req, res, next) { |
116 | 1 | return start_stop.stop(settings, function(err, success) { |
117 | 1 | if (success) { |
118 | 1 | res.cyan(settings.message_stop).ln(); |
119 | } else { | |
120 | 0 | res.magenta('HTTP server was not started').ln(); |
121 | } | |
122 | 1 | return res.prompt(); |
123 | }); | |
124 | }); | |
125 | 1 | return next(); |
126 | }; | |
127 | 1 | if (arguments.length === 1) { |
128 | 1 | settings = arguments[0]; |
129 | 1 | return route; |
130 | } else { | |
131 | 0 | return route.apply(null, arguments); |
132 | } | |
133 | }; |
Line | Hits | Source |
---|---|---|
1 | // Generated by CoffeeScript 1.4.0 | |
2 | 1 | var match, normalize, querystring, utils, |
3 | 0 | __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 | ||
5 | 1 | utils = require('../utils'); |
6 | ||
7 | 1 | querystring = { |
8 | unescape: function(str) { | |
9 | 4 | return decodeURIComponent(str); |
10 | }, | |
11 | parse: function(qs, sep, eq) { | |
12 | 0 | var k, kvp, obj, v, vkps, x, _i, _len, _ref; |
13 | 0 | sep = sep || '&'; |
14 | 0 | eq = eq || '='; |
15 | 0 | obj = {}; |
16 | 0 | if (typeof qs !== 'string') { |
17 | 0 | return obj; |
18 | } | |
19 | 0 | vkps = qs.split(sep); |
20 | 0 | for (_i = 0, _len = vkps.length; _i < _len; _i++) { |
21 | 0 | kvp = vkps[_i]; |
22 | 0 | x = kvp.split(eq); |
23 | 0 | k = querystring.unescape(x[0], true); |
24 | 0 | v = querystring.unescape(x.slice(1).join(eq), true); |
25 | 0 | if (_ref = !k, __indexOf.call(obj, _ref) >= 0) { |
26 | 0 | obj[k] = v; |
27 | 0 | } else if (!Array.isArray(obj[k])) { |
28 | 0 | obj[k] = [obj[k], v]; |
29 | } else { | |
30 | 0 | obj[k].push(v); |
31 | } | |
32 | } | |
33 | 0 | return obj; |
34 | } | |
35 | }; | |
36 | ||
37 | 1 | normalize = function(command, keys, sensitive) { |
38 | 29 | command = command.concat('/?').replace(/\/\(/g, '(?:/').replace(/:(\w+)(\(.*\))?(\?)?/g, function(_, key, format, optional) { |
39 | 6 | keys.push(key); |
40 | 6 | format = format || '([^ ]+)'; |
41 | 6 | optional = optional || ''; |
42 | 6 | return format + optional; |
43 | }).replace(/([\/.])/g, '\\$1').replace(/\*/g, '(.+)'); | |
44 | 29 | return new RegExp('^' + command + '$', (sensitive != null ? 'i' : void 0)); |
45 | }; | |
46 | ||
47 | 1 | match = function(req, routes, i) { |
48 | 14 | var captures, index, j, key, keys, regexp, route, val; |
49 | 14 | if (i == null) { |
50 | 14 | i = 0; |
51 | } | |
52 | 14 | while (i < routes.length) { |
53 | 30 | route = routes[i]; |
54 | 30 | regexp = route.regexp; |
55 | 30 | keys = route.keys; |
56 | 30 | captures = regexp.exec(req.command); |
57 | 30 | if (captures) { |
58 | 14 | route.params = {}; |
59 | 14 | index = 0; |
60 | 14 | j = 1; |
61 | 14 | while (j < captures.length) { |
62 | 4 | key = keys[j - 1]; |
63 | 4 | val = typeof captures[j] === 'string' ? querystring.unescape(captures[j]) : captures[j]; |
64 | 4 | if (key) { |
65 | 4 | route.params[key] = val; |
66 | } else { | |
67 | 0 | route.params['' + index] = val; |
68 | 0 | index++; |
69 | } | |
70 | 4 | j++; |
71 | } | |
72 | 14 | req._route_index = i; |
73 | 14 | return route; |
74 | } | |
75 | 16 | i++; |
76 | } | |
77 | 0 | return null; |
78 | }; | |
79 | ||
80 | 1 | module.exports = function(settings) { |
81 | 13 | var params, routes, shell, _ref; |
82 | 13 | if (!settings.shell) { |
83 | 0 | throw new Error('No shell provided'); |
84 | } | |
85 | 13 | shell = settings.shell; |
86 | 13 | if ((_ref = settings.sensitive) == null) { |
87 | 13 | settings.sensitive = true; |
88 | } | |
89 | 13 | routes = shell.routes = []; |
90 | 13 | params = {}; |
91 | 13 | shell.param = function(name, fn) { |
92 | 0 | if (Array.isArray(name)) { |
93 | 0 | name.forEach(function(name) { |
94 | 0 | return this.param(name, fn); |
95 | }, this); | |
96 | } else { | |
97 | 0 | if (':' === name[0]) { |
98 | 0 | name = name.substr(1); |
99 | } | |
100 | 0 | params[name] = fn; |
101 | } | |
102 | 0 | return this; |
103 | }; | |
104 | 13 | shell.cmd = function(command, description, middleware1, middleware2, fn) { |
105 | 29 | var args, keys, route; |
106 | 29 | args = Array.prototype.slice.call(arguments); |
107 | 29 | route = {}; |
108 | 29 | route.command = args.shift(); |
109 | 29 | if (typeof args[0] === 'string') { |
110 | 15 | route.description = args.shift(); |
111 | } | |
112 | 29 | route.middlewares = utils.flatten(args); |
113 | 29 | keys = []; |
114 | 29 | route.regexp = route.command instanceof RegExp ? route.command : normalize(route.command, keys, settings.sensitive); |
115 | 29 | route.keys = keys; |
116 | 29 | routes.push(route); |
117 | 29 | return this; |
118 | }; | |
119 | 13 | shell.cmd('quit', 'Exit this shell', shell.quit.bind(shell)); |
120 | 13 | return function(req, res, next) { |
121 | 14 | var i, pass, route, self; |
122 | 14 | route = null; |
123 | 14 | self = this; |
124 | 14 | i = 0; |
125 | 14 | pass = function(i) { |
126 | 14 | var keys, param; |
127 | 14 | route = match(req, routes, i); |
128 | 14 | if (!route) { |
129 | 0 | return next(); |
130 | } | |
131 | 14 | i = 0; |
132 | 14 | keys = route.keys; |
133 | 14 | req.params = route.params; |
134 | 14 | param = function(err) { |
135 | 18 | var fn, key, nextMiddleware, val; |
136 | 18 | try { |
137 | 18 | key = keys[i++]; |
138 | 18 | val = req.params[key]; |
139 | 18 | fn = params[key]; |
140 | 18 | if ('route' === err) { |
141 | 0 | return pass(req._route_index + 1); |
142 | 18 | } else if (err) { |
143 | 0 | return next(err); |
144 | 18 | } else if (fn) { |
145 | 0 | if (1 === fn.length) { |
146 | 0 | req.params[key] = fn(val); |
147 | 0 | return param(); |
148 | } else { | |
149 | 0 | return fn(req, res, param, val); |
150 | } | |
151 | 18 | } else if (!key) { |
152 | 14 | i = 0; |
153 | 14 | nextMiddleware = function(err) { |
154 | 15 | fn = route.middlewares[i++]; |
155 | 15 | if ('route' === err) { |
156 | 0 | return pass(req._route_index + 1); |
157 | 15 | } else if (err) { |
158 | 1 | return next(err); |
159 | 14 | } else if (fn) { |
160 | 14 | return fn(req, res, nextMiddleware); |
161 | } else { | |
162 | 0 | return pass(req._route_index + 1); |
163 | } | |
164 | }; | |
165 | 14 | return nextMiddleware(); |
166 | } else { | |
167 | 4 | return param(); |
168 | } | |
169 | } catch (err) { | |
170 | 2 | return next(err); |
171 | } | |
172 | }; | |
173 | 14 | return param(); |
174 | }; | |
175 | 14 | return pass(); |
176 | }; | |
177 | }; |
Line | Hits | Source |
---|---|---|
1 | // Generated by CoffeeScript 1.4.0 | |
2 | 1 | var crypto, exec, exists, fs, md5, path, spawn, start_stop, _ref; |
3 | ||
4 | 1 | crypto = require('crypto'); |
5 | ||
6 | 1 | _ref = require('child_process'), exec = _ref.exec, spawn = _ref.spawn; |
7 | ||
8 | 1 | fs = require('fs'); |
9 | ||
10 | 1 | path = require('path'); |
11 | ||
12 | 1 | exists = fs.exists || path.exists; |
13 | ||
14 | 1 | md5 = function(cmd) { |
15 | 3 | return crypto.createHash('md5').update(cmd).digest('hex'); |
16 | }; | |
17 | ||
18 | /* | |
19 | `start_stop`: Unix process management | |
20 | ------------------------------------- | |
21 | ||
22 | The library start and stop unix child process. Process are by default | |
23 | daemonized and will keep running even if your current process exit. For | |
24 | conveniency, they may also be attached to the current process by | |
25 | providing the `attach` option. | |
26 | */ | |
27 | ||
28 | ||
29 | 1 | module.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) { | |
55 | 4 | var c, check_pid, child, cmdStderr, cmdStdout, start, stderr, stdout, watch; |
56 | 4 | if (options.attach != null) { |
57 | 0 | console.log('Option attach was renamed to attached to be consistent with the new spawn option'); |
58 | 0 | options.detached = !options.attach; |
59 | } | |
60 | 4 | if (options.detached) { |
61 | 2 | child = null; |
62 | 2 | cmdStdout = typeof options.stdout === 'string' ? options.stdout : '/dev/null'; |
63 | 2 | cmdStderr = typeof options.stderr === 'string' ? options.stderr : '/dev/null'; |
64 | 2 | check_pid = function() { |
65 | 2 | return start_stop.pid(options, function(err, pid) { |
66 | 2 | if (!pid) { |
67 | 2 | return watch(); |
68 | } | |
69 | 0 | return start_stop.running(pid, function(err, pid) { |
70 | 0 | if (pid) { |
71 | 0 | return callback(new Error("Pid " + pid + " already running")); |
72 | } | |
73 | 0 | if (options.strict) { |
74 | 0 | return callback(new Error("Pid file reference a dead process")); |
75 | } else { | |
76 | 0 | return watch(); |
77 | } | |
78 | }); | |
79 | }); | |
80 | }; | |
81 | 2 | watch = function() { |
82 | 2 | var ignore, ioptions; |
83 | 2 | if (!options.watch) { |
84 | 2 | return start(); |
85 | } | |
86 | 0 | if (typeof options.watch !== 'string') { |
87 | 0 | options.watch = options.cwd || process.cwd; |
88 | } | |
89 | 0 | ioptions = { |
90 | path: options.watch, | |
91 | ignoreFiles: [".startstopignore"] || options.watchIgnoreFiles | |
92 | }; | |
93 | 0 | console.log('ioptions', ioptions); |
94 | 0 | ignore = require('fstream-ignore'); |
95 | 0 | ignore(ioptions).on('child', function(c) { |
96 | 0 | console.log(c.path); |
97 | 0 | return fs.watchFile(c.path, function(curr, prev) { |
98 | 0 | console.log(c.path); |
99 | 0 | return start_stop.stop(options, function(e) { |
100 | 0 | return start_stop.start(options, function(e) { |
101 | 0 | return console.log('restarted', e); |
102 | }); | |
103 | }); | |
104 | }); | |
105 | }); | |
106 | 0 | return start(); |
107 | }; | |
108 | 2 | start = function() { |
109 | 2 | var cmd, info, pipe; |
110 | 2 | pipe = "</dev/null >" + cmdStdout + " 2>" + cmdStdout; |
111 | 2 | info = 'echo $? $!'; |
112 | 2 | cmd = "" + options.cmd + " " + pipe + " & " + info; |
113 | 2 | return child = exec(cmd, options, function(err, stdout, stderr) { |
114 | 2 | var code, msg, pid, _ref1; |
115 | 2 | _ref1 = stdout.split(' '), code = _ref1[0], pid = _ref1[1]; |
116 | 2 | code = parseInt(code, 10); |
117 | 2 | pid = parseInt(pid, 10); |
118 | 2 | if (code !== 0) { |
119 | 0 | msg = "Process exit with code " + code; |
120 | 0 | return callback(new Error(msg)); |
121 | } | |
122 | 2 | return exists(path.dirname(options.pidfile), function(exists) { |
123 | 2 | if (!exists) { |
124 | 1 | return callback(new Error("Pid directory does not exist")); |
125 | } | |
126 | 1 | return fs.writeFile(options.pidfile, '' + pid, function(err) { |
127 | 1 | return callback(null, pid); |
128 | }); | |
129 | }); | |
130 | }); | |
131 | }; | |
132 | 2 | return check_pid(); |
133 | } else { | |
134 | 2 | c = exec(options.cmd); |
135 | 2 | if (typeof options.stdout === 'string') { |
136 | 0 | stdout = fs.createWriteStream(options.stdout); |
137 | 2 | } else if (options.stdout !== null && typeof options.stdout === 'object') { |
138 | 0 | stdout = options.stdout; |
139 | } else { | |
140 | 2 | stdout = null; |
141 | } | |
142 | 2 | if (typeof options.stderr === 'string') { |
143 | 0 | stdout = fs.createWriteStream(options.stderr); |
144 | 2 | } else if (options.stderr !== null && typeof options.stderr === 'object') { |
145 | 0 | stderr = options.stderr; |
146 | } else { | |
147 | 2 | stderr = null; |
148 | } | |
149 | 2 | return process.nextTick(function() { |
150 | 2 | options.pid = c.pid; |
151 | 2 | 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) { | |
176 | 6 | var kill; |
177 | 6 | if (options.attach != null) { |
178 | 0 | console.log('Option attach was renamed to attached to be consistent with the new spawn option'); |
179 | 0 | options.detached = !options.attach; |
180 | } | |
181 | 6 | if (typeof options === 'string' || typeof options === 'number') { |
182 | 1 | options = { |
183 | pid: parseInt(options, 10), | |
184 | detached: false | |
185 | }; | |
186 | } | |
187 | 6 | kill = function(pid) { |
188 | 3 | var cmds; |
189 | 3 | cmds = "for i in `ps -ef | awk '$3 == '" + pid + "' { print $2 }'`\ndo\n kill $i\ndone\nkill " + pid; |
190 | 3 | return exec(cmds, function(err, stdout, stderr) { |
191 | 3 | if (err) { |
192 | 0 | return callback(new Error("Unexpected exit code " + err.code)); |
193 | } | |
194 | 3 | options.pid = null; |
195 | 3 | return callback(null, true); |
196 | }); | |
197 | }; | |
198 | 6 | if (options.detached) { |
199 | 4 | return start_stop.pid(options, function(err, pid) { |
200 | 4 | if (err) { |
201 | 0 | return callback(err); |
202 | } | |
203 | 4 | if (!pid) { |
204 | 1 | return callback(null, false); |
205 | } | |
206 | 3 | return fs.unlink(options.pidfile, function(err) { |
207 | 3 | if (err) { |
208 | 0 | return callback(err); |
209 | } | |
210 | 3 | return start_stop.running(pid, function(err, running) { |
211 | 3 | if (!running) { |
212 | 2 | if (options.strict) { |
213 | 1 | return callback(new Error("Pid file reference a dead process")); |
214 | } else { | |
215 | 1 | return callback(null, false); |
216 | } | |
217 | } | |
218 | 1 | return kill(pid); |
219 | }); | |
220 | }); | |
221 | }); | |
222 | } else { | |
223 | 2 | 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) { | |
247 | 6 | if (options.attach != null) { |
248 | 0 | console.log('Option attach was renamed to attached to be consistent with the new spawn option'); |
249 | 0 | options.detached = !options.attach; |
250 | } | |
251 | 6 | if (!options.detached) { |
252 | 0 | if (options.pid == null) { |
253 | 0 | return new Error('Expect a pid property in attached mode'); |
254 | } | |
255 | 0 | return callback(null, options.pid); |
256 | } | |
257 | 6 | return start_stop.file(options, function(err, file, exists) { |
258 | 6 | if (!exists) { |
259 | 3 | return callback(null, false); |
260 | } | |
261 | 3 | return fs.readFile(options.pidfile, 'ascii', function(err, pid) { |
262 | 3 | if (err) { |
263 | 0 | return callback(err); |
264 | } | |
265 | 3 | pid = pid.trim(); |
266 | 3 | 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) { | |
292 | 6 | var createDir, pidFileExists, start; |
293 | 6 | if (options.attach != null) { |
294 | 0 | console.log('Option attach was renamed to detached to be consistent with the spawn API'); |
295 | 0 | options.detached = !options.attach; |
296 | } | |
297 | 6 | if (!options.detached) { |
298 | 0 | return callback(null, null, false); |
299 | } | |
300 | 6 | start = function() { |
301 | 6 | var dir, file; |
302 | 6 | if (options.pidfile) { |
303 | 3 | return pidFileExists(); |
304 | } | |
305 | 3 | dir = path.resolve(process.env['HOME'], '.node_shell'); |
306 | 3 | file = md5(options.cmd); |
307 | 3 | options.pidfile = "" + dir + "/" + file + ".pid"; |
308 | 3 | return exists(dir, function(dirExists) { |
309 | 3 | if (!dirExists) { |
310 | 0 | return createDir(); |
311 | } | |
312 | 3 | return pidFileExists(); |
313 | }); | |
314 | }; | |
315 | 6 | createDir = function() { |
316 | 0 | return fs.mkdir(dir, 0x1c0, function(err) { |
317 | 0 | if (err) { |
318 | 0 | return callback(err); |
319 | } | |
320 | 0 | return pidFileExists(); |
321 | }); | |
322 | }; | |
323 | 6 | pidFileExists = function() { |
324 | 6 | return exists(options.pidfile, function(pidFileExists) { |
325 | 6 | return callback(null, options.pidfile, pidFileExists); |
326 | }); | |
327 | }; | |
328 | 6 | 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) { | |
345 | 9 | return exec("ps -ef " + pid + " | grep -v PID", function(err, stdout, stderr) { |
346 | 9 | if (err && err.code !== 1) { |
347 | 0 | return callback(err); |
348 | } | |
349 | 9 | return callback(null, !err); |
350 | }); | |
351 | } | |
352 | }; |
Line | Hits | Source |
---|---|---|
1 | // Generated by CoffeeScript 1.4.0 | |
2 | 1 | var existsSync, fs, path; |
3 | ||
4 | 1 | fs = require('fs'); |
5 | ||
6 | 1 | path = require('path'); |
7 | ||
8 | 1 | existsSync = fs.existsSync || path.existsSync; |
9 | ||
10 | 1 | module.exports = { |
11 | flatten: function(arr, ret) { | |
12 | 29 | var i, _i, _ref; |
13 | 29 | if (ret == null) { |
14 | 29 | ret = []; |
15 | } | |
16 | 29 | for (i = _i = 0, _ref = arr.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) { |
17 | 29 | if (Array.isArray(arr[i])) { |
18 | 0 | this.flatten(arr[i], ret); |
19 | } else { | |
20 | 29 | ret.push(arr[i]); |
21 | } | |
22 | } | |
23 | 29 | return ret; |
24 | }, | |
25 | workspace: function() { | |
26 | 10 | var dir, dirs, _i, _len; |
27 | 10 | dirs = require('module')._nodeModulePaths(process.argv[1]); |
28 | 10 | for (_i = 0, _len = dirs.length; _i < _len; _i++) { |
29 | 30 | dir = dirs[_i]; |
30 | 30 | if (existsSync(dir) || existsSync(path.normalize(dir + '/../package.json'))) { |
31 | 10 | return path.normalize(dir + '/..'); |
32 | } | |
33 | } | |
34 | }, | |
35 | checkPort: function(port, host, callback) { | |
36 | 0 | var cmd; |
37 | 0 | cmd = exec("nc " + host + " " + port + " < /dev/null"); |
38 | 0 | return cmd.on('exit', function(code) { |
39 | 0 | if (code === 0) { |
40 | 0 | return callback(true); |
41 | } | |
42 | 0 | if (code === 1) { |
43 | 0 | return callback(false); |
44 | } | |
45 | 0 | return callback(new Error('The nc (or netcat) utility is required')); |
46 | }); | |
47 | } | |
48 | }; |