From aba8cb1b081d8220f1a2e24a4ecf1125fcd69b9c Mon Sep 17 00:00:00 2001 From: Jeremy Ashkenas Date: Wed, 24 Feb 2010 17:57:58 -0500 Subject: [PATCH] upgrading the optparse library to avoid having to register callbacks for each argument. It just returns a simple options hash. --- lib/command_line.js | 67 ++++++++--------------------------------- lib/optparse.js | 26 ++++++---------- src/command_line.coffee | 32 ++++++-------------- src/optparse.coffee | 19 ++++-------- 4 files changed, 37 insertions(+), 107 deletions(-) diff --git a/lib/command_line.js b/lib/command_line.js index 41787a99..61e7ffbb 100644 --- a/lib/command_line.js +++ b/lib/command_line.js @@ -13,14 +13,20 @@ exports.run = function run() { var flags, separator; parse_options(); + if (options.help) { + return usage(); + } + if (options.version) { + return version(); + } if (options.interactive) { return require('repl'); } if (options.eval) { - return compile_script('terminal', sources[0]); + return compile_script('unknown', sources[0]); } if (!(sources.length)) { - usage(); + return usage(); } separator = sources.indexOf('--'); flags = []; @@ -66,7 +72,7 @@ compile_script = function compile_script(source, code) { var js, o, opts; opts = options; - o = opts.no_wrap ? { + o = opts['no-wrap'] ? { no_wrap: true } : {}; try { @@ -145,57 +151,8 @@ }; // Use OptionParser for all the options. parse_options = function parse_options() { - var oparser, opts, paths; - opts = (options = {}); - oparser = (option_parser = new optparse.OptionParser(SWITCHES)); - oparser.banner = BANNER; - oparser.add('interactive', function() { - return opts.interactive = true; - }); - oparser.add('run', function() { - return opts.run = true; - }); - oparser.add('output', function(dir) { - return opts.output = dir; - }); - oparser.add('watch', function() { - return opts.watch = true; - }); - oparser.add('print', function() { - return opts.print = true; - }); - oparser.add('lint', function() { - return opts.lint = true; - }); - oparser.add('eval', function() { - return opts.eval = true; - }); - oparser.add('tokens', function() { - return opts.tokens = true; - }); - oparser.add('tree', function() { - return opts.tree = true; - }); - oparser.add('no-wrap', function() { - return opts.no_wrap = true; - }); - oparser.add('help', (function(__this) { - var __func = function() { - return usage(); - }; - return (function() { - return __func.apply(__this, arguments); - }); - })(this)); - oparser.add('version', (function(__this) { - var __func = function() { - return version(); - }; - return (function() { - return __func.apply(__this, arguments); - }); - })(this)); - paths = oparser.parse(process.ARGV); - return sources = paths.slice(2, paths.length); + option_parser = new optparse.OptionParser(SWITCHES, BANNER); + options = option_parser.parse(process.ARGV); + return sources = options.arguments.slice(2, options.arguments.length); }; })(); \ No newline at end of file diff --git a/lib/optparse.js b/lib/optparse.js index 911cfe49..987a9761 100755 --- a/lib/optparse.js +++ b/lib/optparse.js @@ -1,21 +1,19 @@ (function(){ var LONG_FLAG, OPTIONAL, SHORT_FLAG, build_rule, build_rules, op, spaces; // Create an OptionParser with a list of valid options. - op = (exports.OptionParser = function OptionParser(rules) { - this.banner = 'Usage: [Options]'; + op = (exports.OptionParser = function OptionParser(rules, banner) { + this.banner = banner || 'Usage: [Options]'; this.options_title = 'Available options:'; this.rules = build_rules(rules); - this.actions = {}; return this; }); - // Add a callback to fire when a particular option is encountered. - op.prototype.add = function add(value, callback) { - return this.actions[value] = callback; - }; // Parse the argument array, calling defined callbacks, returning the remaining non-option arguments. op.prototype.parse = function parse(args) { - var _a, _b, arg, callback, is_option, results, rule, value; - results = []; + var _a, _b, arg, is_option, options, rule; + arguments = Array.prototype.slice.call(arguments, 0); + options = { + arguments: [] + }; args = args.concat([]); while (((arg = args.shift()))) { is_option = false; @@ -23,20 +21,16 @@ for (_b = 0; _b < _a.length; _b++) { rule = _a[_b]; if (rule.letter === arg || rule.flag === arg) { - callback = this.actions[rule.name]; - value = rule.argument && args.shift(); - if (callback) { - callback(value); - } + options[rule.name] = rule.argument ? args.shift() : true; is_option = true; break; } } if (!(is_option)) { - results.push(arg); + options.arguments.push(arg); } } - return results; + return options; }; // Return the help text for this OptionParser, for --help and such. op.prototype.help = function help() { diff --git a/src/command_line.coffee b/src/command_line.coffee index 721411d7..1977d984 100644 --- a/src/command_line.coffee +++ b/src/command_line.coffee @@ -32,9 +32,11 @@ option_parser: null # The CommandLine handles all of the functionality of the `coffee` utility. exports.run: -> parse_options() - return require 'repl' if options.interactive - return compile_script 'terminal', sources[0] if options.eval - usage() unless sources.length + return usage() if options.help + return version() if options.version + return require 'repl' if options.interactive + return compile_script 'unknown', sources[0] if options.eval + return usage() unless sources.length separator: sources.indexOf '--' flags: [] if separator >= 0 @@ -67,7 +69,7 @@ compile_scripts: -> # requested options. Both compile_scripts and watch_scripts share this method. compile_script: (source, code) -> opts: options - o: if opts.no_wrap then {no_wrap: true} else {} + o: if opts['no-wrap'] then {no_wrap: true} else {} try if opts.tokens then coffee.print_tokens coffee.tokenize code else if opts.tree then puts coffee.tree(code).toString() @@ -108,23 +110,7 @@ lint: (js) -> # Use OptionParser for all the options. parse_options: -> - opts: options: {} - oparser: option_parser: new optparse.OptionParser SWITCHES - oparser.banner: BANNER - - oparser.add 'interactive', -> opts.interactive: true - oparser.add 'run', -> opts.run: true - oparser.add 'output', (dir) -> opts.output: dir - oparser.add 'watch', -> opts.watch: true - oparser.add 'print', -> opts.print: true - oparser.add 'lint', -> opts.lint: true - oparser.add 'eval', -> opts.eval: true - oparser.add 'tokens', -> opts.tokens: true - oparser.add 'tree', -> opts.tree: true - oparser.add 'no-wrap', -> opts.no_wrap: true - oparser.add 'help', => usage() - oparser.add 'version', => version() - - paths: oparser.parse(process.ARGV) - sources: paths[2...paths.length] + option_parser: new optparse.OptionParser SWITCHES, BANNER + options: option_parser.parse(process.ARGV) + sources: options.arguments[2...options.arguments.length] diff --git a/src/optparse.coffee b/src/optparse.coffee index c475f569..f424b2d9 100644 --- a/src/optparse.coffee +++ b/src/optparse.coffee @@ -1,30 +1,23 @@ # Create an OptionParser with a list of valid options. -op: exports.OptionParser: (rules) -> - @banner: 'Usage: [Options]' +op: exports.OptionParser: (rules, banner) -> + @banner: banner or 'Usage: [Options]' @options_title: 'Available options:' @rules: build_rules(rules) - @actions: {} this -# Add a callback to fire when a particular option is encountered. -op::add: (value, callback) -> - @actions[value]: callback - # Parse the argument array, calling defined callbacks, returning the remaining non-option arguments. op::parse: (args) -> - results: [] + options: {arguments: []} args: args.concat [] while (arg: args.shift()) is_option: false for rule in @rules if rule.letter is arg or rule.flag is arg - callback: @actions[rule.name] - value: rule.argument and args.shift() - callback(value) if callback + options[rule.name]: if rule.argument then args.shift() else true is_option: true break - results.push arg unless is_option - results + options.arguments.push arg unless is_option + options # Return the help text for this OptionParser, for --help and such. op::help: ->