cli-kiss 0.2.4 → 0.2.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +159 -167
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/docs/.vitepress/config.mts +3 -2
- package/docs/.vitepress/theme/style.css +6 -2
- package/docs/guide/01_getting_started.md +12 -13
- package/docs/guide/02_commands.md +12 -29
- package/docs/guide/03_options.md +16 -25
- package/docs/guide/04_positionals.md +45 -55
- package/docs/guide/05_input_types.md +134 -0
- package/docs/guide/06_run_as_cli.md +143 -0
- package/docs/index.md +3 -2
- package/docs/public/favicon.ico +0 -0
- package/docs/public/hero.png +0 -0
- package/package.json +1 -1
- package/src/index.ts +0 -2
- package/src/lib/Command.ts +14 -35
- package/src/lib/Operation.ts +13 -4
- package/src/lib/Option.ts +118 -162
- package/src/lib/Positional.ts +37 -62
- package/src/lib/Reader.ts +3 -3
- package/src/lib/Run.ts +76 -49
- package/src/lib/Type.ts +227 -143
- package/src/lib/Typo.ts +55 -23
- package/src/lib/Usage.ts +30 -45
- package/tests/unit.Reader.parsings.ts +50 -0
- package/tests/unit.command.execute.ts +13 -13
- package/tests/unit.command.usage.ts +60 -54
- package/tests/unit.runner.colors.ts +199 -0
- package/tests/unit.runner.cycle.ts +69 -55
- package/tests/unit.runner.errors.ts +12 -20
- package/docs/guide/05_types.md +0 -132
- package/docs/guide/06_run.md +0 -160
package/src/lib/Usage.ts
CHANGED
|
@@ -18,9 +18,8 @@ import {
|
|
|
18
18
|
export type UsageCommand = {
|
|
19
19
|
/**
|
|
20
20
|
* Segments of the usage line
|
|
21
|
-
* (e.g. `my-cli <POSITIONAL> subcommand <ANOTHER_POSITIONAL>`).
|
|
22
21
|
*/
|
|
23
|
-
segments: Array<
|
|
22
|
+
segments: Array<{ positional: string } | { subcommand: string }>;
|
|
24
23
|
/**
|
|
25
24
|
* Command metadata.
|
|
26
25
|
*/
|
|
@@ -39,25 +38,6 @@ export type UsageCommand = {
|
|
|
39
38
|
options: Array<UsageOption>;
|
|
40
39
|
};
|
|
41
40
|
|
|
42
|
-
/**
|
|
43
|
-
* One segment of the usage line.
|
|
44
|
-
*/
|
|
45
|
-
export type UsageSegment = { positional: string } | { subcommand: string };
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* Usage metadata. Produced by {@link Operation.generateUsage}, consumed when building {@link UsageCommand}.
|
|
49
|
-
*/
|
|
50
|
-
export type UsageOperation = {
|
|
51
|
-
/**
|
|
52
|
-
* Registered options.
|
|
53
|
-
*/
|
|
54
|
-
options: Array<UsageOption>;
|
|
55
|
-
/**
|
|
56
|
-
* Declared positionals, in order.
|
|
57
|
-
*/
|
|
58
|
-
positionals: Array<UsagePositional>;
|
|
59
|
-
};
|
|
60
|
-
|
|
61
41
|
/**
|
|
62
42
|
* Positional metadata for the `Positionals:` section of help.
|
|
63
43
|
*/
|
|
@@ -65,16 +45,15 @@ export type UsagePositional = {
|
|
|
65
45
|
/**
|
|
66
46
|
* Help text.
|
|
67
47
|
*/
|
|
68
|
-
description
|
|
48
|
+
description?: string | undefined;
|
|
69
49
|
/**
|
|
70
50
|
* Short note shown in parentheses.
|
|
71
51
|
*/
|
|
72
|
-
hint
|
|
52
|
+
hint?: string | undefined;
|
|
73
53
|
/**
|
|
74
54
|
* Placeholder label shown in the usage line and the `Positionals:` section.
|
|
75
|
-
* Required: `<NAME>`, optional: `[NAME]`, variadic: `[NAME]...`.
|
|
76
55
|
*/
|
|
77
|
-
label:
|
|
56
|
+
label: string;
|
|
78
57
|
};
|
|
79
58
|
|
|
80
59
|
/**
|
|
@@ -88,11 +67,11 @@ export type UsageSubcommand = {
|
|
|
88
67
|
/**
|
|
89
68
|
* From {@link CommandInformation.description}.
|
|
90
69
|
*/
|
|
91
|
-
description
|
|
70
|
+
description?: string | undefined;
|
|
92
71
|
/**
|
|
93
72
|
* From {@link CommandInformation.hint}.
|
|
94
73
|
*/
|
|
95
|
-
hint
|
|
74
|
+
hint?: string | undefined;
|
|
96
75
|
};
|
|
97
76
|
|
|
98
77
|
/**
|
|
@@ -102,27 +81,27 @@ export type UsageOption = {
|
|
|
102
81
|
/**
|
|
103
82
|
* Short-form name without `-` (e.g. `"v"`).
|
|
104
83
|
*/
|
|
105
|
-
short
|
|
84
|
+
short?: string | undefined;
|
|
106
85
|
/**
|
|
107
86
|
* Long-form name without `--` (e.g. `"verbose"`).
|
|
108
87
|
*/
|
|
109
|
-
long:
|
|
88
|
+
long: string;
|
|
110
89
|
/**
|
|
111
|
-
*
|
|
90
|
+
* Value placeholder in help (e.g. `"<FILE>"`).
|
|
112
91
|
*/
|
|
113
|
-
|
|
92
|
+
label?: string | undefined;
|
|
114
93
|
/**
|
|
115
|
-
*
|
|
94
|
+
* Extra annotation appended to the option label in help.
|
|
116
95
|
*/
|
|
117
|
-
|
|
96
|
+
annotation?: string | undefined;
|
|
118
97
|
/**
|
|
119
|
-
*
|
|
98
|
+
* Help text.
|
|
120
99
|
*/
|
|
121
|
-
|
|
100
|
+
description?: string | undefined;
|
|
122
101
|
/**
|
|
123
|
-
*
|
|
102
|
+
* Short note shown in parentheses.
|
|
124
103
|
*/
|
|
125
|
-
|
|
104
|
+
hint?: string | undefined;
|
|
126
105
|
};
|
|
127
106
|
|
|
128
107
|
/**
|
|
@@ -137,16 +116,16 @@ export type UsageOption = {
|
|
|
137
116
|
* <detail lines...>
|
|
138
117
|
*
|
|
139
118
|
* Positionals:
|
|
140
|
-
* <
|
|
119
|
+
* <label> <description> (<hint>)
|
|
141
120
|
*
|
|
142
121
|
* Subcommands:
|
|
143
122
|
* <name> <description> (<hint>)
|
|
144
123
|
*
|
|
145
124
|
* Options:
|
|
146
|
-
* -s, --long <
|
|
125
|
+
* -s, --long <label><annotation> <description> (<hint>)
|
|
147
126
|
*
|
|
148
127
|
* Examples:
|
|
149
|
-
* <
|
|
128
|
+
* <explanation>
|
|
150
129
|
* <command line>
|
|
151
130
|
*
|
|
152
131
|
* ```
|
|
@@ -170,7 +149,7 @@ export type UsageOption = {
|
|
|
170
149
|
* ```
|
|
171
150
|
*/
|
|
172
151
|
export function usageToStyledLines(params: {
|
|
173
|
-
cliName:
|
|
152
|
+
cliName: string;
|
|
174
153
|
usage: UsageCommand;
|
|
175
154
|
typoSupport: TypoSupport;
|
|
176
155
|
}) {
|
|
@@ -295,9 +274,15 @@ export function usageToStyledLines(params: {
|
|
|
295
274
|
} else {
|
|
296
275
|
commandLineText.push(textConstants(`--${option.long}`));
|
|
297
276
|
}
|
|
298
|
-
if (option.
|
|
277
|
+
if (option.inlined !== undefined) {
|
|
299
278
|
commandLineText.push(textSubtleInfo("="));
|
|
300
|
-
commandLineText.push(textUserInput(option.
|
|
279
|
+
commandLineText.push(textUserInput(option.inlined));
|
|
280
|
+
}
|
|
281
|
+
if (option.separated !== undefined) {
|
|
282
|
+
for (const separatedValue of option.separated) {
|
|
283
|
+
commandLineText.push(textDelimiter(" "));
|
|
284
|
+
commandLineText.push(textUserInput(separatedValue));
|
|
285
|
+
}
|
|
301
286
|
}
|
|
302
287
|
}
|
|
303
288
|
}
|
|
@@ -310,8 +295,8 @@ export function usageToStyledLines(params: {
|
|
|
310
295
|
}
|
|
311
296
|
|
|
312
297
|
function createInformationals(usage: {
|
|
313
|
-
description
|
|
314
|
-
hint
|
|
298
|
+
description?: string | undefined;
|
|
299
|
+
hint?: string | undefined;
|
|
315
300
|
}): Array<TypoText> {
|
|
316
301
|
const informationals = [];
|
|
317
302
|
if (usage.description) {
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { expect, it } from "@jest/globals";
|
|
2
|
+
import { ReaderArgs } from "../src";
|
|
3
|
+
|
|
4
|
+
it("run", async function () {
|
|
5
|
+
const readerArgs1 = new ReaderArgs(["--val=1", "A", "B", "STOP", "C"]);
|
|
6
|
+
const kOptionVariadicStop = readerArgs1.registerOption({
|
|
7
|
+
longs: ["val"],
|
|
8
|
+
shorts: [],
|
|
9
|
+
parsing: {
|
|
10
|
+
consumeShortGroup: true,
|
|
11
|
+
consumeNextArg: (_inlined, separated, nextArg) =>
|
|
12
|
+
nextArg !== undefined && separated[separated.length - 1] !== "STOP",
|
|
13
|
+
},
|
|
14
|
+
});
|
|
15
|
+
expect(readerArgs1.consumePositional()).toStrictEqual("C");
|
|
16
|
+
expect(readerArgs1.consumePositional()).toStrictEqual(undefined);
|
|
17
|
+
expect(readerArgs1.getOptionValues(kOptionVariadicStop)).toStrictEqual([
|
|
18
|
+
{ inlined: "1", separated: ["A", "B", "STOP"] },
|
|
19
|
+
]);
|
|
20
|
+
|
|
21
|
+
const readerArgs2 = new ReaderArgs(["--val=1", "A", "B", "C"]);
|
|
22
|
+
const kOptionVariadicFull = readerArgs2.registerOption({
|
|
23
|
+
longs: ["val"],
|
|
24
|
+
shorts: [],
|
|
25
|
+
parsing: {
|
|
26
|
+
consumeShortGroup: true,
|
|
27
|
+
consumeNextArg: (_inlined, _separated, nextArg) => nextArg !== undefined,
|
|
28
|
+
},
|
|
29
|
+
});
|
|
30
|
+
expect(readerArgs2.consumePositional()).toStrictEqual(undefined);
|
|
31
|
+
expect(readerArgs2.getOptionValues(kOptionVariadicFull)).toStrictEqual([
|
|
32
|
+
{ inlined: "1", separated: ["A", "B", "C"] },
|
|
33
|
+
]);
|
|
34
|
+
|
|
35
|
+
const readerArgs3 = new ReaderArgs(["--val=2", "A", "B", "--val=1", "C"]);
|
|
36
|
+
const kOptionVariadicKeyed = readerArgs3.registerOption({
|
|
37
|
+
longs: ["val"],
|
|
38
|
+
shorts: [],
|
|
39
|
+
parsing: {
|
|
40
|
+
consumeShortGroup: true,
|
|
41
|
+
consumeNextArg: (inlined, separated) =>
|
|
42
|
+
separated.length < Number(inlined ?? "0"),
|
|
43
|
+
},
|
|
44
|
+
});
|
|
45
|
+
expect(readerArgs3.consumePositional()).toStrictEqual(undefined);
|
|
46
|
+
expect(readerArgs3.getOptionValues(kOptionVariadicKeyed)).toStrictEqual([
|
|
47
|
+
{ inlined: "2", separated: ["A", "B"] },
|
|
48
|
+
{ inlined: "1", separated: ["C"] },
|
|
49
|
+
]);
|
|
50
|
+
});
|
|
@@ -12,9 +12,9 @@ import {
|
|
|
12
12
|
positionalRequired,
|
|
13
13
|
positionalVariadics,
|
|
14
14
|
ReaderArgs,
|
|
15
|
+
type,
|
|
15
16
|
typeList,
|
|
16
17
|
typeNumber,
|
|
17
|
-
typeString,
|
|
18
18
|
} from "../src";
|
|
19
19
|
|
|
20
20
|
const rootCommand = commandChained(
|
|
@@ -33,7 +33,7 @@ const rootCommand = commandChained(
|
|
|
33
33
|
default: false,
|
|
34
34
|
}),
|
|
35
35
|
},
|
|
36
|
-
positionals: [positionalRequired({
|
|
36
|
+
positionals: [positionalRequired({ type: typeNumber() })],
|
|
37
37
|
},
|
|
38
38
|
async function (context, inputs) {
|
|
39
39
|
return { at: "root", context, inputs };
|
|
@@ -46,15 +46,15 @@ const rootCommand = commandChained(
|
|
|
46
46
|
options: {
|
|
47
47
|
string: optionSingleValue({
|
|
48
48
|
long: "string-option",
|
|
49
|
-
type:
|
|
50
|
-
|
|
49
|
+
type: type(),
|
|
50
|
+
defaultWhenNotDefined: () => undefined,
|
|
51
51
|
}),
|
|
52
52
|
number: optionRepeatable({
|
|
53
53
|
long: "number-option",
|
|
54
|
-
type: typeList(typeNumber),
|
|
54
|
+
type: typeList(typeNumber()),
|
|
55
55
|
}),
|
|
56
56
|
},
|
|
57
|
-
positionals: [positionalRequired({ type: typeNumber })],
|
|
57
|
+
positionals: [positionalRequired({ type: typeNumber() })],
|
|
58
58
|
},
|
|
59
59
|
async function (context, inputs) {
|
|
60
60
|
return { at: "mid", context, inputs };
|
|
@@ -66,7 +66,7 @@ const rootCommand = commandChained(
|
|
|
66
66
|
operation(
|
|
67
67
|
{
|
|
68
68
|
options: {},
|
|
69
|
-
positionals: [positionalRequired({ type:
|
|
69
|
+
positionals: [positionalRequired({ type: type() })],
|
|
70
70
|
},
|
|
71
71
|
async function (context, inputs) {
|
|
72
72
|
return { at: "sub1", context, inputs };
|
|
@@ -79,9 +79,9 @@ const rootCommand = commandChained(
|
|
|
79
79
|
{
|
|
80
80
|
options: {},
|
|
81
81
|
positionals: [
|
|
82
|
-
positionalRequired({ type: typeNumber }),
|
|
83
|
-
positionalOptional({ type:
|
|
84
|
-
positionalVariadics({ type:
|
|
82
|
+
positionalRequired({ type: typeNumber() }),
|
|
83
|
+
positionalOptional({ type: type(), default: () => "42" }),
|
|
84
|
+
positionalVariadics({ type: type() }),
|
|
85
85
|
],
|
|
86
86
|
},
|
|
87
87
|
async function (context, inputs) {
|
|
@@ -96,7 +96,7 @@ const rootCommand = commandChained(
|
|
|
96
96
|
it("run", async function () {
|
|
97
97
|
expect(
|
|
98
98
|
await executeInterpreted(
|
|
99
|
-
["-fn=
|
|
99
|
+
["-fn=TRUE", "-fp", "50", "51", "sub1", "final"],
|
|
100
100
|
"Run Context Input",
|
|
101
101
|
rootCommand,
|
|
102
102
|
),
|
|
@@ -166,8 +166,8 @@ it("run", async function () {
|
|
|
166
166
|
"88.88",
|
|
167
167
|
"a,b",
|
|
168
168
|
"final",
|
|
169
|
-
"--
|
|
170
|
-
"--
|
|
169
|
+
"--flag-positive=NO",
|
|
170
|
+
"--flag-negative=false",
|
|
171
171
|
],
|
|
172
172
|
"Run Context Input",
|
|
173
173
|
rootCommand,
|
|
@@ -12,9 +12,10 @@ import {
|
|
|
12
12
|
positionalRequired,
|
|
13
13
|
positionalVariadics,
|
|
14
14
|
ReaderArgs,
|
|
15
|
+
type,
|
|
16
|
+
typeChoice,
|
|
15
17
|
typeList,
|
|
16
18
|
typeNumber,
|
|
17
|
-
typeString,
|
|
18
19
|
typeTuple,
|
|
19
20
|
TypoSupport,
|
|
20
21
|
usageToStyledLines,
|
|
@@ -34,6 +35,13 @@ const rootCommand = commandChained<any, any, any>(
|
|
|
34
35
|
operation(
|
|
35
36
|
{
|
|
36
37
|
options: {
|
|
38
|
+
choiceOption: optionSingleValue({
|
|
39
|
+
long: "choice-option",
|
|
40
|
+
type: typeChoice("choice", ["unset", "empty", "choice1", "choice2"]),
|
|
41
|
+
description: "choice-option description",
|
|
42
|
+
defaultWhenNotInlined: () => "empty",
|
|
43
|
+
defaultWhenNotDefined: () => "unset",
|
|
44
|
+
}),
|
|
37
45
|
booleanFlag: optionFlag({
|
|
38
46
|
short: "b",
|
|
39
47
|
long: "boolean-flag",
|
|
@@ -42,9 +50,8 @@ const rootCommand = commandChained<any, any, any>(
|
|
|
42
50
|
},
|
|
43
51
|
positionals: [
|
|
44
52
|
positionalRequired({
|
|
45
|
-
label: "POS-1",
|
|
46
53
|
description: "Required positional number 1",
|
|
47
|
-
type: typeNumber,
|
|
54
|
+
type: typeNumber("pos-1"),
|
|
48
55
|
}),
|
|
49
56
|
],
|
|
50
57
|
},
|
|
@@ -73,22 +80,20 @@ const rootCommand = commandChained<any, any, any>(
|
|
|
73
80
|
stringOption: optionSingleValue({
|
|
74
81
|
short: "s",
|
|
75
82
|
long: "string-option",
|
|
76
|
-
type:
|
|
77
|
-
|
|
78
|
-
label: "COOL-STUFF",
|
|
83
|
+
type: type("cool-stuff"),
|
|
84
|
+
defaultWhenNotDefined: () => undefined,
|
|
79
85
|
description: "string-option description",
|
|
80
86
|
}),
|
|
81
87
|
complexOption: optionRepeatable({
|
|
82
88
|
long: "complex-option",
|
|
83
|
-
type: typeTuple([typeNumber, typeList(
|
|
89
|
+
type: typeTuple([typeNumber(), typeList(type("string"))]),
|
|
84
90
|
description: "complex-option description",
|
|
85
91
|
}),
|
|
86
92
|
},
|
|
87
93
|
positionals: [
|
|
88
94
|
positionalRequired({
|
|
89
|
-
label: "POS-2",
|
|
90
95
|
description: "Required positional number 2",
|
|
91
|
-
type: typeNumber,
|
|
96
|
+
type: typeNumber("pos-2"),
|
|
92
97
|
}),
|
|
93
98
|
],
|
|
94
99
|
},
|
|
@@ -122,9 +127,8 @@ const rootCommand = commandChained<any, any, any>(
|
|
|
122
127
|
options: {},
|
|
123
128
|
positionals: [
|
|
124
129
|
positionalRequired({
|
|
125
|
-
label: "POS-STRING",
|
|
126
130
|
description: "Required positional string",
|
|
127
|
-
type:
|
|
131
|
+
type: type("pos-3.1"),
|
|
128
132
|
}),
|
|
129
133
|
],
|
|
130
134
|
},
|
|
@@ -148,7 +152,17 @@ const rootCommand = commandChained<any, any, any>(
|
|
|
148
152
|
{ positional: "40" },
|
|
149
153
|
{ positional: "41" },
|
|
150
154
|
{ subcommand: "sub2" },
|
|
151
|
-
{ option: { long: "dudu",
|
|
155
|
+
{ option: { long: "dudu", inlined: "hello" } },
|
|
156
|
+
{ positional: "50" },
|
|
157
|
+
],
|
|
158
|
+
},
|
|
159
|
+
{
|
|
160
|
+
explanation: "Example usage of subcommand 2",
|
|
161
|
+
commandArgs: [
|
|
162
|
+
{ positional: "40" },
|
|
163
|
+
{ positional: "41" },
|
|
164
|
+
{ subcommand: "sub2" },
|
|
165
|
+
{ option: { long: "dudu", separated: ["hello"] } },
|
|
152
166
|
{ positional: "50" },
|
|
153
167
|
],
|
|
154
168
|
},
|
|
@@ -159,29 +173,26 @@ const rootCommand = commandChained<any, any, any>(
|
|
|
159
173
|
options: {
|
|
160
174
|
duduValue: optionSingleValue({
|
|
161
175
|
long: "dudu",
|
|
162
|
-
type:
|
|
163
|
-
|
|
176
|
+
type: type("dudu-value"),
|
|
177
|
+
defaultWhenNotDefined: () => "duduDefault",
|
|
164
178
|
hint: "Dudu option hint",
|
|
165
179
|
description: "Dudu option description",
|
|
166
180
|
}),
|
|
167
181
|
},
|
|
168
182
|
positionals: [
|
|
169
183
|
positionalRequired({
|
|
170
|
-
label: "POS-NUMBER",
|
|
171
184
|
description: "Required positional number",
|
|
172
|
-
type: typeNumber,
|
|
185
|
+
type: typeNumber("pos-3.2"),
|
|
173
186
|
}),
|
|
174
187
|
positionalOptional({
|
|
175
|
-
label: "OPT-POS",
|
|
176
188
|
description: "Optional positional string",
|
|
177
189
|
hint: "Optional positional hint",
|
|
178
|
-
type:
|
|
190
|
+
type: type("pos-4"),
|
|
179
191
|
default: () => "42",
|
|
180
192
|
}),
|
|
181
193
|
positionalVariadics({
|
|
182
|
-
label: "VARIADIC",
|
|
183
194
|
description: "Variadic positionals strings",
|
|
184
|
-
type:
|
|
195
|
+
type: type("pos-5"),
|
|
185
196
|
}),
|
|
186
197
|
],
|
|
187
198
|
},
|
|
@@ -210,17 +221,18 @@ it("run", async function () {
|
|
|
210
221
|
);
|
|
211
222
|
|
|
212
223
|
const usageRoot = [
|
|
213
|
-
"{{Usage:}@darkMagenta}+ {{my-cli}@darkCyan}+ {{<
|
|
224
|
+
"{{Usage:}@darkMagenta}+ {{my-cli}@darkCyan}+ {{<pos-1>}@darkBlue}+ {{[REST]...}@darkBlue}+",
|
|
214
225
|
"",
|
|
215
226
|
"{Root command description}+",
|
|
216
227
|
"{{Root command details.}-}*",
|
|
217
228
|
"{{Root second line of command details.}-}*",
|
|
218
229
|
"",
|
|
219
230
|
"{{Positionals:}@darkGreen}+",
|
|
220
|
-
" {{<
|
|
231
|
+
" {{<pos-1>}@darkBlue}+ Required positional number 1",
|
|
221
232
|
"",
|
|
222
233
|
"{{Options:}@darkGreen}+",
|
|
223
|
-
"
|
|
234
|
+
" {{--choice-option}@darkCyan}+ {{<choice>}@darkBlue}+ choice-option description",
|
|
235
|
+
" {{-b}@darkCyan}+, {{--boolean-flag}@darkCyan}+{{[=no]}-}* boolean-flag description",
|
|
224
236
|
"",
|
|
225
237
|
"{{Examples:}@darkGreen}+",
|
|
226
238
|
" {{# Example usage of the root command}-}*",
|
|
@@ -228,24 +240,25 @@ it("run", async function () {
|
|
|
228
240
|
"",
|
|
229
241
|
];
|
|
230
242
|
const usageMid = [
|
|
231
|
-
"{{Usage:}@darkMagenta}+ {{my-cli}@darkCyan}+ {{<
|
|
243
|
+
"{{Usage:}@darkMagenta}+ {{my-cli}@darkCyan}+ {{<pos-1>}@darkBlue}+ {{<pos-2>}@darkBlue}+ {{<subcommand>}@darkBlue}+",
|
|
232
244
|
"",
|
|
233
245
|
"{Mid command description}+",
|
|
234
246
|
"{{Mid command details.}-}*",
|
|
235
247
|
"{{Mid second line of command details.}-}*",
|
|
236
248
|
"",
|
|
237
249
|
"{{Positionals:}@darkGreen}+",
|
|
238
|
-
" {{<
|
|
239
|
-
" {{<
|
|
250
|
+
" {{<pos-1>}@darkBlue}+ Required positional number 1",
|
|
251
|
+
" {{<pos-2>}@darkBlue}+ Required positional number 2",
|
|
240
252
|
"",
|
|
241
253
|
"{{Subcommands:}@darkGreen}+",
|
|
242
254
|
" {{sub1}@darkCyan}+ Subcommand 1 description",
|
|
243
255
|
" {{sub2}@darkCyan}+ Subcommand 2 description {{(Subcommand 2 hint)}-}*",
|
|
244
256
|
"",
|
|
245
257
|
"{{Options:}@darkGreen}+",
|
|
258
|
+
" {{--choice-option}@darkCyan}+ {{<choice>}@darkBlue}+ choice-option description",
|
|
246
259
|
" {{-b}@darkCyan}+, {{--boolean-flag}@darkCyan}+{{[=no]}-}* boolean-flag description",
|
|
247
|
-
" {{-s}@darkCyan}+, {{--string-option}@darkCyan}+ {{<
|
|
248
|
-
" {{--complex-option}@darkCyan}+ {{<
|
|
260
|
+
" {{-s}@darkCyan}+, {{--string-option}@darkCyan}+ {{<cool-stuff>}@darkBlue}+ string-option description",
|
|
261
|
+
" {{--complex-option}@darkCyan}+ {{<number,string[,string]...>}@darkBlue}+{{ [*]}-}* complex-option description",
|
|
249
262
|
"",
|
|
250
263
|
"{{Examples:}@darkGreen}+",
|
|
251
264
|
" {{# Example usage of the mid command}-}*",
|
|
@@ -253,21 +266,22 @@ it("run", async function () {
|
|
|
253
266
|
"",
|
|
254
267
|
];
|
|
255
268
|
const usageSub1 = [
|
|
256
|
-
"{{Usage:}@darkMagenta}+ {{my-cli}@darkCyan}+ {{<
|
|
269
|
+
"{{Usage:}@darkMagenta}+ {{my-cli}@darkCyan}+ {{<pos-1>}@darkBlue}+ {{<pos-2>}@darkBlue}+ {{sub1}@darkCyan}+ {{<pos-3.1>}@darkBlue}+",
|
|
257
270
|
"",
|
|
258
271
|
"{Subcommand 1 description}+",
|
|
259
272
|
"{{Subcommand 1 details.}-}*",
|
|
260
273
|
"{{Subcommand 1 second line of details.}-}*",
|
|
261
274
|
"",
|
|
262
275
|
"{{Positionals:}@darkGreen}+",
|
|
263
|
-
" {{<
|
|
264
|
-
" {{<
|
|
265
|
-
" {{<
|
|
276
|
+
" {{<pos-1>}@darkBlue}+ Required positional number 1",
|
|
277
|
+
" {{<pos-2>}@darkBlue}+ Required positional number 2",
|
|
278
|
+
" {{<pos-3.1>}@darkBlue}+ Required positional string",
|
|
266
279
|
"",
|
|
267
280
|
"{{Options:}@darkGreen}+",
|
|
281
|
+
" {{--choice-option}@darkCyan}+ {{<choice>}@darkBlue}+ choice-option description",
|
|
268
282
|
" {{-b}@darkCyan}+, {{--boolean-flag}@darkCyan}+{{[=no]}-}* boolean-flag description",
|
|
269
|
-
" {{-s}@darkCyan}+, {{--string-option}@darkCyan}+ {{<
|
|
270
|
-
" {{--complex-option}@darkCyan}+ {{<
|
|
283
|
+
" {{-s}@darkCyan}+, {{--string-option}@darkCyan}+ {{<cool-stuff>}@darkBlue}+ string-option description",
|
|
284
|
+
" {{--complex-option}@darkCyan}+ {{<number,string[,string]...>}@darkBlue}+{{ [*]}-}* complex-option description",
|
|
271
285
|
"",
|
|
272
286
|
"{{Examples:}@darkGreen}+",
|
|
273
287
|
" {{# Example usage of subcommand 1}-}*",
|
|
@@ -275,28 +289,31 @@ it("run", async function () {
|
|
|
275
289
|
"",
|
|
276
290
|
];
|
|
277
291
|
const usageSub2 = [
|
|
278
|
-
"{{Usage:}@darkMagenta}+ {{my-cli}@darkCyan}+ {{<
|
|
292
|
+
"{{Usage:}@darkMagenta}+ {{my-cli}@darkCyan}+ {{<pos-1>}@darkBlue}+ {{<pos-2>}@darkBlue}+ {{sub2}@darkCyan}+ {{<pos-3.2>}@darkBlue}+ {{[pos-4]}@darkBlue}+ {{[pos-5]...}@darkBlue}+",
|
|
279
293
|
"",
|
|
280
294
|
"{Subcommand 2 description}+ {{(Subcommand 2 hint)}-}*",
|
|
281
295
|
"{{Subcommand 2 details.}-}*",
|
|
282
296
|
"{{Subcommand 2 second line of details.}-}*",
|
|
283
297
|
"",
|
|
284
298
|
"{{Positionals:}@darkGreen}+",
|
|
285
|
-
" {{<
|
|
286
|
-
" {{<
|
|
287
|
-
" {{<
|
|
288
|
-
" {{[
|
|
289
|
-
" {{[
|
|
299
|
+
" {{<pos-1>}@darkBlue}+ Required positional number 1",
|
|
300
|
+
" {{<pos-2>}@darkBlue}+ Required positional number 2",
|
|
301
|
+
" {{<pos-3.2>}@darkBlue}+ Required positional number",
|
|
302
|
+
" {{[pos-4]}@darkBlue}+ Optional positional string {{(Optional positional hint)}-}*",
|
|
303
|
+
" {{[pos-5]...}@darkBlue}+ Variadic positionals strings",
|
|
290
304
|
"",
|
|
291
305
|
"{{Options:}@darkGreen}+",
|
|
306
|
+
" {{--choice-option}@darkCyan}+ {{<choice>}@darkBlue}+ choice-option description",
|
|
292
307
|
" {{-b}@darkCyan}+, {{--boolean-flag}@darkCyan}+{{[=no]}-}* boolean-flag description",
|
|
293
|
-
" {{-s}@darkCyan}+, {{--string-option}@darkCyan}+ {{<
|
|
294
|
-
" {{--complex-option}@darkCyan}+ {{<
|
|
295
|
-
" {{--dudu}@darkCyan}+ {{<
|
|
308
|
+
" {{-s}@darkCyan}+, {{--string-option}@darkCyan}+ {{<cool-stuff>}@darkBlue}+ string-option description",
|
|
309
|
+
" {{--complex-option}@darkCyan}+ {{<number,string[,string]...>}@darkBlue}+{{ [*]}-}* complex-option description",
|
|
310
|
+
" {{--dudu}@darkCyan}+ {{<dudu-value>}@darkBlue}+ Dudu option description {{(Dudu option hint)}-}*",
|
|
296
311
|
"",
|
|
297
312
|
"{{Examples:}@darkGreen}+",
|
|
298
313
|
" {{# Example usage of subcommand 2}-}*",
|
|
299
314
|
" {{my-cli}@darkCyan}+ {{40}@darkBlue}+ {{41}@darkBlue}+ {{sub2}@darkCyan}+ {{--dudu}@darkCyan}+{{=}-}*{{hello}@darkBlue}+ {{50}@darkBlue}+",
|
|
315
|
+
" {{# Example usage of subcommand 2}-}*",
|
|
316
|
+
" {{my-cli}@darkCyan}+ {{40}@darkBlue}+ {{41}@darkBlue}+ {{sub2}@darkCyan}+ {{--dudu}@darkCyan}+ {{hello}@darkBlue}+ {{50}@darkBlue}+",
|
|
300
317
|
"",
|
|
301
318
|
];
|
|
302
319
|
|
|
@@ -325,17 +342,6 @@ async function getUsage<Context, Result>(
|
|
|
325
342
|
) {
|
|
326
343
|
const readerArgs = new ReaderArgs(args);
|
|
327
344
|
const commandDecoder = command.consumeAndMakeDecoder(readerArgs);
|
|
328
|
-
/*
|
|
329
|
-
try {
|
|
330
|
-
const interpreter = commandDecoder.decodeAndMakeInterpreter();
|
|
331
|
-
const result = await interpreter.executeWithContext(
|
|
332
|
-
"" as unknown as Context,
|
|
333
|
-
);
|
|
334
|
-
console.log(result);
|
|
335
|
-
} catch (error) {
|
|
336
|
-
console.log(TypoSupport.tty().computeStyledErrorMessage(error));
|
|
337
|
-
}
|
|
338
|
-
*/
|
|
339
345
|
return usageToStyledLines({
|
|
340
346
|
cliName: "my-cli",
|
|
341
347
|
usage: commandDecoder.generateUsage(),
|