93 lines
2.0 KiB
JavaScript
93 lines
2.0 KiB
JavaScript
const debugHelper = require('./debug-helper')
|
|
|
|
/**
|
|
* Parse command line arguments
|
|
*/
|
|
class Arguments {
|
|
flags = {}
|
|
|
|
options = {}
|
|
|
|
arguments = []
|
|
}
|
|
exports.Arguments = Arguments
|
|
|
|
const helpCode = 'ARGHELP'
|
|
exports.helpCode = helpCode
|
|
|
|
const errorCode = 'ARGV'
|
|
exports.errorCode = errorCode
|
|
|
|
/**
|
|
* Parses the command line arguments
|
|
* @param {string[]} flags Allowed flags
|
|
* @param {string[]} options Allowed options
|
|
* @param {boolean} allowArgs Whether to allow unnamed arguments
|
|
* @returns {Arguments}
|
|
*/
|
|
function parse(flags, options, allowArgs) {
|
|
flags = flags || []
|
|
options = options || []
|
|
allowArgs = typeof(allowArgs) === 'boolean' ? allowArgs : true
|
|
|
|
const result = new Arguments()
|
|
|
|
// Check for --help
|
|
const argv = process.argv.slice(2)
|
|
if (argv.some(x => x === '--help')) {
|
|
throwError('Help requested', helpCode)
|
|
}
|
|
|
|
// Parse
|
|
for (let i = 0; i < argv.length; i++) {
|
|
const arg = argv[i]
|
|
const nextArg = i + 1 < argv.length ? argv[i + 1] : null
|
|
|
|
// Starts with "--"
|
|
if (arg.startsWith('--')) {
|
|
const name = arg.substr(2)
|
|
|
|
// Legal flag
|
|
if (flags.some(x => x === name)) {
|
|
debugHelper.debug(`arg: ${arg} (flag)`)
|
|
result.flags[name] = true
|
|
continue
|
|
}
|
|
|
|
// Unknown option
|
|
if (!options.some(x => x === name)) {
|
|
throwError(`Unknown option '${name}'`)
|
|
}
|
|
|
|
// Missing value following option
|
|
if (nextArg === null || nextArg.startsWith('--')) {
|
|
throwError(`Option '${name}' must have a value`)
|
|
}
|
|
|
|
// Legal option
|
|
debugHelper.debug(`arg: ${arg} (option)`)
|
|
result.options[name] = nextArg
|
|
i++
|
|
continue
|
|
}
|
|
|
|
// Unexpected argument
|
|
if (!allowArgs) {
|
|
throwError(`Unexpected argument '${arg}'`)
|
|
}
|
|
|
|
// Legal argument
|
|
debugHelper.debug(`arg: ${arg}`)
|
|
result.arguments.push(arg)
|
|
}
|
|
|
|
return result
|
|
}
|
|
exports.parse = parse
|
|
|
|
function throwError(message, code) {
|
|
const err = new Error(message)
|
|
err.code = code || errorCode
|
|
throw err
|
|
}
|
|
exports.throwError = throwError |