@flowscripter/dynamic-cli-framework 1.2.1 → 1.3.0
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/README/core-service-providers.md +2 -2
- package/README/development.md +3 -6
- package/README/implementation-details.md +17 -17
- package/README/key-concepts.md +17 -17
- package/README.md +4 -4
- package/bun.lock +0 -2
- package/index.ts +22 -30
- package/package.json +19 -19
- package/src/api/argument/Argument.ts +1 -1
- package/src/api/argument/ArgumentValueTypes.ts +3 -10
- package/src/api/argument/ComplexOption.ts +5 -9
- package/src/api/command/GlobalCommand.ts +1 -4
- package/src/api/service/core/ArgumentPrompterService.ts +1 -3
- package/src/api/service/core/AsciiBannerGeneratorService.ts +1 -4
- package/src/api/service/core/CompletionService.ts +2 -6
- package/src/api/service/core/ImagePrinterService.ts +1 -2
- package/src/api/service/core/KeyValueService.ts +1 -2
- package/src/api/service/core/PrettyPrinterService.ts +1 -4
- package/src/api/service/core/PrinterService.ts +8 -9
- package/src/api/service/core/PrompterService.ts +4 -11
- package/src/api/service/core/ShutdownService.ts +1 -2
- package/src/api/service/core/SyntaxHighlighterService.ts +1 -5
- package/src/api/service/core/Table.ts +7 -25
- package/src/api/service/core/TreePrinterService.ts +1 -2
- package/src/cli/BaseCLI.ts +17 -47
- package/src/cli/DefaultRuntimeCLI.ts +1 -4
- package/src/command/CompletionCommand.ts +19 -45
- package/src/command/MultiCommandCliHelpCommand.ts +45 -92
- package/src/command/SingleCommandCliHelpCommand.ts +17 -28
- package/src/command/UsageCommand.ts +6 -12
- package/src/command/VersionCommand.ts +2 -6
- package/src/launcher.ts +4 -2
- package/src/runtime/DefaultContext.ts +2 -5
- package/src/runtime/argument/ArgumentTypeGuards.ts +1 -3
- package/src/runtime/command/CommandTypeGuards.ts +5 -14
- package/src/runtime/command/CommandValidator.ts +56 -118
- package/src/runtime/parser.ts +13 -17
- package/src/runtime/registry/CommandRegistry.ts +2 -7
- package/src/runtime/registry/DefaultCommandRegistry.ts +32 -84
- package/src/runtime/registry/DefaultServiceProviderRegistry.ts +3 -9
- package/src/runtime/runner.ts +103 -142
- package/src/runtime/scanner.ts +28 -46
- package/src/runtime/values/ValuePopulationResult.ts +1 -2
- package/src/runtime/values/argumentValueMerge.ts +16 -28
- package/src/runtime/values/argumentValueValidation.ts +21 -67
- package/src/runtime/values/globalCommandValuePopulation.ts +9 -18
- package/src/runtime/values/subCommandValuePopulation.ts +42 -65
- package/src/service/argumentPrompter/ArgumentPrompterServiceProvider.ts +3 -10
- package/src/service/argumentPrompter/DefaultArgumentPrompterService.ts +22 -59
- package/src/service/asciiBannerGenerator/AsciiBannerGeneratorServiceProvider.ts +5 -14
- package/src/service/asciiBannerGenerator/DefaultAsciiBannerGeneratorService.ts +59 -77
- package/src/service/banner/BannerServiceProvider.ts +13 -35
- package/src/service/banner/command/NoBannerCommand.ts +2 -8
- package/src/service/chiselAsciiBannerGenerator/ChiselFontAsciiBannerGeneratorService.ts +5 -10
- package/src/service/completion/CompletionServiceProvider.ts +20 -48
- package/src/service/completion/DefaultCompletionService.ts +17 -56
- package/src/service/completion/shell/ShellHandler.ts +1 -3
- package/src/service/completion/shell/fish.ts +1 -1
- package/src/service/completion/shell/powershell.ts +2 -12
- package/src/service/completion/shell/zsh.ts +1 -1
- package/src/service/configuration/ConfigurationServiceProvider.ts +40 -133
- package/src/service/configuration/DefaultKeyValueService.ts +6 -20
- package/src/service/configuration/DefaultSecretService.ts +10 -14
- package/src/service/configuration/command/ConfigCommand.ts +1 -4
- package/src/service/configuration/command/DumpConfigCommand.ts +9 -21
- package/src/service/dataDumpGenerator/DataDumpGeneratorServiceProvider.ts +5 -14
- package/src/service/dataDumpGenerator/DefaultDataDumpGeneratorService.ts +5 -12
- package/src/service/imagePrinter/DefaultImagePrinterService.ts +1 -5
- package/src/service/imagePrinter/ImagePrinterServiceProvider.ts +1 -4
- package/src/service/prettyPrinter/DefaultPrettyPrinterService.ts +4 -12
- package/src/service/prettyPrinter/PrettyPrinterServiceProvider.ts +3 -10
- package/src/service/printer/DefaultPrinterService.ts +20 -83
- package/src/service/printer/PrinterServiceProvider.ts +3 -11
- package/src/service/printer/command/DarkModeCommand.ts +3 -10
- package/src/service/printer/command/LogLevelCommand.ts +7 -26
- package/src/service/printer/command/NoColorCommand.ts +3 -10
- package/src/service/printer/command/NoHyperlinksCommand.ts +3 -10
- package/src/service/printer/terminal/Progress.ts +99 -90
- package/src/service/printer/terminal/Spinner.ts +7 -26
- package/src/service/prompter/DefaultPrompterService.ts +2 -6
- package/src/service/prompter/PrompterServiceProvider.ts +3 -11
- package/src/service/prompter/command/NoPromptCommand.ts +3 -10
- package/src/service/prompter/prompt/PromptContext.ts +5 -18
- package/src/service/prompter/prompt/promptMultiSelect.ts +6 -21
- package/src/service/prompter/prompt/promptOpenUrl.ts +7 -22
- package/src/service/prompter/prompt/promptSingleSelect.ts +6 -23
- package/src/service/prompter/prompt/promptText.ts +10 -27
- package/src/service/prompter/prompt/promptToggle.ts +8 -8
- package/src/service/shutdown/ShutdownServiceProvider.ts +3 -10
- package/src/service/syntaxHighlighter/DefaultSyntaxHighlighterService.ts +13 -26
- package/src/service/syntaxHighlighter/SyntaxHighlighterServiceProvider.ts +8 -21
- package/src/service/tableGenerator/DefaultTableGeneratorService.ts +44 -68
- package/src/service/tableGenerator/TableGeneratorServiceProvider.ts +7 -16
- package/src/service/treePrinter/DefaultTreePrinterService.ts +2 -7
- package/src/service/treePrinter/TreePrinterServiceProvider.ts +4 -12
- package/src/terminal/ImageRenderer.ts +35 -54
- package/src/terminal/PngDecoder.ts +10 -19
- package/src/terminal/TtyStyler.ts +11 -9
- package/src/terminal/TtyTerminal.ts +2 -10
- package/src/terminal/supportsHyperlinks.ts +4 -10
- package/src/util/configHelper.ts +3 -10
- package/src/util/envVarHelper.ts +50 -88
- package/src/util/helpHelper.ts +123 -193
- package/src/util/logger.ts +12 -42
- package/src/util/runnerHelper.ts +20 -61
- package/tests/cli/BaseCLI.test.ts +23 -80
- package/tests/command/CompletionCommand.test.ts +1 -6
- package/tests/command/MultiCommandCliHelpCommand.test.ts +51 -205
- package/tests/command/SingleCommandCliHelpCommand.test.ts +21 -103
- package/tests/command/UsageCommand.test.ts +4 -10
- package/tests/fixtures/Command.ts +87 -68
- package/tests/fixtures/CommandRegistry.ts +1 -3
- package/tests/fixtures/Context.ts +3 -11
- package/tests/fixtures/ServiceProviderRegistry.ts +1 -1
- package/tests/fixtures/prettierPluginFoo.ts +1 -1
- package/tests/fixtures/util.ts +2 -8
- package/tests/runtime/argument/ArgumentTypeGuards.test.ts +1 -3
- package/tests/runtime/command/CommandValidator.test.ts +881 -604
- package/tests/runtime/parser.test.ts +222 -246
- package/tests/runtime/registry/DefaultCommandRegistry.test.ts +15 -37
- package/tests/runtime/registry/DefaultServiceProviderRegistry.test.ts +2 -8
- package/tests/runtime/runner.test.ts +231 -281
- package/tests/runtime/scanner.test.ts +277 -475
- package/tests/runtime/values/argumentValueMerge.test.ts +133 -81
- package/tests/runtime/values/argumentValueValidation.test.ts +444 -588
- package/tests/runtime/values/globalCommandValuePopulation.test.ts +71 -253
- package/tests/runtime/values/subCommandValuePopulation.test.ts +1342 -1570
- package/tests/service/argumentPrompter/ArgumentPrompterServiceProvider.test.ts +3 -12
- package/tests/service/argumentPrompter/DefaultArgumentPrompterService.test.ts +36 -45
- package/tests/service/asciiBannerGenerator/AsciiBannerGeneratorServiceProvider.test.ts +2 -8
- package/tests/service/asciiBannerGenerator/DefaultAsciiBannerGeneratorService.test.ts +40 -62
- package/tests/service/banner/BannerServiceProvider.test.ts +5 -18
- package/tests/service/banner/command/NoBannerCommand.test.ts +1 -4
- package/tests/service/completion/CompletionServiceProvider.test.ts +145 -214
- package/tests/service/completion/DefaultCompletionService.test.ts +17 -79
- package/tests/service/completion/shell/fish.test.ts +1 -3
- package/tests/service/configuration/ConfigurationServiceProvider.test.ts +26 -75
- package/tests/service/configuration/DefaultKeyValueService.test.ts +9 -21
- package/tests/service/configuration/DefaultSecretService.test.ts +7 -15
- package/tests/service/configuration/command/DumpConfigCommand.test.ts +4 -13
- package/tests/service/dataDumpGenerator/DataDumpGeneratorServiceProvider.test.ts +6 -12
- package/tests/service/dataDumpGenerator/DefaultDataDumpGeneratorService.test.ts +1 -10
- package/tests/service/imagePrinter/DefaultImagePrinterService.test.ts +5 -70
- package/tests/service/prettyPrinter/DefaultPrettyPrinterService.test.ts +4 -11
- package/tests/service/prettyPrinter/PrettyPrinterServiceProvider.test.ts +2 -6
- package/tests/service/printer/DefaultPrinterService.test.ts +57 -255
- package/tests/service/printer/PrinterServiceProvider.test.ts +2 -8
- package/tests/service/printer/command/DarkModeCommand.test.ts +4 -12
- package/tests/service/printer/command/LogLevelCommand.test.ts +4 -17
- package/tests/service/printer/command/NoColorCommand.test.ts +4 -12
- package/tests/service/printer/command/NoHyperlinksCommand.test.ts +7 -21
- package/tests/service/printer/terminal/Progress.test.ts +1 -3
- package/tests/service/printer/terminal/Spinner.test.ts +2 -8
- package/tests/service/prompter/DefaultPrompterService.test.ts +52 -69
- package/tests/service/prompter/PrompterServiceProvider.test.ts +2 -8
- package/tests/service/shutdown/ShutdownServiceProvider.test.ts +1 -3
- package/tests/service/syntaxHighlighter/DefaultSyntaxHighlighterService.test.ts +13 -99
- package/tests/service/syntaxHighlighter/SyntaxHighlighterServiceProvider.test.ts +2 -7
- package/tests/service/tableGenerator/DefaultTableGeneratorService.test.ts +12 -33
- package/tests/service/tableGenerator/TableGeneratorServiceProvider.test.ts +2 -2
- package/tests/service/treePrinter/DefaultTreePrinterService.test.ts +4 -6
- package/tests/service/treePrinter/TreePrinterServiceProvider.test.ts +4 -8
- package/tests/terminal/ImageRenderer.test.ts +2 -11
- package/tests/terminal/PngDecoder.test.ts +2 -6
- package/tests/util/configHelper.test.ts +55 -137
- package/tests/util/envVarHelper.test.ts +46 -110
package/src/runtime/runner.ts
CHANGED
|
@@ -17,16 +17,9 @@ import {
|
|
|
17
17
|
printParseResultError,
|
|
18
18
|
printUnusedArgsWarning,
|
|
19
19
|
} from "../util/runnerHelper.ts";
|
|
20
|
-
import {
|
|
21
|
-
scanForGlobalModifierCommandClauses,
|
|
22
|
-
scanForNonModifierCommandClause,
|
|
23
|
-
} from "./scanner.ts";
|
|
20
|
+
import { scanForGlobalModifierCommandClauses, scanForNonModifierCommandClause } from "./scanner.ts";
|
|
24
21
|
import type ServiceProviderRegistry from "./registry/ServiceProviderRegistry.ts";
|
|
25
|
-
import {
|
|
26
|
-
parseGlobalCommandClause,
|
|
27
|
-
type ParseResult,
|
|
28
|
-
parseSubCommandClause,
|
|
29
|
-
} from "./parser.ts";
|
|
22
|
+
import { parseGlobalCommandClause, type ParseResult, parseSubCommandClause } from "./parser.ts";
|
|
30
23
|
import type ConfigurationServiceProvider from "../service/configuration/ConfigurationServiceProvider.ts";
|
|
31
24
|
import type GlobalModifierCommand from "../api/command/GlobalModifierCommand.ts";
|
|
32
25
|
import type GroupCommand from "../api/command/GroupCommand.ts";
|
|
@@ -45,9 +38,7 @@ async function attemptPromptForMissingArguments(
|
|
|
45
38
|
if (!context.doesServiceExist(ARGUMENT_PROMPTER_SERVICE_ID)) {
|
|
46
39
|
return undefined;
|
|
47
40
|
}
|
|
48
|
-
const service = context.getServiceById(
|
|
49
|
-
ARGUMENT_PROMPTER_SERVICE_ID,
|
|
50
|
-
) as ArgumentPrompterService;
|
|
41
|
+
const service = context.getServiceById(ARGUMENT_PROMPTER_SERVICE_ID) as ArgumentPrompterService;
|
|
51
42
|
try {
|
|
52
43
|
const updated = await service.promptForMissingArguments(parseResult);
|
|
53
44
|
if (updated.invalidArguments.length === 0) {
|
|
@@ -78,17 +69,12 @@ async function executeParsedCommand(
|
|
|
78
69
|
): Promise<RunResult> {
|
|
79
70
|
try {
|
|
80
71
|
if (parseResult.groupCommand !== undefined) {
|
|
81
|
-
logger.debug(
|
|
82
|
-
"Executing group command with name: %s",
|
|
83
|
-
parseResult!.groupCommand!.name,
|
|
84
|
-
);
|
|
72
|
+
logger.debug("Executing group command with name: %s", parseResult!.groupCommand!.name);
|
|
85
73
|
if (
|
|
86
74
|
configurationServiceProvider?.keyValueServiceEnabled ||
|
|
87
75
|
configurationServiceProvider?.secretServiceEnabled
|
|
88
76
|
) {
|
|
89
|
-
configurationServiceProvider.setCommandKeyValueScope(
|
|
90
|
-
parseResult!.groupCommand!.name,
|
|
91
|
-
);
|
|
77
|
+
configurationServiceProvider.setCommandKeyValueScope(parseResult!.groupCommand!.name);
|
|
92
78
|
}
|
|
93
79
|
await parseResult.groupCommand.execute(context);
|
|
94
80
|
if (
|
|
@@ -109,9 +95,7 @@ async function executeParsedCommand(
|
|
|
109
95
|
configurationServiceProvider?.keyValueServiceEnabled ||
|
|
110
96
|
configurationServiceProvider?.secretServiceEnabled
|
|
111
97
|
) {
|
|
112
|
-
configurationServiceProvider.setCommandKeyValueScope(
|
|
113
|
-
parseResult.command.name,
|
|
114
|
-
);
|
|
98
|
+
configurationServiceProvider.setCommandKeyValueScope(parseResult.command.name);
|
|
115
99
|
}
|
|
116
100
|
if (isSubCommand(parseResult.command)) {
|
|
117
101
|
await parseResult.command.execute(
|
|
@@ -134,12 +118,7 @@ async function executeParsedCommand(
|
|
|
134
118
|
if ((err as Error).message === "Interrupted") {
|
|
135
119
|
throw err;
|
|
136
120
|
}
|
|
137
|
-
await printCommandExecutionError(
|
|
138
|
-
context,
|
|
139
|
-
parseResult,
|
|
140
|
-
err as Error,
|
|
141
|
-
isDefaultCommand,
|
|
142
|
-
);
|
|
121
|
+
await printCommandExecutionError(context, parseResult, err as Error, isDefaultCommand);
|
|
143
122
|
return {
|
|
144
123
|
runState: RunState.EXECUTION_ERROR,
|
|
145
124
|
command: parseResult.command,
|
|
@@ -166,10 +145,7 @@ async function findAndExecuteGlobalModifierCommands(
|
|
|
166
145
|
availableArgSequences: ReadonlyArray<ReadonlyArray<string>>,
|
|
167
146
|
unusedArgSequences: Array<ReadonlyArray<string>>,
|
|
168
147
|
globalModifierCommandsByName: ReadonlyMap<string, GlobalModifierCommand>,
|
|
169
|
-
globalModifierCommandsByShortAlias: ReadonlyMap<
|
|
170
|
-
string,
|
|
171
|
-
GlobalModifierCommand
|
|
172
|
-
>,
|
|
148
|
+
globalModifierCommandsByShortAlias: ReadonlyMap<string, GlobalModifierCommand>,
|
|
173
149
|
configurationServiceProvider: ConfigurationServiceProvider | undefined,
|
|
174
150
|
context: Context,
|
|
175
151
|
): Promise<RunResult | undefined> {
|
|
@@ -177,9 +153,7 @@ async function findAndExecuteGlobalModifierCommands(
|
|
|
177
153
|
const globalModifierCommandParseResults: Array<ParseResult> = [];
|
|
178
154
|
|
|
179
155
|
// maintain a list of remaining GlobalModifierCommands to scan
|
|
180
|
-
let remainingGlobalModifierCommands = Array.from(
|
|
181
|
-
globalModifierCommandsByName.values(),
|
|
182
|
-
);
|
|
156
|
+
let remainingGlobalModifierCommands = Array.from(globalModifierCommandsByName.values());
|
|
183
157
|
const scanResult = scanForGlobalModifierCommandClauses(
|
|
184
158
|
availableArgSequences,
|
|
185
159
|
globalModifierCommandsByName,
|
|
@@ -190,14 +164,10 @@ async function findAndExecuteGlobalModifierCommands(
|
|
|
190
164
|
unusedArgSequences.push(...scanResult.unusedArgSequences);
|
|
191
165
|
|
|
192
166
|
if (scanResult.globalModifierCommandClauses) {
|
|
193
|
-
for (
|
|
194
|
-
const globalModifierCommandClause of scanResult
|
|
195
|
-
.globalModifierCommandClauses
|
|
196
|
-
) {
|
|
167
|
+
for (const globalModifierCommandClause of scanResult.globalModifierCommandClauses) {
|
|
197
168
|
// parse and fast fail on error
|
|
198
169
|
const defaultArgumentValues = configurationServiceProvider
|
|
199
|
-
? await configurationServiceProvider
|
|
200
|
-
.getDefaultArgumentValues(
|
|
170
|
+
? await configurationServiceProvider.getDefaultArgumentValues(
|
|
201
171
|
context.cliConfig,
|
|
202
172
|
globalModifierCommandClause.command,
|
|
203
173
|
)
|
|
@@ -226,9 +196,9 @@ async function findAndExecuteGlobalModifierCommands(
|
|
|
226
196
|
|
|
227
197
|
// remove current GlobalModifierCommand from the list which we will later continue to
|
|
228
198
|
// scan for as a default command in the ConfigurationServiceProvider
|
|
229
|
-
remainingGlobalModifierCommands = remainingGlobalModifierCommands.filter(
|
|
230
|
-
command,
|
|
231
|
-
)
|
|
199
|
+
remainingGlobalModifierCommands = remainingGlobalModifierCommands.filter(
|
|
200
|
+
(command) => command.name !== globalModifierCommandClause.command.name,
|
|
201
|
+
);
|
|
232
202
|
}
|
|
233
203
|
}
|
|
234
204
|
|
|
@@ -236,16 +206,21 @@ async function findAndExecuteGlobalModifierCommands(
|
|
|
236
206
|
for (const globalModifierCommand of remainingGlobalModifierCommands) {
|
|
237
207
|
// if there is a config entry run this by default even though no arguments were provided on the command line
|
|
238
208
|
const defaultArgumentValues = configurationServiceProvider
|
|
239
|
-
? await configurationServiceProvider
|
|
240
|
-
|
|
209
|
+
? await configurationServiceProvider.getDefaultArgumentValues(
|
|
210
|
+
context.cliConfig,
|
|
211
|
+
globalModifierCommand,
|
|
212
|
+
)
|
|
241
213
|
: undefined;
|
|
242
214
|
|
|
243
215
|
if (defaultArgumentValues !== undefined) {
|
|
244
216
|
// parse and fast fail on error
|
|
245
|
-
const parseResult = parseGlobalCommandClause(
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
217
|
+
const parseResult = parseGlobalCommandClause(
|
|
218
|
+
{
|
|
219
|
+
command: globalModifierCommand,
|
|
220
|
+
potentialArgs: [],
|
|
221
|
+
},
|
|
222
|
+
defaultArgumentValues as PopulatedArgumentSingleValueType,
|
|
223
|
+
);
|
|
249
224
|
|
|
250
225
|
if (parseResult.invalidArguments.length > 0) {
|
|
251
226
|
await printParseResultError(context, parseResult);
|
|
@@ -262,9 +237,10 @@ async function findAndExecuteGlobalModifierCommands(
|
|
|
262
237
|
}
|
|
263
238
|
|
|
264
239
|
// execute GlobalModifierCommand clauses in executePriority order
|
|
265
|
-
globalModifierCommandParseResults.sort(
|
|
266
|
-
(b
|
|
267
|
-
|
|
240
|
+
globalModifierCommandParseResults.sort(
|
|
241
|
+
(a, b) =>
|
|
242
|
+
(b.command as GlobalModifierCommand).executePriority -
|
|
243
|
+
(a.command as GlobalModifierCommand).executePriority,
|
|
268
244
|
);
|
|
269
245
|
for (const parseResult of globalModifierCommandParseResults) {
|
|
270
246
|
// execute and fast fail on error
|
|
@@ -315,8 +291,7 @@ async function findAndExecuteNonModifierCommand(
|
|
|
315
291
|
|
|
316
292
|
if (scanResult.nonModifierCommandClause) {
|
|
317
293
|
const defaultArgumentValues = configurationServiceProvider
|
|
318
|
-
? await configurationServiceProvider
|
|
319
|
-
.getDefaultArgumentValues(
|
|
294
|
+
? await configurationServiceProvider.getDefaultArgumentValues(
|
|
320
295
|
context.cliConfig,
|
|
321
296
|
scanResult.nonModifierCommandClause.command,
|
|
322
297
|
)
|
|
@@ -335,10 +310,7 @@ async function findAndExecuteNonModifierCommand(
|
|
|
335
310
|
}
|
|
336
311
|
|
|
337
312
|
if (parseResult.invalidArguments.length > 0) {
|
|
338
|
-
const prompted = await attemptPromptForMissingArguments(
|
|
339
|
-
parseResult,
|
|
340
|
-
context,
|
|
341
|
-
);
|
|
313
|
+
const prompted = await attemptPromptForMissingArguments(parseResult, context);
|
|
342
314
|
if (prompted) {
|
|
343
315
|
parseResult = prompted;
|
|
344
316
|
} else {
|
|
@@ -360,28 +332,33 @@ async function findAndExecuteNonModifierCommand(
|
|
|
360
332
|
for (const nonModifierCommand of nonModifierCommandsByName.values()) {
|
|
361
333
|
// if there is a config entry run this by default even though no arguments were provided on the command line
|
|
362
334
|
const defaultArgumentValues = configurationServiceProvider
|
|
363
|
-
? await configurationServiceProvider
|
|
364
|
-
|
|
335
|
+
? await configurationServiceProvider.getDefaultArgumentValues(
|
|
336
|
+
context.cliConfig,
|
|
337
|
+
nonModifierCommand,
|
|
338
|
+
)
|
|
365
339
|
: undefined;
|
|
366
340
|
|
|
367
341
|
if (defaultArgumentValues !== undefined) {
|
|
368
342
|
if (isGlobalCommand(nonModifierCommand)) {
|
|
369
|
-
parseResult = parseGlobalCommandClause(
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
343
|
+
parseResult = parseGlobalCommandClause(
|
|
344
|
+
{
|
|
345
|
+
command: nonModifierCommand,
|
|
346
|
+
potentialArgs: [],
|
|
347
|
+
},
|
|
348
|
+
defaultArgumentValues as PopulatedArgumentSingleValueType,
|
|
349
|
+
);
|
|
373
350
|
} else {
|
|
374
|
-
parseResult = parseSubCommandClause(
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
351
|
+
parseResult = parseSubCommandClause(
|
|
352
|
+
{
|
|
353
|
+
command: nonModifierCommand,
|
|
354
|
+
potentialArgs: [],
|
|
355
|
+
},
|
|
356
|
+
defaultArgumentValues as PopulatedArgumentValues,
|
|
357
|
+
);
|
|
378
358
|
}
|
|
379
359
|
|
|
380
360
|
if (parseResult.invalidArguments.length > 0) {
|
|
381
|
-
const prompted = await attemptPromptForMissingArguments(
|
|
382
|
-
parseResult,
|
|
383
|
-
context,
|
|
384
|
-
);
|
|
361
|
+
const prompted = await attemptPromptForMissingArguments(parseResult, context);
|
|
385
362
|
if (prompted) {
|
|
386
363
|
parseResult = prompted;
|
|
387
364
|
} else {
|
|
@@ -409,11 +386,7 @@ async function findAndExecuteNonModifierCommand(
|
|
|
409
386
|
await printUnusedArgsWarning(context, unusedArgs.flat());
|
|
410
387
|
}
|
|
411
388
|
|
|
412
|
-
return executeParsedCommand(
|
|
413
|
-
parseResult,
|
|
414
|
-
context,
|
|
415
|
-
configurationServiceProvider,
|
|
416
|
-
);
|
|
389
|
+
return executeParsedCommand(parseResult, context, configurationServiceProvider);
|
|
417
390
|
}
|
|
418
391
|
|
|
419
392
|
/**
|
|
@@ -433,8 +406,10 @@ async function findAndExecuteDefaultNonModifierCommand(
|
|
|
433
406
|
context: Context,
|
|
434
407
|
): Promise<RunResult | undefined> {
|
|
435
408
|
const defaultArgumentValues = configurationServiceProvider
|
|
436
|
-
? await configurationServiceProvider
|
|
437
|
-
|
|
409
|
+
? await configurationServiceProvider.getDefaultArgumentValues(
|
|
410
|
+
context.cliConfig,
|
|
411
|
+
defaultNonModifierCommand,
|
|
412
|
+
)
|
|
438
413
|
: undefined;
|
|
439
414
|
const isGlobal = isGlobalCommand(defaultNonModifierCommand);
|
|
440
415
|
let parseResult: ParseResult | undefined;
|
|
@@ -450,15 +425,21 @@ async function findAndExecuteDefaultNonModifierCommand(
|
|
|
450
425
|
continue;
|
|
451
426
|
}
|
|
452
427
|
if (isGlobal) {
|
|
453
|
-
parseResult = parseGlobalCommandClause(
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
428
|
+
parseResult = parseGlobalCommandClause(
|
|
429
|
+
{
|
|
430
|
+
command: defaultNonModifierCommand,
|
|
431
|
+
potentialArgs: [...argSequence],
|
|
432
|
+
},
|
|
433
|
+
defaultArgumentValues as PopulatedArgumentSingleValueType,
|
|
434
|
+
);
|
|
457
435
|
} else {
|
|
458
|
-
parseResult = parseSubCommandClause(
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
436
|
+
parseResult = parseSubCommandClause(
|
|
437
|
+
{
|
|
438
|
+
command: defaultNonModifierCommand,
|
|
439
|
+
potentialArgs: [...argSequence],
|
|
440
|
+
},
|
|
441
|
+
defaultArgumentValues as PopulatedArgumentValues,
|
|
442
|
+
);
|
|
462
443
|
}
|
|
463
444
|
|
|
464
445
|
// add any unused args back to the list of still unused args
|
|
@@ -476,27 +457,29 @@ async function findAndExecuteDefaultNonModifierCommand(
|
|
|
476
457
|
// if there are no arguments for the command or there is a config entry
|
|
477
458
|
let commandHasNoArgs;
|
|
478
459
|
if (isGlobal) {
|
|
479
|
-
commandHasNoArgs =
|
|
480
|
-
(defaultNonModifierCommand as GlobalCommand).argument === undefined;
|
|
460
|
+
commandHasNoArgs = (defaultNonModifierCommand as GlobalCommand).argument === undefined;
|
|
481
461
|
} else {
|
|
482
462
|
commandHasNoArgs =
|
|
483
|
-
(
|
|
484
|
-
(
|
|
463
|
+
(defaultNonModifierCommand as SubCommand).options.length === 0 &&
|
|
464
|
+
(defaultNonModifierCommand as SubCommand).positionals.length === 0;
|
|
485
465
|
}
|
|
486
|
-
if (
|
|
487
|
-
(parseResult === undefined) &&
|
|
488
|
-
(commandHasNoArgs || (defaultArgumentValues !== undefined))
|
|
489
|
-
) {
|
|
466
|
+
if (parseResult === undefined && (commandHasNoArgs || defaultArgumentValues !== undefined)) {
|
|
490
467
|
if (isGlobal) {
|
|
491
|
-
parseResult = parseGlobalCommandClause(
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
468
|
+
parseResult = parseGlobalCommandClause(
|
|
469
|
+
{
|
|
470
|
+
command: defaultNonModifierCommand,
|
|
471
|
+
potentialArgs: [],
|
|
472
|
+
},
|
|
473
|
+
defaultArgumentValues as PopulatedArgumentSingleValueType,
|
|
474
|
+
);
|
|
495
475
|
} else {
|
|
496
|
-
parseResult = parseSubCommandClause(
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
476
|
+
parseResult = parseSubCommandClause(
|
|
477
|
+
{
|
|
478
|
+
command: defaultNonModifierCommand,
|
|
479
|
+
potentialArgs: [],
|
|
480
|
+
},
|
|
481
|
+
defaultArgumentValues as PopulatedArgumentValues,
|
|
482
|
+
);
|
|
500
483
|
}
|
|
501
484
|
|
|
502
485
|
if (parseResult.invalidArguments.length > 0) {
|
|
@@ -507,10 +490,7 @@ async function findAndExecuteDefaultNonModifierCommand(
|
|
|
507
490
|
|
|
508
491
|
// if there were invalid arguments, attempt prompting before treating as error
|
|
509
492
|
if (lastErroneousParseResult) {
|
|
510
|
-
const prompted = await attemptPromptForMissingArguments(
|
|
511
|
-
lastErroneousParseResult,
|
|
512
|
-
context,
|
|
513
|
-
);
|
|
493
|
+
const prompted = await attemptPromptForMissingArguments(lastErroneousParseResult, context);
|
|
514
494
|
if (prompted) {
|
|
515
495
|
parseResult = prompted;
|
|
516
496
|
lastErroneousParseResult = undefined;
|
|
@@ -534,12 +514,7 @@ async function findAndExecuteDefaultNonModifierCommand(
|
|
|
534
514
|
await printUnusedArgsWarning(context, unusedArgs.flat());
|
|
535
515
|
}
|
|
536
516
|
|
|
537
|
-
return executeParsedCommand(
|
|
538
|
-
parseResult,
|
|
539
|
-
context,
|
|
540
|
-
configurationServiceProvider,
|
|
541
|
-
true,
|
|
542
|
-
);
|
|
517
|
+
return executeParsedCommand(parseResult, context, configurationServiceProvider, true);
|
|
543
518
|
}
|
|
544
519
|
|
|
545
520
|
/**
|
|
@@ -618,10 +593,7 @@ export async function run(
|
|
|
618
593
|
context: Context,
|
|
619
594
|
defaultCommand?: Command,
|
|
620
595
|
): Promise<RunResult> {
|
|
621
|
-
if (
|
|
622
|
-
defaultCommand && !isSubCommand(defaultCommand) &&
|
|
623
|
-
!isGlobalCommand(defaultCommand)
|
|
624
|
-
) {
|
|
596
|
+
if (defaultCommand && !isSubCommand(defaultCommand) && !isGlobalCommand(defaultCommand)) {
|
|
625
597
|
throw new Error(
|
|
626
598
|
"If a default command is provided, if must be a global command or sub-command!",
|
|
627
599
|
);
|
|
@@ -635,12 +607,10 @@ export async function run(
|
|
|
635
607
|
// for each ServiceProvider (they are returned in servicePriority order)
|
|
636
608
|
for (const serviceProvider of serviceProviderRegistry.getServiceProviders()) {
|
|
637
609
|
// using the GlobalModifierCommands instances provided by the ServiceProvider...
|
|
638
|
-
const globalModifierCommandsByName =
|
|
639
|
-
.getGlobalModifierCommandsByNameProvidedByService(
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
const globalModifierCommandsByShortAlias = commandRegistry
|
|
643
|
-
.getGlobalModifierCommandsByShortAliasProvidedByService(
|
|
610
|
+
const globalModifierCommandsByName =
|
|
611
|
+
commandRegistry.getGlobalModifierCommandsByNameProvidedByService(serviceProvider.serviceId);
|
|
612
|
+
const globalModifierCommandsByShortAlias =
|
|
613
|
+
commandRegistry.getGlobalModifierCommandsByShortAliasProvidedByService(
|
|
644
614
|
serviceProvider.serviceId,
|
|
645
615
|
);
|
|
646
616
|
|
|
@@ -674,9 +644,7 @@ export async function run(
|
|
|
674
644
|
configurationServiceProvider?.keyValueServiceEnabled ||
|
|
675
645
|
configurationServiceProvider?.secretServiceEnabled
|
|
676
646
|
) {
|
|
677
|
-
configurationServiceProvider.setServiceKeyValueScope(
|
|
678
|
-
serviceProvider.serviceId,
|
|
679
|
-
);
|
|
647
|
+
configurationServiceProvider.setServiceKeyValueScope(serviceProvider.serviceId);
|
|
680
648
|
}
|
|
681
649
|
|
|
682
650
|
await serviceProvider.initService(context);
|
|
@@ -689,10 +657,10 @@ export async function run(
|
|
|
689
657
|
}
|
|
690
658
|
|
|
691
659
|
// using the GlobalModifierCommands instances which are NOT provided by a ServiceProvider...
|
|
692
|
-
const globalModifierCommandsByName =
|
|
693
|
-
.getGlobalModifierCommandsByNameNotProvidedByService();
|
|
694
|
-
const globalModifierCommandsByShortAlias =
|
|
695
|
-
.getGlobalModifierCommandsByShortAliasNotProvidedByService();
|
|
660
|
+
const globalModifierCommandsByName =
|
|
661
|
+
commandRegistry.getGlobalModifierCommandsByNameNotProvidedByService();
|
|
662
|
+
const globalModifierCommandsByShortAlias =
|
|
663
|
+
commandRegistry.getGlobalModifierCommandsByShortAliasNotProvidedByService();
|
|
696
664
|
|
|
697
665
|
// if there are GlobalModifierCommands NOT provided by the ServiceProvider...
|
|
698
666
|
if (globalModifierCommandsByName.size > 0) {
|
|
@@ -717,13 +685,10 @@ export async function run(
|
|
|
717
685
|
}
|
|
718
686
|
|
|
719
687
|
// using the non-modifier Command instances...
|
|
720
|
-
const nonModifierCommandsByName = commandRegistry
|
|
721
|
-
|
|
722
|
-
const globalCommandsByShortAlias = commandRegistry
|
|
723
|
-
.getGlobalCommandsByShortAlias();
|
|
688
|
+
const nonModifierCommandsByName = commandRegistry.getNonModifierCommandsByName();
|
|
689
|
+
const globalCommandsByShortAlias = commandRegistry.getGlobalCommandsByShortAlias();
|
|
724
690
|
// and any group/member instance combinations...
|
|
725
|
-
const groupAndMemberCommandByJoinedName = commandRegistry
|
|
726
|
-
.getGroupAndMemberCommandsByJoinedName();
|
|
691
|
+
const groupAndMemberCommandByJoinedName = commandRegistry.getGroupAndMemberCommandsByJoinedName();
|
|
727
692
|
|
|
728
693
|
// ...scan arguments, parse a resulting clause and execute a resulting parsed non-modifier Command
|
|
729
694
|
let runResult = await findAndExecuteNonModifierCommand(
|
|
@@ -764,11 +729,7 @@ export async function run(
|
|
|
764
729
|
|
|
765
730
|
// give up if we haven't successfully parsed a non-modifier Command by now
|
|
766
731
|
if (availableArgs.length > 0) {
|
|
767
|
-
await printNoCommandRecognisedError(
|
|
768
|
-
context,
|
|
769
|
-
commandRegistry,
|
|
770
|
-
availableArgs.flat(),
|
|
771
|
-
);
|
|
732
|
+
await printNoCommandRecognisedError(context, commandRegistry, availableArgs.flat());
|
|
772
733
|
} else {
|
|
773
734
|
await printNoCommandSpecifiedError(context);
|
|
774
735
|
}
|
package/src/runtime/scanner.ts
CHANGED
|
@@ -67,14 +67,14 @@ function normaliseFirstArgumentIfRequired(
|
|
|
67
67
|
// --<global_[modifier_]command_name>=<value>
|
|
68
68
|
// -<global_[modifier_]command_short_alias>
|
|
69
69
|
// -<global_[modifier_]command_short_alias>=<value>
|
|
70
|
-
if (
|
|
70
|
+
if (firstArg!.length < 2 || firstArg!.charAt(0) !== "-") {
|
|
71
71
|
return args;
|
|
72
72
|
}
|
|
73
73
|
|
|
74
74
|
// looking for:
|
|
75
75
|
// --<global_[modifier_]command_name>
|
|
76
76
|
// --<global_[modifier_]command_name>=<value>
|
|
77
|
-
if (
|
|
77
|
+
if (firstArg!.length > 2 && firstArg!.charAt(1) === "-") {
|
|
78
78
|
let potentialGlobalCommandName = firstArg!.slice(2);
|
|
79
79
|
|
|
80
80
|
// looking for:
|
|
@@ -82,9 +82,10 @@ function normaliseFirstArgumentIfRequired(
|
|
|
82
82
|
// <global_modifier_command_name>=<value>
|
|
83
83
|
let nextArg: string | undefined;
|
|
84
84
|
if (potentialGlobalCommandName.includes("=")) {
|
|
85
|
-
[potentialGlobalCommandName, nextArg] = potentialGlobalCommandName.split(
|
|
86
|
-
|
|
87
|
-
|
|
85
|
+
[potentialGlobalCommandName, nextArg] = potentialGlobalCommandName.split(/=(.*)/) as [
|
|
86
|
+
string,
|
|
87
|
+
string | undefined,
|
|
88
|
+
];
|
|
88
89
|
}
|
|
89
90
|
|
|
90
91
|
if (!globalCommandsByName.has(potentialGlobalCommandName)) {
|
|
@@ -95,8 +96,8 @@ function normaliseFirstArgumentIfRequired(
|
|
|
95
96
|
// nothing changed
|
|
96
97
|
return args;
|
|
97
98
|
}
|
|
98
|
-
logger.debug(
|
|
99
|
-
`Normalised arg: '${firstArg}' to: '--${potentialGlobalCommandName} ${nextArg}'
|
|
99
|
+
logger.debug(
|
|
100
|
+
() => `Normalised arg: '${firstArg}' to: '--${potentialGlobalCommandName} ${nextArg}'`,
|
|
100
101
|
);
|
|
101
102
|
return [`--${potentialGlobalCommandName}`, nextArg, ...args.slice(1)];
|
|
102
103
|
}
|
|
@@ -111,11 +112,9 @@ function normaliseFirstArgumentIfRequired(
|
|
|
111
112
|
// <global_[modifier_]command_short_alias>=<value>
|
|
112
113
|
let nextArg: string | undefined;
|
|
113
114
|
if (potentialGlobalCommandShortAlias.includes("=")) {
|
|
114
|
-
[potentialGlobalCommandShortAlias, nextArg] =
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
string | undefined,
|
|
118
|
-
];
|
|
115
|
+
[potentialGlobalCommandShortAlias, nextArg] = potentialGlobalCommandShortAlias.split(
|
|
116
|
+
/=(.*)/,
|
|
117
|
+
) as [string, string | undefined];
|
|
119
118
|
}
|
|
120
119
|
|
|
121
120
|
if (!globalCommandsByShortAlias) {
|
|
@@ -124,23 +123,17 @@ function normaliseFirstArgumentIfRequired(
|
|
|
124
123
|
}
|
|
125
124
|
|
|
126
125
|
// looking for <global_[modifier_]command_short_alias>
|
|
127
|
-
const globalCommand = globalCommandsByShortAlias.get(
|
|
128
|
-
potentialGlobalCommandShortAlias,
|
|
129
|
-
);
|
|
126
|
+
const globalCommand = globalCommandsByShortAlias.get(potentialGlobalCommandShortAlias);
|
|
130
127
|
if (!globalCommand) {
|
|
131
128
|
// nothing changed
|
|
132
129
|
return args;
|
|
133
130
|
}
|
|
134
131
|
|
|
135
132
|
if (nextArg) {
|
|
136
|
-
logger.debug(() =>
|
|
137
|
-
`Normalised arg: '${firstArg}' to: '--${globalCommand.name} ${nextArg}'`
|
|
138
|
-
);
|
|
133
|
+
logger.debug(() => `Normalised arg: '${firstArg}' to: '--${globalCommand.name} ${nextArg}'`);
|
|
139
134
|
return [`--${globalCommand.name}`, nextArg, ...args.slice(1)];
|
|
140
135
|
}
|
|
141
|
-
logger.debug(() =>
|
|
142
|
-
`Normalised arg: '${firstArg}' to: '--${globalCommand.name}'`
|
|
143
|
-
);
|
|
136
|
+
logger.debug(() => `Normalised arg: '${firstArg}' to: '--${globalCommand.name}'`);
|
|
144
137
|
return [`--${globalCommand.name}`, ...args.slice(1)];
|
|
145
138
|
}
|
|
146
139
|
|
|
@@ -178,10 +171,7 @@ function scanForNextCommandClause(
|
|
|
178
171
|
// check for Global[Modifier]Command name
|
|
179
172
|
const command = commandsByName.get(potentialCommandName);
|
|
180
173
|
if (command) {
|
|
181
|
-
logger.debug(
|
|
182
|
-
"Found global [modifier] command name: %s",
|
|
183
|
-
potentialCommandName,
|
|
184
|
-
);
|
|
174
|
+
logger.debug("Found global [modifier] command name: %s", potentialCommandName);
|
|
185
175
|
return {
|
|
186
176
|
commandClause: {
|
|
187
177
|
command,
|
|
@@ -191,7 +181,7 @@ function scanForNextCommandClause(
|
|
|
191
181
|
};
|
|
192
182
|
}
|
|
193
183
|
}
|
|
194
|
-
if (!includeSubCommands ||
|
|
184
|
+
if (!includeSubCommands || currentArg![0] === "-") {
|
|
195
185
|
unusedArgs.push(currentArg!);
|
|
196
186
|
continue;
|
|
197
187
|
}
|
|
@@ -240,10 +230,7 @@ function scanForNextCommandClause(
|
|
|
240
230
|
}
|
|
241
231
|
}
|
|
242
232
|
// if group parsing was not needed, revert state if necessary
|
|
243
|
-
if (
|
|
244
|
-
potentialMemberCommandNameArgumentUsed &&
|
|
245
|
-
(potentialMemberSubCommandName !== undefined)
|
|
246
|
-
) {
|
|
233
|
+
if (potentialMemberCommandNameArgumentUsed && potentialMemberSubCommandName !== undefined) {
|
|
247
234
|
pendingArgs.unshift(potentialMemberSubCommandName!);
|
|
248
235
|
}
|
|
249
236
|
}
|
|
@@ -286,17 +273,13 @@ function scanForNextCommandClause(
|
|
|
286
273
|
export function scanForGlobalModifierCommandClauses(
|
|
287
274
|
argSequences: ReadonlyArray<ReadonlyArray<string>>,
|
|
288
275
|
globalModifierCommandsByName: ReadonlyMap<string, GlobalModifierCommand>,
|
|
289
|
-
globalModifierCommandsByShortAlias: ReadonlyMap<
|
|
290
|
-
string,
|
|
291
|
-
GlobalModifierCommand
|
|
292
|
-
>,
|
|
276
|
+
globalModifierCommandsByShortAlias: ReadonlyMap<string, GlobalModifierCommand>,
|
|
293
277
|
): ScanResult {
|
|
294
|
-
logger.debug(
|
|
295
|
-
|
|
296
|
-
JSON.stringify(argSequences)
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
}'`
|
|
278
|
+
logger.debug(
|
|
279
|
+
() =>
|
|
280
|
+
`Scanning args: '${JSON.stringify(argSequences)}' for global modifier commands: '${Array.from(
|
|
281
|
+
globalModifierCommandsByName.keys(),
|
|
282
|
+
).join(" ")}'`,
|
|
300
283
|
);
|
|
301
284
|
|
|
302
285
|
const scanResult: ScanResult = {
|
|
@@ -375,12 +358,11 @@ export function scanForNonModifierCommandClause(
|
|
|
375
358
|
{ groupCommand: GroupCommand; command: SubCommand }
|
|
376
359
|
>,
|
|
377
360
|
): ScanResult {
|
|
378
|
-
logger.debug(
|
|
379
|
-
|
|
380
|
-
JSON.stringify(argSequences)
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
}'`
|
|
361
|
+
logger.debug(
|
|
362
|
+
() =>
|
|
363
|
+
`Scanning args: '${JSON.stringify(argSequences)}' for non-modifier commands: '${Array.from(
|
|
364
|
+
nonModifierCommandsByName.keys(),
|
|
365
|
+
).join(" ")}'`,
|
|
384
366
|
);
|
|
385
367
|
|
|
386
368
|
const scanResult: ScanResult = {
|
|
@@ -32,8 +32,7 @@ export interface SubCommandValuePopulationResult extends ValuePopulationResult {
|
|
|
32
32
|
/**
|
|
33
33
|
* A container holding the result of argument value population for a {@link GlobalCommand} or by extension a {@link GlobalModifierCommand}.
|
|
34
34
|
*/
|
|
35
|
-
export interface GlobalCommandValuePopulationResult
|
|
36
|
-
extends ValuePopulationResult {
|
|
35
|
+
export interface GlobalCommandValuePopulationResult extends ValuePopulationResult {
|
|
37
36
|
/**
|
|
38
37
|
* Populated argument value.
|
|
39
38
|
*/
|