Index: tools/vulcanize/node_modules/vulcanize/node_modules/nopt/lib/nopt.js |
diff --git a/tools/vulcanize/node_modules/vulcanize/node_modules/nopt/lib/nopt.js b/tools/vulcanize/node_modules/vulcanize/node_modules/nopt/lib/nopt.js |
new file mode 100644 |
index 0000000000000000000000000000000000000000..20f3b5b1ddde7f25de09708b5e645c05f51a60b6 |
--- /dev/null |
+++ b/tools/vulcanize/node_modules/vulcanize/node_modules/nopt/lib/nopt.js |
@@ -0,0 +1,612 @@ |
+// info about each config option. |
+ |
+var debug = process.env.DEBUG_NOPT || process.env.NOPT_DEBUG |
+ ? function () { console.error.apply(console, arguments) } |
+ : function () {} |
+ |
+var url = require("url") |
+ , path = require("path") |
+ , Stream = require("stream").Stream |
+ , abbrev = require("abbrev") |
+ |
+module.exports = exports = nopt |
+exports.clean = clean |
+ |
+exports.typeDefs = |
+ { String : { type: String, validate: validateString } |
+ , Boolean : { type: Boolean, validate: validateBoolean } |
+ , url : { type: url, validate: validateUrl } |
+ , Number : { type: Number, validate: validateNumber } |
+ , path : { type: path, validate: validatePath } |
+ , Stream : { type: Stream, validate: validateStream } |
+ , Date : { type: Date, validate: validateDate } |
+ } |
+ |
+function nopt (types, shorthands, args, slice) { |
+ args = args || process.argv |
+ types = types || {} |
+ shorthands = shorthands || {} |
+ if (typeof slice !== "number") slice = 2 |
+ |
+ debug(types, shorthands, args, slice) |
+ |
+ args = args.slice(slice) |
+ var data = {} |
+ , key |
+ , remain = [] |
+ , cooked = args |
+ , original = args.slice(0) |
+ |
+ parse(args, data, remain, types, shorthands) |
+ // now data is full |
+ clean(data, types, exports.typeDefs) |
+ data.argv = {remain:remain,cooked:cooked,original:original} |
+ Object.defineProperty(data.argv, 'toString', { value: function () { |
+ return this.original.map(JSON.stringify).join(" ") |
+ }, enumerable: false }) |
+ return data |
+} |
+ |
+function clean (data, types, typeDefs) { |
+ typeDefs = typeDefs || exports.typeDefs |
+ var remove = {} |
+ , typeDefault = [false, true, null, String, Number, Array] |
+ |
+ Object.keys(data).forEach(function (k) { |
+ if (k === "argv") return |
+ var val = data[k] |
+ , isArray = Array.isArray(val) |
+ , type = types[k] |
+ if (!isArray) val = [val] |
+ if (!type) type = typeDefault |
+ if (type === Array) type = typeDefault.concat(Array) |
+ if (!Array.isArray(type)) type = [type] |
+ |
+ debug("val=%j", val) |
+ debug("types=", type) |
+ val = val.map(function (val) { |
+ // if it's an unknown value, then parse false/true/null/numbers/dates |
+ if (typeof val === "string") { |
+ debug("string %j", val) |
+ val = val.trim() |
+ if ((val === "null" && ~type.indexOf(null)) |
+ || (val === "true" && |
+ (~type.indexOf(true) || ~type.indexOf(Boolean))) |
+ || (val === "false" && |
+ (~type.indexOf(false) || ~type.indexOf(Boolean)))) { |
+ val = JSON.parse(val) |
+ debug("jsonable %j", val) |
+ } else if (~type.indexOf(Number) && !isNaN(val)) { |
+ debug("convert to number", val) |
+ val = +val |
+ } else if (~type.indexOf(Date) && !isNaN(Date.parse(val))) { |
+ debug("convert to date", val) |
+ val = new Date(val) |
+ } |
+ } |
+ |
+ if (!types.hasOwnProperty(k)) { |
+ return val |
+ } |
+ |
+ // allow `--no-blah` to set 'blah' to null if null is allowed |
+ if (val === false && ~type.indexOf(null) && |
+ !(~type.indexOf(false) || ~type.indexOf(Boolean))) { |
+ val = null |
+ } |
+ |
+ var d = {} |
+ d[k] = val |
+ debug("prevalidated val", d, val, types[k]) |
+ if (!validate(d, k, val, types[k], typeDefs)) { |
+ if (exports.invalidHandler) { |
+ exports.invalidHandler(k, val, types[k], data) |
+ } else if (exports.invalidHandler !== false) { |
+ debug("invalid: "+k+"="+val, types[k]) |
+ } |
+ return remove |
+ } |
+ debug("validated val", d, val, types[k]) |
+ return d[k] |
+ }).filter(function (val) { return val !== remove }) |
+ |
+ if (!val.length) delete data[k] |
+ else if (isArray) { |
+ debug(isArray, data[k], val) |
+ data[k] = val |
+ } else data[k] = val[0] |
+ |
+ debug("k=%s val=%j", k, val, data[k]) |
+ }) |
+} |
+ |
+function validateString (data, k, val) { |
+ data[k] = String(val) |
+} |
+ |
+function validatePath (data, k, val) { |
+ data[k] = path.resolve(String(val)) |
+ return true |
+} |
+ |
+function validateNumber (data, k, val) { |
+ debug("validate Number %j %j %j", k, val, isNaN(val)) |
+ if (isNaN(val)) return false |
+ data[k] = +val |
+} |
+ |
+function validateDate (data, k, val) { |
+ debug("validate Date %j %j %j", k, val, Date.parse(val)) |
+ var s = Date.parse(val) |
+ if (isNaN(s)) return false |
+ data[k] = new Date(val) |
+} |
+ |
+function validateBoolean (data, k, val) { |
+ if (val instanceof Boolean) val = val.valueOf() |
+ else if (typeof val === "string") { |
+ if (!isNaN(val)) val = !!(+val) |
+ else if (val === "null" || val === "false") val = false |
+ else val = true |
+ } else val = !!val |
+ data[k] = val |
+} |
+ |
+function validateUrl (data, k, val) { |
+ val = url.parse(String(val)) |
+ if (!val.host) return false |
+ data[k] = val.href |
+} |
+ |
+function validateStream (data, k, val) { |
+ if (!(val instanceof Stream)) return false |
+ data[k] = val |
+} |
+ |
+function validate (data, k, val, type, typeDefs) { |
+ // arrays are lists of types. |
+ if (Array.isArray(type)) { |
+ for (var i = 0, l = type.length; i < l; i ++) { |
+ if (type[i] === Array) continue |
+ if (validate(data, k, val, type[i], typeDefs)) return true |
+ } |
+ delete data[k] |
+ return false |
+ } |
+ |
+ // an array of anything? |
+ if (type === Array) return true |
+ |
+ // NaN is poisonous. Means that something is not allowed. |
+ if (type !== type) { |
+ debug("Poison NaN", k, val, type) |
+ delete data[k] |
+ return false |
+ } |
+ |
+ // explicit list of values |
+ if (val === type) { |
+ debug("Explicitly allowed %j", val) |
+ // if (isArray) (data[k] = data[k] || []).push(val) |
+ // else data[k] = val |
+ data[k] = val |
+ return true |
+ } |
+ |
+ // now go through the list of typeDefs, validate against each one. |
+ var ok = false |
+ , types = Object.keys(typeDefs) |
+ for (var i = 0, l = types.length; i < l; i ++) { |
+ debug("test type %j %j %j", k, val, types[i]) |
+ var t = typeDefs[types[i]] |
+ if (t && type === t.type) { |
+ var d = {} |
+ ok = false !== t.validate(d, k, val) |
+ val = d[k] |
+ if (ok) { |
+ // if (isArray) (data[k] = data[k] || []).push(val) |
+ // else data[k] = val |
+ data[k] = val |
+ break |
+ } |
+ } |
+ } |
+ debug("OK? %j (%j %j %j)", ok, k, val, types[i]) |
+ |
+ if (!ok) delete data[k] |
+ return ok |
+} |
+ |
+function parse (args, data, remain, types, shorthands) { |
+ debug("parse", args, data, remain) |
+ |
+ var key = null |
+ , abbrevs = abbrev(Object.keys(types)) |
+ , shortAbbr = abbrev(Object.keys(shorthands)) |
+ |
+ for (var i = 0; i < args.length; i ++) { |
+ var arg = args[i] |
+ debug("arg", arg) |
+ |
+ if (arg.match(/^-{2,}$/)) { |
+ // done with keys. |
+ // the rest are args. |
+ remain.push.apply(remain, args.slice(i + 1)) |
+ args[i] = "--" |
+ break |
+ } |
+ var hadEq = false |
+ if (arg.charAt(0) === "-" && arg.length > 1) { |
+ if (arg.indexOf("=") !== -1) { |
+ hadEq = true |
+ var v = arg.split("=") |
+ arg = v.shift() |
+ v = v.join("=") |
+ args.splice.apply(args, [i, 1].concat([arg, v])) |
+ } |
+ |
+ // see if it's a shorthand |
+ // if so, splice and back up to re-parse it. |
+ var shRes = resolveShort(arg, shorthands, shortAbbr, abbrevs) |
+ debug("arg=%j shRes=%j", arg, shRes) |
+ if (shRes) { |
+ debug(arg, shRes) |
+ args.splice.apply(args, [i, 1].concat(shRes)) |
+ if (arg !== shRes[0]) { |
+ i -- |
+ continue |
+ } |
+ } |
+ arg = arg.replace(/^-+/, "") |
+ var no = null |
+ while (arg.toLowerCase().indexOf("no-") === 0) { |
+ no = !no |
+ arg = arg.substr(3) |
+ } |
+ |
+ if (abbrevs[arg]) arg = abbrevs[arg] |
+ |
+ var isArray = types[arg] === Array || |
+ Array.isArray(types[arg]) && types[arg].indexOf(Array) !== -1 |
+ |
+ // allow unknown things to be arrays if specified multiple times. |
+ if (!types.hasOwnProperty(arg) && data.hasOwnProperty(arg)) { |
+ if (!Array.isArray(data[arg])) |
+ data[arg] = [data[arg]] |
+ isArray = true |
+ } |
+ |
+ var val |
+ , la = args[i + 1] |
+ |
+ var isBool = typeof no === 'boolean' || |
+ types[arg] === Boolean || |
+ Array.isArray(types[arg]) && types[arg].indexOf(Boolean) !== -1 || |
+ (typeof types[arg] === 'undefined' && !hadEq) || |
+ (la === "false" && |
+ (types[arg] === null || |
+ Array.isArray(types[arg]) && ~types[arg].indexOf(null))) |
+ |
+ if (isBool) { |
+ // just set and move along |
+ val = !no |
+ // however, also support --bool true or --bool false |
+ if (la === "true" || la === "false") { |
+ val = JSON.parse(la) |
+ la = null |
+ if (no) val = !val |
+ i ++ |
+ } |
+ |
+ // also support "foo":[Boolean, "bar"] and "--foo bar" |
+ if (Array.isArray(types[arg]) && la) { |
+ if (~types[arg].indexOf(la)) { |
+ // an explicit type |
+ val = la |
+ i ++ |
+ } else if ( la === "null" && ~types[arg].indexOf(null) ) { |
+ // null allowed |
+ val = null |
+ i ++ |
+ } else if ( !la.match(/^-{2,}[^-]/) && |
+ !isNaN(la) && |
+ ~types[arg].indexOf(Number) ) { |
+ // number |
+ val = +la |
+ i ++ |
+ } else if ( !la.match(/^-[^-]/) && ~types[arg].indexOf(String) ) { |
+ // string |
+ val = la |
+ i ++ |
+ } |
+ } |
+ |
+ if (isArray) (data[arg] = data[arg] || []).push(val) |
+ else data[arg] = val |
+ |
+ continue |
+ } |
+ |
+ if (la && la.match(/^-{2,}$/)) { |
+ la = undefined |
+ i -- |
+ } |
+ |
+ val = la === undefined ? true : la |
+ if (isArray) (data[arg] = data[arg] || []).push(val) |
+ else data[arg] = val |
+ |
+ i ++ |
+ continue |
+ } |
+ remain.push(arg) |
+ } |
+} |
+ |
+function resolveShort (arg, shorthands, shortAbbr, abbrevs) { |
+ // handle single-char shorthands glommed together, like |
+ // npm ls -glp, but only if there is one dash, and only if |
+ // all of the chars are single-char shorthands, and it's |
+ // not a match to some other abbrev. |
+ arg = arg.replace(/^-+/, '') |
+ |
+ // if it's an exact known option, then don't go any further |
+ if (abbrevs[arg] === arg) |
+ return null |
+ |
+ // if it's an exact known shortopt, same deal |
+ if (shorthands[arg]) { |
+ // make it an array, if it's a list of words |
+ if (shorthands[arg] && !Array.isArray(shorthands[arg])) |
+ shorthands[arg] = shorthands[arg].split(/\s+/) |
+ |
+ return shorthands[arg] |
+ } |
+ |
+ // first check to see if this arg is a set of single-char shorthands |
+ var singles = shorthands.___singles |
+ if (!singles) { |
+ singles = Object.keys(shorthands).filter(function (s) { |
+ return s.length === 1 |
+ }).reduce(function (l,r) { |
+ l[r] = true |
+ return l |
+ }, {}) |
+ shorthands.___singles = singles |
+ debug('shorthand singles', singles) |
+ } |
+ |
+ var chrs = arg.split("").filter(function (c) { |
+ return singles[c] |
+ }) |
+ |
+ if (chrs.join("") === arg) return chrs.map(function (c) { |
+ return shorthands[c] |
+ }).reduce(function (l, r) { |
+ return l.concat(r) |
+ }, []) |
+ |
+ |
+ // if it's an arg abbrev, and not a literal shorthand, then prefer the arg |
+ if (abbrevs[arg] && !shorthands[arg]) |
+ return null |
+ |
+ // if it's an abbr for a shorthand, then use that |
+ if (shortAbbr[arg]) |
+ arg = shortAbbr[arg] |
+ |
+ // make it an array, if it's a list of words |
+ if (shorthands[arg] && !Array.isArray(shorthands[arg])) |
+ shorthands[arg] = shorthands[arg].split(/\s+/) |
+ |
+ return shorthands[arg] |
+} |
+ |
+if (module === require.main) { |
+var assert = require("assert") |
+ , util = require("util") |
+ |
+ , shorthands = |
+ { s : ["--loglevel", "silent"] |
+ , d : ["--loglevel", "info"] |
+ , dd : ["--loglevel", "verbose"] |
+ , ddd : ["--loglevel", "silly"] |
+ , noreg : ["--no-registry"] |
+ , reg : ["--registry"] |
+ , "no-reg" : ["--no-registry"] |
+ , silent : ["--loglevel", "silent"] |
+ , verbose : ["--loglevel", "verbose"] |
+ , h : ["--usage"] |
+ , H : ["--usage"] |
+ , "?" : ["--usage"] |
+ , help : ["--usage"] |
+ , v : ["--version"] |
+ , f : ["--force"] |
+ , desc : ["--description"] |
+ , "no-desc" : ["--no-description"] |
+ , "local" : ["--no-global"] |
+ , l : ["--long"] |
+ , p : ["--parseable"] |
+ , porcelain : ["--parseable"] |
+ , g : ["--global"] |
+ } |
+ |
+ , types = |
+ { aoa: Array |
+ , nullstream: [null, Stream] |
+ , date: Date |
+ , str: String |
+ , browser : String |
+ , cache : path |
+ , color : ["always", Boolean] |
+ , depth : Number |
+ , description : Boolean |
+ , dev : Boolean |
+ , editor : path |
+ , force : Boolean |
+ , global : Boolean |
+ , globalconfig : path |
+ , group : [String, Number] |
+ , gzipbin : String |
+ , logfd : [Number, Stream] |
+ , loglevel : ["silent","win","error","warn","info","verbose","silly"] |
+ , long : Boolean |
+ , "node-version" : [false, String] |
+ , npaturl : url |
+ , npat : Boolean |
+ , "onload-script" : [false, String] |
+ , outfd : [Number, Stream] |
+ , parseable : Boolean |
+ , pre: Boolean |
+ , prefix: path |
+ , proxy : url |
+ , "rebuild-bundle" : Boolean |
+ , registry : url |
+ , searchopts : String |
+ , searchexclude: [null, String] |
+ , shell : path |
+ , t: [Array, String] |
+ , tag : String |
+ , tar : String |
+ , tmp : path |
+ , "unsafe-perm" : Boolean |
+ , usage : Boolean |
+ , user : String |
+ , username : String |
+ , userconfig : path |
+ , version : Boolean |
+ , viewer: path |
+ , _exit : Boolean |
+ } |
+ |
+; [["-v", {version:true}, []] |
+ ,["---v", {version:true}, []] |
+ ,["ls -s --no-reg connect -d", |
+ {loglevel:"info",registry:null},["ls","connect"]] |
+ ,["ls ---s foo",{loglevel:"silent"},["ls","foo"]] |
+ ,["ls --registry blargle", {}, ["ls"]] |
+ ,["--no-registry", {registry:null}, []] |
+ ,["--no-color true", {color:false}, []] |
+ ,["--no-color false", {color:true}, []] |
+ ,["--no-color", {color:false}, []] |
+ ,["--color false", {color:false}, []] |
+ ,["--color --logfd 7", {logfd:7,color:true}, []] |
+ ,["--color=true", {color:true}, []] |
+ ,["--logfd=10", {logfd:10}, []] |
+ ,["--tmp=/tmp -tar=gtar",{tmp:"/tmp",tar:"gtar"},[]] |
+ ,["--tmp=tmp -tar=gtar", |
+ {tmp:path.resolve(process.cwd(), "tmp"),tar:"gtar"},[]] |
+ ,["--logfd x", {}, []] |
+ ,["a -true -- -no-false", {true:true},["a","-no-false"]] |
+ ,["a -no-false", {false:false},["a"]] |
+ ,["a -no-no-true", {true:true}, ["a"]] |
+ ,["a -no-no-no-false", {false:false}, ["a"]] |
+ ,["---NO-no-No-no-no-no-nO-no-no"+ |
+ "-No-no-no-no-no-no-no-no-no"+ |
+ "-no-no-no-no-NO-NO-no-no-no-no-no-no"+ |
+ "-no-body-can-do-the-boogaloo-like-I-do" |
+ ,{"body-can-do-the-boogaloo-like-I-do":false}, []] |
+ ,["we are -no-strangers-to-love "+ |
+ "--you-know=the-rules --and=so-do-i "+ |
+ "---im-thinking-of=a-full-commitment "+ |
+ "--no-you-would-get-this-from-any-other-guy "+ |
+ "--no-gonna-give-you-up "+ |
+ "-no-gonna-let-you-down=true "+ |
+ "--no-no-gonna-run-around false "+ |
+ "--desert-you=false "+ |
+ "--make-you-cry false "+ |
+ "--no-tell-a-lie "+ |
+ "--no-no-and-hurt-you false" |
+ ,{"strangers-to-love":false |
+ ,"you-know":"the-rules" |
+ ,"and":"so-do-i" |
+ ,"you-would-get-this-from-any-other-guy":false |
+ ,"gonna-give-you-up":false |
+ ,"gonna-let-you-down":false |
+ ,"gonna-run-around":false |
+ ,"desert-you":false |
+ ,"make-you-cry":false |
+ ,"tell-a-lie":false |
+ ,"and-hurt-you":false |
+ },["we", "are"]] |
+ ,["-t one -t two -t three" |
+ ,{t: ["one", "two", "three"]} |
+ ,[]] |
+ ,["-t one -t null -t three four five null" |
+ ,{t: ["one", "null", "three"]} |
+ ,["four", "five", "null"]] |
+ ,["-t foo" |
+ ,{t:["foo"]} |
+ ,[]] |
+ ,["--no-t" |
+ ,{t:["false"]} |
+ ,[]] |
+ ,["-no-no-t" |
+ ,{t:["true"]} |
+ ,[]] |
+ ,["-aoa one -aoa null -aoa 100" |
+ ,{aoa:["one", null, 100]} |
+ ,[]] |
+ ,["-str 100" |
+ ,{str:"100"} |
+ ,[]] |
+ ,["--color always" |
+ ,{color:"always"} |
+ ,[]] |
+ ,["--no-nullstream" |
+ ,{nullstream:null} |
+ ,[]] |
+ ,["--nullstream false" |
+ ,{nullstream:null} |
+ ,[]] |
+ ,["--notadate=2011-01-25" |
+ ,{notadate: "2011-01-25"} |
+ ,[]] |
+ ,["--date 2011-01-25" |
+ ,{date: new Date("2011-01-25")} |
+ ,[]] |
+ ,["-cl 1" |
+ ,{config: true, length: 1} |
+ ,[] |
+ ,{config: Boolean, length: Number, clear: Boolean} |
+ ,{c: "--config", l: "--length"}] |
+ ,["--acount bla" |
+ ,{"acount":true} |
+ ,["bla"] |
+ ,{account: Boolean, credentials: Boolean, options: String} |
+ ,{a:"--account", c:"--credentials",o:"--options"}] |
+ ,["--clear" |
+ ,{clear:true} |
+ ,[] |
+ ,{clear:Boolean,con:Boolean,len:Boolean,exp:Boolean,add:Boolean,rep:Boolean} |
+ ,{c:"--con",l:"--len",e:"--exp",a:"--add",r:"--rep"}] |
+ ,["--file -" |
+ ,{"file":"-"} |
+ ,[] |
+ ,{file:String} |
+ ,{}] |
+ ,["--file -" |
+ ,{"file":true} |
+ ,["-"] |
+ ,{file:Boolean} |
+ ,{}] |
+ ].forEach(function (test) { |
+ var argv = test[0].split(/\s+/) |
+ , opts = test[1] |
+ , rem = test[2] |
+ , actual = nopt(test[3] || types, test[4] || shorthands, argv, 0) |
+ , parsed = actual.argv |
+ delete actual.argv |
+ console.log(util.inspect(actual, false, 2, true), parsed.remain) |
+ for (var i in opts) { |
+ var e = JSON.stringify(opts[i]) |
+ , a = JSON.stringify(actual[i] === undefined ? null : actual[i]) |
+ if (e && typeof e === "object") { |
+ assert.deepEqual(e, a) |
+ } else { |
+ assert.equal(e, a) |
+ } |
+ } |
+ assert.deepEqual(rem, parsed.remain) |
+ }) |
+} |