/// <summary> /// Parses input before pipeline execution. /// </summary> protected virtual async Task <int> ParseInput(IReadOnlyList <string> commandLineArguments, RootSchema root) { //TODO: CommandInput.Parse as middleware step CommandInput input = CommandInputResolver.Parse(commandLineArguments, root.GetCommandNames()); CliContext.Input = input; return(await ExecuteCommand()); }
/// <inheritdoc/> public async Task <int> ExecuteCommandAsync(IEnumerable <string> commandLineArguments) { _logger.LogInformation("Executing command '{CommandLineArguments}'.", commandLineArguments); using (IServiceScope serviceScope = _serviceScopeFactory.CreateScope()) { IServiceProvider provider = serviceScope.ServiceProvider; ICliContext cliContext = provider.GetRequiredService <ICliContext>(); Guid cliContextId = cliContext.Id; _logger.LogDebug("New scope created with CliContext {CliContextId}.", cliContextId); CommandInput input = CommandInputResolver.Parse(commandLineArguments, _rootSchemaAccessor.RootSchema.GetCommandNames()); ((CliContext)cliContext).Input = input; try { // Execute middleware pipeline await RunPipelineAsync(provider, cliContext); } catch (Exception ex) { _logger.LogDebug("Exception occured. Trying to find exception handler."); IEnumerable <ICliExceptionHandler> exceptionHandlers = provider.GetServices <ICliExceptionHandler>(); foreach (ICliExceptionHandler handler in exceptionHandlers) { if (handler.HandleException(ex)) { _logger.LogDebug(ex, "Exception handled by {ExceptionHandlerType}.", handler.GetType().FullName); return(ExitCodes.FromException(ex)); } } _logger.LogCritical(ex, "Unhandled exception during command execution."); throw; } finally { _logger.LogDebug("Disposed scope with CliContext {CliContextId}.", cliContextId); } return(cliContext.ExitCode ?? ExitCodes.Error); } }
private async Task RunInteractivelyAsync(RootSchema root) { IConsole console = CliContext.Console; string executableName = CliContext.Metadata.ExecutableName; do { string[]? commandLineArguments = GetInput(console, executableName); if (commandLineArguments is null) { console.ResetColor(); return; } CommandInput input = CommandInputResolver.Parse(commandLineArguments, root.GetCommandNames()); CliContext.Input = input; //TODO maybe refactor with some clever IDisposable class await ExecuteCommand(); console.ResetColor(); }while (!console.GetCancellationToken().IsCancellationRequested); }
protected override async Task <int> ParseInput(IReadOnlyList <string> commandLineArguments, RootSchema root) { CommandInput input = CommandInputResolver.Parse(commandLineArguments, root.GetCommandNames()); CliContext.Input = input; if (input.IsInteractiveDirectiveSpecified) { CliContext.IsInteractiveMode = true; // we don't want to run default command for e.g. `[interactive]` but we want to run if there is sth else if (!input.IsDefaultCommandOrEmpty) { await ExecuteCommand(); } await RunInteractivelyAsync(root); return(ExitCodes.Success); // called after Ctrl+C } return(await ExecuteCommand()); }