From d920639fe065ee600709df087215df489d00af9f Mon Sep 17 00:00:00 2001 From: dormouse-bot <287024035+dormouse-bot@users.noreply.github.com> Date: Sat, 30 May 2026 07:28:06 +0000 Subject: [PATCH] Make `dor help ` show the command's help `dor help split` (and other subcommands) printed the root help, dropping the subject. `dor split --help` worked as expected. Map `help ` to ` --help` and update the help-target resolver to match, so the two forms produce identical output. Co-Authored-By: Claude Opus 4.7 --- dor/src/cli.ts | 16 ++++++++++++++-- dor/test/cli-help.test.mjs | 13 ++++++++++++- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/dor/src/cli.ts b/dor/src/cli.ts index 26d49da..bb8a2bc 100644 --- a/dor/src/cli.ts +++ b/dor/src/cli.ts @@ -98,7 +98,7 @@ interface CaptureProcess extends StricliProcess { export async function runCli(argv: string[], options: CliOptions = {}): Promise { const helpTarget = getHelpTarget(argv); - const [commandName, ...args] = argv[0] === 'help' ? ['--help'] : argv; + const [commandName, ...args] = rewriteHelpArgv(argv); if (commandName === 'ensure' && !args.includes('-h') && !args.includes('--help')) { const delimiterCheck = validateEnsureDelimiter(args); @@ -126,7 +126,13 @@ type HelpTarget = | { scope: 'command'; commandName: string }; function getHelpTarget(argv: string[]): HelpTarget | undefined { - if (argv.length === 0 || argv[0] === 'help' || (argv.length === 1 && (argv[0] === '--help' || argv[0] === '-h'))) { + if (argv[0] === 'help') { + const subject = argv[1]; + return subject && isCommandName(subject) + ? { scope: 'command', commandName: subject } + : { scope: 'root' }; + } + if (argv.length === 0 || (argv.length === 1 && (argv[0] === '--help' || argv[0] === '-h'))) { return { scope: 'root' }; } @@ -138,6 +144,12 @@ function getHelpTarget(argv: string[]): HelpTarget | undefined { return undefined; } +function rewriteHelpArgv(argv: string[]): string[] { + if (argv[0] !== 'help') return argv; + const subject = argv[1]; + return subject && isCommandName(subject) ? [subject, '--help'] : ['--help']; +} + function isCommandName(value: string): value is keyof typeof ROUTES { return value in ROUTES; } diff --git a/dor/test/cli-help.test.mjs b/dor/test/cli-help.test.mjs index 8699ea3..0351d2e 100644 --- a/dor/test/cli-help.test.mjs +++ b/dor/test/cli-help.test.mjs @@ -15,6 +15,11 @@ test('help snapshots cover every command in global help', async (t) => { assert.deepEqual(await runCli([]), globalHelp, 'no-arg dor should print root help'); assert.deepEqual(await runCli(['help']), globalHelp, 'dor help should print root help'); + assert.deepEqual( + await runCli(['help', 'not-a-command']), + globalHelp, + 'dor help should print root help', + ); await t.test('dor', async () => { await snapshotHelp({ @@ -26,14 +31,20 @@ test('help snapshots cover every command in global help', async (t) => { }); for (const command of commandNames) { + const commandHelp = await runCli([command, '--help']); await t.test(`dor ${command}`, async () => { await snapshotHelp({ file: command, title: `dor ${command}`, invocation: `dor ${command} --help`, - result: await runCli([command, '--help']), + result: commandHelp, }); }); + assert.deepEqual( + await runCli(['help', command]), + commandHelp, + `dor help ${command} should match dor ${command} --help`, + ); } await assertSnapshotInventory(['dor', ...commandNames]);