Parse only positional arguments after the first is encountered

This commit is contained in:
Jerko Steiner 2019-08-18 08:36:00 +07:00
parent 385555123a
commit b807e84539
3 changed files with 40 additions and 29 deletions

View File

@ -167,8 +167,8 @@ describe('argparse', () => {
`${CMD} [OPTIONS]`,
'',
'Options:',
' --value [VALUE]',
' --help boolean',
' --value [VALUE]',
' --help boolean',
].join('\n'))
})
it('can be used to extract finite number of values', () => {
@ -194,9 +194,9 @@ describe('argparse', () => {
`${CMD} [OPTIONS]`,
'',
'Options:',
' --value [VALUE1 VALUE2 VALUE3]',
'-o, --other number',
' --help boolean',
' --value [VALUE1 VALUE2 VALUE3]',
' -o, --other number',
' --help boolean',
].join('\n'))
})
it('can be used to collect any remaining arguments when n = "+"', () => {
@ -222,9 +222,9 @@ describe('argparse', () => {
`${CMD} [OPTIONS]`,
'',
'Options:',
' --value VALUE... (required)',
' --other number',
' --help boolean',
' --value VALUE... (required)',
' --other number',
' --help boolean',
].join('\n'))
})
it('can collect remaining positional arguments when n = "*"', () => {
@ -259,8 +259,8 @@ describe('argparse', () => {
' VALUE string[] (required)',
'',
'Options:',
' --other number',
' --help boolean',
' --other number',
' --help boolean',
].join('\n'))
})
})
@ -319,7 +319,7 @@ Positional arguments:
b: 'bbb',
})
})
it('works amongs regular arguments', () => {
it('works amongst regular arguments', () => {
const {parse} = argparse({
arg1: {
type: 'string',
@ -332,11 +332,16 @@ Positional arguments:
type: 'string',
},
})
expect(parse([CMD, '--arg1', 'one', '2', '--arg3', 'three'])).toEqual({
expect(parse([CMD, '--arg1', 'one', '--arg3', 'three', '2'])).toEqual({
arg1: 'one',
arg2: 2,
arg3: 'three',
})
expect(parse([CMD, '2'])).toEqual({
arg1: '',
arg2: 2,
arg3: '',
})
})
})
@ -355,10 +360,10 @@ Positional arguments:
`${CMD} [OPTIONS]`,
'',
'Options:',
' --one string',
' --two number',
' --three boolean',
' --help boolean',
' --one string',
' --two number',
' --three boolean',
' --help boolean',
].join('\n'))
})
it('returns help string with alias, description, and samples', () => {
@ -390,9 +395,9 @@ Positional arguments:
' THREE number',
'',
'Options:',
'-o, --one string first argument ' +
'(required, default: choice-1, choices: choice-1,choice-2)',
' --help boolean',
' -o, --one string first argument ' +
'(required, default: choice-1, choices: choice-1,choice-2)',
' --help boolean',
].join('\n'))
})

View File

@ -231,8 +231,8 @@ export function help(command: string, config: IArgsConfig) {
const argConfig = config[argument]
const {alias, type, required, n} = argConfig
const name = alias
? `-${alias}, --${argument}`
: ` --${argument}`
? ` -${alias}, --${argument}`
: ` --${argument}`
const description = getDescription(argConfig)
const argType = getArgType(type, argument, required, n)
const nameAndType = `${name} ${argType}`
@ -338,9 +338,9 @@ export function argparse<T extends IArgsConfig>(
return lastArgName
}
function getNextPositional(): string {
function getNextPositional(argument: string): string {
const p = positional.shift()
assert(!!p, 'No defined positional arguments')
assert(!!p, 'Unknown positional argument: ' + argument)
return p!
}
@ -352,9 +352,12 @@ export function argparse<T extends IArgsConfig>(
continue
}
const isPositional = argument.substring(0, 1) !== '-' || onlyPositionals
if (isPositional) {
onlyPositionals = true
}
const argName = !isPositional
? processFlags(argument)
: getNextPositional()
: getNextPositional(argument)
const argConfig = config[argName]
if (!isPositional && argName === 'help') {
log(help(command, config))

View File

@ -9,18 +9,21 @@ const commandNames = Object.keys(commands).filter(cmd => !cmd.startsWith('_'))
const {parse} = argparse({
help: arg('boolean', {alias: 'h'}),
debug: arg('boolean'),
command: arg('string[]', {
n: '+',
command: arg('string', {
required: true,
positional: true,
description: '\n ' + commandNames.join('\n '),
choices: commandNames,
}),
args: arg('string[]', {
n: '*',
positional: true,
}),
})
type TArgs = ReturnType<typeof parse>
async function run(args: TArgs, exit: (code: number) => void) {
const commandName = args.command[0]
const commandName = args.command
if (!(commandName in commands)) {
const c = commandNames
log.info(
@ -29,7 +32,7 @@ async function run(args: TArgs, exit: (code: number) => void) {
return
}
const command = (commands as any)[commandName] as TCommand
await command(...args.command)
await command(args.command, ...args.args)
}
async function start(