index.js 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465
  1. // Generated by LiveScript 1.6.0
  2. (function(){
  3. var VERSION, ref$, id, map, compact, any, groupBy, partition, chars, isItNaN, keys, Obj, camelize, deepIs, closestString, nameToRaw, dasherize, naturalJoin, generateHelp, generateHelpForOption, parsedTypeCheck, parseType, parseLevn, camelizeKeys, parseString, main, toString$ = {}.toString, slice$ = [].slice, arrayFrom$ = Array.from || function(x){return slice$.call(x);};
  4. VERSION = '0.9.4';
  5. ref$ = require('prelude-ls'), id = ref$.id, map = ref$.map, compact = ref$.compact, any = ref$.any, groupBy = ref$.groupBy, partition = ref$.partition, chars = ref$.chars, isItNaN = ref$.isItNaN, keys = ref$.keys, Obj = ref$.Obj, camelize = ref$.camelize;
  6. deepIs = require('deep-is');
  7. ref$ = require('./util'), closestString = ref$.closestString, nameToRaw = ref$.nameToRaw, dasherize = ref$.dasherize, naturalJoin = ref$.naturalJoin;
  8. ref$ = require('./help'), generateHelp = ref$.generateHelp, generateHelpForOption = ref$.generateHelpForOption;
  9. ref$ = require('type-check'), parsedTypeCheck = ref$.parsedTypeCheck, parseType = ref$.parseType;
  10. parseLevn = require('levn').parsedTypeParse;
  11. camelizeKeys = function(obj){
  12. var key, value, resultObj$ = {};
  13. for (key in obj) {
  14. value = obj[key];
  15. resultObj$[camelize(key)] = value;
  16. }
  17. return resultObj$;
  18. };
  19. parseString = function(string){
  20. var assignOpt, regex, replaceRegex, result;
  21. assignOpt = '--?[a-zA-Z][-a-z-A-Z0-9]*=';
  22. regex = RegExp('(?:' + assignOpt + ')?(?:\'(?:\\\\\'|[^\'])+\'|"(?:\\\\"|[^"])+")|[^\'"\\s]+', 'g');
  23. replaceRegex = RegExp('^(' + assignOpt + ')?[\'"]([\\s\\S]*)[\'"]$');
  24. result = map(function(it){
  25. return it.replace(replaceRegex, '$1$2');
  26. }, string.match(regex) || []);
  27. return result;
  28. };
  29. main = function(libOptions){
  30. var opts, defaults, required, traverse, getOption, parse;
  31. opts = {};
  32. defaults = {};
  33. required = [];
  34. if (toString$.call(libOptions.stdout).slice(8, -1) === 'Undefined') {
  35. libOptions.stdout = process.stdout;
  36. }
  37. libOptions.positionalAnywhere == null && (libOptions.positionalAnywhere = true);
  38. libOptions.typeAliases == null && (libOptions.typeAliases = {});
  39. libOptions.defaults == null && (libOptions.defaults = {});
  40. if (libOptions.concatRepeatedArrays != null) {
  41. libOptions.defaults.concatRepeatedArrays = libOptions.concatRepeatedArrays;
  42. }
  43. if (libOptions.mergeRepeatedObjects != null) {
  44. libOptions.defaults.mergeRepeatedObjects = libOptions.mergeRepeatedObjects;
  45. }
  46. traverse = function(options){
  47. var i$, len$, option, name, k, ref$, v, type, that, e, parsedPossibilities, parsedType, j$, len1$, possibility, rawDependsType, dependsOpts, dependsType, cra, alias, shortNames, longNames;
  48. if (toString$.call(options).slice(8, -1) !== 'Array') {
  49. throw new Error('No options defined.');
  50. }
  51. for (i$ = 0, len$ = options.length; i$ < len$; ++i$) {
  52. option = options[i$];
  53. if (option.heading == null) {
  54. name = option.option;
  55. if (opts[name] != null) {
  56. throw new Error("Option '" + name + "' already defined.");
  57. }
  58. for (k in ref$ = libOptions.defaults) {
  59. v = ref$[k];
  60. option[k] == null && (option[k] = v);
  61. }
  62. if (option.type === 'Boolean') {
  63. option.boolean == null && (option.boolean = true);
  64. }
  65. if (option.parsedType == null) {
  66. if (!option.type) {
  67. throw new Error("No type defined for option '" + name + "'.");
  68. }
  69. try {
  70. type = (that = libOptions.typeAliases[option.type]) != null
  71. ? that
  72. : option.type;
  73. option.parsedType = parseType(type);
  74. } catch (e$) {
  75. e = e$;
  76. throw new Error("Option '" + name + "': Error parsing type '" + option.type + "': " + e.message);
  77. }
  78. }
  79. if (option['default']) {
  80. try {
  81. defaults[name] = parseLevn(option.parsedType, option['default']);
  82. } catch (e$) {
  83. e = e$;
  84. throw new Error("Option '" + name + "': Error parsing default value '" + option['default'] + "' for type '" + option.type + "': " + e.message);
  85. }
  86. }
  87. if (option['enum'] && !option.parsedPossiblities) {
  88. parsedPossibilities = [];
  89. parsedType = option.parsedType;
  90. for (j$ = 0, len1$ = (ref$ = option['enum']).length; j$ < len1$; ++j$) {
  91. possibility = ref$[j$];
  92. try {
  93. parsedPossibilities.push(parseLevn(parsedType, possibility));
  94. } catch (e$) {
  95. e = e$;
  96. throw new Error("Option '" + name + "': Error parsing enum value '" + possibility + "' for type '" + option.type + "': " + e.message);
  97. }
  98. }
  99. option.parsedPossibilities = parsedPossibilities;
  100. }
  101. if (that = option.dependsOn) {
  102. if (that.length) {
  103. ref$ = [].concat(option.dependsOn), rawDependsType = ref$[0], dependsOpts = slice$.call(ref$, 1);
  104. dependsType = rawDependsType.toLowerCase();
  105. if (dependsOpts.length) {
  106. if (dependsType === 'and' || dependsType === 'or') {
  107. option.dependsOn = [dependsType].concat(arrayFrom$(dependsOpts));
  108. } else {
  109. throw new Error("Option '" + name + "': If you have more than one dependency, you must specify either 'and' or 'or'");
  110. }
  111. } else {
  112. if ((ref$ = dependsType.toLowerCase()) === 'and' || ref$ === 'or') {
  113. option.dependsOn = null;
  114. } else {
  115. option.dependsOn = ['and', rawDependsType];
  116. }
  117. }
  118. } else {
  119. option.dependsOn = null;
  120. }
  121. }
  122. if (option.required) {
  123. required.push(name);
  124. }
  125. opts[name] = option;
  126. if (option.concatRepeatedArrays != null) {
  127. cra = option.concatRepeatedArrays;
  128. if ('Boolean' === toString$.call(cra).slice(8, -1)) {
  129. option.concatRepeatedArrays = [cra, {}];
  130. } else if (cra.length === 1) {
  131. option.concatRepeatedArrays = [cra[0], {}];
  132. } else if (cra.length !== 2) {
  133. throw new Error("Invalid setting for concatRepeatedArrays");
  134. }
  135. }
  136. if (option.alias || option.aliases) {
  137. if (name === 'NUM') {
  138. throw new Error("-NUM option can't have aliases.");
  139. }
  140. if (option.alias) {
  141. option.aliases == null && (option.aliases = [].concat(option.alias));
  142. }
  143. for (j$ = 0, len1$ = (ref$ = option.aliases).length; j$ < len1$; ++j$) {
  144. alias = ref$[j$];
  145. if (opts[alias] != null) {
  146. throw new Error("Option '" + alias + "' already defined.");
  147. }
  148. opts[alias] = option;
  149. }
  150. ref$ = partition(fn$, option.aliases), shortNames = ref$[0], longNames = ref$[1];
  151. option.shortNames == null && (option.shortNames = shortNames);
  152. option.longNames == null && (option.longNames = longNames);
  153. }
  154. if ((!option.aliases || option.shortNames.length === 0) && option.type === 'Boolean' && option['default'] === 'true') {
  155. option.negateName = true;
  156. }
  157. }
  158. }
  159. function fn$(it){
  160. return it.length === 1;
  161. }
  162. };
  163. traverse(libOptions.options);
  164. getOption = function(name){
  165. var opt, possiblyMeant;
  166. opt = opts[name];
  167. if (opt == null) {
  168. possiblyMeant = closestString(keys(opts), name);
  169. throw new Error("Invalid option '" + nameToRaw(name) + "'" + (possiblyMeant ? " - perhaps you meant '" + nameToRaw(possiblyMeant) + "'?" : '.'));
  170. }
  171. return opt;
  172. };
  173. parse = function(input, arg$){
  174. var slice, obj, positional, restPositional, overrideRequired, prop, setValue, setDefaults, checkRequired, mutuallyExclusiveError, checkMutuallyExclusive, checkDependency, checkDependencies, checkProp, args, key, value, option, ref$, i$, len$, arg, that, result, short, argName, usingAssign, val, flags, len, j$, len1$, i, flag, opt, name, valPrime, negated, noedName;
  175. slice = (arg$ != null
  176. ? arg$
  177. : {}).slice;
  178. obj = {};
  179. positional = [];
  180. restPositional = false;
  181. overrideRequired = false;
  182. prop = null;
  183. setValue = function(name, value){
  184. var opt, val, cra, e, currentType;
  185. opt = getOption(name);
  186. if (opt.boolean) {
  187. val = value;
  188. } else {
  189. try {
  190. cra = opt.concatRepeatedArrays;
  191. if (cra != null && cra[0] && cra[1].oneValuePerFlag && opt.parsedType.length === 1 && opt.parsedType[0].structure === 'array') {
  192. val = [parseLevn(opt.parsedType[0].of, value)];
  193. } else {
  194. val = parseLevn(opt.parsedType, value);
  195. }
  196. } catch (e$) {
  197. e = e$;
  198. throw new Error("Invalid value for option '" + name + "' - expected type " + opt.type + ", received value: " + value + ".");
  199. }
  200. if (opt['enum'] && !any(function(it){
  201. return deepIs(it, val);
  202. }, opt.parsedPossibilities)) {
  203. throw new Error("Option " + name + ": '" + val + "' not one of " + naturalJoin(opt['enum']) + ".");
  204. }
  205. }
  206. currentType = toString$.call(obj[name]).slice(8, -1);
  207. if (obj[name] != null) {
  208. if (opt.concatRepeatedArrays != null && opt.concatRepeatedArrays[0] && currentType === 'Array') {
  209. obj[name] = obj[name].concat(val);
  210. } else if (opt.mergeRepeatedObjects && currentType === 'Object') {
  211. import$(obj[name], val);
  212. } else {
  213. obj[name] = val;
  214. }
  215. } else {
  216. obj[name] = val;
  217. }
  218. if (opt.restPositional) {
  219. restPositional = true;
  220. }
  221. if (opt.overrideRequired) {
  222. overrideRequired = true;
  223. }
  224. };
  225. setDefaults = function(){
  226. var name, ref$, value;
  227. for (name in ref$ = defaults) {
  228. value = ref$[name];
  229. if (obj[name] == null) {
  230. obj[name] = value;
  231. }
  232. }
  233. };
  234. checkRequired = function(){
  235. var i$, ref$, len$, name;
  236. if (overrideRequired) {
  237. return;
  238. }
  239. for (i$ = 0, len$ = (ref$ = required).length; i$ < len$; ++i$) {
  240. name = ref$[i$];
  241. if (!obj[name]) {
  242. throw new Error("Option " + nameToRaw(name) + " is required.");
  243. }
  244. }
  245. };
  246. mutuallyExclusiveError = function(first, second){
  247. throw new Error("The options " + nameToRaw(first) + " and " + nameToRaw(second) + " are mutually exclusive - you cannot use them at the same time.");
  248. };
  249. checkMutuallyExclusive = function(){
  250. var rules, i$, len$, rule, present, j$, len1$, element, k$, len2$, opt;
  251. rules = libOptions.mutuallyExclusive;
  252. if (!rules) {
  253. return;
  254. }
  255. for (i$ = 0, len$ = rules.length; i$ < len$; ++i$) {
  256. rule = rules[i$];
  257. present = null;
  258. for (j$ = 0, len1$ = rule.length; j$ < len1$; ++j$) {
  259. element = rule[j$];
  260. if (toString$.call(element).slice(8, -1) === 'Array') {
  261. for (k$ = 0, len2$ = element.length; k$ < len2$; ++k$) {
  262. opt = element[k$];
  263. if (opt in obj) {
  264. if (present != null) {
  265. mutuallyExclusiveError(present, opt);
  266. } else {
  267. present = opt;
  268. break;
  269. }
  270. }
  271. }
  272. } else {
  273. if (element in obj) {
  274. if (present != null) {
  275. mutuallyExclusiveError(present, element);
  276. } else {
  277. present = element;
  278. }
  279. }
  280. }
  281. }
  282. }
  283. };
  284. checkDependency = function(option){
  285. var dependsOn, type, targetOptionNames, i$, len$, targetOptionName, targetOption;
  286. dependsOn = option.dependsOn;
  287. if (!dependsOn || option.dependenciesMet) {
  288. return true;
  289. }
  290. type = dependsOn[0], targetOptionNames = slice$.call(dependsOn, 1);
  291. for (i$ = 0, len$ = targetOptionNames.length; i$ < len$; ++i$) {
  292. targetOptionName = targetOptionNames[i$];
  293. targetOption = obj[targetOptionName];
  294. if (targetOption && checkDependency(targetOption)) {
  295. if (type === 'or') {
  296. return true;
  297. }
  298. } else if (type === 'and') {
  299. throw new Error("The option '" + option.option + "' did not have its dependencies met.");
  300. }
  301. }
  302. if (type === 'and') {
  303. return true;
  304. } else {
  305. throw new Error("The option '" + option.option + "' did not meet any of its dependencies.");
  306. }
  307. };
  308. checkDependencies = function(){
  309. var name;
  310. for (name in obj) {
  311. checkDependency(opts[name]);
  312. }
  313. };
  314. checkProp = function(){
  315. if (prop) {
  316. throw new Error("Value for '" + prop + "' of type '" + getOption(prop).type + "' required.");
  317. }
  318. };
  319. switch (toString$.call(input).slice(8, -1)) {
  320. case 'String':
  321. args = parseString(input.slice(slice != null ? slice : 0));
  322. break;
  323. case 'Array':
  324. args = input.slice(slice != null ? slice : 2);
  325. break;
  326. case 'Object':
  327. obj = {};
  328. for (key in input) {
  329. value = input[key];
  330. if (key !== '_') {
  331. option = getOption(dasherize(key));
  332. if (parsedTypeCheck(option.parsedType, value)) {
  333. obj[option.option] = value;
  334. } else {
  335. throw new Error("Option '" + option.option + "': Invalid type for '" + value + "' - expected type '" + option.type + "'.");
  336. }
  337. }
  338. }
  339. checkMutuallyExclusive();
  340. checkDependencies();
  341. setDefaults();
  342. checkRequired();
  343. return ref$ = camelizeKeys(obj), ref$._ = input._ || [], ref$;
  344. default:
  345. throw new Error("Invalid argument to 'parse': " + input + ".");
  346. }
  347. for (i$ = 0, len$ = args.length; i$ < len$; ++i$) {
  348. arg = args[i$];
  349. if (arg === '--') {
  350. restPositional = true;
  351. } else if (restPositional) {
  352. positional.push(arg);
  353. } else {
  354. if (that = arg.match(/^(--?)([a-zA-Z][-a-zA-Z0-9]*)(=)?(.*)?$/)) {
  355. result = that;
  356. checkProp();
  357. short = result[1].length === 1;
  358. argName = result[2];
  359. usingAssign = result[3] != null;
  360. val = result[4];
  361. if (usingAssign && val == null) {
  362. throw new Error("No value for '" + argName + "' specified.");
  363. }
  364. if (short) {
  365. flags = chars(argName);
  366. len = flags.length;
  367. for (j$ = 0, len1$ = flags.length; j$ < len1$; ++j$) {
  368. i = j$;
  369. flag = flags[j$];
  370. opt = getOption(flag);
  371. name = opt.option;
  372. if (restPositional) {
  373. positional.push(flag);
  374. } else if (i === len - 1) {
  375. if (usingAssign) {
  376. valPrime = opt.boolean ? parseLevn([{
  377. type: 'Boolean'
  378. }], val) : val;
  379. setValue(name, valPrime);
  380. } else if (opt.boolean) {
  381. setValue(name, true);
  382. } else {
  383. prop = name;
  384. }
  385. } else if (opt.boolean) {
  386. setValue(name, true);
  387. } else {
  388. throw new Error("Can't set argument '" + flag + "' when not last flag in a group of short flags.");
  389. }
  390. }
  391. } else {
  392. negated = false;
  393. if (that = argName.match(/^no-(.+)$/)) {
  394. negated = true;
  395. noedName = that[1];
  396. opt = getOption(noedName);
  397. } else {
  398. opt = getOption(argName);
  399. }
  400. name = opt.option;
  401. if (opt.boolean) {
  402. valPrime = usingAssign ? parseLevn([{
  403. type: 'Boolean'
  404. }], val) : true;
  405. if (negated) {
  406. setValue(name, !valPrime);
  407. } else {
  408. setValue(name, valPrime);
  409. }
  410. } else {
  411. if (negated) {
  412. throw new Error("Only use 'no-' prefix for Boolean options, not with '" + noedName + "'.");
  413. }
  414. if (usingAssign) {
  415. setValue(name, val);
  416. } else {
  417. prop = name;
  418. }
  419. }
  420. }
  421. } else if (that = arg.match(/^-([0-9]+(?:\.[0-9]+)?)$/)) {
  422. opt = opts.NUM;
  423. if (!opt) {
  424. throw new Error('No -NUM option defined.');
  425. }
  426. setValue(opt.option, that[1]);
  427. } else {
  428. if (prop) {
  429. setValue(prop, arg);
  430. prop = null;
  431. } else {
  432. positional.push(arg);
  433. if (!libOptions.positionalAnywhere) {
  434. restPositional = true;
  435. }
  436. }
  437. }
  438. }
  439. }
  440. checkProp();
  441. checkMutuallyExclusive();
  442. checkDependencies();
  443. setDefaults();
  444. checkRequired();
  445. return ref$ = camelizeKeys(obj), ref$._ = positional, ref$;
  446. };
  447. return {
  448. parse: parse,
  449. parseArgv: function(it){
  450. return parse(it, {
  451. slice: 2
  452. });
  453. },
  454. generateHelp: generateHelp(libOptions),
  455. generateHelpForOption: generateHelpForOption(getOption, libOptions)
  456. };
  457. };
  458. main.VERSION = VERSION;
  459. module.exports = main;
  460. function import$(obj, src){
  461. var own = {}.hasOwnProperty;
  462. for (var key in src) if (own.call(src, key)) obj[key] = src[key];
  463. return obj;
  464. }
  465. }).call(this);