UNPKG

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