Socket
Socket
Sign inDemoInstall

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 0.7.0 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

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc