UNPKG

4.45 kBJavaScriptView Raw
1exports.readOptions = readOptions;
2exports.readValue = readValue;
3exports.readPropertySetters = readPropertySetters;
4
5// takes commandline args, space-separated
6// flags is array of flag names
7// optFlags is array of flags that have option values
8// optFlags suck up arguments until next flag
9// returns { [flag]: true / false, ..., [optFlag]: value, ..., args: [all non-flag args] }
10function readOptions(inArgs, flags, optFlags) {
11 // output options object
12 var options = { args: [] };
13
14 flags = flags || [];
15 optFlags = optFlags || [];
16
17 var curOptionFlag;
18
19 function getFlagMatch(arg, flags) {
20 var index;
21
22 if (arg.startsWith('--')) {
23 index = flags.indexOf(arg.substr(2));
24 if (index !== -1)
25 return flags[index];
26 }
27 else if (arg.startsWith('-')) {
28 return flags.filter(function(f) {
29 return f.substr(0, 1) === arg.substr(1, 1);
30 })[0];
31 }
32 }
33
34 // de-sugar any coupled single-letter flags
35 // -abc -> -a -b -c
36 var args = [];
37 inArgs.forEach(function(arg) {
38 if (arg[0] == '-' && arg.length > 1 && arg[1] != '-') {
39 for (var i = 1; i < arg.length; i++)
40 args.push('-' + arg[i]);
41 }
42 else {
43 args.push(arg);
44 }
45 });
46
47 args.forEach(function(arg) {
48 var flag = getFlagMatch(arg, flags);
49 var optFlag = getFlagMatch(arg, optFlags);
50
51 // option flag -> suck up args
52 if (optFlag) {
53 curOptionFlag = optFlag;
54 options[curOptionFlag] = [];
55 }
56 // normal boolean flag
57 else if (flag) {
58 options[flag] = true;
59 }
60 // value argument
61 else {
62 if (curOptionFlag)
63 options[curOptionFlag].push(arg);
64 else
65 options.args.push(arg);
66 }
67 });
68
69 // flag values are strings
70 optFlags.forEach(function(flag) {
71 if (options[flag])
72 options[flag] = options[flag].join(' ');
73 });
74
75 return options;
76}
77
78// this will get a value in its true type from the CLI
79function readValue(val) {
80 val = val.trim();
81 if (val === 'true' || val === 'false')
82 return eval(val);
83 else if (parseInt(val).toString() == val)
84 return parseInt(val);
85 else if (val[0] == '{' && val[val.length - 1] == '}')
86 return eval('(' + val + ')');
87 else if (val[0] == '[' && val[val.length - 1] == ']')
88 if (val.indexOf('\'') == -1 && val.indexOf('\"') == -1)
89 return val.substr(1, val.length - 2).split(',').map(function(item) {
90 return item.trim();
91 });
92 else
93 return eval('(' + val + ')');
94 else
95 return val;
96}
97
98function readPropertySetters(str, dottedProperties) {
99 var outObj = {};
100
101 function setProperty(target, p, value) {
102 var pParts = p.split('.');
103 var curPart;
104 while (pParts.length) {
105 if (curPart !== undefined)
106 target = target[curPart] = target[curPart] || {};
107 curPart = pParts.shift();
108
109 // allow properties to be indicated by square brackets as well (a.b['c'].d)
110 if (curPart.indexOf('[') != -1) {
111 var lastPart = curPart.substr(curPart.indexOf('[') + 1);
112 lastPart = lastPart + (lastPart ? '.' : '') + pParts.join('.');
113 if (lastPart.indexOf(']') == -1 || lastPart.indexOf(']') == 0)
114 continue;
115
116 var bracketPart = lastPart.substr(0, lastPart.indexOf(']'));
117 if (bracketPart[0] == '"' && bracketPart[bracketPart.length - 1] == '"' || bracketPart[0] == '\'' && bracketPart[bracketPart.length - 1] == '\'')
118 bracketPart = bracketPart.substr(1, bracketPart.length - 2);
119
120 curPart = curPart.substr(0, curPart.indexOf('['));
121
122 lastPart = lastPart.substr(lastPart.indexOf(']') + 1);
123 if (lastPart[0] == '.')
124 lastPart = lastPart.substr(1);
125 pParts = [bracketPart].concat(lastPart ? lastPart.split('.') : []);
126 }
127 }
128 setValue(target, curPart, value);
129 }
130 function setValue(target, p, value) {
131 if (p.substr(p.length - 2, 2) == '[]')
132 target[p.substr(0, p.length - 2)] = value.split(',');
133 else
134 target[p] = value;
135 }
136
137 var parts = str.split('=');
138 var lastProp;
139 parts.forEach(function(part, index) {
140 if (!lastProp) {
141 lastProp = part;
142 return;
143 }
144
145 var value = readValue(index == parts.length - 1 ? part : part.substr(0, part.lastIndexOf(' ')));
146 lastProp = lastProp.trim();
147 if (dottedProperties)
148 setProperty(outObj, lastProp, value);
149 else
150 setValue(outObj, lastProp, value);
151 lastProp = part.substr(part.lastIndexOf(' ') + 1).trim();
152 });
153
154 return outObj;
155}
\No newline at end of file