1
0
Fork 0
mirror of https://github.com/jashkenas/coffeescript.git synced 2022-11-09 12:23:24 -05:00

Added recursive compilation and monitoring option to coffee command

This commit is contained in:
Trevor Burnham 2010-05-03 17:38:59 -04:00
parent ee4e34bf6d
commit fa8cc7976a
2 changed files with 99 additions and 55 deletions

View file

@ -1,5 +1,5 @@
(function(){
var BANNER, CoffeeScript, SWITCHES, _a, compile_options, compile_script, compile_scripts, compile_stdio, exec, fs, lint, option_parser, options, optparse, parse_options, path, print_tokens, sources, spawn, usage, version, watch_scripts, write_js;
var BANNER, CoffeeScript, SWITCHES, _a, base, compile_options, compile_script, compile_scripts, compile_stdio, exec, fs, is_watched, lint, option_parser, options, optparse, parse_options, path, print_tokens, sources, spawn, usage, version, watch, write_js;
// The `coffee` utility. Handles command-line compilation of CoffeeScript
// into various forms: saved into `.js` files or printed to stdout, piped to
// [JSLint](http://javascriptlint.com/) or recompiled every time the source is
@ -16,10 +16,12 @@
// The help banner that is printed when `coffee` is called without arguments.
BANNER = 'coffee compiles CoffeeScript source files into JavaScript.\n\nUsage:\n coffee path/to/script.coffee';
// The list of all the valid option flags that `coffee` knows how to handle.
SWITCHES = [['-c', '--compile', 'compile to JavaScript and save as .js files'], ['-i', '--interactive', 'run an interactive CoffeeScript REPL'], ['-o', '--output [DIR]', 'set the directory for compiled JavaScript'], ['-w', '--watch', 'watch scripts for changes, and recompile'], ['-p', '--print', 'print the compiled JavaScript to stdout'], ['-l', '--lint', 'pipe the compiled JavaScript through JSLint'], ['-s', '--stdio', 'listen for and compile scripts over stdio'], ['-e', '--eval', 'compile a string from the command line'], ['--no-wrap', 'compile without the top-level function wrapper'], ['-t', '--tokens', 'print the tokens that the lexer produces'], ['-n', '--nodes', 'print the parse tree that Jison produces'], ['-v', '--version', 'display CoffeeScript version'], ['-h', '--help', 'display this help message']];
SWITCHES = [['-c', '--compile', 'compile to JavaScript and save as .js files'], ['-i', '--interactive', 'run an interactive CoffeeScript REPL'], ['-o', '--output [DIR]', 'set the directory for compiled JavaScript'], ['-w', '--watch', 'watch scripts for changes, and recompile'], ['-p', '--print', 'print the compiled JavaScript to stdout'], ['-m', '--monitor', 'show a message every time a script is compiled'], ['-l', '--lint', 'pipe the compiled JavaScript through JSLint'], ['-s', '--stdio', 'listen for and compile scripts over stdio'], ['-e', '--eval', 'compile a string from the command line'], ['--no-wrap', 'compile without the top-level function wrapper'], ['-t', '--tokens', 'print the tokens that the lexer produces'], ['-n', '--nodes', 'print the parse tree that Jison produces'], ['-v', '--version', 'display CoffeeScript version'], ['-h', '--help', 'display this help message']];
// Top-level objects shared by all the functions.
options = {};
sources = [];
base = '';
is_watched = {};
option_parser = null;
// Run `coffee` by parsing passed options and determining what action to take.
// Many flags cause us to divert before compiling anything. Flags passed after
@ -52,22 +54,43 @@
sources = sources.slice(0, separator);
}
process.ARGV = (process.argv = flags);
if (options.watch) {
watch_scripts();
}
return compile_scripts();
};
// Asynchronously read in each CoffeeScript in a list of source files and
// compile them.
// compile them. If a directory is passed, recursively compile all source
// files in it and all subdirectories.
compile_scripts = function compile_scripts() {
var compile, run;
compile = function compile(source) {
if (is_watched[source]) {
return null;
}
return path.exists(source, function(exists) {
if (!(exists)) {
throw new Error(("File not found: " + source));
}
return fs.readFile(source, function(err, code) {
return compile_script(source, code);
return fs.stat(source, function(err, stats) {
if (stats.isDirectory()) {
return fs.readdir(source, function(err, files) {
var _b, _c, _d, _e, file;
_b = []; _d = files;
for (_c = 0, _e = _d.length; _c < _e; _c++) {
file = _d[_c];
_b.push(compile(path.join(source, file)));
}
return _b;
});
} else if (source === base || path.extname(source) === '.coffee') {
if (options.monitor) {
puts('Compiling ' + source);
}
fs.readFile(source, function(err, code) {
return compile_script(source, code);
});
if (options.watch) {
return watch(source);
}
}
});
});
};
@ -76,14 +99,17 @@
_b = []; _d = sources;
for (_c = 0, _e = _d.length; _c < _e; _c++) {
source = _d[_c];
_b.push(compile(source));
_b.push((function() {
base = source;
return compile(source);
})());
}
return _b;
};
if (!(options.output && options.compile)) {
return run();
run();
if (options.watch) {
return setInterval(run, 500);
}
return exec(("mkdir -p " + options.output), run);
};
// Compile a single source script, containing the given code, according to the
// requested options. Both compile_scripts and watch_scripts share this method
@ -133,40 +159,38 @@
return compile_script('stdio', code);
});
};
// Watch a list of source CoffeeScript files using `fs.watchFile`, recompiling
// them every time the files are updated. May be used in combination with other
// options, such as `--lint` or `--print`.
watch_scripts = function watch_scripts() {
var _b, _c, _d, _e, source, watch;
watch = function watch(source) {
return fs.watchFile(source, {
persistent: true,
interval: 500
}, function(curr, prev) {
if (curr.mtime.getTime() === prev.mtime.getTime()) {
return null;
}
return fs.readFile(source, function(err, code) {
return compile_script(source, code);
});
// Watch a source CoffeeScript file using `fs.watchFile`, recompiling it every
// time the file is updated. May be used in combination with other options,
// such as `--lint` or `--print`.
watch = function watch(source) {
is_watched[source] = true;
return fs.watchFile(source, {
persistent: true,
interval: 500
}, function(curr, prev) {
if (curr.mtime.getTime() === prev.mtime.getTime()) {
return null;
}
if (options.monitor) {
puts('Recompiling ' + source);
}
return fs.readFile(source, function(err, code) {
return compile_script(source, code);
});
};
_b = []; _d = sources;
for (_c = 0, _e = _d.length; _c < _e; _c++) {
source = _d[_c];
_b.push(watch(source));
}
return _b;
});
};
// Write out a JavaScript source file with the compiled code. By default, files
// are written out in `cwd` as `.js` files with the same name, but the output
// directory can be customized with `--output`.
write_js = function write_js(source, js) {
var dir, filename, js_path;
var dir, filename, js_path, src_dir;
filename = path.basename(source, path.extname(source)) + '.js';
dir = options.output || path.dirname(source);
src_dir = path.dirname(source);
dir = options.output ? path.join(options.output, src_dir.substring(base.length)) : src_dir;
js_path = path.join(dir, filename);
return fs.writeFile(js_path, js);
return exec(("mkdir -p " + dir), function(error, stdout, stderr) {
return fs.writeFile(js_path, js);
});
};
// Pipe compiled JS through JSLint (requires a working `jsl` command), printing
// any errors or warnings that arise.

View file

@ -26,6 +26,7 @@ SWITCHES: [
['-o', '--output [DIR]', 'set the directory for compiled JavaScript']
['-w', '--watch', 'watch scripts for changes, and recompile']
['-p', '--print', 'print the compiled JavaScript to stdout']
['-m', '--monitor', 'show a message every time a script is compiled']
['-l', '--lint', 'pipe the compiled JavaScript through JSLint']
['-s', '--stdio', 'listen for and compile scripts over stdio']
['-e', '--eval', 'compile a string from the command line']
@ -39,6 +40,8 @@ SWITCHES: [
# Top-level objects shared by all the functions.
options: {}
sources: []
base: ''
is_watched: {}
option_parser: null
# Run `coffee` by parsing passed options and determining what action to take.
@ -58,19 +61,34 @@ exports.run: ->
flags: sources[(separator + 1)...sources.length]
sources: sources[0...separator]
process.ARGV: process.argv: flags
watch_scripts() if options.watch
compile_scripts()
# Asynchronously read in each CoffeeScript in a list of source files and
# compile them.
# compile them. If a directory is passed, recursively compile all source
# files in it and all subdirectories.
compile_scripts: ->
compile: (source) ->
return if is_watched[source]
path.exists source, (exists) ->
throw new Error "File not found: $source" unless exists
fs.readFile source, (err, code) -> compile_script(source, code)
run: -> compile(source) for source in sources
return run() unless options.output and options.compile
exec "mkdir -p $options.output", run
fs.stat source, (err, stats) ->
if stats.isDirectory()
fs.readdir source, (err, files) ->
for file in files
compile path.join(source, file)
else if source == base or path.extname(source) == '.coffee'
puts 'Compiling ' + source if options.monitor
fs.readFile source, (err, code) -> compile_script(source, code)
watch(source) if options.watch
run: ->
for source in sources
base = source
compile(source)
run()
if options.watch
setInterval run, 500
# Compile a single source script, containing the given code, according to the
# requested options. Both compile_scripts and watch_scripts share this method
@ -101,24 +119,26 @@ compile_stdio: ->
stdin.addListener 'end', ->
compile_script 'stdio', code
# Watch a list of source CoffeeScript files using `fs.watchFile`, recompiling
# them every time the files are updated. May be used in combination with other
# options, such as `--lint` or `--print`.
watch_scripts: ->
watch: (source) ->
fs.watchFile source, {persistent: true, interval: 500}, (curr, prev) ->
return if curr.mtime.getTime() is prev.mtime.getTime()
fs.readFile source, (err, code) -> compile_script(source, code)
watch(source) for source in sources
# Watch a source CoffeeScript file using `fs.watchFile`, recompiling it every
# time the file is updated. May be used in combination with other options,
# such as `--lint` or `--print`.
watch: (source) ->
is_watched[source] = true
fs.watchFile source, {persistent: true, interval: 500}, (curr, prev) ->
return if curr.mtime.getTime() is prev.mtime.getTime()
puts 'Recompiling ' + source if options.monitor
fs.readFile source, (err, code) -> compile_script(source, code)
# Write out a JavaScript source file with the compiled code. By default, files
# are written out in `cwd` as `.js` files with the same name, but the output
# directory can be customized with `--output`.
write_js: (source, js) ->
filename: path.basename(source, path.extname(source)) + '.js'
dir: options.output or path.dirname(source)
src_dir: path.dirname(source)
dir: if options.output then \
path.join options.output, src_dir.substring(base.length) else src_dir
js_path: path.join dir, filename
fs.writeFile js_path, js
exec "mkdir -p $dir", (error, stdout, stderr) -> fs.writeFile js_path, js
# Pipe compiled JS through JSLint (requires a working `jsl` command), printing
# any errors or warnings that arise.