From b224d58a36321a42add61efa842466c632f53033 Mon Sep 17 00:00:00 2001 From: Jeremy Ashkenas Date: Sat, 13 Feb 2010 10:16:28 -0500 Subject: [PATCH] don't make the command-line so OOP-y -- it's just a script --- lib/coffee_script/command_line.js | 65 +++++++++++++++++-------------- src/command_line.coffee | 59 +++++++++++++++------------- 2 files changed, 67 insertions(+), 57 deletions(-) diff --git a/lib/coffee_script/command_line.js b/lib/coffee_script/command_line.js index 9304f69c..96a6648e 100644 --- a/lib/coffee_script/command_line.js +++ b/lib/coffee_script/command_line.js @@ -1,5 +1,5 @@ (function(){ - var BANNER, SWITCHES, WATCH_INTERVAL, coffee, optparse, path, posix; + var BANNER, SWITCHES, WATCH_INTERVAL, coffee, compile, compile_scripts, lint, option_parser, options, optparse, parse_options, path, posix, sources, tokenize, usage, version, write_js; posix = require('posix'); path = require('path'); coffee = require('coffee-script'); @@ -7,41 +7,46 @@ BANNER = "coffee compiles CoffeeScript source files into JavaScript.\n\nUsage:\n coffee path/to/script.coffee"; SWITCHES = [['-i', '--interactive', 'run an interactive CoffeeScript REPL'], ['-r', '--run', 'compile and run a CoffeeScript'], ['-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'], ['-e', '--eval', 'compile a cli scriptlet or read from stdin'], ['-t', '--tokens', 'print the tokens that the lexer produces'], ['--tree', 'print the parse tree that Jison produces'], ['-n', '--no-wrap', 'raw output, no function safety wrapper'], ['-g', '--globals', 'attach all top-level variables as globals'], ['-v', '--version', 'display CoffeeScript version'], ['-h', '--help', 'display this help message']]; WATCH_INTERVAL = 0.5; + options = {}; + sources = []; + option_parser = null; // The CommandLine handles all of the functionality of the `coffee` utility. exports.run = function run() { - this.parse_options(); - if (!(this.sources.length)) { - this.usage(); + parse_options(); + if (options.interactive) { + launch_repl(); } - this.compile_scripts(); + if (!(sources.length)) { + usage(); + } + compile_scripts(); return this; }; // The "--help" usage message. - exports.usage = function usage() { - puts('\n' + this.option_parser.toString() + '\n'); + usage = function usage() { + puts('\n' + option_parser.toString() + '\n'); return process.exit(0); }; // The "--version" message. - exports.version = function version() { + version = function version() { puts("CoffeeScript version " + coffee.VERSION); return process.exit(0); }; // Compile a single source file to JavaScript. - exports.compile = function compile(script, source) { - var options; + compile = function compile(script, source) { source = source || 'error'; options = {}; - if (this.options.no_wrap) { + if (options.no_wrap) { options.no_wrap = true; } - if (this.options.globals) { + if (options.globals) { options.globals = true; } try { return CoffeeScript.compile(script, options); } catch (error) { process.stdio.writeError(source + ': ' + error.toString()); - if (!(this.options.watch)) { + if (!(options.watch)) { process.exit(1); } return null; @@ -49,16 +54,16 @@ }; // Compiles the source CoffeeScript, returning the desired JavaScript, tokens, // or JSLint results. - exports.compile_scripts = function compile_scripts() { + compile_scripts = function compile_scripts() { var opts, source; - if (!((source = this.sources.shift()))) { + if (!((source = sources.shift()))) { return null; } - opts = this.options; + opts = options; return posix.cat(source).addCallback(function(code) { var js; if (opts.tokens) { - puts(exports.tokenize(code)); + puts(tokenize(code)); } else if (opts.tree) { puts(coffee.tree(code).toString()); } else { @@ -68,26 +73,26 @@ } else if (opts.print) { puts(js); } else if (opts.lint) { - exports.lint(js); + lint(js); } else { - exports.write_js(source, coffee.compile(code)); + write_js(source, coffee.compile(code)); } } - return exports.compile_scripts(); + return compile_scripts(); }); }; // Write out a JavaScript source file with the compiled code. - exports.write_js = function write_js(source, js) { + write_js = function write_js(source, js) { var dir, filename, js_path; filename = path.basename(source, path.extname(source)) + '.js'; - dir = this.options.output || path.dirname(source); + dir = options.output || path.dirname(source); js_path = path.join(dir, filename); return posix.open(js_path, process.O_CREAT | process.O_WRONLY | process.O_TRUNC, parseInt('0755', 8)).addCallback(function(fd) { return posix.write(fd, js); }); }; // Pretty-print the token stream. - exports.tokenize = function tokenize(code) { + tokenize = function tokenize(code) { var strings; strings = coffee.tokenize(code).map(function(token) { return '[' + token[0] + ' ' + token[1].toString().replace(/\n/, '\\n') + ']'; @@ -95,7 +100,7 @@ return strings.join(' '); }; // Pipe compiled JS through JSLint (requires a working 'jsl' command). - exports.lint = function lint(js) { + lint = function lint(js) { var jsl; jsl = process.createChildProcess('jsl', ['-nologo', '-stdin']); jsl.addListener('output', function(result) { @@ -112,10 +117,10 @@ return jsl.close(); }; // Use OptionParser for all the options. - exports.parse_options = function parse_options() { + parse_options = function parse_options() { var oparser, opts, paths; - opts = (this.options = {}); - oparser = (this.option_parser = new optparse.OptionParser(SWITCHES)); + opts = (options = {}); + oparser = (option_parser = new optparse.OptionParser(SWITCHES)); oparser.banner = BANNER; oparser.add = oparser['on']; oparser.add('interactive', function() { @@ -147,7 +152,7 @@ }); oparser.add('help', (function(__this) { var __func = function() { - return this.usage(); + return usage(); }; return (function() { return __func.apply(__this, arguments); @@ -155,13 +160,13 @@ })(this)); oparser.add('version', (function(__this) { var __func = function() { - return this.version(); + return version(); }; return (function() { return __func.apply(__this, arguments); }); })(this)); paths = oparser.parse(process.ARGV); - return this.sources = paths.slice(2, paths.length); + return sources = paths.slice(2, paths.length); }; })(); \ No newline at end of file diff --git a/src/command_line.coffee b/src/command_line.coffee index 11dc2466..1296c67f 100644 --- a/src/command_line.coffee +++ b/src/command_line.coffee @@ -28,68 +28,73 @@ SWITCHES: [ WATCH_INTERVAL: 0.5 +options: {} +sources: [] +option_parser: null + # The CommandLine handles all of the functionality of the `coffee` utility. exports.run: -> - @parse_options() - @usage() unless @sources.length - @compile_scripts() + parse_options() + launch_repl() if options.interactive + usage() unless sources.length + compile_scripts() this # The "--help" usage message. -exports.usage: -> - puts '\n' + @option_parser.toString() + '\n' +usage: -> + puts '\n' + option_parser.toString() + '\n' process.exit 0 # The "--version" message. -exports.version: -> +version: -> puts "CoffeeScript version " + coffee.VERSION process.exit 0 # Compile a single source file to JavaScript. -exports.compile: (script, source) -> +compile: (script, source) -> source ||= 'error' options: {} - options.no_wrap: true if @options.no_wrap - options.globals: true if @options.globals + options.no_wrap: true if options.no_wrap + options.globals: true if options.globals try CoffeeScript.compile(script, options) catch error process.stdio.writeError(source + ': ' + error.toString()) - process.exit 1 unless @options.watch + process.exit 1 unless options.watch null # Compiles the source CoffeeScript, returning the desired JavaScript, tokens, # or JSLint results. -exports.compile_scripts: -> - return unless source: @sources.shift() - opts: @options +compile_scripts: -> + return unless source: sources.shift() + opts: options posix.cat(source).addCallback (code) -> - if opts.tokens then puts exports.tokenize(code) + if opts.tokens then puts tokenize(code) else if opts.tree then puts coffee.tree(code).toString() else js: coffee.compile code if opts.run then eval js else if opts.print then puts js - else if opts.lint then exports.lint js - else exports.write_js source, coffee.compile code - exports.compile_scripts() + else if opts.lint then lint js + else write_js source, coffee.compile code + compile_scripts() # Write out a JavaScript source file with the compiled code. -exports.write_js: (source, js) -> +write_js: (source, js) -> filename: path.basename(source, path.extname(source)) + '.js' - dir: @options.output or path.dirname(source) + dir: options.output or path.dirname(source) js_path: path.join dir, filename posix.open(js_path, process.O_CREAT | process.O_WRONLY | process.O_TRUNC, parseInt('0755', 8)).addCallback (fd) -> posix.write(fd, js) # Pretty-print the token stream. -exports.tokenize: (code) -> +tokenize: (code) -> strings: coffee.tokenize(code).map (token) -> '[' + token[0] + ' ' + token[1].toString().replace(/\n/, '\\n') + ']' strings.join(' ') # Pipe compiled JS through JSLint (requires a working 'jsl' command). -exports.lint: (js) -> +lint: (js) -> jsl: process.createChildProcess('jsl', ['-nologo', '-stdin']) jsl.addListener 'output', (result) -> puts result.replace(/\n/g, '') if result @@ -99,9 +104,9 @@ exports.lint: (js) -> jsl.close() # Use OptionParser for all the options. -exports.parse_options: -> - opts: @options: {} - oparser: @option_parser: new optparse.OptionParser SWITCHES +parse_options: -> + opts: options: {} + oparser: option_parser: new optparse.OptionParser SWITCHES oparser.banner: BANNER oparser.add: oparser['on'] @@ -114,8 +119,8 @@ exports.parse_options: -> oparser.add 'eval', -> opts.eval: true oparser.add 'tokens', -> opts.tokens: true oparser.add 'tree', -> opts.tree: true - oparser.add 'help', => @usage() - oparser.add 'version', => @version() + oparser.add 'help', => usage() + oparser.add 'version', => version() paths: oparser.parse(process.ARGV) - @sources: paths[2...paths.length] + sources: paths[2...paths.length]