2010-07-24 15:31:43 +00:00
( function ( ) {
2010-09-21 02:13:08 +00:00
var BANNER , CoffeeScript , EventEmitter , SWITCHES , _ref , compileOptions , compileScript , compileScripts , compileStdio , exec , fs , helpers , lint , optionParser , optparse , opts , parseOptions , path , printTokens , sources , spawn , usage , version , watch , writeJs ;
2010-02-16 00:08:14 +00:00
fs = require ( 'fs' ) ;
2010-02-13 03:59:21 +00:00
path = require ( 'path' ) ;
2010-03-16 03:39:46 +00:00
optparse = require ( './optparse' ) ;
CoffeeScript = require ( './coffee-script' ) ;
2010-09-25 00:29:44 +00:00
helpers = require ( './helpers' ) ;
2010-09-28 20:47:12 +00:00
_ref = require ( 'child_process' ) , spawn = _ref . spawn , exec = _ref . exec ;
EventEmitter = require ( 'events' ) . EventEmitter ;
2010-09-25 08:39:19 +00:00
helpers . extend ( CoffeeScript , new EventEmitter ) ;
2010-08-08 13:54:18 +00:00
global . CoffeeScript = CoffeeScript ;
2010-03-18 00:47:27 +00:00
BANNER = 'coffee compiles CoffeeScript source files into JavaScript.\n\nUsage:\n coffee path/to/script.coffee' ;
2010-08-08 03:33:35 +00:00
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' ] , [ '-r' , '--require [FILE*]' , 'require a library before executing your script' ] , [ '--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' ] ] ;
2010-08-15 12:32:09 +00:00
opts = { } ;
2010-02-13 15:16:28 +00:00
sources = [ ] ;
2010-06-12 23:05:13 +00:00
optionParser = null ;
2010-05-15 03:40:04 +00:00
exports . run = function ( ) {
2010-02-16 06:04:48 +00:00
var flags , separator ;
2010-06-12 23:05:13 +00:00
parseOptions ( ) ;
2010-08-15 12:32:09 +00:00
if ( opts . help ) {
2010-02-24 22:57:58 +00:00
return usage ( ) ;
}
2010-08-15 12:32:09 +00:00
if ( opts . version ) {
2010-02-24 22:57:58 +00:00
return version ( ) ;
}
2010-08-15 12:32:09 +00:00
if ( opts . interactive ) {
2010-03-16 03:39:46 +00:00
return require ( './repl' ) ;
2010-02-13 15:07:59 +00:00
}
2010-08-15 12:32:09 +00:00
if ( opts . stdio ) {
2010-06-12 23:05:13 +00:00
return compileStdio ( ) ;
2010-02-24 23:18:29 +00:00
}
2010-08-15 12:32:09 +00:00
if ( opts . eval ) {
2010-06-12 23:05:13 +00:00
return compileScript ( 'console' , sources [ 0 ] ) ;
2010-02-14 04:27:13 +00:00
}
2010-02-13 15:16:28 +00:00
if ( ! ( sources . length ) ) {
2010-06-12 15:09:30 +00:00
return require ( './repl' ) ;
2010-02-13 15:16:28 +00:00
}
2010-02-16 06:04:48 +00:00
separator = sources . indexOf ( '--' ) ;
flags = [ ] ;
if ( separator >= 0 ) {
2010-03-31 00:06:44 +00:00
flags = sources . slice ( ( separator + 1 ) , sources . length ) ;
sources = sources . slice ( 0 , separator ) ;
2010-02-16 06:04:48 +00:00
}
2010-08-15 12:32:09 +00:00
if ( opts . run ) {
2010-07-10 19:36:54 +00:00
flags = sources . slice ( 1 , sources . length + 1 ) . concat ( flags ) ;
sources = [ sources [ 0 ] ] ;
}
2010-03-07 01:09:08 +00:00
process . ARGV = ( process . argv = flags ) ;
2010-06-12 23:05:13 +00:00
return compileScripts ( ) ;
2010-02-11 06:57:33 +00:00
} ;
2010-06-12 23:05:13 +00:00
compileScripts = function ( ) {
2010-10-07 03:24:32 +00:00
var _i , _len , _ref2 , _result ;
2010-10-07 01:13:11 +00:00
_result = [ ] ;
2010-10-07 03:24:32 +00:00
for ( _i = 0 , _len = ( _ref2 = sources ) . length ; _i < _len ; _i ++ ) {
2010-06-14 01:21:30 +00:00
( function ( ) {
var base , compile ;
2010-10-07 03:24:32 +00:00
var source = _ref2 [ _i ] ;
2010-09-19 12:29:15 +00:00
return _result . push ( ( function ( ) {
2010-06-14 01:21:30 +00:00
base = source ;
compile = function ( source , topLevel ) {
return path . exists ( source , function ( exists ) {
if ( ! ( exists ) ) {
2010-10-04 12:50:50 +00:00
throw new Error ( "File not found: " + source ) ;
2010-06-14 01:21:30 +00:00
}
return fs . stat ( source , function ( err , stats ) {
if ( stats . isDirectory ( ) ) {
return fs . readdir ( source , function ( err , files ) {
2010-10-01 22:26:37 +00:00
var _j , _len2 , _result2 , file ;
_result2 = [ ] ;
for ( _j = 0 , _len2 = files . length ; _j < _len2 ; _j ++ ) {
file = files [ _j ] ;
2010-09-19 12:29:15 +00:00
_result2 . push ( compile ( path . join ( source , file ) ) ) ;
2010-06-14 01:21:30 +00:00
}
2010-09-19 12:29:15 +00:00
return _result2 ;
2010-06-14 01:21:30 +00:00
} ) ;
} else if ( topLevel || path . extname ( source ) === '.coffee' ) {
fs . readFile ( source , function ( err , code ) {
return compileScript ( source , code . toString ( ) , base ) ;
} ) ;
2010-10-02 00:52:23 +00:00
return opts . watch ? watch ( source , base ) : undefined ;
2010-05-05 03:22:28 +00:00
}
2010-06-14 01:21:30 +00:00
} ) ;
2010-05-03 21:38:59 +00:00
} ) ;
2010-06-14 01:21:30 +00:00
} ;
return compile ( source , true ) ;
} ) ( ) ) ;
} ) ( ) ;
2010-02-11 06:57:33 +00:00
}
2010-09-19 12:29:15 +00:00
return _result ;
2010-02-17 04:59:32 +00:00
} ;
2010-08-15 12:32:09 +00:00
compileScript = function ( file , input , base ) {
2010-09-21 02:13:08 +00:00
var _i , _len , _ref2 , o , options , req , t , task ;
2010-08-15 12:32:09 +00:00
o = opts ;
options = compileOptions ( file ) ;
Add command-line compiler hooks. To invoke, pass a file after -r and listen for any of these events: 'compile', 'success' and 'exception'. Example:
coffee -e -r ./snarl 'Hello!'
Contents of 'snarl.coffee' in the working directory:
http = require 'http'
CoffeeScript.on 'exception', (err) ->
client = http.createClient 9889, 'localhost'
request = client.request 'GET', '/?d={"action":1,"applicationName":"CoffeeScript","title":' + JSON.stringify(err.message) + ',"description":' + JSON.stringify(err.stack) + ',"priority":3}'
request.end()
err.handled = yes
To examine arguments available for each event (for debugging and getting started), use `puts JSON.stringify arguments`.
See http://nodejs.org/api.html#modules-309 and NODE_PATH for more details on how -r looks for files.
2010-08-07 17:24:37 +00:00
if ( o . require ) {
2010-10-07 03:24:32 +00:00
for ( _i = 0 , _len = ( _ref2 = o . require ) . length ; _i < _len ; _i ++ ) {
2010-09-21 02:13:08 +00:00
req = _ref2 [ _i ] ;
2010-09-08 12:48:40 +00:00
require ( helpers . starts ( req , '.' ) ? fs . realpathSync ( req ) : req ) ;
Add command-line compiler hooks. To invoke, pass a file after -r and listen for any of these events: 'compile', 'success' and 'exception'. Example:
coffee -e -r ./snarl 'Hello!'
Contents of 'snarl.coffee' in the working directory:
http = require 'http'
CoffeeScript.on 'exception', (err) ->
client = http.createClient 9889, 'localhost'
request = client.request 'GET', '/?d={"action":1,"applicationName":"CoffeeScript","title":' + JSON.stringify(err.message) + ',"description":' + JSON.stringify(err.stack) + ',"priority":3}'
request.end()
err.handled = yes
To examine arguments available for each event (for debugging and getting started), use `puts JSON.stringify arguments`.
See http://nodejs.org/api.html#modules-309 and NODE_PATH for more details on how -r looks for files.
2010-08-07 17:24:37 +00:00
}
}
2010-02-17 04:59:32 +00:00
try {
2010-08-15 12:32:09 +00:00
t = ( task = {
file : file ,
input : input ,
options : options
} ) ;
CoffeeScript . emit ( 'compile' , task ) ;
2010-02-24 23:56:32 +00:00
if ( o . tokens ) {
2010-08-15 12:32:09 +00:00
return printTokens ( CoffeeScript . tokens ( t . input ) ) ;
2010-02-25 23:42:35 +00:00
} else if ( o . nodes ) {
2010-09-26 19:47:52 +00:00
return puts ( CoffeeScript . nodes ( t . input ) . toString ( ) . trim ( ) ) ;
2010-03-08 02:49:08 +00:00
} else if ( o . run ) {
2010-08-15 12:32:09 +00:00
return CoffeeScript . run ( t . input , t . options ) ;
2010-02-13 04:09:57 +00:00
} else {
2010-08-15 12:32:09 +00:00
t . output = CoffeeScript . compile ( t . input , t . options ) ;
2010-08-12 22:28:38 +00:00
CoffeeScript . emit ( 'success' , task ) ;
2010-10-02 00:52:23 +00:00
return o . print ? print ( t . output ) : ( o . compile ? writeJs ( t . file , t . output , base ) : ( o . lint ? lint ( t . output ) : undefined ) ) ;
2010-02-13 04:09:57 +00:00
}
2010-02-17 04:59:32 +00:00
} catch ( err ) {
2010-08-12 22:28:38 +00:00
CoffeeScript . emit ( 'failure' , err , task ) ;
2010-08-08 03:33:35 +00:00
if ( CoffeeScript . listeners ( 'failure' ) . length ) {
2010-10-07 02:24:52 +00:00
return ;
2010-02-17 04:59:32 +00:00
}
2010-08-15 12:32:09 +00:00
if ( o . watch ) {
return puts ( err . message ) ;
Add command-line compiler hooks. To invoke, pass a file after -r and listen for any of these events: 'compile', 'success' and 'exception'. Example:
coffee -e -r ./snarl 'Hello!'
Contents of 'snarl.coffee' in the working directory:
http = require 'http'
CoffeeScript.on 'exception', (err) ->
client = http.createClient 9889, 'localhost'
request = client.request 'GET', '/?d={"action":1,"applicationName":"CoffeeScript","title":' + JSON.stringify(err.message) + ',"description":' + JSON.stringify(err.stack) + ',"priority":3}'
request.end()
err.handled = yes
To examine arguments available for each event (for debugging and getting started), use `puts JSON.stringify arguments`.
See http://nodejs.org/api.html#modules-309 and NODE_PATH for more details on how -r looks for files.
2010-08-07 17:24:37 +00:00
}
2010-08-15 12:32:09 +00:00
error ( err . stack ) ;
return process . exit ( 1 ) ;
2010-02-17 04:59:32 +00:00
}
} ;
2010-06-12 23:05:13 +00:00
compileStdio = function ( ) {
2010-04-10 22:05:35 +00:00
var code , stdin ;
2010-02-24 23:18:29 +00:00
code = '' ;
2010-04-10 22:05:35 +00:00
stdin = process . openStdin ( ) ;
2010-07-18 11:54:44 +00:00
stdin . on ( 'data' , function ( buffer ) {
2010-10-02 00:52:23 +00:00
return buffer ? code += buffer . toString ( ) : undefined ;
2010-02-24 23:18:29 +00:00
} ) ;
2010-07-18 11:54:44 +00:00
return stdin . on ( 'end' , function ( ) {
2010-06-12 23:05:13 +00:00
return compileScript ( 'stdio' , code ) ;
2010-02-24 23:18:29 +00:00
} ) ;
} ;
2010-05-15 03:40:04 +00:00
watch = function ( source , base ) {
2010-05-03 21:38:59 +00:00
return fs . watchFile ( source , {
persistent : true ,
interval : 500
} , function ( curr , prev ) {
2010-09-09 01:08:17 +00:00
if ( curr . size === prev . size && curr . mtime . getTime ( ) === prev . mtime . getTime ( ) ) {
2010-10-07 02:24:52 +00:00
return ;
2010-05-03 21:38:59 +00:00
}
return fs . readFile ( source , function ( err , code ) {
2010-09-09 00:55:34 +00:00
if ( err ) {
throw err ;
}
2010-06-12 23:05:13 +00:00
return compileScript ( source , code . toString ( ) , base ) ;
2010-02-22 00:59:27 +00:00
} ) ;
2010-05-03 21:38:59 +00:00
} ) ;
2010-02-11 06:57:33 +00:00
} ;
2010-06-12 23:05:13 +00:00
writeJs = function ( source , js , base ) {
var baseDir , compile , dir , filename , jsPath , srcDir ;
2010-02-13 03:59:21 +00:00
filename = path . basename ( source , path . extname ( source ) ) + '.js' ;
2010-06-12 23:05:13 +00:00
srcDir = path . dirname ( source ) ;
baseDir = srcDir . substring ( base . length ) ;
2010-08-15 12:32:09 +00:00
dir = opts . output ? path . join ( opts . output , baseDir ) : srcDir ;
2010-06-12 23:05:13 +00:00
jsPath = path . join ( dir , filename ) ;
2010-05-15 03:40:04 +00:00
compile = function ( ) {
2010-08-05 03:42:46 +00:00
if ( js . length <= 0 ) {
js = ' ' ;
2010-08-05 01:36:03 +00:00
}
2010-06-13 18:21:02 +00:00
return fs . writeFile ( jsPath , js , function ( err ) {
2010-10-04 12:50:50 +00:00
return opts . compile && opts . watch ? puts ( "Compiled " + source ) : undefined ;
2010-06-13 18:21:02 +00:00
} ) ;
2010-05-05 03:22:28 +00:00
} ;
return path . exists ( dir , function ( exists ) {
2010-10-04 12:50:50 +00:00
return exists ? compile ( ) : exec ( "mkdir -p " + dir , compile ) ;
2010-05-03 21:38:59 +00:00
} ) ;
2010-02-13 03:59:21 +00:00
} ;
2010-05-15 03:40:04 +00:00
lint = function ( js ) {
2010-08-14 20:02:01 +00:00
var conf , jsl , printIt ;
2010-06-12 23:05:13 +00:00
printIt = function ( buffer ) {
2010-08-14 20:02:01 +00:00
return puts ( buffer . toString ( ) . trim ( ) ) ;
2010-04-10 22:05:35 +00:00
} ;
2010-08-14 20:02:01 +00:00
conf = _ _dirname + '/../extras/jsl.conf' ;
jsl = spawn ( 'jsl' , [ '-nologo' , '-stdin' , '-conf' , conf ] ) ;
2010-07-18 11:54:44 +00:00
jsl . stdout . on ( 'data' , printIt ) ;
jsl . stderr . on ( 'data' , printIt ) ;
2010-04-10 22:05:35 +00:00
jsl . stdin . write ( js ) ;
return jsl . stdin . end ( ) ;
2010-02-13 04:09:57 +00:00
} ;
2010-06-12 23:05:13 +00:00
printTokens = function ( tokens ) {
2010-10-01 22:26:37 +00:00
var _i , _len , _ref2 , _result , strings , tag , token , value ;
2010-02-24 23:56:32 +00:00
strings = ( function ( ) {
2010-10-01 22:26:37 +00:00
_result = [ ] ;
for ( _i = 0 , _len = tokens . length ; _i < _len ; _i ++ ) {
token = tokens [ _i ] ;
2010-09-19 12:29:15 +00:00
_result . push ( ( function ( ) {
2010-10-01 22:26:37 +00:00
_ref2 = [ token [ 0 ] , token [ 1 ] . toString ( ) . replace ( /\n/ , '\\n' ) ] , tag = _ref2 [ 0 ] , value = _ref2 [ 1 ] ;
2010-10-04 12:50:50 +00:00
return "[" + tag + " " + value + "]" ;
2010-04-10 18:40:05 +00:00
} ) ( ) ) ;
2010-02-24 23:56:32 +00:00
}
2010-09-19 12:29:15 +00:00
return _result ;
2010-04-10 18:40:05 +00:00
} ) ( ) ;
2010-02-24 23:56:32 +00:00
return puts ( strings . join ( ' ' ) ) ;
} ;
2010-06-12 23:05:13 +00:00
parseOptions = function ( ) {
2010-03-08 02:49:08 +00:00
var o ;
2010-08-21 23:16:02 +00:00
optionParser = new optparse . OptionParser ( SWITCHES , BANNER ) ;
2010-08-15 12:32:09 +00:00
o = ( opts = optionParser . parse ( process . argv . slice ( 2 , process . argv . length ) ) ) ;
2010-10-01 22:17:35 +00:00
o . compile || ( o . compile = ! ! o . output ) ;
2010-08-15 12:32:09 +00:00
o . run = ! ( o . compile || o . print || o . lint ) ;
o . print = ! ! ( o . print || ( o . eval || o . stdio && o . compile ) ) ;
return ( sources = o . arguments ) ;
2010-02-11 06:57:33 +00:00
} ;
2010-07-31 00:37:12 +00:00
compileOptions = function ( fileName ) {
2010-03-08 03:08:24 +00:00
var o ;
o = {
2010-07-31 00:37:12 +00:00
fileName : fileName
2010-03-08 03:08:24 +00:00
} ;
2010-08-15 12:32:09 +00:00
o . noWrap = opts [ 'no-wrap' ] ;
2010-03-08 03:08:24 +00:00
return o ;
2010-02-24 23:18:29 +00:00
} ;
2010-05-15 03:40:04 +00:00
usage = function ( ) {
2010-06-12 23:05:13 +00:00
puts ( optionParser . help ( ) ) ;
2010-03-07 05:28:58 +00:00
return process . exit ( 0 ) ;
} ;
2010-05-15 03:40:04 +00:00
version = function ( ) {
2010-08-14 21:25:29 +00:00
puts ( "CoffeeScript version " + ( CoffeeScript . VERSION ) ) ;
2010-03-07 05:28:58 +00:00
return process . exit ( 0 ) ;
} ;
2010-09-21 07:53:58 +00:00
} ) . call ( this ) ;