1 |
|
2 | var actions, altEnv, argsHint, colors, compile, deferred, doAction, env, environment, input, inspector, keypress, kids, lib, lstatSync, mocha, normalize, primaryTabComplete, program, prompt, readFileSync, readdirSync, refresh, run, secondaryTabComplete, sep, shutdown, spawn, spec, src, test, watch, watcher, _ref, _ref1,
|
3 | __slice = [].slice;
|
4 |
|
5 | deferred = require('also').deferred;
|
6 |
|
7 | watcher = require('./watcher').watcher;
|
8 |
|
9 | environment = require('./environment').environment;
|
10 |
|
11 | inspector = require('./inspector').inspector;
|
12 |
|
13 | _ref = require('fs'), readFileSync = _ref.readFileSync, readdirSync = _ref.readdirSync, lstatSync = _ref.lstatSync;
|
14 |
|
15 | normalize = require('path').normalize;
|
16 |
|
17 | spawn = require('child_process').spawn;
|
18 |
|
19 | sep = require('path').sep;
|
20 |
|
21 | compile = require('coffee-script').compile;
|
22 |
|
23 | colors = require('colors');
|
24 |
|
25 | program = require('commander');
|
26 |
|
27 | keypress = require('keypress');
|
28 |
|
29 | keypress(process.stdin);
|
30 |
|
31 | program.version(JSON.parse(readFileSync(__dirname + '/../package.json'), 'utf8').version);
|
32 |
|
33 | program.option('-w, --no-watch', 'Dont watch spec and src dirs.');
|
34 |
|
35 | program.option('-n, --no-env', 'Dont load .env.test');
|
36 |
|
37 | program.option('-m, --mocha', 'Use mocha.');
|
38 |
|
39 | program.option('-e, --alt-env [name]', 'Loads .env.name');
|
40 |
|
41 | program.option(' --spec [dir]', 'Specify alternate spec dir.', 'spec');
|
42 |
|
43 | program.option(' --src [dir]', 'Specify alternate src dir.', 'src');
|
44 |
|
45 | program.option(' --lib [dir]', 'Specify alternate compile target.', 'lib');
|
46 |
|
47 | _ref1 = program.parse(process.argv), env = _ref1.env, altEnv = _ref1.altEnv, mocha = _ref1.mocha, watch = _ref1.watch, spec = _ref1.spec, src = _ref1.src, lib = _ref1.lib, env = _ref1.env;
|
48 |
|
49 | kids = [];
|
50 |
|
51 | test = deferred(function(_arg, file) {
|
52 | var args, bin, ipsoPath, resolve, running;
|
53 | resolve = _arg.resolve;
|
54 | if (!mocha) {
|
55 | console.log('\nipso: ' + "Unspecified spec scaffold.".red, "ipso --mocha");
|
56 | refresh();
|
57 | return;
|
58 | }
|
59 | ipsoPath = normalize(__dirname + '/ipso');
|
60 | bin = normalize(__dirname + '/../node_modules/.bin/mocha');
|
61 | args = ['--colors', '--compilers', 'coffee:coffee-script', '--require', 'should', file];
|
62 | console.log('\nipso: ' + ("node_modules/.bin/mocha " + (args.join(' '))).grey);
|
63 | process.env.IPSO_SRC = src;
|
64 | running = spawn(bin, args, {
|
65 | stdio: 'inherit'
|
66 | });
|
67 | return running.on('exit', resolve);
|
68 | });
|
69 |
|
70 | compile = deferred(function(_arg) {
|
71 | var args, bin, resolve, running;
|
72 | resolve = _arg.resolve;
|
73 | bin = normalize(__dirname + '/../node_modules/.bin/coffee');
|
74 | args = ['-c', '-b', '-o', lib, src];
|
75 | console.log('\nipso: ' + ("node_modules/.bin/coffee " + (args.join(' '))).grey);
|
76 | running = spawn(bin, args, {
|
77 | stdio: 'inherit'
|
78 | });
|
79 | return running.on('exit', resolve);
|
80 | });
|
81 |
|
82 | if (env || typeof altEnv === 'string') {
|
83 | environment(altEnv);
|
84 | }
|
85 |
|
86 | if (watch) {
|
87 | watcher({
|
88 | path: program.spec || 'spec',
|
89 | handler: {
|
90 | change: function(file, stats) {
|
91 | return test(file).then(function() {
|
92 | return refresh();
|
93 | });
|
94 | }
|
95 | }
|
96 | });
|
97 | watcher({
|
98 | path: program.src || 'src',
|
99 | handler: {
|
100 | change: function(file, stats) {
|
101 | if (!file.match(/\.coffee/)) {
|
102 | return;
|
103 | }
|
104 | return compile().then(function() {
|
105 | var specFile;
|
106 | refresh();
|
107 | specFile = file.replace(/\.coffee$/, '_spec.coffee');
|
108 | specFile = specFile.replace(process.cwd() + sep + src, spec);
|
109 | return test(specFile);
|
110 | }).then(function() {
|
111 | return refresh();
|
112 | });
|
113 | }
|
114 | }
|
115 | });
|
116 | }
|
117 |
|
118 | prompt = '> ';
|
119 |
|
120 | input = '';
|
121 |
|
122 | argsHint = '';
|
123 |
|
124 | actions = {
|
125 | 'inspect': {
|
126 | args: ' [<web-port>, <debug-port>] <script>',
|
127 | secondary: 'pathWalker'
|
128 | }
|
129 | };
|
130 |
|
131 | primaryTabComplete = function() {
|
132 | var action, matches;
|
133 | matches = [];
|
134 | for (action in actions) {
|
135 | if (action.match(new RegExp("^" + input))) {
|
136 | matches.push(action);
|
137 | }
|
138 | }
|
139 | if (matches.length === 0) {
|
140 | input = '';
|
141 | return primaryTabComplete();
|
142 | }
|
143 | return matches;
|
144 | };
|
145 |
|
146 | secondaryTabComplete = function(act) {
|
147 | var all, file, files, last, part, parts, path, secondaryType, select, stat, _i, _len;
|
148 | try {
|
149 | secondaryType = actions[act].secondary;
|
150 | } catch (_error) {}
|
151 | if (!secondaryType) {
|
152 | return [];
|
153 | }
|
154 | if (secondaryType === 'pathWalker') {
|
155 | try {
|
156 | all = input.split(' ').pop();
|
157 | } catch (_error) {}
|
158 | parts = all.split(sep);
|
159 | last = parts.pop();
|
160 | path = process.cwd() + sep + parts.join(sep) + sep;
|
161 | files = readdirSync(path);
|
162 | select = files.filter(function(file) {
|
163 | return file.match(new RegExp("^" + last));
|
164 | });
|
165 | if (select.length === 1) {
|
166 | input += select[0].slice(last.length);
|
167 | file = input.split(' ').pop();
|
168 | stat = lstatSync(process.cwd() + sep + file);
|
169 | if (stat.isDirectory()) {
|
170 | input += sep;
|
171 | }
|
172 | } else {
|
173 | console.log();
|
174 | for (_i = 0, _len = select.length; _i < _len; _i++) {
|
175 | part = select[_i];
|
176 | stat = lstatSync(path + part);
|
177 | if (stat.isDirectory()) {
|
178 | console.log(part + sep);
|
179 | } else {
|
180 | console.log(part);
|
181 | }
|
182 | }
|
183 | }
|
184 | return [];
|
185 | }
|
186 | };
|
187 |
|
188 | refresh = function(output, stream) {
|
189 | if (output != null) {
|
190 | switch (stream) {
|
191 | case 'stderr':
|
192 | process.stdout.write(output.red);
|
193 | break;
|
194 | default:
|
195 | process.stdout.write(output);
|
196 | }
|
197 | }
|
198 | input = input.replace(' ', ' ');
|
199 | process.stdout.clearLine();
|
200 | process.stdout.cursorTo(0);
|
201 | process.stdout.write(prompt + input + argsHint);
|
202 | return process.stdout.cursorTo((prompt + input).length);
|
203 | };
|
204 |
|
205 | shutdown = function(code) {
|
206 | var kid, _i, _len;
|
207 | for (_i = 0, _len = kids.length; _i < _len; _i++) {
|
208 | kid = kids[_i];
|
209 | kid.kill();
|
210 | }
|
211 | return process.exit(code);
|
212 | };
|
213 |
|
214 | doAction = function() {
|
215 | var act, args, trimmed, _ref2;
|
216 | if (input === '') {
|
217 | return;
|
218 | }
|
219 | _ref2 = input.split(' '), act = _ref2[0], args = 2 <= _ref2.length ? __slice.call(_ref2, 1) : [];
|
220 | trimmed = args.filter(function(arg) {
|
221 | return arg !== '';
|
222 | });
|
223 | input = '';
|
224 | switch (act) {
|
225 | case 'inspect':
|
226 | return inspector({
|
227 | args: args
|
228 | }, kids, refresh);
|
229 | default:
|
230 | if (act != null) {
|
231 | return console.log({
|
232 | action: act,
|
233 | args: trimmed
|
234 | });
|
235 | }
|
236 | }
|
237 | };
|
238 |
|
239 | run = function() {
|
240 | var stdin;
|
241 | stdin = process.openStdin();
|
242 | process.stdin.setRawMode(true);
|
243 | refresh();
|
244 | return process.stdin.on('keypress', function(chunk, key) {
|
245 | var act, action, ctrl, m, matches, meta, name, sequence, shift, _i, _len, _ref2;
|
246 | argsHint = '';
|
247 | try {
|
248 | name = key.name, ctrl = key.ctrl, meta = key.meta, shift = key.shift, sequence = key.sequence;
|
249 | } catch (_error) {}
|
250 | if (ctrl) {
|
251 | switch (name) {
|
252 | case 'd':
|
253 | shutdown(0);
|
254 | break;
|
255 | case 'c':
|
256 | input = '';
|
257 | refresh();
|
258 | }
|
259 | return;
|
260 | }
|
261 | if (name === 'backspace') {
|
262 | input = input.slice(0, -1);
|
263 | return refresh();
|
264 | }
|
265 | if (name === 'tab') {
|
266 | try {
|
267 | _ref2 = input.match(/^(.*?)\s/), m = _ref2[0], act = _ref2[1];
|
268 | } catch (_error) {}
|
269 | if (act != null) {
|
270 | matches = secondaryTabComplete(act);
|
271 | } else {
|
272 | matches = primaryTabComplete();
|
273 | }
|
274 | if (matches.length === 1) {
|
275 | input = matches[0];
|
276 | argsHint = ' ' + actions[matches[0]].args.grey;
|
277 | return refresh();
|
278 | } else {
|
279 | console.log();
|
280 | for (_i = 0, _len = matches.length; _i < _len; _i++) {
|
281 | action = matches[_i];
|
282 | console.log(action, actions[action].args.grey);
|
283 | }
|
284 | return refresh();
|
285 | }
|
286 | }
|
287 | if (name === 'return') {
|
288 | process.stdout.write('\n');
|
289 | doAction();
|
290 | process.stdout.write(prompt + input);
|
291 | return;
|
292 | }
|
293 | if (!chunk) {
|
294 | return;
|
295 | }
|
296 | input += chunk.toString();
|
297 | return refresh();
|
298 | });
|
299 | };
|
300 |
|
301 | run();
|