Skip to content

Commit 72efdea

Browse files
committed
feat(plugin-help): display subcommands
1 parent 4e029f5 commit 72efdea

3 files changed

Lines changed: 94 additions & 5 deletions

File tree

packages/plugin-help/src/renderer.ts

Lines changed: 49 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1-
import type { Clerc, ClercFlagsDefinition, Command } from "@clerc/core";
1+
import type {
2+
Clerc,
3+
ClercFlagsDefinition,
4+
Command,
5+
CommandsMap,
6+
} from "@clerc/core";
27
import {
38
formatFlagName,
49
formatVersion,
@@ -165,9 +170,46 @@ export class HelpRenderer {
165170
};
166171
}
167172

173+
private getSubcommands(parentCommandName: string): CommandsMap {
174+
const subcommands = new Map<string, Command>();
175+
176+
if (!parentCommandName) {
177+
return subcommands;
178+
}
179+
180+
const prefix = `${parentCommandName} `;
181+
182+
for (const [name, command] of this._cli._commands) {
183+
if (name.startsWith(prefix) && name !== parentCommandName) {
184+
const subcommandName = name.slice(prefix.length);
185+
subcommands.set(subcommandName, command);
186+
}
187+
}
188+
189+
return subcommands;
190+
}
191+
168192
private renderCommands() {
169193
const commands = this._cli._commands;
170-
if (this._command || commands.size === 0) {
194+
195+
// If a command is selected, show its subcommands
196+
let commandsToShow: CommandsMap;
197+
let title = "Commands";
198+
let prefix = "";
199+
200+
if (this._command) {
201+
prefix = this._command.name ? `${this._command.name} ` : "";
202+
title = "Subcommands";
203+
commandsToShow = this.getSubcommands(this._command.name);
204+
205+
if (commandsToShow.size === 0) {
206+
return;
207+
}
208+
} else {
209+
commandsToShow = commands;
210+
}
211+
212+
if (commandsToShow.size === 0) {
171213
return;
172214
}
173215

@@ -176,15 +218,17 @@ export class HelpRenderer {
176218
const defaultCommands: string[][] = [];
177219
let rootCommand: string[] = [];
178220

179-
for (const command of commands.values()) {
221+
for (const command of commandsToShow.values()) {
180222
if ((command as any).__isAlias || command.help?.show === false) {
181223
continue;
182224
}
183225

184226
const group = command.help?.group;
185227
validateGroup(group, this._commandGroups, "command", command.name);
186228

187-
const commandName = yc.cyan(formatCommandName(command.name));
229+
const commandName = yc.cyan(
230+
formatCommandName(command.name.slice(prefix.length)),
231+
);
188232
const aliases = command.alias
189233
? ` (${toArray(command.alias).join(", ")})`
190234
: "";
@@ -233,7 +277,7 @@ export class HelpRenderer {
233277
}
234278

235279
return {
236-
title: "Commands",
280+
title,
237281
body,
238282
};
239283
}

packages/plugin-help/test/__snapshots__/plugin-help.test.ts.snap

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,32 @@
11
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
22

3+
exports[`plugin-help > grouping > should display subcommands 1`] = `
4+
[
5+
[
6+
"test parent - Parent command
7+
8+
Usage
9+
$ test parent [flags]
10+
11+
Subcommands
12+
child1 First child command
13+
child2 Second child command
14+
15+
Global Flags
16+
--help, -h Boolean Show help [default: false]",
17+
],
18+
[
19+
"test - Parent command
20+
21+
Usage
22+
$ test [flags]
23+
24+
Global Flags
25+
--help, -h Boolean Show help [default: false]",
26+
],
27+
]
28+
`;
29+
330
exports[`plugin-help > grouping > should group command flags 1`] = `
431
[
532
[

packages/plugin-help/test/plugin-help.test.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,5 +163,23 @@ describe("plugin-help", () => {
163163

164164
expect(getConsoleMock("log").mock.calls).toMatchSnapshot();
165165
});
166+
167+
it("should display subcommands", () => {
168+
TestBaseCli()
169+
.use(helpPlugin())
170+
.command("parent", "Parent command")
171+
.command("parent child1", "First child command")
172+
.command("parent child2", "Second child command")
173+
.parse(["parent", "--help"]);
174+
175+
TestBaseCli()
176+
.use(helpPlugin())
177+
.command("", "Parent command")
178+
.command("child1", "First child command")
179+
.command("child2", "Second child command")
180+
.parse(["--help"]);
181+
182+
expect(getConsoleMock("log").mock.calls).toMatchSnapshot();
183+
});
166184
});
167185
});

0 commit comments

Comments
 (0)