Plato on Github
Report Home
node_modules/dreamopt/lib/dreamopt.js
Maintainability
57.56
Lines of code
890
Difficulty
156.63
Estimated Errors
12.36
Function weight
By Complexity
By SLOC
// Generated by CoffeeScript 1.3.3 (function() { var ARGUMENT, COMMAND, Command, DUMMY, DefaultHandlers, HEADER, OPTION, OPTION_BOOL, OPTION_DESC, OPTION_DESC_DEFAULT, OPTION_DESC_TAG, OPTION_LONG, OPTION_METAVARS, OPTION_SHORT, Option, SUBSUBSUB, Syntax, TEXT, USAGE, Usage, UsageSection, alignment, cleanUpMetaVarName, cleanUpNameForUsingAsVarName, createError, formatMetaVar, formatUsageString, indent, parse, separator, width, wordwrap, wrapText, __slice = [].slice; wordwrap = require('wordwrap'); USAGE = /^Usage:/; HEADER = /^[^-].*:$/; OPTION = /^\s+-/; COMMAND = /^\s+([\w.-]+)(?:\s{2,}(.*))?$/; TEXT = /^\S/; ARGUMENT = /^\s+(?:[A-Z._-][A-Z0-9._-]+|<[^\s>]+>)(?:\s\s|$)/; OPTION_DESC = /^(.*?)\s{2,}(.*)$/; OPTION_METAVARS = /^([^\s,]+(?:,\s*\S+)?)((?:\s(?:[A-Z._-][A-Z0-9._-]+|<[^\s>]+>))*)$/; OPTION_SHORT = /^(-\S)(?:,\s*(.*))?$/; OPTION_LONG = /^(--\S+)$/; OPTION_BOOL = /^--\[no-\](.*)$/; OPTION_DESC_TAG = /^(.*)\#(\w+)(?:\(([^()]*)\))?\s*$/; DUMMY = /\#/; OPTION_DESC_DEFAULT = /\((?:default:|default\s+is|defaults\s+to)\s+([^()]+)\)/i; SUBSUBSUB = ['command', 'subcommand', 'subsubcommand', 'subsubsubcommand']; createError = function(message) { var e; e = new Error(message); e.isCommandLineError = true; return e; }; DefaultHandlers = { auto: function(value) { if (typeof value !== 'string') { return value; } if (!isNaN(Number(value))) { return Number(value); } return value; }, string: function(value) { return value; }, int: function(value) { if (typeof value !== 'string') { return value; } if (isNaN(parseInt(value, 10))) { throw createError("Integer value required: " + value); } return parseInt(value, 10); }, flag: function(value, options, optionName, tagValue) { var _ref, _ref1; if (!(value != null)) { return true; } if (typeof value !== 'string') { return value; } if ((_ref = value.toLowerCase()) === '0' || _ref === 'false' || _ref === 'no' || _ref === 'off') { return false; } if ((_ref1 = value.toLowerCase()) === '' || _ref1 === '1' || _ref1 === 'true' || _ref1 === 'yes' || _ref1 === 'on') { return true; } throw new Error("Invalid flag value " + (JSON.stringify(value)) + " for option " + optionName); } }; alignment = 24; indent = " "; separator = " "; width = 100; wrapText = require('wordwrap')(width); formatUsageString = function(left, right) { var actualAlignment, descriptionWidth, firstLine, otherLines, overhead, padding, wrappedLineIndent, _ref; overhead = indent.length + separator.length; if (left.length < alignment - overhead) { padding = new Array(alignment - overhead - left.length + 1).join(' '); } else { padding = ''; } actualAlignment = overhead + left.length + padding.length; descriptionWidth = width - actualAlignment; wrappedLineIndent = new Array(actualAlignment + 1).join(' '); _ref = wordwrap(descriptionWidth)(right).trim().split('\n'), firstLine = _ref[0], otherLines = 2 <= _ref.length ? __slice.call(_ref, 1) : []; right = [firstLine].concat(otherLines.map(function(line) { return wrappedLineIndent + line; })).join("\n"); if (otherLines.length) { right += "\n"; } return " " + left + padding + " " + right; }; cleanUpMetaVarName = function(name) { var $; if ($ = name.match(/^<(.*)>$/)) { return $[1]; } else { return name; } }; formatMetaVar = function(metavar) { if (metavar === metavar.toUpperCase()) { return metavar; } else { return "<" + metavar + ">"; } }; cleanUpNameForUsingAsVarName = function(name, isOption) { if (!isOption) { if (name === name.toUpperCase()) { name = name.toLowerCase(); } } return name; }; Option = (function() { function Option(shortOpt, longOpt, desc, tagPairs, metavars, defaultValue) { var $, name, tag, value, _i, _len, _ref; this.shortOpt = shortOpt; this.longOpt = longOpt; this.desc = desc; this.metavars = metavars; this.defaultValue = defaultValue; if (this.longOpt || this.shortOpt) { this.name = this.longOpt && this.longOpt.slice(2) || this.shortOpt.slice(1); } else if (this.metavars.length) { this.name = this.metavars[0]; if ($ = this.name.match(/^\[(.*)\]$/)) { this.name = $[1]; } this.name = cleanUpMetaVarName(this.name); } this.metavars = (function() { var _i, _len, _ref, _results; _ref = this.metavars; _results = []; for (_i = 0, _len = _ref.length; _i < _len; _i++) { name = _ref[_i]; _results.push(cleanUpMetaVarName(name)); } return _results; }).call(this); this["var"] = cleanUpNameForUsingAsVarName(this.name, this.longOpt || this.shortOpt); this.tags = {}; this.tagsOrder = []; for (_i = 0, _len = tagPairs.length; _i < _len; _i++) { _ref = tagPairs[_i], tag = _ref[0], value = _ref[1]; this.tags[tag] = value; this.tagsOrder.push(tag); switch (tag) { case 'default': this.defaultValue = value; break; case 'var': this["var"] = value; } } this.func = null; } Option.prototype.leftUsageComponent = function() { var longOpt, mv, string; longOpt = this.longOpt; if (longOpt && this.tags.acceptsno) { longOpt = "--[no-]" + longOpt.slice(2); } string = (function() { switch (false) { case !(this.shortOpt && longOpt): return "" + this.shortOpt + ", " + longOpt; case !this.shortOpt: return this.shortOpt; case !this.longOpt: return " " + longOpt; default: return ''; } }).call(this); if (this.metavars) { string = string + (string && ' ' || '') + ((function() { var _i, _len, _ref, _results; _ref = this.metavars; _results = []; for (_i = 0, _len = _ref.length; _i < _len; _i++) { mv = _ref[_i]; _results.push(formatMetaVar(mv)); } return _results; }).call(this)).join(' '); } return string; }; Option.prototype.toUsageString = function() { return formatUsageString(this.leftUsageComponent(), this.desc); }; Option.prototype.coerce = function(value, options, syntax) { var any, handler, newValue, tag, _i, _len, _ref; any = false; _ref = this.tagsOrder; for (_i = 0, _len = _ref.length; _i < _len; _i++) { tag = _ref[_i]; if (handler = syntax.handlers[tag] || DefaultHandlers[tag]) { newValue = handler(value, options, this.leftUsageComponent(), this.tags[tag]); if (typeof newValue !== void 0) { value = newValue; } any = true; } } if (!any) { value = DefaultHandlers.auto(value, options, syntax, this.leftUsageComponent()); } return value; }; return Option; })(); Command = (function() { function Command(name, desc, syntax) { this.name = name; this.desc = desc; this.syntax = syntax; this.func = null; this.desc || (this.desc = this.syntax.usage.firstPreambleLine()); } Command.prototype.leftUsageComponent = function() { return this.name; }; Command.prototype.toUsageString = function() { return formatUsageString(this.leftUsageComponent(), this.desc); }; return Command; })(); UsageSection = (function() { function UsageSection(type, header) { this.type = type; this.header = header; this.lines = []; } UsageSection.prototype.toUsageString = function() { var line; return (this.header ? "" + this.header + "\n" : '') + ((function() { var _i, _len, _ref, _results; _ref = this.lines; _results = []; for (_i = 0, _len = _ref.length; _i < _len; _i++) { line = _ref[_i]; _results.push("" + line + "\n"); } return _results; }).call(this)).join(''); }; return UsageSection; })(); Usage = (function() { function Usage() { this.sections = []; this.lastSection = null; this.implicitHeaders = { preamble: "", text: "", options: "Options:", "arguments": "Arguments:", commands: "Commands:" }; this.startSectionType('preamble'); } Usage.prototype.startSection = function(type, header) { this.lastSection = new UsageSection(type, header); return this.sections.push(this.lastSection); }; Usage.prototype.endSection = function() { return this.lastSection = null; }; Usage.prototype.startSectionType = function(type) { var _ref, _ref1; if (((_ref = this.lastSection) != null ? _ref.type : void 0) === type) { return; } if (this.lastSection && (type === '*')) { return; } if (((_ref1 = this.lastSection) != null ? _ref1.type : void 0) === '*') { return this.lastSection.type = type; } else { return this.startSection(type, this.implicitHeaders[type]); } }; Usage.prototype.add = function(sectionType, line) { if ((sectionType === 'text') && (this.sections.length === 1) && (this.sections[0].lines.length === 0)) { sectionType = 'preamble'; } this.startSectionType(sectionType); return this.lastSection.lines.push(line); }; Usage.prototype.filtered = function() { var result, section; result = new Usage(); result.sections = (function() { var _i, _len, _ref, _ref1, _results; _ref = this.sections; _results = []; for (_i = 0, _len = _ref.length; _i < _len; _i++) { section = _ref[_i]; if (!((_ref1 = section.type) === 'preamble' || _ref1 === 'commands')) { _results.push(section); } } return _results; }).call(this); return result; }; Usage.prototype.firstPreambleLine = function() { return this.sections[0].lines[0] || ''; }; Usage.prototype.toUsageString = function() { var s, section, usageStrings; usageStrings = (function() { var _i, _len, _ref, _results; _ref = this.sections; _results = []; for (_i = 0, _len = _ref.length; _i < _len; _i++) { section = _ref[_i]; _results.push(section.toUsageString()); } return _results; }).call(this); return ((function() { var _i, _len, _results; _results = []; for (_i = 0, _len = usageStrings.length; _i < _len; _i++) { s = usageStrings[_i]; if (s) { _results.push(s); } } return _results; })()).join("\n"); }; Usage.toUsageString = function(usages) { var s, usage, usageStrings; usageStrings = (function() { var _i, _len, _results; _results = []; for (_i = 0, _len = usages.length; _i < _len; _i++) { usage = usages[_i]; _results.push(usage.toUsageString()); } return _results; })(); return ((function() { var _i, _len, _results; _results = []; for (_i = 0, _len = usageStrings.length; _i < _len; _i++) { s = usageStrings[_i]; if (s) { _results.push(s); } } return _results; })()).join("\n"); }; return Usage; })(); Syntax = (function() { function Syntax(handlers, specs, parent, parentContext) { this.handlers = handlers; if (specs == null) { specs = []; } this.parent = parent != null ? parent : null; this.parentContext = parentContext != null ? parentContext : ''; this.usage = new Usage(); this.options = []; this["arguments"] = []; this.commands = {}; this.commandsOrder = []; if (this.parent) { this.parentContexts = [this.parentContext].concat(this.parent.parentContexts); } else { this.parentContexts = []; } this.nestingLevel = (this.parent ? this.parent.nestingLevel + 1 : 0); this.shortOptions = {}; this.longOptions = {}; if (specs) { this.add(specs); } } Syntax.prototype.add = function(specs, options) { var $, command, desc, func, gotArray, gotFunction, name, option, spec, subspecs, subsyntax, _; if (options == null) { options = {}; } if (typeof specs !== 'object') { specs = [specs]; } specs = specs.slice(0); gotArray = function() { return (typeof specs[0] === 'object') && (specs[0] instanceof Array); }; gotFunction = function() { return typeof specs[0] === 'function'; }; while (spec = specs.shift()) { if (typeof spec !== 'string') { throw new Error("Expected string spec, found " + (typeof spec)); } if (spec.match(HEADER)) { this.usage.startSection('*', spec); } else if (spec.match(USAGE)) { this.usage.add('usage', "" + spec); } else if (spec.match(OPTION)) { this.options.push((option = Option.parse(spec.trim()))); if (option.shortOpt) { this.shortOptions[option.shortOpt.slice(1)] = option; } if (option.longOpt) { this.longOptions[option.longOpt.slice(2)] = option; } if (gotFunction()) { option.func = specs.shift(); } this.usage.add('options', option.toUsageString()); } else if (!gotArray() && spec.match(ARGUMENT)) { this["arguments"].push((option = Option.parse(spec.trim()))); if (gotFunction()) { option.func = specs.shift(); } this.usage.add('arguments', option.toUsageString()); } else if ($ = spec.match(COMMAND)) { _ = $[0], name = $[1], desc = $[2]; desc = (desc || '').trim(); func = gotFunction() ? specs.shift() : null; if (gotArray()) { subspecs = specs.shift(); } else if ((subspecs = typeof options.loadCommandSyntax === "function" ? options.loadCommandSyntax(this.parentContexts.concat([name]).join(' ')) : void 0)) { } else { throw new Error("Array must follow a command spec: " + (JSON.stringify(spec))); } subsyntax = new Syntax(this.handlers, [], this, name); subsyntax.add(subspecs, options); command = new Command(name, desc, subsyntax); command.func = func; this.commands[name] = command; this.commandsOrder.push(name); this.usage.add('commands', command.toUsageString()); } else if (spec.trim() === '') { this.usage.endSection(); } else if (spec.match(TEXT)) { this.usage.add('text', "\n" + wrapText(spec.trim())); } else { throw new Error("String spec invalid: " + (JSON.stringify(spec))); } } return this; }; Syntax.prototype.filteredUsages = function() { var _ref; return [this.usage.filtered()].concat(((_ref = this.parent) != null ? _ref.filteredUsages() : void 0) || []); }; Syntax.prototype.toUsageString = function() { var _ref; return Usage.toUsageString([this.usage].concat(((_ref = this.parent) != null ? _ref.filteredUsages() : void 0) || [])); }; Syntax.prototype.parse = function(argv, options) { var $, allArguments, arg, assignValue, c, command, commands, executeHook, func, funcs, index, key, name, option, positional, processOption, remainder, result, subarg, syntax, value, _, _i, _j, _k, _l, _len, _len1, _len2, _len3, _len4, _m, _ref, _ref1, _this = this; argv = argv.slice(0); result = {}; positional = []; funcs = []; commands = []; syntax = this; executeHook = function(option, value) { var newValue; if (option.func) { if (option.tags.delayfunc) { funcs.push([option.func, option, value]); } else { newValue = option.func(value, result, syntax, option); if (newValue != null) { value = newValue; } } } return value; }; processOption = function(result, arg, option, value) { var index, metavar, subvalue, _i, _len, _ref; switch (option.metavars.length) { case 0: value = true; break; case 1: if (value == null) { value = argv.shift(); } if (typeof value === 'undefined') { throw createError("Option " + arg + " requires an argument: " + (option.leftUsageComponent())); } break; default: value = []; _ref = option.metavars; for (index = _i = 0, _len = _ref.length; _i < _len; index = ++_i) { metavar = _ref[index]; value.push((subvalue = argv.shift())); if (typeof subvalue === 'undefined') { throw createError("Option " + arg + " requires " + option.metavars.length + " arguments: " + (option.leftUsageComponent())); } } } return option.coerce(value, result, syntax); }; assignValue = function(result, option, value) { if (option.tags.list) { if (!result.hasOwnProperty(option["var"])) { result[option["var"]] = []; } if (value != null) { return result[option["var"]].push(value); } } else { return result[option["var"]] = value; } }; while (arg = argv.shift()) { if (arg === '--') { while (arg = argv.shift()) { positional.push(arg); } } else if (arg === '-') { positional.push(arg); } else if (arg.match(/^--no-/) && (option = syntax.lookupLongOption(arg.slice(5), result)) && option.tags.flag) { assignValue(result, option, false); } else if ($ = arg.match(/^--([^=]+)(?:=(.*))?$/)) { _ = $[0], name = $[1], value = $[2]; if (option = syntax.lookupLongOption(name, result)) { value = processOption(result, arg, option, value); value = executeHook(option, value); assignValue(result, option, value); } else { throw createError("Unknown long option: " + arg); } } else if (arg.match(/^-/)) { remainder = arg.slice(1); while (remainder) { subarg = remainder[0]; remainder = remainder.slice(1); if (option = syntax.lookupShortOption(subarg, result)) { if (remainder && option.metavars.length > 0) { value = remainder; remainder = ''; } else { value = void 0; } value = processOption(result, arg, option, value); value = executeHook(option, value); assignValue(result, option, value); } else { if (arg === ("-" + subarg)) { throw createError("Unknown short option " + arg); } else { throw createError("Unknown short option -" + subarg + " in " + arg); } } } } else if ((positional.length === 0) && (command = syntax.lookupCommand(arg, result))) { commands.push(command); if (key = options.commandKeys[syntax.nestingLevel]) { result[key] = arg; } if (key = options.compoundCommandKey) { result[key] = ((function() { var _i, _len, _results; _results = []; for (_i = 0, _len = commands.length; _i < _len; _i++) { c = commands[_i]; _results.push(c.name); } return _results; })()).join(' '); } syntax = command.syntax; } else { positional.push(arg); } } if (syntax.commandsOrder.length > 0) { if (positional.length === 0) { throw createError("No " + SUBSUBSUB[syntax.nestingLevel] + " specified"); } else { throw createError("Unknown " + SUBSUBSUB[syntax.nestingLevel] + " '" + positional[0] + "'"); } } _ref = syntax.allOptions(); for (_i = 0, _len = _ref.length; _i < _len; _i++) { option = _ref[_i]; if (!result.hasOwnProperty(option["var"])) { if (option.tags.required) { throw createError("Missing required option: " + (option.leftUsageComponent())); } if ((option.defaultValue != null) || option.tags.fancydefault || option.tags.list) { if (option.defaultValue != null) { value = option.coerce(option.defaultValue, result, syntax); } else { value = null; } value = executeHook(option, value); assignValue(result, option, value); } } } allArguments = syntax.allArguments(); for (index = _j = 0, _len1 = positional.length; _j < _len1; index = ++_j) { arg = positional[index]; if (option = allArguments[index]) { value = option.coerce(arg, result, syntax); value = executeHook(option, value); positional[index] = value; if (option["var"]) { assignValue(result, option, value); } } } for (index = _k = 0, _len2 = allArguments.length; _k < _len2; index = ++_k) { option = allArguments[index]; if (index >= positional.length) { if (option.tags.required) { throw createError("Missing required argument \#" + (index + 1) + ": " + (option.leftUsageComponent())); } if ((option.defaultValue != null) || option.tags.fancydefault) { if (option.defaultValue != null) { value = option.coerce(option.defaultValue, result, syntax); } else { value = null; } value = executeHook(option, value); if (option["var"]) { assignValue(result, option, value); } if (index === positional.length) { positional.push(value); } else if (!option["var"] && !option.func) { throw new Error("Cannot apply default value to argument \#" + (index + 1) + " (" + (option.leftUsageComponent()) + ") because no #var is specified, no func is provided and previous arguments don't have default values"); } } } } result.argv = positional; for (_l = 0, _len3 = funcs.length; _l < _len3; _l++) { _ref1 = funcs[_l], func = _ref1[0], option = _ref1[1], value = _ref1[2]; func(value, result, syntax, option); } for (_m = 0, _len4 = commands.length; _m < _len4; _m++) { command = commands[_m]; if (typeof command.func === "function") { command.func(result); } } return result; }; Syntax.prototype.lookupLongOption = function(name, result) { var option, _base; if (!this.longOptions.hasOwnProperty(name)) { if (this.parent && (option = this.parent.lookupLongOption(name, result))) { return option; } if (typeof (_base = this.handlers).resolveLongOption === "function") { _base.resolveLongOption(name, result, this); } } if (this.longOptions.hasOwnProperty(name)) { return this.longOptions[name]; } else { return null; } }; Syntax.prototype.lookupShortOption = function(name, result) { var option, _base; if (!this.shortOptions.hasOwnProperty(name)) { if (this.parent && (option = this.parent.lookupShortOption(name, result))) { return option; } if (typeof (_base = this.handlers).resolveShortOption === "function") { _base.resolveShortOption(name, result, this); } } if (this.shortOptions.hasOwnProperty(name)) { return this.shortOptions[name]; } else { return null; } }; Syntax.prototype.lookupCommand = function(name, result) { var command, _base; if (!this.commands.hasOwnProperty(name)) { if (this.parent && (command = this.parent.lookupCommand(name, result))) { return command; } if (typeof (_base = this.handlers).resolveCommand === "function") { _base.resolveCommand(name, result, this); } } if (this.commands.hasOwnProperty(name)) { return this.commands[name]; } else { return null; } }; Syntax.prototype.allOptions = function() { var _ref; return (((_ref = this.parent) != null ? _ref.allOptions() : void 0) || []).concat(this.options); }; Syntax.prototype.allArguments = function() { var _ref; return (((_ref = this.parent) != null ? _ref.allArguments() : void 0) || []).concat(this["arguments"]); }; Syntax.prototype.allCommands = function() { return this.commandsOrder; }; return Syntax; })(); Option.parse = function(spec) { var $, defaultValue, desc, isOption, longOpt, metavars, options, shortOpt, tag, tags, value, _, _ref, _ref1, _ref2, _ref3, _ref4; isOption = (' ' + spec).match(OPTION); _ref = spec.match(OPTION_DESC) || [void 0, spec, ""], _ = _ref[0], options = _ref[1], desc = _ref[2]; if (isOption) { _ref1 = options.match(OPTION_METAVARS) || [void 0, options, ""], _ = _ref1[0], options = _ref1[1], metavars = _ref1[2]; _ref2 = options.match(OPTION_SHORT) || [void 0, "", options], _ = _ref2[0], shortOpt = _ref2[1], options = _ref2[2]; _ref3 = (options || '').match(OPTION_LONG) || [void 0, "", options], _ = _ref3[0], longOpt = _ref3[1], options = _ref3[2]; } else { _ref4 = [options, ""], metavars = _ref4[0], options = _ref4[1]; } metavars = metavars && metavars.trim() && metavars.trim().split(/\s+/) || []; tags = ((function() { var _results; _results = []; while ($ = desc.match(OPTION_DESC_TAG)) { _results.push(((_ = $[0], desc = $[1], tag = $[2], value = $[3], $), [tag, value != null ? value : true])); } return _results; })()); tags.reverse(); if (longOpt && longOpt.match(OPTION_BOOL)) { tags.push(['acceptsno', true]); longOpt = longOpt.replace('--[no-]', '--'); } if (isOption && metavars.length === 0) { tags.push(['flag', true]); } if ($ = desc.match(OPTION_DESC_DEFAULT)) { defaultValue = $[1]; if (defaultValue.match(/\s/)) { defaultValue = void 0; tags.push(['fancydefault', true]); } } if (options) { throw new Error("Invalid option spec format (cannot parse " + (JSON.stringify(options)) + "): " + (JSON.stringify(spec))); } if (isOption && !(shortOpt || longOpt)) { throw new Error("Invalid option spec format !(shortOpt || longOpt): " + (JSON.stringify(spec))); } return new Option(shortOpt || null, longOpt || null, desc.trim(), tags, metavars, defaultValue); }; parse = function(specs, options) { var syntax, _ref, _ref1, _ref2, _ref3, _ref4; if (options == null) { options = {}; } if ((_ref = options.handlers) == null) { options.handlers = {}; } if ((_ref1 = options.argv) == null) { options.argv = process.argv.slice(2); } if ((_ref2 = options.error) == null) { options.error = function(e) { process.stderr.write("" + (e.message.trim()) + ". Run with --help for help.\n"); return process.exit(10); }; } if ((_ref3 = options.help) == null) { options.help = function(text) { process.stdout.write(text.trim() + "\n"); return process.exit(0); }; } if ((_ref4 = options.commandKeys) == null) { options.commandKeys = ['command', 'subcommand', 'subsubcommand', 'subsubsubcommand']; } options.compoundCommandKey = null; syntax = new Syntax(options.handlers); syntax.add(specs, options); if (!syntax.longOptions.help) { syntax.add([ " -h, --help Display this usage information", function(v, o, syntax) { return options.help(syntax.toUsageString()); } ]); } try { return syntax.parse(options.argv, options); } catch (e) { if (e.isCommandLineError) { return options.error(e); } else { throw e; } } }; module.exports = parse; module.exports.parseOptionSpec = Option.parse; module.exports.Syntax = Syntax; }).call(this);