-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathindex.js
138 lines (126 loc) · 4.49 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
module.exports = tav = { };
// Arguments
Object.defineProperty(tav, "args", {
value : [],
enumerable : false
});
Object.defineProperty(tav, "set", {
/**
* Sets options.
* @param spec Specification
* @param banner Banner
* @param strict Assume unexpected params as error.
*/
value : function(spec, banner, strict) {
spec = spec || {};
banner = banner || "Usage:";
var self = this;
var incoming = process.argv.slice(2); // incoming params
/**
* Returns extra items frob b
* @param a
* @param b
* @returns {Array}
*/
var arrayDiff = function(a, b) {
return b.filter(function(i) {
return a.indexOf(i) == -1;
});
};
/**
* Check conditions. If help setted - always exit.
* @param parsed Parsed specs
*/
var check = function(parsed) {
var end = false, message = "", code = 0, outer = console.log;
var setted = Object.keys(self);
var specced = Object.keys(parsed);
var required = arrayDiff(setted, specced);
var unexpected = arrayDiff(specced, setted);
// If any required options is not provided - crash it!
if (required.length) {
end = true;
code = 1;
outer = console.error;
message += "Required but not provided:\n --"
+ required.join("\n --") + "\n";
}
// + unexpected
if (unexpected.length) {
message += "Unexpected options:\n --"
+ unexpected.join("\n --") + "\n";
}
message += (message.length ?
"\nRun with --help for more info" : "");
if (strict && message.length) {
end = true;
code = 1;
outer = console.error;
}
// If --help, exit without error
if (incoming.indexOf("--help") != -1) {
end = true;
code = 0;
outer = console.log;
message = Object.keys(parsed).reduce(function(msg, k) {
return msg + parsed[k].note + "\n --" + k
+ (parsed[k].req ? " *required\n" : "\n");
}, "") + "Help. This message.\n --help\n";
}
if (end) {
// exiting
outer(banner + "\n");
outer(message);
process.exit(code);
}
};
// Fill spec and default values
var parsed = {};
Object.keys(spec).forEach(function(name) {
var req = spec[name].value === undefined ? true : false;
var note = spec[name].note || "Note not provided";
parsed[name] = {
req : req,
note : note
};
// If value not required - set it
if (!req) {
self[name] = spec[name].value;
}
});
// Evaluate process.argv
var numRe = /^[0-9.]+$/;
incoming.filter(function(chunk) {
return chunk != "--help" && chunk != "--";
})
.forEach(function(chunk) {
if (chunk.substring(0,2) == "--") {
var tokens = chunk.substring(2).split("=");
var name = tokens[0];
// Expected option - evaluate value
if (tokens.length == 1) {
// Boolean
var value = true;
} else {
var value = tokens.length > 2 ?
tokens.slice(1).join('=') : tokens[1];
if (numRe.test(value)) {
value = parseFloat(value);
}
}
if (self[name] instanceof Array) {
self[name].push(value);
} else {
self[name] = value;
}
} else {
// Just argument
self.args.push(chunk);
}
});
check(parsed);
return this;
},
enumerable : false,
configurable : false
});