Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
80677 views
1
// Generated by CoffeeScript 1.9.3
2
(function() {
3
var BANNER, CoffeeScript, EventEmitter, SWITCHES, compileJoin, compileOptions, compilePath, compileScript, compileStdio, exec, findDirectoryIndex, forkNode, fs, helpers, hidden, joinTimeout, makePrelude, mkdirp, notSources, optionParser, optparse, opts, outputPath, parseOptions, path, printLine, printTokens, printWarn, ref, removeSource, removeSourceDir, silentUnlink, sourceCode, sources, spawn, timeLog, usage, useWinPathSep, version, wait, watch, watchDir, watchedDirs, writeJs,
4
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; };
5
6
fs = require('fs');
7
8
path = require('path');
9
10
helpers = require('./helpers');
11
12
optparse = require('./optparse');
13
14
CoffeeScript = require('./coffee-script');
15
16
ref = require('child_process'), spawn = ref.spawn, exec = ref.exec;
17
18
EventEmitter = require('events').EventEmitter;
19
20
useWinPathSep = path.sep === '\\';
21
22
helpers.extend(CoffeeScript, new EventEmitter);
23
24
printLine = function(line) {
25
return process.stdout.write(line + '\n');
26
};
27
28
printWarn = function(line) {
29
return process.stderr.write(line + '\n');
30
};
31
32
hidden = function(file) {
33
return /^\.|~$/.test(file);
34
};
35
36
BANNER = 'Usage: coffee [options] path/to/script.coffee -- [args]\n\nIf called without options, `coffee` will run your script.';
37
38
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'], ['-m', '--map', 'generate source map and save as .js.map files'], ['-n', '--nodes', 'print out the parse tree that the parser produces'], ['--nodejs [ARGS]', 'pass options directly to the "node" binary'], ['--no-header', 'suppress the "Generated by" header'], ['-o', '--output [DIR]', 'set the output directory for compiled JavaScript'], ['-p', '--print', 'print out the compiled JavaScript'], ['-r', '--require [MODULE*]', 'require the given module before eval or REPL'], ['-s', '--stdio', 'listen for and compile scripts over stdio'], ['-l', '--literate', 'treat stdio as literate style coffee-script'], ['-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']];
39
40
opts = {};
41
42
sources = [];
43
44
sourceCode = [];
45
46
notSources = {};
47
48
watchedDirs = {};
49
50
optionParser = null;
51
52
exports.run = function() {
53
var i, len, literals, ref1, replCliOpts, results, source;
54
parseOptions();
55
replCliOpts = {
56
useGlobal: true
57
};
58
if (opts.require) {
59
opts.prelude = makePrelude(opts.require);
60
}
61
replCliOpts.prelude = opts.prelude;
62
if (opts.nodejs) {
63
return forkNode();
64
}
65
if (opts.help) {
66
return usage();
67
}
68
if (opts.version) {
69
return version();
70
}
71
if (opts.interactive) {
72
return require('./repl').start(replCliOpts);
73
}
74
if (opts.stdio) {
75
return compileStdio();
76
}
77
if (opts["eval"]) {
78
return compileScript(null, opts["arguments"][0]);
79
}
80
if (!opts["arguments"].length) {
81
return require('./repl').start(replCliOpts);
82
}
83
literals = opts.run ? opts["arguments"].splice(1) : [];
84
process.argv = process.argv.slice(0, 2).concat(literals);
85
process.argv[0] = 'coffee';
86
if (opts.output) {
87
opts.output = path.resolve(opts.output);
88
}
89
if (opts.join) {
90
opts.join = path.resolve(opts.join);
91
console.error('\nThe --join option is deprecated and will be removed in a future version.\n\nIf for some reason it\'s necessary to share local variables between files,\nreplace...\n\n $ coffee --compile --join bundle.js -- a.coffee b.coffee c.coffee\n\nwith...\n\n $ cat a.coffee b.coffee c.coffee | coffee --compile --stdio > bundle.js\n');
92
}
93
ref1 = opts["arguments"];
94
results = [];
95
for (i = 0, len = ref1.length; i < len; i++) {
96
source = ref1[i];
97
source = path.resolve(source);
98
results.push(compilePath(source, true, source));
99
}
100
return results;
101
};
102
103
makePrelude = function(requires) {
104
return requires.map(function(module) {
105
var _, match, name;
106
if (match = module.match(/^(.*)=(.*)$/)) {
107
_ = match[0], name = match[1], module = match[2];
108
}
109
name || (name = helpers.baseFileName(module, true, useWinPathSep));
110
return name + " = require('" + module + "')";
111
}).join(';');
112
};
113
114
compilePath = function(source, topLevel, base) {
115
var code, err, file, files, i, len, results, stats;
116
if (indexOf.call(sources, source) >= 0 || watchedDirs[source] || !topLevel && (notSources[source] || hidden(source))) {
117
return;
118
}
119
try {
120
stats = fs.statSync(source);
121
} catch (_error) {
122
err = _error;
123
if (err.code === 'ENOENT') {
124
console.error("File not found: " + source);
125
process.exit(1);
126
}
127
throw err;
128
}
129
if (stats.isDirectory()) {
130
if (path.basename(source) === 'node_modules') {
131
notSources[source] = true;
132
return;
133
}
134
if (opts.run) {
135
compilePath(findDirectoryIndex(source), topLevel, base);
136
return;
137
}
138
if (opts.watch) {
139
watchDir(source, base);
140
}
141
try {
142
files = fs.readdirSync(source);
143
} catch (_error) {
144
err = _error;
145
if (err.code === 'ENOENT') {
146
return;
147
} else {
148
throw err;
149
}
150
}
151
results = [];
152
for (i = 0, len = files.length; i < len; i++) {
153
file = files[i];
154
results.push(compilePath(path.join(source, file), false, base));
155
}
156
return results;
157
} else if (topLevel || helpers.isCoffee(source)) {
158
sources.push(source);
159
sourceCode.push(null);
160
delete notSources[source];
161
if (opts.watch) {
162
watch(source, base);
163
}
164
try {
165
code = fs.readFileSync(source);
166
} catch (_error) {
167
err = _error;
168
if (err.code === 'ENOENT') {
169
return;
170
} else {
171
throw err;
172
}
173
}
174
return compileScript(source, code.toString(), base);
175
} else {
176
return notSources[source] = true;
177
}
178
};
179
180
findDirectoryIndex = function(source) {
181
var err, ext, i, index, len, ref1;
182
ref1 = CoffeeScript.FILE_EXTENSIONS;
183
for (i = 0, len = ref1.length; i < len; i++) {
184
ext = ref1[i];
185
index = path.join(source, "index" + ext);
186
try {
187
if ((fs.statSync(index)).isFile()) {
188
return index;
189
}
190
} catch (_error) {
191
err = _error;
192
if (err.code !== 'ENOENT') {
193
throw err;
194
}
195
}
196
}
197
console.error("Missing index.coffee or index.litcoffee in " + source);
198
return process.exit(1);
199
};
200
201
compileScript = function(file, input, base) {
202
var compiled, err, message, o, options, t, task;
203
if (base == null) {
204
base = null;
205
}
206
o = opts;
207
options = compileOptions(file, base);
208
try {
209
t = task = {
210
file: file,
211
input: input,
212
options: options
213
};
214
CoffeeScript.emit('compile', task);
215
if (o.tokens) {
216
return printTokens(CoffeeScript.tokens(t.input, t.options));
217
} else if (o.nodes) {
218
return printLine(CoffeeScript.nodes(t.input, t.options).toString().trim());
219
} else if (o.run) {
220
CoffeeScript.register();
221
if (opts.prelude) {
222
CoffeeScript["eval"](opts.prelude, t.options);
223
}
224
return CoffeeScript.run(t.input, t.options);
225
} else if (o.join && t.file !== o.join) {
226
if (helpers.isLiterate(file)) {
227
t.input = helpers.invertLiterate(t.input);
228
}
229
sourceCode[sources.indexOf(t.file)] = t.input;
230
return compileJoin();
231
} else {
232
compiled = CoffeeScript.compile(t.input, t.options);
233
t.output = compiled;
234
if (o.map) {
235
t.output = compiled.js;
236
t.sourceMap = compiled.v3SourceMap;
237
}
238
CoffeeScript.emit('success', task);
239
if (o.print) {
240
return printLine(t.output.trim());
241
} else if (o.compile || o.map) {
242
return writeJs(base, t.file, t.output, options.jsPath, t.sourceMap);
243
}
244
}
245
} catch (_error) {
246
err = _error;
247
CoffeeScript.emit('failure', err, task);
248
if (CoffeeScript.listeners('failure').length) {
249
return;
250
}
251
message = err.stack || ("" + err);
252
if (o.watch) {
253
return printLine(message + '\x07');
254
} else {
255
printWarn(message);
256
return process.exit(1);
257
}
258
}
259
};
260
261
compileStdio = function() {
262
var code, stdin;
263
code = '';
264
stdin = process.openStdin();
265
stdin.on('data', function(buffer) {
266
if (buffer) {
267
return code += buffer.toString();
268
}
269
});
270
return stdin.on('end', function() {
271
return compileScript(null, code);
272
});
273
};
274
275
joinTimeout = null;
276
277
compileJoin = function() {
278
if (!opts.join) {
279
return;
280
}
281
if (!sourceCode.some(function(code) {
282
return code === null;
283
})) {
284
clearTimeout(joinTimeout);
285
return joinTimeout = wait(100, function() {
286
return compileScript(opts.join, sourceCode.join('\n'), opts.join);
287
});
288
}
289
};
290
291
watch = function(source, base) {
292
var compile, compileTimeout, err, prevStats, rewatch, startWatcher, watchErr, watcher;
293
watcher = null;
294
prevStats = null;
295
compileTimeout = null;
296
watchErr = function(err) {
297
if (err.code !== 'ENOENT') {
298
throw err;
299
}
300
if (indexOf.call(sources, source) < 0) {
301
return;
302
}
303
try {
304
rewatch();
305
return compile();
306
} catch (_error) {
307
removeSource(source, base);
308
return compileJoin();
309
}
310
};
311
compile = function() {
312
clearTimeout(compileTimeout);
313
return compileTimeout = wait(25, function() {
314
return fs.stat(source, function(err, stats) {
315
if (err) {
316
return watchErr(err);
317
}
318
if (prevStats && stats.size === prevStats.size && stats.mtime.getTime() === prevStats.mtime.getTime()) {
319
return rewatch();
320
}
321
prevStats = stats;
322
return fs.readFile(source, function(err, code) {
323
if (err) {
324
return watchErr(err);
325
}
326
compileScript(source, code.toString(), base);
327
return rewatch();
328
});
329
});
330
});
331
};
332
startWatcher = function() {
333
return watcher = fs.watch(source).on('change', compile).on('error', function(err) {
334
if (err.code !== 'EPERM') {
335
throw err;
336
}
337
return removeSource(source, base);
338
});
339
};
340
rewatch = function() {
341
if (watcher != null) {
342
watcher.close();
343
}
344
return startWatcher();
345
};
346
try {
347
return startWatcher();
348
} catch (_error) {
349
err = _error;
350
return watchErr(err);
351
}
352
};
353
354
watchDir = function(source, base) {
355
var err, readdirTimeout, startWatcher, stopWatcher, watcher;
356
watcher = null;
357
readdirTimeout = null;
358
startWatcher = function() {
359
return watcher = fs.watch(source).on('error', function(err) {
360
if (err.code !== 'EPERM') {
361
throw err;
362
}
363
return stopWatcher();
364
}).on('change', function() {
365
clearTimeout(readdirTimeout);
366
return readdirTimeout = wait(25, function() {
367
var err, file, files, i, len, results;
368
try {
369
files = fs.readdirSync(source);
370
} catch (_error) {
371
err = _error;
372
if (err.code !== 'ENOENT') {
373
throw err;
374
}
375
return stopWatcher();
376
}
377
results = [];
378
for (i = 0, len = files.length; i < len; i++) {
379
file = files[i];
380
results.push(compilePath(path.join(source, file), false, base));
381
}
382
return results;
383
});
384
});
385
};
386
stopWatcher = function() {
387
watcher.close();
388
return removeSourceDir(source, base);
389
};
390
watchedDirs[source] = true;
391
try {
392
return startWatcher();
393
} catch (_error) {
394
err = _error;
395
if (err.code !== 'ENOENT') {
396
throw err;
397
}
398
}
399
};
400
401
removeSourceDir = function(source, base) {
402
var file, i, len, sourcesChanged;
403
delete watchedDirs[source];
404
sourcesChanged = false;
405
for (i = 0, len = sources.length; i < len; i++) {
406
file = sources[i];
407
if (!(source === path.dirname(file))) {
408
continue;
409
}
410
removeSource(file, base);
411
sourcesChanged = true;
412
}
413
if (sourcesChanged) {
414
return compileJoin();
415
}
416
};
417
418
removeSource = function(source, base) {
419
var index;
420
index = sources.indexOf(source);
421
sources.splice(index, 1);
422
sourceCode.splice(index, 1);
423
if (!opts.join) {
424
silentUnlink(outputPath(source, base));
425
silentUnlink(outputPath(source, base, '.js.map'));
426
return timeLog("removed " + source);
427
}
428
};
429
430
silentUnlink = function(path) {
431
var err, ref1;
432
try {
433
return fs.unlinkSync(path);
434
} catch (_error) {
435
err = _error;
436
if ((ref1 = err.code) !== 'ENOENT' && ref1 !== 'EPERM') {
437
throw err;
438
}
439
}
440
};
441
442
outputPath = function(source, base, extension) {
443
var basename, dir, srcDir;
444
if (extension == null) {
445
extension = ".js";
446
}
447
basename = helpers.baseFileName(source, true, useWinPathSep);
448
srcDir = path.dirname(source);
449
if (!opts.output) {
450
dir = srcDir;
451
} else if (source === base) {
452
dir = opts.output;
453
} else {
454
dir = path.join(opts.output, path.relative(base, srcDir));
455
}
456
return path.join(dir, basename + extension);
457
};
458
459
mkdirp = function(dir, fn) {
460
var mkdirs, mode;
461
mode = 0x1ff & ~process.umask();
462
return (mkdirs = function(p, fn) {
463
return fs.exists(p, function(exists) {
464
if (exists) {
465
return fn();
466
} else {
467
return mkdirs(path.dirname(p), function() {
468
return fs.mkdir(p, mode, function(err) {
469
if (err) {
470
return fn(err);
471
}
472
return fn();
473
});
474
});
475
}
476
});
477
})(dir, fn);
478
};
479
480
writeJs = function(base, sourcePath, js, jsPath, generatedSourceMap) {
481
var compile, jsDir, sourceMapPath;
482
if (generatedSourceMap == null) {
483
generatedSourceMap = null;
484
}
485
sourceMapPath = outputPath(sourcePath, base, ".js.map");
486
jsDir = path.dirname(jsPath);
487
compile = function() {
488
if (opts.compile) {
489
if (js.length <= 0) {
490
js = ' ';
491
}
492
if (generatedSourceMap) {
493
js = js + "\n//# sourceMappingURL=" + (helpers.baseFileName(sourceMapPath, false, useWinPathSep)) + "\n";
494
}
495
fs.writeFile(jsPath, js, function(err) {
496
if (err) {
497
printLine(err.message);
498
return process.exit(1);
499
} else if (opts.compile && opts.watch) {
500
return timeLog("compiled " + sourcePath);
501
}
502
});
503
}
504
if (generatedSourceMap) {
505
return fs.writeFile(sourceMapPath, generatedSourceMap, function(err) {
506
if (err) {
507
printLine("Could not write source map: " + err.message);
508
return process.exit(1);
509
}
510
});
511
}
512
};
513
return fs.exists(jsDir, function(itExists) {
514
if (itExists) {
515
return compile();
516
} else {
517
return mkdirp(jsDir, compile);
518
}
519
});
520
};
521
522
wait = function(milliseconds, func) {
523
return setTimeout(func, milliseconds);
524
};
525
526
timeLog = function(message) {
527
return console.log(((new Date).toLocaleTimeString()) + " - " + message);
528
};
529
530
printTokens = function(tokens) {
531
var strings, tag, token, value;
532
strings = (function() {
533
var i, len, results;
534
results = [];
535
for (i = 0, len = tokens.length; i < len; i++) {
536
token = tokens[i];
537
tag = token[0];
538
value = token[1].toString().replace(/\n/, '\\n');
539
results.push("[" + tag + " " + value + "]");
540
}
541
return results;
542
})();
543
return printLine(strings.join(' '));
544
};
545
546
parseOptions = function() {
547
var o;
548
optionParser = new optparse.OptionParser(SWITCHES, BANNER);
549
o = opts = optionParser.parse(process.argv.slice(2));
550
o.compile || (o.compile = !!o.output);
551
o.run = !(o.compile || o.print || o.map);
552
return o.print = !!(o.print || (o["eval"] || o.stdio && o.compile));
553
};
554
555
compileOptions = function(filename, base) {
556
var answer, cwd, jsDir, jsPath;
557
answer = {
558
filename: filename,
559
literate: opts.literate || helpers.isLiterate(filename),
560
bare: opts.bare,
561
header: opts.compile && !opts['no-header'],
562
sourceMap: opts.map
563
};
564
if (filename) {
565
if (base) {
566
cwd = process.cwd();
567
jsPath = outputPath(filename, base);
568
jsDir = path.dirname(jsPath);
569
answer = helpers.merge(answer, {
570
jsPath: jsPath,
571
sourceRoot: path.relative(jsDir, cwd),
572
sourceFiles: [path.relative(cwd, filename)],
573
generatedFile: helpers.baseFileName(jsPath, false, useWinPathSep)
574
});
575
} else {
576
answer = helpers.merge(answer, {
577
sourceRoot: "",
578
sourceFiles: [helpers.baseFileName(filename, false, useWinPathSep)],
579
generatedFile: helpers.baseFileName(filename, true, useWinPathSep) + ".js"
580
});
581
}
582
}
583
return answer;
584
};
585
586
forkNode = function() {
587
var args, nodeArgs, p;
588
nodeArgs = opts.nodejs.split(/\s+/);
589
args = process.argv.slice(1);
590
args.splice(args.indexOf('--nodejs'), 2);
591
p = spawn(process.execPath, nodeArgs.concat(args), {
592
cwd: process.cwd(),
593
env: process.env,
594
stdio: [0, 1, 2]
595
});
596
return p.on('exit', function(code) {
597
return process.exit(code);
598
});
599
};
600
601
usage = function() {
602
return printLine((new optparse.OptionParser(SWITCHES, BANNER)).help());
603
};
604
605
version = function() {
606
return printLine("CoffeeScript version " + CoffeeScript.VERSION);
607
};
608
609
}).call(this);
610
611