Created
January 12, 2017 17:35
-
-
Save mashingan/68f2930b0e311af02a2c5b573209c175 to your computer and use it in GitHub Desktop.
An attempt to implement cmd parser like commander.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var mycommander = require('./mycommander'); | |
console.log(mycommander); | |
console.log(process.argv.slice(2)); | |
mycommander | |
.option('-f, --foo i', 'Integer value for foo', parseInt, 0) | |
.option('-b, --bar j', 'Integer value for bar', parseInt, 0) | |
.option('-z, --baz', 'Boolean argument baz') | |
.parse(process.argv.slice(2)); | |
console.log(mycommander); | |
console.log(mycommander.foo.value); | |
console.log(mycommander.bar.value); | |
console.log(mycommander.baz.value); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function MyCommander() { | |
var self = this; | |
self.option = function (cmdString, info, parserCb, defaultVal) { | |
return option(self, cmdString, info, parserCb, defaultVal); | |
}; | |
self.parse = function (args) { | |
return parse(self, args); | |
}; | |
self.prompt = prompt; | |
//somehow cannot be functioning well | |
//self.confirm = confirm; | |
return this; | |
} | |
function option (thisObj, cmdString, info, parserCb, defaultVal) { | |
var cmds = cmdString.split(',').map(function (option) { | |
return option.trim(); | |
}); | |
var shortOpt; | |
var idx = 0; | |
if (cmds.length === 1 && cmds[0].indexOf('--') === 0) { | |
idx = 0; | |
} | |
else if (cmds.length === 2 && cmds[1].indexOf('--') === 0) { | |
idx = 1; | |
shortOpt = cmds[0]; | |
} | |
var memberName = cmds[idx].trim().substr(2).trim().split(' ')[0]; | |
memberName = memberName.split('=', 2)[0]; | |
thisObj[memberName] = {}; | |
thisObj[memberName].info = info; | |
if (shortOpt) thisObj[shortOpt] = memberName; | |
thisObj[memberName].parse = function (value) { | |
var result = value? parserCb(value) : | |
(defaultVal !== undefined) ? defaultVal : true; | |
console.log('parse result:', result); | |
return result; | |
}; | |
return thisObj; | |
} | |
function parse(thisObj, args) { | |
var prevArg = ''; | |
args.forEach(function (arg, idx) { | |
arg = arg.trim(); | |
switch (optionTester(arg)) { | |
case 'option': | |
var somearg = getMemberName(thisObj, arg); | |
if (prevArg) { | |
executeParse(thisObj, prevArg); | |
} else if (idx === args.length - 1) { | |
executeParse(thisObj, somearg); | |
} | |
prevArg = somearg; | |
break; | |
case 'option-value': | |
if (prevArg) { | |
executeParse(thisObj, prevArg); | |
} | |
var optVal = arg.split('=', 2); | |
var thearg = optVal[0]; | |
var value = optVal[1]; | |
var memberName; | |
try { | |
memberName = getMemberName(thisObj, thearg); | |
} catch (error) { | |
console.log(error); | |
} | |
thisObj[memberName].value = thisObj[memberName].parse(value); | |
prevArg = ''; | |
break; | |
case 'value': | |
if (prevArg) { | |
thisObj[prevArg].value = thisObj[prevArg].parse(arg); | |
prevArg = ''; | |
} | |
break; | |
} | |
}); | |
return thisObj; | |
} | |
function getMemberName (thisObj, opt) { | |
if (opt.indexOf('--') === 0) | |
return opt.substr(2); | |
else if (opt.indexOf('-') === 0) | |
return thisObj[opt]; | |
else | |
throw new Error('No ' + opt + ' option defined.'); | |
} | |
function executeParse (thisObj, memberName) { | |
thisObj[memberName].value = thisObj[memberName].parse(); | |
} | |
function optionTester (arg) { | |
if (arg.indexOf('=') !== -1) | |
return 'option-value'; | |
else if (arg.indexOf('--') === 0 || arg.indexOf('-') === 0) | |
return 'option'; | |
else | |
return 'value'; | |
} | |
function prompt(question, cb) { | |
console.log(question); | |
process.stdin.on('data', cb); | |
process.stdin.setEncoding('utf8'); | |
process.stdin.resume(); | |
} | |
function confirm(question, cb) { | |
prompt(question, function(data) { | |
var trueAnswer = [ 'y', 'ok', 'yes', 'true' ]; | |
if (trueAnswer.indexOf(data.toLowerCase()) !== -1) { | |
cb(true); | |
} | |
else { | |
cb(false); | |
} | |
}); | |
} | |
module.exports = (function () { return new MyCommander(); })(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment