This repository has been archived by the owner on Oct 30, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 214
/
cli.js
135 lines (116 loc) · 3.81 KB
/
cli.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
/*
* Copyright (c) 2011-2012, Yahoo! Inc. All rights reserved.
* Copyrights licensed under the New BSD License.
* See the accompanying LICENSE file for terms.
*/
/*jslint anon:true, node:true */
'use strict';
var utils = require('./utils'),
libpath = require('path');
/*
* A command is expected to export the following:
* run - The function that executes the command. The signature is:
* run(params, options, callback);
* usage - Help information for this command, as a string.
* options - Option info for supported options. Optional.
*
* Option info must be provided as an array of option objects, each with the
* following keys:
* shortName - Short (1-char) option name, without leading dash (e.g. 'v').
* longName - Long option name, without leading dashes (e.g. 'verbose').
* hasValue - True is this option requires a value. Optional; default false.
*/
/*
* Creates a map keyed by both short and long option names, to simplify lookup
* of option info from command line args.
*/
function makeOptionMap(optionInfo) {
var optionMap = {};
if (optionInfo) {
optionInfo.forEach(function(info) {
if (info.shortName) {
optionMap['-' + info.shortName] = info;
}
if (info.longName) {
optionMap['--' + info.longName] = info;
}
});
}
return optionMap;
}
/*
* Parses command line args based on the provided option info. Returns a map
* with three keys:
* params - an array of the specified parameters
* options - a map of options, keyed by long name
* errors - an array of error strings for reporting
*/
function parseArgs(args, optionInfo) {
var optionMap = makeOptionMap(optionInfo),
params = [],
options = {},
errors = [],
option,
arg;
while (args.length > 0) {
arg = args.shift();
if (arg.charAt(0) === '-') {
option = optionMap[arg];
if (option) {
if (option.hasValue) {
if (args.length === 0) {
errors.push('Missing value for option: ' + arg);
} else {
options[option.longName] = args.shift();
}
} else {
options[option.longName] = true;
}
} else {
errors.push('Invalid option: ' + arg);
}
} else {
params.push(arg);
}
}
return { params: params, options: options, errors: errors };
}
// ---------- Start of mainline code ----------
function main() {
var args = process.argv.slice(2),
commandName = (args.length === 0 ? 'help' : args.shift()),
command,
argInfo;
try {
command = require('mojito-cli-cmd-' + commandName);
} catch (e) {
try {
/*jslint nomen: true */
command = require(libpath.join(__dirname, '../app/commands/', commandName));
} catch (e2) {
utils.error('Error loading command: ' + command + ' ' + e2.message,
'mojito <command> [<params>] [<options>]');
return;
}
}
if (args.length === 0) {
argInfo = { command: 'help', params: [], options: {} };
} else {
argInfo = parseArgs(args, command.options);
}
if (argInfo.errors && argInfo.errors.length > 0) {
argInfo.errors.forEach(function(e) {
utils.log(e);
});
utils.error('Invalid command line.', "Try 'mojito help <command>'.");
return;
}
command.run(argInfo.params, argInfo.options, function(err, usg, die) {
if (err) {
utils.error(err, usg, die);
} else {
utils.success('mojito done.');
}
});
}
exports.run = main;