🚀 Big News: Socket Acquires Coana to Bring Reachability Analysis to Every Appsec Team.Learn more
Socket
Book a DemoInstallSign in
Socket

dreamopt

Package Overview
Dependencies
Maintainers
1
Versions
5
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

dreamopt - npm Package Compare versions

Comparing version

to
0.8.0

1

examples/date.js

@@ -0,1 +1,2 @@

// Generated by IcedCoffeeScript 1.3.1c
(function() {

@@ -2,0 +3,0 @@ var options, _ref;

@@ -0,1 +1,2 @@

// Generated by IcedCoffeeScript 1.3.1c
(function() {

@@ -2,0 +3,0 @@ var options;

500

lib/dreamopt.js
// 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, Syntax, TEXT, USAGE, alignment, formatUsageString, handleUsage, indent, parse, printUsage, separator, width, wordwrap, wrapText,
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;

@@ -14,11 +14,11 @@

COMMAND = /^\s+(\w+)(?:\s{2,}(\S.*))$/;
COMMAND = /^\s+([\w.-]+)(?:\s{2,}(.*))?$/;
ARGUMENT = /^\s+.*\s\s|^\s+\S+$/;
TEXT = /^\S/;
ARGUMENT = /^\s+(?:[A-Z._-][A-Z0-9._-]+|<[^\s>]+>)(?:\s\s|$)/;
OPTION_DESC = /^(.*?)\s{2,}(.*)$/;
OPTION_METAVARS = /^([^\s,]+(?:,\s*\S+)?)\s+([^,].*)$/;
OPTION_METAVARS = /^([^\s,]+(?:,\s*\S+)?)((?:\s(?:[A-Z._-][A-Z0-9._-]+|<[^\s>]+>))*)$/;

@@ -37,2 +37,11 @@ OPTION_SHORT = /^(-\S)(?:,\s*(.*))?$/;

SUBSUBSUB = ['command', 'subcommand', 'subsubcommand', 'subsubsubcommand'];
createError = function(message) {
var e;
e = new Error(message);
e.isCommandLineError = true;
return e;
};
DefaultHandlers = {

@@ -56,3 +65,3 @@ auto: function(value) {

if (isNaN(parseInt(value, 10))) {
throw new Error("Integer value required: " + value);
throw createError("Integer value required: " + value);
}

@@ -110,6 +119,32 @@ return parseInt(value, 10);

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 $, tag, value, _i, _len, _ref;
var $, name, tag, value, _i, _len, _ref;
this.shortOpt = shortOpt;

@@ -127,4 +162,15 @@ this.longOpt = longOpt;

}
this.name = cleanUpMetaVarName(this.name);
}
this["var"] = 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 = {};

@@ -148,3 +194,3 @@ this.tagsOrder = [];

Option.prototype.leftUsageComponent = function() {
var longOpt, string;
var longOpt, mv, string;
longOpt = this.longOpt;

@@ -167,3 +213,12 @@ if (longOpt && this.tags.acceptsno) {

if (this.metavars) {
string = string + (string && ' ' || '') + this.metavars.join(' ');
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(' ');
}

@@ -208,2 +263,3 @@ return string;

this.func = null;
this.desc || (this.desc = this.syntax.usage.firstPreambleLine());
}

@@ -223,5 +279,153 @@

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) {
function Syntax(handlers, specs, parent, parentContext) {
this.handlers = handlers;

@@ -231,3 +435,5 @@ if (specs == null) {

}
this.usage = [];
this.parent = parent != null ? parent : null;
this.parentContext = parentContext != null ? parentContext : '';
this.usage = new Usage();
this.options = [];

@@ -237,13 +443,10 @@ this["arguments"] = [];

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 = {};
this.usageFound = false;
this.headerAdded = false;
this.implicitHeaders = {
options: "Options:",
"arguments": "Arguments:",
commands: "Commands:"
};
this.lastSectionType = 'none';
this.customHeaderAdded = false;
if (specs) {

@@ -254,18 +457,7 @@ this.add(specs);

Syntax.prototype.addHeader = function(header) {
this.usage.push("\n" + header);
return this.lastSectionType = 'any';
};
Syntax.prototype.ensureHeaderExists = function(sectionType) {
if (this.lastSectionType === 'any') {
return this.lastSectionType = sectionType;
} else if (this.lastSectionType !== sectionType) {
this.addHeader(this.implicitHeaders[sectionType]);
return this.lastSectionType = sectionType;
Syntax.prototype.add = function(specs, options) {
var $, command, desc, func, gotArray, gotFunction, name, option, spec, subspecs, subsyntax, _;
if (options == null) {
options = {};
}
};
Syntax.prototype.add = function(specs) {
var $, command, desc, gotArray, gotFunction, name, option, spec, subsyntax;
if (typeof specs !== 'object') {

@@ -286,6 +478,5 @@ specs = [specs];

if (spec.match(HEADER)) {
this.addHeader(spec);
this.usage.startSection('*', spec);
} else if (spec.match(USAGE)) {
this.usage.unshift("" + spec);
this.usageFound = true;
this.usage.add('usage', "" + spec);
} else if (spec.match(OPTION)) {

@@ -302,4 +493,3 @@ this.options.push((option = Option.parse(spec.trim())));

}
this.ensureHeaderExists('options');
this.usage.push(option.toUsageString());
this.usage.add('options', option.toUsageString());
} else if (!gotArray() && spec.match(ARGUMENT)) {

@@ -310,16 +500,25 @@ this["arguments"].push((option = Option.parse(spec.trim())));

}
this.ensureHeaderExists('arguments');
this.usage.push(option.toUsageString());
this.usage.add('arguments', option.toUsageString());
} else if ($ = spec.match(COMMAND)) {
name = $[0], desc = $[1];
if (!gotArray()) {
_ = $[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, specs.shift());
this.commands[name] = command = new Command(name, desc, subsyntax);
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.ensureHeaderExists('commands');
this.usage.push(command.toUsageString());
this.usage.add('commands', command.toUsageString());
} else if (spec.trim() === '') {
this.usage.endSection();
} else if (spec.match(TEXT)) {
this.usage.push("\n" + wrapText(spec.trim()));
this.usage.add('text', "\n" + wrapText(spec.trim()));
} else {

@@ -332,18 +531,14 @@ throw new Error("String spec invalid: " + (JSON.stringify(spec)));

Syntax.prototype.filteredUsages = function() {
var _ref;
return [this.usage.filtered()].concat(((_ref = this.parent) != null ? _ref.filteredUsages() : void 0) || []);
};
Syntax.prototype.toUsageString = function() {
var line;
return ((function() {
var _i, _len, _ref, _results;
_ref = this.usage;
_results = [];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
line = _ref[_i];
_results.push(line + "\n");
}
return _results;
}).call(this)).join('');
var _ref;
return Usage.toUsageString([this.usage].concat(((_ref = this.parent) != null ? _ref.filteredUsages() : void 0) || []));
};
Syntax.prototype.parse = function(argv) {
var $, arg, assignValue, executeHook, func, funcs, index, name, option, positional, processOption, remainder, result, subarg, value, _, _i, _j, _k, _l, _len, _len1, _len2, _len3, _ref, _ref1, _ref2,
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;

@@ -354,2 +549,4 @@ argv = argv.slice(0);

funcs = [];
commands = [];
syntax = this;
executeHook = function(option, value) {

@@ -361,3 +558,3 @@ var newValue;

} else {
newValue = option.func(value, result, _this, option);
newValue = option.func(value, result, syntax, option);
if (newValue != null) {

@@ -381,3 +578,3 @@ value = newValue;

if (typeof value === 'undefined') {
throw new Error("Option " + arg + " requires an argument: " + (option.leftUsageComponent()));
throw createError("Option " + arg + " requires an argument: " + (option.leftUsageComponent()));
}

@@ -392,7 +589,7 @@ break;

if (typeof subvalue === 'undefined') {
throw new Error("Option " + arg + " requires " + option.metavars.length + " arguments: " + (option.leftUsageComponent()));
throw createError("Option " + arg + " requires " + option.metavars.length + " arguments: " + (option.leftUsageComponent()));
}
}
}
return option.coerce(value, result, _this);
return option.coerce(value, result, syntax);
};

@@ -418,7 +615,7 @@ assignValue = function(result, option, value) {

positional.push(arg);
} else if (arg.match(/^--no-/) && (option = this.lookupLongOption(arg.slice(5), result)) && option.tags.flag) {
} 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 = this.lookupLongOption(name, result)) {
if (option = syntax.lookupLongOption(name, result)) {
value = processOption(result, arg, option, value);

@@ -428,3 +625,3 @@ value = executeHook(option, value);

} else {
throw new Error("Unknown long option: " + arg);
throw createError("Unknown long option: " + arg);
}

@@ -436,3 +633,3 @@ } else if (arg.match(/^-/)) {

remainder = remainder.slice(1);
if (option = this.lookupShortOption(subarg, result)) {
if (option = syntax.lookupShortOption(subarg, result)) {
if (remainder && option.metavars.length > 0) {

@@ -449,8 +646,25 @@ value = remainder;

if (arg === ("-" + subarg)) {
throw new Error("Unknown short option " + arg);
throw createError("Unknown short option " + arg);
} else {
throw new Error("Unknown short option -" + subarg + " in " + arg);
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 {

@@ -460,3 +674,10 @@ positional.push(arg);

}
_ref = this.options;
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++) {

@@ -466,7 +687,7 @@ option = _ref[_i];

if (option.tags.required) {
throw new Error("Missing required option: " + (option.leftUsageComponent()));
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, this);
value = option.coerce(option.defaultValue, result, syntax);
} else {

@@ -480,6 +701,7 @@ value = null;

}
allArguments = syntax.allArguments();
for (index = _j = 0, _len1 = positional.length; _j < _len1; index = ++_j) {
arg = positional[index];
if (option = this["arguments"][index]) {
value = option.coerce(arg, result, this);
if (option = allArguments[index]) {
value = option.coerce(arg, result, syntax);
value = executeHook(option, value);

@@ -492,12 +714,11 @@ positional[index] = value;

}
_ref1 = this["arguments"];
for (index = _k = 0, _len2 = _ref1.length; _k < _len2; index = ++_k) {
option = _ref1[index];
for (index = _k = 0, _len2 = allArguments.length; _k < _len2; index = ++_k) {
option = allArguments[index];
if (index >= positional.length) {
if (option.tags.required) {
throw new Error("Missing required argument \#" + (index + 1) + ": " + (option.leftUsageComponent()));
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, this);
value = option.coerce(option.defaultValue, result, syntax);
} else {

@@ -520,5 +741,11 @@ value = null;

for (_l = 0, _len3 = funcs.length; _l < _len3; _l++) {
_ref2 = funcs[_l], func = _ref2[0], option = _ref2[1], value = _ref2[2];
func(value, result, this, option);
_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;

@@ -528,4 +755,7 @@ };

Syntax.prototype.lookupLongOption = function(name, result) {
var _base;
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") {

@@ -543,4 +773,7 @@ _base.resolveLongOption(name, result, this);

Syntax.prototype.lookupShortOption = function(name, result) {
var _base;
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") {

@@ -557,2 +790,33 @@ _base.resolveShortOption(name, result, this);

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;

@@ -573,3 +837,3 @@

}
metavars = metavars && metavars.split(/\s+/) || [];
metavars = metavars && metavars.trim() && metavars.trim().split(/\s+/) || [];
tags = ((function() {

@@ -607,33 +871,47 @@ var _results;

printUsage = function(usage) {
console.error(usage);
return process.exit(1);
};
handleUsage = function(printUsage, value, options, syntax) {
return printUsage(syntax.toUsageString());
};
parse = function(specs, handlers, argv) {
var syntax;
if (!(argv != null) && (handlers instanceof Array)) {
argv = handlers;
handlers = {};
parse = function(specs, options) {
var syntax, _ref, _ref1, _ref2, _ref3, _ref4;
if (options == null) {
options = {};
}
if (handlers == null) {
handlers = {};
if ((_ref = options.handlers) == null) {
options.handlers = {};
}
if (argv == null) {
argv = process.argv.slice(2);
if ((_ref1 = options.argv) == null) {
options.argv = process.argv.slice(2);
}
syntax = new Syntax(handlers, specs);
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, s) {
var _ref;
return handleUsage((_ref = handlers.printUsage) != null ? _ref : printUsage, v, o, s);
" -h, --help Display this usage information", function(v, o, syntax) {
return options.help(syntax.toUsageString());
}
]);
}
return syntax.parse(argv);
try {
return syntax.parse(options.argv, options);
} catch (e) {
if (e.isCommandLineError) {
return options.error(e);
} else {
throw e;
}
}
};

@@ -640,0 +918,0 @@

@@ -5,3 +5,3 @@ {

"description": "Command-line parser with readable syntax from your sweetest dreams",
"version": "0.7.0",
"version": "0.8.0",
"homepage": "https://github.com/andreyvit/dreamopt.js",

@@ -8,0 +8,0 @@ "repository": {

@@ -7,6 +7,6 @@ Command-Line Parser With Readable Syntax From Your Sweetest Dreams

options = require('dreamopt') [
"Usage: myscript [options] source [destination]"
"Usage: myscript [options] <source> [<destination>]"
" source Source file to compile into css #required"
" destination Destination file (defaults to source file with .css extension)", (value, options) ->
" <source> Source file to compile into css #required"
" <destination> Destination file (defaults to source file with .css extension)", (value, options) ->
if !value

@@ -65,2 +65,3 @@ return options.source.replace(/\.mess/, '') + '.css'

* mandatory and optional arguments/options
* commands, subcommands, subsubcommands, with command-specific options and per-command help/usage
* default values

@@ -86,3 +87,3 @@ * optional callback functions

options = require('dreamopt')(spec, [customTags], [argv])
options = require('dreamopt')(spec, [options])

@@ -92,8 +93,13 @@ where:

* `spec` is a required array of strings
* `customTags` is an optional hash with custom tag handlers
* `argv` is an optional array of arguments to use instead of `process.argv.slice(2)`
* `options` is an optional hash (i.e. a JavaScript object)
If you leave out `customTags` but specify `argv`, you don't need to include an empty argument: `require('dreamopt')(spec, argv)`.
The following options can be specified:
* `options.argv` is an array of command-line arguments, defaults to `process.argv.slice(2)`
* `options.customTags` is a hash with custom tag handlers
* `options.error(err)` is a function that handles syntax error, the default one prints `err.message` and exits
* `options.help(usage)` is a function that handles `--help`, the default one prints `usage` and exits
* `options.loadCommandSyntax(command)` is a function that returns the subcommand syntax for the given command
Specification format

@@ -106,6 +112,8 @@ --------------------

* `Something:` — a header, it is displayed verbatim with appropriate spacing; if you don't define any headers, dreamopt will add the default ones as needed (“Arguments:” and “Options:”)
* `-s, --long VALUE Description #tag1 #tag2(val2)` — option definition; must start with at least one space; if description or tags are specified, they must be separated from the option itself by at least two spaces; tags must be in the end and may have optional values
* `arg Description #tag1 #tag2` — positional argument definition, same format as options
* `-s, --long <value> Description #tag1 #tag2(val2)` — option definition; must start with at least one space; if description or tags are specified, they must be separated from the option itself by at least two spaces; tags must be in the end and may have optional values
* `-s, --long VALUE Description #tag1 #tag2(val2)` — can use `VALUE` instead of `<value>`
* `<arg> Description #tag1 #tag2` — positional argument definition, same format as options
* `ARG Description #tag1 #tag2` — can use `ARG` instead of `<arg>`
* after an option or an argument, you can include a function to be invoked when the option/argument is encountered
* `command Description` followed by an array — subcommand definition; these are not functional yet, but should be parsed properly
* `command Description` followed by a handler function (optional) and an array (required unless you provide `options.loadCommandSyntax`) — subcommand definition

@@ -115,2 +123,94 @@ Any other lines that don't start with whitespace are output verbatim, as a paragraph of text. (Lines that start with whitespace must conform to option, argument or subcommand syntax.)

Commands
--------
Syntax:
options = require('dreamopt') [
"Commands:"
" init Create a new repository in the current folder", []
" commit Commit the staged changes", []
"Common options:"
" -v, --verbose Print tons of useless info"
]
switch options.command
when 'init'
...
when 'commit'
...
You can specify a function to run for each command:
doInit = (options) ->
...
doCommit = (options) ->
...
options = require('dreamopt') [
"Commands:"
" init Create a new repository in the current folder", [], doInit
" commit Commit the staged changes", [], doCommit
]
Command-specific options and help:
INIT_SYNTAX = [
"Create a new repository in the current folder."
" -b, --bare Create a bare repository"
]
COMMIT_SYNTAX = [
"Commit the staged changes."
"Usage: git commit [options] [<file>...]"
" -a, --all Auto-add all changes"
"<file> The file to commit #list"
]
options = require('dreamopt') [
"Commands:"
" init", doInit, INIT_SYNTAX
" commit", doCommit, COMMIT_SYNTAX
"Common options:"
" -v, --verbose Print tons of useless info"
]
Modularizing your code:
# main.coffee:
options = require('dreamopt') [
"Commands:
" init"
" commit"
"Common options:"
" -v, --verbose Print tons of useless info"
], {
loadCommandSyntax: (command) -> require("./commands/#{command}").usage
}
require("./commands/#{options.command}").run(options)
# commands/commit.coffee:
exports.usage = [
"Commit the staged changes."
"Usage: git commit [options] [<file>...]"
" -a, --all Auto-add all changes"
"<file> The file to commit #list"
]
exports.run = (options) ->
...
Commands can be nested, which results in `options.command`, `options.subcommand`, `options.subsubcommand` etc; loadCommandSyntax is called with a space-separated command name for nested commands.
Coercion, validation and custom tags

@@ -166,7 +266,7 @@ ------------------------------------

Usage: myscript [options] source.mess [destination.css]
Usage: myscript [options] <source.mess> [<destination.css>]
Arguments:
source Source file to compile into css
destination Destination file (defaults to source file with .css extension)
<source> Source file to compile into css
<destination> Destination file (defaults to source file with .css extension)

@@ -185,2 +285,2 @@ Processing options:

You can provide `customTags.printUsage(usageText)` function to customize the way this usage info is printed; the default implementation outputs the argument via `console.error` and executes `process.exit(1)`.
You can provide `options.help(usageText)` function to customize the way this usage info is printed; the default implementation outputs the argument via `process.stdout.write` and executes `process.exit(0)`.

@@ -0,4 +1,5 @@

// Generated by CoffeeScript 1.3.3
(function() {
var assert, dreamopt, o, oo, ooo,
__hasProp = Object.prototype.hasOwnProperty;
var GIT_SYNTAX, assert, dreamopt, o, oo, ooo,
__hasProp = {}.hasOwnProperty;

@@ -9,2 +10,4 @@ assert = require('assert');

GIT_SYNTAX = [" remote", ["Manage set of tracked repositories.", " add", ["Adds a remote named <name> for the repository at <url>.", "Usage: git remote add <name> <url>", " <name> name of remote ref", " <url> repository url"], " rename", ["Rename the remote named <old> to <new>.", "Usage: git remote rename <old> <new>", " <old> old remote ref name", " <new> new remote ref name"], " rm", ["Remove the remote named <name>.", "Usage: git remote rm <name>", " <name> remote ref name"]], " push", ["Update remote refs along with associated objects.", "Usage: git push <repository> <refspec>", " <repository> The 'remote' repository that is destination of a push operation.", " <refspec> Used to specify with what <src> object the <dst> ref is to be updated."], "Global options:"];
o = function(syntax, argv, expected) {

@@ -16,3 +19,8 @@ expected.argv || (expected.argv = []);

before(function() {
return _actual = dreamopt(syntax, argv);
return _actual = dreamopt(syntax, {
argv: argv,
error: function(e) {
throw e;
}
});
});

@@ -30,3 +38,3 @@ _fn = function(k, v) {

return it("should not return any other option keys", function() {
var k, keys, v;
var keys;
keys = {};

@@ -55,3 +63,8 @@ for (k in _actual) {

try {
return _actual = dreamopt(syntax, argv);
return _actual = dreamopt(syntax, {
argv: argv,
error: function(e) {
throw e;
}
});
} catch (e) {

@@ -68,14 +81,36 @@ return _err = e;

ooo = function(syntax, expectedUsage) {
return it("should display correct usage info", function() {
var captureUsage, _usage;
_usage = null;
captureUsage = function(usage) {
return _usage = usage;
};
dreamopt(syntax, {
printUsage: captureUsage
}, ['--help']);
return assert.equal(_usage.trim(), expectedUsage.trim(), "Usage mismatch, actual:\n" + (_usage.trim()) + "\n\nExpected:\n" + (expectedUsage.trim()) + "\n");
});
ooo = function(syntax, expectedUsage, argv) {
var doit;
if (argv == null) {
argv = [];
}
doit = function() {
return it("should display correct usage info", function() {
var captureUsage, _usage;
_usage = null;
captureUsage = function(usage) {
_usage = usage;
throw new Error("bail out of captureUsage");
};
try {
dreamopt(syntax, {
argv: argv.concat(['--help']),
help: captureUsage,
error: function(e) {
throw e;
}
});
} catch (e) {
if (e.message !== "bail out of captureUsage") {
throw e;
}
}
return assert.equal(_usage.trim(), expectedUsage.trim(), "Usage mismatch, actual:\n" + (_usage.trim()) + "\n\nExpected:\n" + (expectedUsage.trim()) + "\n");
});
};
if (argv.length > 0) {
return describe("when given " + (argv.concat(['--help']).join(' ')), doit);
} else {
return doit();
}
};

@@ -86,3 +121,3 @@

var syntax;
syntax = [" -a, --AAA Simple option", " -b, --BBB COUNT Option with value", " -c, --[no-]ccc Flag option"];
syntax = [" -a, --AAA Simple option", " -b, --BBB COUNT Option with value", " -c, --[no-]ccc Flag option", " -d, --ddd <value> Another option with value"];
o(syntax, [''], {});

@@ -135,7 +170,7 @@ o(syntax, ['-a'], {

oo(syntax, ['--BBB'], /requires an argument/);
return ooo(syntax, "Options:\n -a, --AAA Simple option\n -b, --BBB COUNT Option with value\n -c, --[no-]ccc Flag option\n -h, --help Display this usage information");
return ooo(syntax, "Options:\n -a, --AAA Simple option\n -b, --BBB COUNT Option with value\n -c, --[no-]ccc Flag option\n -d, --ddd <value> Another option with value\n -h, --help Display this usage information");
});
describe("with a syntax that has two positional arguments and one option (-v/--verbose)", function() {
var syntax;
syntax = [" -v, --verbose Be verbose", " first First positional arg", " second Second positional arg"];
syntax = [" -v, --verbose Be verbose", " <first> First positional arg", " <second> Second positional arg"];
o(syntax, [], {});

@@ -173,3 +208,3 @@ o(syntax, ['-v'], {

var syntax;
syntax = [" first First positional arg (default: 10)", " second Second positional arg (default: 20)"];
syntax = [" FIRST First positional arg (default: 10)", " SECOND Second positional arg (default: 20)"];
o(syntax, [], {

@@ -193,3 +228,3 @@ argv: [10, 20],

var syntax;
syntax = [" first First positional arg #required", " second Second positional arg (default: 20)"];
syntax = [" <first> First positional arg #required", " <second> Second positional arg (default: 20)"];
oo(syntax, [], /required/);

@@ -209,3 +244,3 @@ o(syntax, ['foo'], {

var syntax;
syntax = [" --src FILE Source file #required", " first First positional arg"];
syntax = [" --src FILE Source file #required", " <first> First positional arg"];
oo(syntax, [], /required/);

@@ -228,3 +263,3 @@ oo(syntax, ['foo'], /required/);

});
return describe("with a syntax that has a list option", function() {
describe("with a syntax that has a list option", function() {
var syntax;

@@ -245,2 +280,71 @@ syntax = [" --src FILE Source file #list"];

});
describe("with a syntax that has two subcommands", function() {
var barHandler, syntax;
barHandler = function(result) {
return result.bbbar = 42;
};
syntax = [" foo Do something", [], " bar Do something else", barHandler, []];
oo(syntax, [], /no command specified/i);
o(syntax, ['foo'], {
argv: [],
command: 'foo'
});
return o(syntax, ['bar'], {
argv: [],
command: 'bar',
bbbar: 42
});
});
describe("with a syntax that has a subcommand with local options", function() {
var syntax;
syntax = [" foo Do something", [], " bar Do something else", [" --boz Enable boz"], " -v, --verbose Verbose"];
oo(syntax, [], /no command specified/i);
o(syntax, ['foo'], {
argv: [],
command: 'foo'
});
o(syntax, ['-v', 'foo'], {
argv: [],
command: 'foo',
verbose: true
});
o(syntax, ['foo', '-v'], {
argv: [],
command: 'foo',
verbose: true
});
oo(syntax, ['foo', '--boz'], /unknown long option/i);
o(syntax, ['bar'], {
argv: [],
command: 'bar'
});
o(syntax, ['bar', '--boz'], {
argv: [],
command: 'bar',
boz: true
});
o(syntax, ['-v', 'bar', '--boz'], {
argv: [],
command: 'bar',
boz: true,
verbose: true
});
return o(syntax, ['bar', '--boz', '-v'], {
argv: [],
command: 'bar',
boz: true,
verbose: true
});
});
return describe("with a git-style syntax", function() {
oo(GIT_SYNTAX, [], /no command specified/i);
o(GIT_SYNTAX, ['push'], {
argv: [],
command: 'push'
});
ooo(GIT_SYNTAX, "Commands:\n remote Manage set of tracked repositories.\n push Update remote refs along with associated objects.\n\nGlobal options:\n -h, --help Display this usage information");
ooo(GIT_SYNTAX, "Update remote refs along with associated objects.\n\nUsage: git push <repository> <refspec>\n\nArguments:\n <repository> The 'remote' repository that is destination of a push operation.\n <refspec> Used to specify with what <src> object the <dst> ref is to be updated.\n\nGlobal options:\n -h, --help Display this usage information", ['push']);
ooo(GIT_SYNTAX, "Manage set of tracked repositories.\n\nCommands:\n add Adds a remote named <name> for the repository at <url>.\n rename Rename the remote named <old> to <new>.\n rm Remove the remote named <name>.\n\nGlobal options:\n -h, --help Display this usage information", ['remote']);
return ooo(GIT_SYNTAX, "Adds a remote named <name> for the repository at <url>.\n\nUsage: git remote add <name> <url>\n\nArguments:\n <name> name of remote ref\n <url> repository url\n\nGlobal options:\n -h, --help Display this usage information", ['remote', 'add']);
});
});

@@ -247,0 +351,0 @@

@@ -0,1 +1,2 @@

// Generated by IcedCoffeeScript 1.3.1c
(function() {

@@ -58,3 +59,3 @@ var assert, o, parseOptionSpec;

});
describe("metavar", function() {
describe("uppercase metavar", function() {
o("-c FILE", {

@@ -82,2 +83,25 @@ shortOpt: '-c',

});
describe("angular-bracketed metavar", function() {
o("-c <file>", {
shortOpt: '-c',
longOpt: null,
desc: "",
tags: {},
metavars: ['file']
});
o("--code <file>", {
shortOpt: null,
longOpt: '--code',
desc: "",
tags: {},
metavars: ['file']
});
return o("-c, --code <file>", {
shortOpt: '-c',
longOpt: '--code',
desc: "",
tags: {},
metavars: ['file']
});
});
describe("two metavars", function() {

@@ -98,2 +122,16 @@ o("-c SRC DST", {

});
o("--code SRC <dst>", {
shortOpt: null,
longOpt: '--code',
desc: "",
tags: {},
metavars: ['SRC', 'dst']
});
o("--code <src> <dst>", {
shortOpt: null,
longOpt: '--code',
desc: "",
tags: {},
metavars: ['src', 'dst']
});
return o("-c, --code SRC DST", {

@@ -230,3 +268,3 @@ shortOpt: '-c',

describe("positional argument", function() {
return o("srcfile Source file", {
o("SRCFILE Source file", {
shortOpt: null,

@@ -236,2 +274,9 @@ longOpt: null,

tags: {},
metavars: ['SRCFILE']
});
return o("<srcfile> Source file", {
shortOpt: null,
longOpt: null,
desc: "Source file",
tags: {},
metavars: ['srcfile']

@@ -238,0 +283,0 @@ });

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet