Skip to content

Commit fe64573

Browse files
authored
feat: support command-specific help and improve display quality (#52)
1 parent 06b557f commit fe64573

File tree

8 files changed

+228
-179
lines changed

8 files changed

+228
-179
lines changed

README.md

Lines changed: 58 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -13,31 +13,66 @@
1313
$ npm install --global @asyncapi/cli
1414
```
1515

16+
### Getting Started
17+
Go ahead and run command `asyncapi --help` to get complete help for using CLI. If having doubt about any particular command do run `asyncapi <command> --help` to get help for that command.
18+
1619
### CLI
20+
Help string for all the supported commands
21+
22+
- #### `asyncapi --help`
23+
```
24+
USAGE
25+
26+
asyncapi [options] [command]
27+
28+
OPTIONS
29+
30+
-h, --help display help for command
31+
--version output the version number
32+
33+
COMMANDS
34+
35+
validate validate asyncapi file
36+
context Manage contexts
37+
```
38+
39+
- #### `asyncapi validate --help`
1740
```
18-
$ asyncapi --help
19-
20-
Usage
21-
$ asyncapi command options
22-
23-
Commands
24-
validate
25-
Options
26-
-c --context context-name saved in the store
27-
-w --watch Enable watchMode (not implemented yet)
28-
-f --file File path of the specification file
29-
30-
context
31-
current show the current set context
32-
list show the list of all stored contexts
33-
remove <context-name> remove a context from the store
34-
use <context-name> set any context from store as current
35-
add <context-name> <filepath> add/update new context
36-
37-
Examples
38-
$ asyncapi context add dummy ./asyncapi.yml
39-
$ asyncapi validate --context=dummy
40-
$ asyncapi validate --file=./asyncapi.yml
41+
USAGE
42+
43+
asyncapi validate [options]
44+
45+
OPTIONS
46+
47+
-h, --help display help for command
48+
-f, --file <spec-file-path> Path of the asyncapi file
49+
-c, --context <saved-context-name> context name to use
50+
-w, --watch Enable Watch Mode (not implemented yet)
51+
```
52+
53+
- #### `asyncapi context --help`
54+
```
55+
USAGE
56+
57+
asyncapi context [options] [command]
58+
59+
Context is what makes it easier for you to work with multiple AsyncAPI files.
60+
You can add multiple different files to a contextThis way you do not have to pass
61+
--file flag with path to the file every time but just --context flag with reference name
62+
You can also set a default context, so neither --file nor --context flags are needed.
63+
64+
OPTIONS
65+
66+
-h, --help display help for command
67+
68+
COMMANDS
69+
70+
list list of all saved contexts
71+
current see current context
72+
use <context-name> set given context as default/current
73+
add <context-name> <spec-file-path> add/update context
74+
remove <context-name> remove a context
75+
4176
```
4277

4378
> For now --context flag is requried to run validate command

src/CliModels.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
export type Command = string;
1+
export type Command = string | undefined;
22
export type HelpMessage = string;
33
export type Arguments = string[];
44

@@ -12,11 +12,13 @@ export class CliInput {
1212
private readonly _command: Command
1313
private readonly _options: Options
1414
private readonly _arguments: Arguments
15+
private readonly _help: boolean | undefined
1516

16-
private constructor(command: Command, options: Options, args: Arguments) {
17+
private constructor(command: Command, options: Options, args: Arguments, help?:boolean) {
1718
this._command = command;
1819
this._options = options;
1920
this._arguments = args;
21+
this._help = help;
2022
}
2123

2224
get command(): Command {
@@ -31,15 +33,19 @@ export class CliInput {
3133
return this._arguments;
3234
}
3335

36+
get help(): boolean | undefined {
37+
return this._help;
38+
}
39+
3440
static createFromMeow(meowOutput: any): CliInput {
3541
const [command, ...args] = meowOutput.input;
3642
const { context, watch, file } = meowOutput.flags;
37-
return new CliInput(command || 'help', { context, watch, file }, args);
43+
return new CliInput(command, { context, watch, file }, args, meowOutput.flags.help);
3844
}
3945

4046
static createSubCommand(cliInput: CliInput): CliInput {
4147
const [command, ...args] = cliInput.arguments;
42-
return new CliInput(command || 'help', cliInput.options, args);
48+
return new CliInput(command, cliInput.options, args);
4349
}
4450
}
4551

src/CommandsRouter.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,21 @@ import React from 'react';
22
import Validate from './components/Validate/Validate';
33
import { contextRouter } from './components/Context';
44
import { CliInput } from './CliModels';
5+
import { CommandName, HelpMessageBuilder } from './help-message';
56

67
const commandsDictionary = (cliInput: CliInput): Record<string, any> => ({
78
validate: <Validate options={cliInput.options} />,
89
context: contextRouter(cliInput)
910
});
1011

1112
export const commandsRouter = (cli: any): any => {
13+
const helpMessage = new HelpMessageBuilder();
1214
const cliInput = CliInput.createFromMeow(cli);
15+
if (!cliInput.command) {
16+
return <helpMessage.HelpComponent />;
17+
}
18+
if (cliInput.help) {
19+
return <helpMessage.HelpComponent command={cliInput.command as CommandName} />;
20+
}
1321
return commandsDictionary(cliInput)[cliInput.command];
1422
};

src/cli.ts

Lines changed: 5 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -5,28 +5,8 @@ import { render } from 'ink';
55
import meow from 'meow';
66
import { commandsRouter } from './CommandsRouter';
77

8-
const cli = meow(`
9-
Usage
10-
$ asyncapi command options
11-
12-
Commands
13-
validate
14-
Options
15-
-c --context context-name saved in the store
16-
-w --watch Enable watchMode (not implemented yet)
17-
-f --file File path of the specification file
18-
context
19-
current show the current set context
20-
list show the list of all stored context
21-
remove <context-name> remove a context from the store
22-
use <context-name> set any context as current
23-
add <context-name> <filepath> add/update new context
24-
25-
Examples
26-
$ asyncapi context add dummy ./asyncapi.yml
27-
$ asyncapi validate --context=dummy
28-
$ asyncapi validate --file=./asyncapi.yml
29-
`, {
8+
const cli = meow({
9+
autoHelp: false,
3010
flags: {
3111
context: {
3212
alias: 'c',
@@ -43,6 +23,9 @@ const cli = meow(`
4323
alias: 'f',
4424
type: 'string',
4525
isRequired: false
26+
},
27+
help: {
28+
alias: 'h'
4629
}
4730
}
4831
});

src/components/Context/index.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
/* eslint-disable @typescript-eslint/no-non-null-assertion */
12
import React from 'react';
23

34
import { ListContexts,AddContext,RemoveContext,ShowCurrentContext,SetCurrent } from './Context';
@@ -13,5 +14,5 @@ const commandDictionary = (cliInput: CliInput): Record<string, any> => ({
1314

1415
export const contextRouter = (cliInput: CliInput): any => {
1516
const subCommand = CliInput.createSubCommand(cliInput);
16-
return commandDictionary(subCommand)[subCommand.command];
17+
return commandDictionary(subCommand)[subCommand.command!];
1718
};

src/help-message.spec.ts

Lines changed: 0 additions & 30 deletions
This file was deleted.

src/help-message.ts

Lines changed: 0 additions & 99 deletions
This file was deleted.

0 commit comments

Comments
 (0)