yargs
Advanced tools
Comparing version 1.3.3 to 2.1.1
110
index.js
@@ -24,3 +24,3 @@ var path = require('path'); | ||
if (!cwd) cwd = process.cwd(); | ||
self.$0 = process.argv | ||
@@ -35,3 +35,3 @@ .slice(0,2) | ||
; | ||
if (process.env._ != undefined && process.argv[1] == process.env._) { | ||
@@ -49,3 +49,3 @@ self.$0 = process.env._.replace( | ||
alias: {}, | ||
default: [], | ||
default: {}, | ||
requiresArg: [], | ||
@@ -59,3 +59,3 @@ count: [], | ||
self.resetOptions(); | ||
self.boolean = function (bools) { | ||
@@ -81,3 +81,3 @@ options.boolean.push.apply(options.boolean, [].concat(bools)); | ||
}; | ||
self.string = function (strings) { | ||
@@ -87,3 +87,3 @@ options.string.push.apply(options.string, [].concat(strings)); | ||
}; | ||
self.default = function (key, value) { | ||
@@ -100,3 +100,3 @@ if (typeof key === 'object') { | ||
}; | ||
self.alias = function (x, y) { | ||
@@ -118,3 +118,3 @@ if (typeof x === 'object') { | ||
}; | ||
var demanded = {}; | ||
@@ -140,3 +140,3 @@ self.demand = self.required = self.require = function (keys, msg) { | ||
} | ||
return self; | ||
@@ -168,7 +168,7 @@ }; | ||
} | ||
usage = msg; | ||
if (opts) self.options(opts); | ||
return self; | ||
@@ -199,6 +199,10 @@ }; | ||
} | ||
process.exit(1); | ||
if (exitProcess){ | ||
process.exit(1); | ||
}else{ | ||
throw new Error(msg); | ||
} | ||
} | ||
} | ||
var checks = []; | ||
@@ -224,7 +228,7 @@ self.check = function (f) { | ||
}; | ||
self.parse = function (args) { | ||
return parseArgs(args); | ||
}; | ||
self.option = self.options = function (key, opt) { | ||
@@ -247,3 +251,3 @@ if (typeof key === 'object') { | ||
} | ||
if (opt.boolean || opt.type === 'boolean') { | ||
@@ -285,3 +289,3 @@ self.boolean(key); | ||
}; | ||
self.showHelp = function (fn) { | ||
@@ -324,4 +328,14 @@ if (!fn) fn = console.error.bind(console); | ||
var exitProcess = true; | ||
self.exitProcess = function (enabled) { | ||
if (typeof enabled !== 'boolean') { | ||
enabled = true; | ||
} | ||
exitProcess = enabled; | ||
return self; | ||
}; | ||
self.help = function () { | ||
if (!self.parsed) parseArgs(processArgs); // run parser, if it has not already been executed. | ||
if (arguments.length > 0) { | ||
@@ -340,3 +354,3 @@ return self.addHelpOpt.apply(self, arguments); | ||
); | ||
var help = keys.length ? [ 'Options:' ] : []; | ||
@@ -391,11 +405,11 @@ | ||
})); | ||
var desclen = longest(Object.keys(descriptions).map(function (d) { | ||
var desclen = longest(Object.keys(descriptions).map(function (d) { | ||
return descriptions[d] || ''; | ||
})); | ||
keys.forEach(function (key) { | ||
var kswitch = switches[key]; | ||
var desc = descriptions[key] || ''; | ||
if (wrap) { | ||
@@ -406,13 +420,13 @@ desc = wordwrap(switchlen + 4, wrap)(desc) | ||
} | ||
var spadding = new Array( | ||
Math.max(switchlen - kswitch.length + 3, 0) | ||
).join(' '); | ||
var dpadding = new Array( | ||
Math.max(desclen - desc.length + 1, 0) | ||
).join(' '); | ||
var type = null; | ||
if (options.boolean[key]) type = '[boolean]'; | ||
@@ -422,7 +436,7 @@ if (options.count[key]) type = '[count]'; | ||
if (options.normalize[key]) type = '[string]'; | ||
if (!wrap && dpadding.length > 0) { | ||
desc += dpadding; | ||
} | ||
var prelude = ' ' + kswitch + spadding; | ||
@@ -440,5 +454,5 @@ var extra = [ | ||
].filter(Boolean).join(' '); | ||
var body = [ desc, extra ].filter(Boolean).join(' '); | ||
if (wrap) { | ||
@@ -448,3 +462,3 @@ var dlines = desc.split('\n'); | ||
+ (dlines.length === 1 ? prelude.length : 0) | ||
body = desc + (dlen + extra.length > wrap - 2 | ||
@@ -458,10 +472,10 @@ ? '\n' | ||
} | ||
help.push(prelude + body); | ||
}); | ||
if (keys.length) help.push(''); | ||
return help.join('\n'); | ||
}; | ||
Object.defineProperty(self, 'argv', { | ||
@@ -471,3 +485,3 @@ get : function () { return parseArgs(processArgs) }, | ||
}); | ||
function parseArgs (args) { | ||
@@ -485,7 +499,11 @@ var parsed = minimist(args, options), | ||
self.showHelp(console.log); | ||
process.exit(0); | ||
if (exitProcess){ | ||
process.exit(0); | ||
} | ||
} | ||
else if (key === versionOpt) { | ||
process.stdout.write(version); | ||
process.exit(0); | ||
if (exitProcess){ | ||
process.exit(0); | ||
} | ||
} | ||
@@ -520,7 +538,7 @@ }); | ||
else if (missingRequiredArgs.length > 1) { | ||
message = "Missing argument values: " + missingRequiredArgs.join(", "); | ||
var message = "Missing argument values: " + missingRequiredArgs.join(", "); | ||
fail(message); | ||
} | ||
} | ||
var missing = null; | ||
@@ -533,3 +551,3 @@ Object.keys(demanded).forEach(function (key) { | ||
}); | ||
if (missing) { | ||
@@ -636,6 +654,6 @@ var customMsgs = []; | ||
} | ||
return argv; | ||
} | ||
function longest (xs) { | ||
@@ -647,3 +665,3 @@ return Math.max.apply( | ||
} | ||
return self; | ||
@@ -658,6 +676,6 @@ }; | ||
var bs = path.normalize(base).split('/').slice(1); | ||
for (var i = 0; ds[i] && ds[i] == bs[i]; i++); | ||
ds.splice(0, i); bs.splice(0, i); | ||
var p = path.normalize( | ||
@@ -664,0 +682,0 @@ bs.map(function () { return '..' }).concat(ds).join('/') |
@@ -84,2 +84,7 @@ var path = require('path'); | ||
function setArg (key, val) { | ||
// handle parsing boolean arguments --foo=true --bar false. | ||
if (flags.bools[key] || (aliases[key] ? flags.bools[aliases[key]] : false)) { | ||
if (typeof val === 'string') val = val === 'true'; | ||
} | ||
if (/-/.test(key) && !(aliases[key] && aliases[key].length)) { | ||
@@ -97,14 +102,2 @@ var c = toCamelCase(key); | ||
if (flags.configs[key]) { | ||
try { | ||
var config = JSON.parse(fs.readFileSync(val, 'utf8')); | ||
Object.keys(config).forEach(function (key) { | ||
setArg(key, config[key]); | ||
}); | ||
} catch (ex) { | ||
console.error('Invalid JSON config file: ' + val); | ||
throw ex; | ||
} | ||
} | ||
setKey(argv, key.split('.'), value); | ||
@@ -134,2 +127,32 @@ | ||
// set args from config.json file, this should be | ||
// applied last so that defaults can be applied. | ||
function setConfig (argv) { | ||
var configLookup = {}; | ||
// expand defaults/aliases, in-case any happen to reference | ||
// the config.json file. | ||
applyDefaultsAndAliases(configLookup, aliases, defaults); | ||
Object.keys(flags.configs).forEach(function(configKey) { | ||
var configPath = argv[configKey] || configLookup[configKey]; | ||
if (configPath) { | ||
try { | ||
var config = JSON.parse(fs.readFileSync(configPath, 'utf8')); | ||
Object.keys(config).forEach(function (key) { | ||
// setting arguments via CLI takes precedence over | ||
// values within the config file. | ||
if (argv[key] === undefined) { | ||
delete argv[key]; | ||
setArg(key, config[key]); | ||
} | ||
}); | ||
} catch (ex) { | ||
console.error('Invalid JSON config file: ' + configPath); | ||
throw ex; | ||
} | ||
} | ||
}); | ||
} | ||
for (var i = 0; i < args.length; i++) { | ||
@@ -159,7 +182,7 @@ var arg = args[i]; | ||
else if (/^(true|false)$/.test(next)) { | ||
setArg(key, next === 'true'); | ||
setArg(key, next); | ||
i++; | ||
} | ||
else { | ||
setArg(key, true); | ||
setArg(key, defaultForType(guessType(key, flags))); | ||
} | ||
@@ -198,3 +221,3 @@ } | ||
else { | ||
setArg(letters[j], true); | ||
setArg(letters[j], defaultForType(guessType(letters[j], flags))); | ||
} | ||
@@ -212,7 +235,7 @@ } | ||
else if (args[i+1] && /true|false/.test(args[i+1])) { | ||
setArg(key, args[i+1] === 'true'); | ||
setArg(key, args[i+1]); | ||
i++; | ||
} | ||
else { | ||
setArg(key, true); | ||
setArg(key, defaultForType(guessType(key, flags))); | ||
} | ||
@@ -228,12 +251,5 @@ } | ||
Object.keys(defaults).forEach(function (key) { | ||
if (!hasKey(argv, key.split('.'))) { | ||
setKey(argv, key.split('.'), defaults[key]); | ||
setConfig(argv); | ||
applyDefaultsAndAliases(argv, aliases, defaults); | ||
(aliases[key] || []).forEach(function (x) { | ||
setKey(argv, x.split('.'), defaults[key]); | ||
}); | ||
} | ||
}); | ||
Object.keys(flags.counts).forEach(function (key) { | ||
@@ -254,2 +270,14 @@ setArg(key, defaults[key]); | ||
function applyDefaultsAndAliases(obj, aliases, defaults) { | ||
Object.keys(defaults).forEach(function (key) { | ||
if (!hasKey(obj, key.split('.'))) { | ||
setKey(obj, key.split('.'), defaults[key]); | ||
(aliases[key] || []).forEach(function (x) { | ||
setKey(obj, x.split('.'), defaults[key]); | ||
}); | ||
} | ||
}); | ||
} | ||
function hasKey (obj, keys) { | ||
@@ -272,3 +300,2 @@ var o = obj; | ||
var key = keys[keys.length - 1]; | ||
@@ -289,2 +316,21 @@ if (typeof value === 'function') { | ||
// return a default value, given the type of a flag., | ||
// e.g., key of type 'string' will default to '', rather than 'true'. | ||
function defaultForType (type) { | ||
var def = { | ||
boolean: true, | ||
string: '' | ||
}; | ||
return def[type]; | ||
} | ||
// given a flag, enforce a default type. | ||
function guessType (key, flags) { | ||
var type = 'boolean'; | ||
if (flags.strings && flags.strings[key]) type = 'string'; | ||
return type; | ||
} | ||
function isNumber (x) { | ||
@@ -291,0 +337,0 @@ if (typeof x === 'number') return true; |
@@ -50,2 +50,2 @@ // Simplified version of https://github.com/substack/node-wordwrap | ||
}; | ||
}; | ||
}; |
{ | ||
"name": "yargs", | ||
"version": "1.3.3", | ||
"version": "2.1.1", | ||
"description": "Light-weight option parsing with an argv hash. No optstrings attached.", | ||
"main": "./index.js", | ||
"files": [ | ||
"index.js", | ||
"lib", | ||
"LICENSE" | ||
], | ||
"dependencies": {}, | ||
"devDependencies": { | ||
"hashish": "*", | ||
"mocha": "*", | ||
"chai": "*" | ||
"blanket": "^1.1.6", | ||
"chai": "^1.10.0", | ||
"hashish": "0.0.4", | ||
"mocha": "^2.1.0", | ||
"mocoverage": "^1.0.0" | ||
}, | ||
"scripts": { | ||
"test": "mocha -R nyan" | ||
"test": "mocha --check-leaks --ui exports --require blanket -R mocoverage" | ||
}, | ||
@@ -19,2 +26,15 @@ "repository": { | ||
}, | ||
"config": { | ||
"blanket": { | ||
"pattern": [ | ||
"lib", | ||
"index.js" | ||
], | ||
"data-cover-never": [ | ||
"node_modules", | ||
"test" | ||
], | ||
"output-reporter": "spec" | ||
} | ||
}, | ||
"keywords": [ | ||
@@ -21,0 +41,0 @@ "argument", |
@@ -413,2 +413,4 @@ yargs | ||
.option(key, opt) | ||
----------------- | ||
.options(key, opt) | ||
@@ -424,3 +426,3 @@ ------------------ | ||
var argv = require('yargs') | ||
.options('f', { | ||
.option('f', { | ||
alias : 'file', | ||
@@ -579,2 +581,7 @@ default : '/etc/passwd', | ||
.exitProcess(enable) | ||
---------------------------------- | ||
By default, yargs exits the process when the user passes a help flag, uses the `.version` functionality or when validation fails. Calling `.exitProcess(false)` disables this behavior, enabling further actions after yargs have been validated. | ||
.parse(args) | ||
@@ -581,0 +588,0 @@ ------------ |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
Shell access
Supply chain riskThis module accesses the system shell. Accessing the system shell increases the risk of executing arbitrary code.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
689
4
49985
5
6
879
2