diff --git a/packages/argparse/src/argparse.test.ts b/packages/argparse/src/argparse.test.ts index 92fb744..b9be5ed 100644 --- a/packages/argparse/src/argparse.test.ts +++ b/packages/argparse/src/argparse.test.ts @@ -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')) }) diff --git a/packages/argparse/src/argparse.ts b/packages/argparse/src/argparse.ts index be9596c..fffc624 100644 --- a/packages/argparse/src/argparse.ts +++ b/packages/argparse/src/argparse.ts @@ -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( 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( 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)) diff --git a/packages/scripts/src/index.ts b/packages/scripts/src/index.ts index 1164a2f..fa4d222 100644 --- a/packages/scripts/src/index.ts +++ b/packages/scripts/src/index.ts @@ -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 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(