UNPKG

15.5 kBJavaScriptView Raw
1// Generated by CoffeeScript 1.4.0
2(function() {
3 var BANNER, CoffeeScript, EventEmitter, SWITCHES, compileJoin, compileOptions, compilePath, compileScript, compileStdio, exec, exists, forkNode, fs, helpers, hidden, joinTimeout, lint, loadRequires, notSources, optionParser, optparse, opts, outputPath, parseOptions, path, printLine, printTokens, printWarn, removeSource, sourceCode, sources, spawn, timeLog, unwatchDir, usage, version, wait, watch, watchDir, watchers, writeJs, _ref;
4
5 fs = require('fs');
6
7 path = require('path');
8
9 helpers = require('./helpers');
10
11 optparse = require('./optparse');
12
13 CoffeeScript = require('./coffee-script');
14
15 _ref = require('child_process'), spawn = _ref.spawn, exec = _ref.exec;
16
17 EventEmitter = require('events').EventEmitter;
18
19 exists = fs.exists || path.exists;
20
21 helpers.extend(CoffeeScript, new EventEmitter);
22
23 printLine = function(line) {
24 return process.stdout.write(line + '\n');
25 };
26
27 printWarn = function(line) {
28 return process.stderr.write(line + '\n');
29 };
30
31 hidden = function(file) {
32 return /^\.|~$/.test(file);
33 };
34
35 BANNER = 'Usage: coffee [options] path/to/script.coffee -- [args]\n\nIf called without options, `coffee` will run your script.';
36
37 SWITCHES = [['-b', '--bare', 'compile without a top-level function wrapper'], ['-c', '--compile', 'compile to JavaScript and save as .js files'], ['-e', '--eval', 'pass a string from the command line as input'], ['-h', '--help', 'display this help message'], ['-i', '--interactive', 'run an interactive CoffeeScript REPL'], ['-j', '--join [FILE]', 'concatenate the source CoffeeScript before compiling'], ['-l', '--lint', 'pipe the compiled JavaScript through JavaScript Lint'], ['-n', '--nodes', 'print out the parse tree that the parser produces'], ['--nodejs [ARGS]', 'pass options directly to the "node" binary'], ['-o', '--output [DIR]', 'set the output directory for compiled JavaScript'], ['-p', '--print', 'print out the compiled JavaScript'], ['-r', '--require [FILE*]', 'require a library before executing your script'], ['-s', '--stdio', 'listen for and compile scripts over stdio'], ['-t', '--tokens', 'print out the tokens that the lexer/rewriter produce'], ['-v', '--version', 'display the version number'], ['-w', '--watch', 'watch scripts for changes and rerun commands']];
38
39 opts = {};
40
41 sources = [];
42
43 sourceCode = [];
44
45 notSources = {};
46
47 watchers = {};
48
49 optionParser = null;
50
51 exports.run = function() {
52 var literals, source, _i, _len, _results;
53 parseOptions();
54 if (opts.nodejs) {
55 return forkNode();
56 }
57 if (opts.help) {
58 return usage();
59 }
60 if (opts.version) {
61 return version();
62 }
63 if (opts.require) {
64 loadRequires();
65 }
66 if (opts.interactive) {
67 return require('./repl');
68 }
69 if (opts.watch && !fs.watch) {
70 return printWarn("The --watch feature depends on Node v0.6.0+. You are running " + process.version + ".");
71 }
72 if (opts.stdio) {
73 return compileStdio();
74 }
75 if (opts["eval"]) {
76 return compileScript(null, sources[0]);
77 }
78 if (!sources.length) {
79 return require('./repl');
80 }
81 literals = opts.run ? sources.splice(1) : [];
82 process.argv = process.argv.slice(0, 2).concat(literals);
83 process.argv[0] = 'coffee';
84 process.execPath = require.main.filename;
85 _results = [];
86 for (_i = 0, _len = sources.length; _i < _len; _i++) {
87 source = sources[_i];
88 _results.push(compilePath(source, true, path.normalize(source)));
89 }
90 return _results;
91 };
92
93 compilePath = function(source, topLevel, base) {
94 return fs.stat(source, function(err, stats) {
95 if (err && err.code !== 'ENOENT') {
96 throw err;
97 }
98 if ((err != null ? err.code : void 0) === 'ENOENT') {
99 if (topLevel && source.slice(-7) !== '.coffee') {
100 source = sources[sources.indexOf(source)] = "" + source + ".coffee";
101 return compilePath(source, topLevel, base);
102 }
103 if (topLevel) {
104 console.error("File not found: " + source);
105 process.exit(1);
106 }
107 return;
108 }
109 if (stats.isDirectory()) {
110 if (opts.watch) {
111 watchDir(source, base);
112 }
113 return fs.readdir(source, function(err, files) {
114 var file, index, _ref1, _ref2;
115 if (err && err.code !== 'ENOENT') {
116 throw err;
117 }
118 if ((err != null ? err.code : void 0) === 'ENOENT') {
119 return;
120 }
121 index = sources.indexOf(source);
122 files = files.filter(function(file) {
123 return !hidden(file);
124 });
125 [].splice.apply(sources, [index, index - index + 1].concat(_ref1 = (function() {
126 var _i, _len, _results;
127 _results = [];
128 for (_i = 0, _len = files.length; _i < _len; _i++) {
129 file = files[_i];
130 _results.push(path.join(source, file));
131 }
132 return _results;
133 })())), _ref1;
134 [].splice.apply(sourceCode, [index, index - index + 1].concat(_ref2 = files.map(function() {
135 return null;
136 }))), _ref2;
137 return files.forEach(function(file) {
138 return compilePath(path.join(source, file), false, base);
139 });
140 });
141 } else if (topLevel || path.extname(source) === '.coffee') {
142 if (opts.watch) {
143 watch(source, base);
144 }
145 return fs.readFile(source, function(err, code) {
146 if (err && err.code !== 'ENOENT') {
147 throw err;
148 }
149 if ((err != null ? err.code : void 0) === 'ENOENT') {
150 return;
151 }
152 return compileScript(source, code.toString(), base);
153 });
154 } else {
155 notSources[source] = true;
156 return removeSource(source, base);
157 }
158 });
159 };
160
161 compileScript = function(file, input, base) {
162 var o, options, t, task;
163 o = opts;
164 options = compileOptions(file);
165 try {
166 t = task = {
167 file: file,
168 input: input,
169 options: options
170 };
171 CoffeeScript.emit('compile', task);
172 if (o.tokens) {
173 return printTokens(CoffeeScript.tokens(t.input));
174 } else if (o.nodes) {
175 return printLine(CoffeeScript.nodes(t.input).toString().trim());
176 } else if (o.run) {
177 return CoffeeScript.run(t.input, t.options);
178 } else if (o.join && t.file !== o.join) {
179 sourceCode[sources.indexOf(t.file)] = t.input;
180 return compileJoin();
181 } else {
182 t.output = CoffeeScript.compile(t.input, t.options);
183 CoffeeScript.emit('success', task);
184 if (o.print) {
185 return printLine(t.output.trim());
186 } else if (o.compile) {
187 return writeJs(t.file, t.output, base);
188 } else if (o.lint) {
189 return lint(t.file, t.output);
190 }
191 }
192 } catch (err) {
193 CoffeeScript.emit('failure', err, task);
194 if (CoffeeScript.listeners('failure').length) {
195 return;
196 }
197 if (o.watch) {
198 return printLine(err.message + '\x07');
199 }
200 printWarn(err instanceof Error && err.stack || ("ERROR: " + err));
201 return process.exit(1);
202 }
203 };
204
205 compileStdio = function() {
206 var code, stdin;
207 code = '';
208 stdin = process.openStdin();
209 stdin.on('data', function(buffer) {
210 if (buffer) {
211 return code += buffer.toString();
212 }
213 });
214 return stdin.on('end', function() {
215 return compileScript(null, code);
216 });
217 };
218
219 joinTimeout = null;
220
221 compileJoin = function() {
222 if (!opts.join) {
223 return;
224 }
225 if (!sourceCode.some(function(code) {
226 return code === null;
227 })) {
228 clearTimeout(joinTimeout);
229 return joinTimeout = wait(100, function() {
230 return compileScript(opts.join, sourceCode.join('\n'), opts.join);
231 });
232 }
233 };
234
235 loadRequires = function() {
236 var realFilename, req, _i, _len, _ref1;
237 realFilename = module.filename;
238 module.filename = '.';
239 _ref1 = opts.require;
240 for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
241 req = _ref1[_i];
242 require(req);
243 }
244 return module.filename = realFilename;
245 };
246
247 watch = function(source, base) {
248 var compile, compileTimeout, prevStats, rewatch, watchErr, watcher;
249 prevStats = null;
250 compileTimeout = null;
251 watchErr = function(e) {
252 if (e.code === 'ENOENT') {
253 if (sources.indexOf(source) === -1) {
254 return;
255 }
256 try {
257 rewatch();
258 return compile();
259 } catch (e) {
260 removeSource(source, base, true);
261 return compileJoin();
262 }
263 } else {
264 throw e;
265 }
266 };
267 compile = function() {
268 clearTimeout(compileTimeout);
269 return compileTimeout = wait(25, function() {
270 return fs.stat(source, function(err, stats) {
271 if (err) {
272 return watchErr(err);
273 }
274 if (prevStats && stats.size === prevStats.size && stats.mtime.getTime() === prevStats.mtime.getTime()) {
275 return rewatch();
276 }
277 prevStats = stats;
278 return fs.readFile(source, function(err, code) {
279 if (err) {
280 return watchErr(err);
281 }
282 compileScript(source, code.toString(), base);
283 return rewatch();
284 });
285 });
286 });
287 };
288 try {
289 watcher = fs.watch(source, compile);
290 } catch (e) {
291 watchErr(e);
292 }
293 return rewatch = function() {
294 if (watcher != null) {
295 watcher.close();
296 }
297 return watcher = fs.watch(source, compile);
298 };
299 };
300
301 watchDir = function(source, base) {
302 var readdirTimeout, watcher;
303 readdirTimeout = null;
304 try {
305 return watcher = fs.watch(source, function() {
306 clearTimeout(readdirTimeout);
307 return readdirTimeout = wait(25, function() {
308 return fs.readdir(source, function(err, files) {
309 var file, _i, _len, _results;
310 if (err) {
311 if (err.code !== 'ENOENT') {
312 throw err;
313 }
314 watcher.close();
315 return unwatchDir(source, base);
316 }
317 _results = [];
318 for (_i = 0, _len = files.length; _i < _len; _i++) {
319 file = files[_i];
320 if (!(!hidden(file) && !notSources[file])) {
321 continue;
322 }
323 file = path.join(source, file);
324 if (sources.some(function(s) {
325 return s.indexOf(file) >= 0;
326 })) {
327 continue;
328 }
329 sources.push(file);
330 sourceCode.push(null);
331 _results.push(compilePath(file, false, base));
332 }
333 return _results;
334 });
335 });
336 });
337 } catch (e) {
338 if (e.code !== 'ENOENT') {
339 throw e;
340 }
341 }
342 };
343
344 unwatchDir = function(source, base) {
345 var file, prevSources, toRemove, _i, _len;
346 prevSources = sources.slice(0);
347 toRemove = (function() {
348 var _i, _len, _results;
349 _results = [];
350 for (_i = 0, _len = sources.length; _i < _len; _i++) {
351 file = sources[_i];
352 if (file.indexOf(source) >= 0) {
353 _results.push(file);
354 }
355 }
356 return _results;
357 })();
358 for (_i = 0, _len = toRemove.length; _i < _len; _i++) {
359 file = toRemove[_i];
360 removeSource(file, base, true);
361 }
362 if (!sources.some(function(s, i) {
363 return prevSources[i] !== s;
364 })) {
365 return;
366 }
367 return compileJoin();
368 };
369
370 removeSource = function(source, base, removeJs) {
371 var index, jsPath;
372 index = sources.indexOf(source);
373 sources.splice(index, 1);
374 sourceCode.splice(index, 1);
375 if (removeJs && !opts.join) {
376 jsPath = outputPath(source, base);
377 return exists(jsPath, function(itExists) {
378 if (itExists) {
379 return fs.unlink(jsPath, function(err) {
380 if (err && err.code !== 'ENOENT') {
381 throw err;
382 }
383 return timeLog("removed " + source);
384 });
385 }
386 });
387 }
388 };
389
390 outputPath = function(source, base) {
391 var baseDir, dir, filename, srcDir;
392 filename = path.basename(source, path.extname(source)) + '.js';
393 srcDir = path.dirname(source);
394 baseDir = base === '.' ? srcDir : srcDir.substring(base.length);
395 dir = opts.output ? path.join(opts.output, baseDir) : srcDir;
396 return path.join(dir, filename);
397 };
398
399 writeJs = function(source, js, base) {
400 var compile, jsDir, jsPath;
401 jsPath = outputPath(source, base);
402 jsDir = path.dirname(jsPath);
403 compile = function() {
404 if (js.length <= 0) {
405 js = ' ';
406 }
407 return fs.writeFile(jsPath, js, function(err) {
408 if (err) {
409 return printLine(err.message);
410 } else if (opts.compile && opts.watch) {
411 return timeLog("compiled " + source);
412 }
413 });
414 };
415 return exists(jsDir, function(itExists) {
416 if (itExists) {
417 return compile();
418 } else {
419 return exec("mkdir -p " + jsDir, compile);
420 }
421 });
422 };
423
424 wait = function(milliseconds, func) {
425 return setTimeout(func, milliseconds);
426 };
427
428 timeLog = function(message) {
429 return console.log("" + ((new Date).toLocaleTimeString()) + " - " + message);
430 };
431
432 lint = function(file, js) {
433 var conf, jsl, printIt;
434 printIt = function(buffer) {
435 return printLine(file + ':\t' + buffer.toString().trim());
436 };
437 conf = __dirname + '/../../extras/jsl.conf';
438 jsl = spawn('jsl', ['-nologo', '-stdin', '-conf', conf]);
439 jsl.stdout.on('data', printIt);
440 jsl.stderr.on('data', printIt);
441 jsl.stdin.write(js);
442 return jsl.stdin.end();
443 };
444
445 printTokens = function(tokens) {
446 var strings, tag, token, value;
447 strings = (function() {
448 var _i, _len, _ref1, _results;
449 _results = [];
450 for (_i = 0, _len = tokens.length; _i < _len; _i++) {
451 token = tokens[_i];
452 _ref1 = [token[0], token[1].toString().replace(/\n/, '\\n')], tag = _ref1[0], value = _ref1[1];
453 _results.push("[" + tag + " " + value + "]");
454 }
455 return _results;
456 })();
457 return printLine(strings.join(' '));
458 };
459
460 parseOptions = function() {
461 var i, o, source, _i, _len;
462 optionParser = new optparse.OptionParser(SWITCHES, BANNER);
463 o = opts = optionParser.parse(process.argv.slice(2));
464 o.compile || (o.compile = !!o.output);
465 o.run = !(o.compile || o.print || o.lint);
466 o.print = !!(o.print || (o["eval"] || o.stdio && o.compile));
467 sources = o["arguments"];
468 for (i = _i = 0, _len = sources.length; _i < _len; i = ++_i) {
469 source = sources[i];
470 sourceCode[i] = null;
471 }
472 };
473
474 compileOptions = function(filename) {
475 return {
476 filename: filename,
477 bare: opts.bare,
478 header: opts.compile
479 };
480 };
481
482 forkNode = function() {
483 var args, nodeArgs;
484 nodeArgs = opts.nodejs.split(/\s+/);
485 args = process.argv.slice(1);
486 args.splice(args.indexOf('--nodejs'), 2);
487 return spawn(process.execPath, nodeArgs.concat(args), {
488 cwd: process.cwd(),
489 env: process.env,
490 customFds: [0, 1, 2]
491 });
492 };
493
494 usage = function() {
495 return printLine((new optparse.OptionParser(SWITCHES, BANNER)).help());
496 };
497
498 version = function() {
499 return printLine("CoffeeScript version " + CoffeeScript.VERSION);
500 };
501
502}).call(this);