/// <summary> /// When true /// </summary> /// <param name="appRunner"></param> /// <param name="case">The case to apply</param> /// <param name="applyToNameOverrides">Case should be applied to names overridden in attributes.</param> /// <returns></returns> public static AppRunner UseNameCasing(this AppRunner appRunner, Case @case, bool applyToNameOverrides = false) { return(applyToNameOverrides ? appRunner.Configure(b => b.NameTransformation = (attributes, memberName, nameOverride, commandNodeType) => (nameOverride ?? memberName).ChangeCase(@case)) : appRunner.Configure(b => b.NameTransformation = (attributes, memberName, nameOverride, commandNodeType) => nameOverride ?? memberName.ChangeCase(@case))); }
/// <summary>Run the console in memory and get the results that would be output to the shell</summary> public static AppRunnerResult RunInMem(this AppRunner runner, string[] args, Action <string> logLine = null, Func <TestConsole, string> onReadLine = null, IEnumerable <string> pipedInput = null, IPromptResponder promptResponder = null, TestConfig config = null) { logLine = logLine ?? Console.WriteLine; config = config ?? TestConfig.Default; IDisposable logProvider = config.PrintCommandDotNetLogs ? TestToolsLogProvider.InitLogProvider(logLine) : new DisposableAction(() => { }); using (logProvider) { var testConsole = new TestConsole( onReadLine, pipedInput, promptResponder == null ? (Func <TestConsole, ConsoleKeyInfo>)null : promptResponder.OnReadKey); runner.Configure(c => c.Console = testConsole); CommandContext context = null; Task <int> CaptureCommandContext(CommandContext commandContext, ExecutionDelegate next) { context = commandContext; return(next(commandContext)); } runner.Configure(c => c.UseMiddleware(CaptureCommandContext, MiddlewareStages.PreTokenize)); var captures = InjectTestCaptures(runner); try { var exitCode = runner.Run(args); return(new AppRunnerResult(exitCode, runner, context, testConsole, captures, config) .LogResult(logLine)); } catch (Exception e) { var result = new AppRunnerResult(1, runner, context, testConsole, captures, config, e); if (config.OnError.CaptureAndReturnResult) { testConsole.Error.WriteLine(e.Message); logLine(e.Message); logLine(e.StackTrace); return(result.LogResult(logLine, onError: true)); } result.LogResult(logLine, onError: true); throw; } } }
internal static AppRunner SetArgumentDefaultsFrom(AppRunner appRunner, Func <IArgument, ArgumentDefault>[] getDefaultValueCallbacks) { // run before help command so help will display the updated defaults return(appRunner.Configure(c => { var config = c.Services.Get <Config>(); if (config == null) { config = new Config { GetDefaultValueCallbacks = getDefaultValueCallbacks }; c.Services.Add(config); // run before help so the default values can be displayed in the help text c.UseMiddleware(SetDefaults, MiddlewareSteps.SetArgumentDefaults.Stage, MiddlewareSteps.SetArgumentDefaults.Order); } else { config.GetDefaultValueCallbacks = config.GetDefaultValueCallbacks.Union(getDefaultValueCallbacks).ToArray(); } })); }
private static AppRunner RegisterContainer(this AppRunner appRunner, AppConfigs configs) { var config = configs.Default ?? new AppConfig(); var containerBuilder = new ContainerBuilder(); containerBuilder.RegisterInstance(configs); containerBuilder.RegisterInstance(config); containerBuilder.RegisterType <BitBucketRepoCommand>().InstancePerLifetimeScope(); containerBuilder.RegisterType <GlobalConfigCommand>().InstancePerLifetimeScope(); containerBuilder.RegisterType <LocalRepoCommand>().InstancePerLifetimeScope(); containerBuilder.RegisterType <BbService>().InstancePerLifetimeScope(); containerBuilder.RegisterType <GitService>().InstancePerLifetimeScope(); containerBuilder.RegisterServerBbApi(config); containerBuilder.RegisterType <CommandContextHolder>().InstancePerLifetimeScope(); containerBuilder.Register(c => c.Resolve <CommandContextHolder>().Context) .As <CommandContext>() .InstancePerLifetimeScope(); containerBuilder .Register(c => c.Resolve <CommandContext>().Console) .As <IConsole>() .InstancePerLifetimeScope(); appRunner.Configure(r => r.UseMiddleware( SetCommandContextForDependencyResolver, MiddlewareSteps.DependencyResolver.BeginScope + 1)); return(appRunner.UseAutofac(containerBuilder.Build())); }
/// <summary>Run the console in memory and get the results that would be output to the shell</summary> public static AppRunnerResult RunInMem(this AppRunner runner, string[] args, ILogger logger, Func <TestConsole, string> onReadLine = null, IEnumerable <string> pipedInput = null, IPromptResponder promptResponder = null) { TestToolsLogProvider.InitLogProvider(logger); var testConsole = new TestConsole( onReadLine, pipedInput, promptResponder == null ? (Func <TestConsole, ConsoleKeyInfo>)null : promptResponder.OnReadKey); runner.Configure(c => c.Console = testConsole); var outputs = InjectTestOutputs(runner); try { var exitCode = runner.Run(args); var consoleOut = testConsole.Joined.ToString(); logger?.WriteLine("\nconsole output:\n"); logger?.WriteLine(consoleOut); return(new AppRunnerResult(exitCode, testConsole, outputs)); } catch (Exception e) { logger?.WriteLine("\nconsole output:\n"); logger?.WriteLine(testConsole.Joined.ToString()); throw; } }
internal static AppRunner UseTimerDirective(this AppRunner appRunner) { return(appRunner.Configure(c => { c.UseMiddleware(TimerDirective, MiddlewareSteps.DebugDirective - 1); })); }
public static AppRunner GiveCancellationTokenToFlurl(this AppRunner appRunner) { FlurlHttp.GlobalSettings.HttpClientFactory = new MyDefaultHttpClientFactory(); return(appRunner.Configure(cfg => cfg.UseMiddleware(SetCancellationTokenToFlurl, MiddlewareStages.PostBindValuesPreInvoke))); }
private static TestOutputs InjectTestOutputs(AppRunner runner) { TestOutputs outputs = new TestOutputs(); runner.Configure(c => c.UseMiddleware((context, next) => { context.InvocationPipeline.All .Select(i => i.Instance) .ForEach(instance => { instance.GetType() .GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) .Where(p => p.PropertyType == typeof(TestOutputs)) .ForEach(p => { // principal of least surprise // if the test class sets the instance, then use that instance var value = (TestOutputs)p.GetValue(instance); if (value == null) { p.SetValue(instance, outputs); } else { outputs.UseOutputsFromInstance(value); } }); }); return(next(context)); }, MiddlewareStages.PostBindValuesPreInvoke)); return(outputs); }
internal static AppRunner SetArgumentDefaultsFrom(AppRunner appRunner, Func <IArgument, ArgumentDefault?>[] getDefaultValueCallbacks) { if (getDefaultValueCallbacks == null) { throw new ArgumentNullException(nameof(getDefaultValueCallbacks)); } // run before help command so help will display the updated defaults return(appRunner.Configure(c => { var config = c.Services.GetOrDefault <Config>(); if (config == null) { // run before help so the default values can be displayed in the help text c.UseMiddleware(SetDefaults, MiddlewareSteps.SetArgumentDefaults); c.Services.Add(config = new Config(getDefaultValueCallbacks)); } else { config.GetDefaultValueCallbacks = config.GetDefaultValueCallbacks.Union(getDefaultValueCallbacks).ToArray(); } })); }
public static AppRunner UseInteractiveMode(this AppRunner appRunner, string appName) { return(appRunner.Configure(c => { // use the existing appRunner to reuse the configuration. c.UseParameterResolver(ctx => new InteractiveSession(appRunner, appName, ctx)); })); }
/// <summary> /// Override the resources to localize or change the text used in the <see cref="SpectreArgumentPrompter"/> /// </summary> /// <param name="appRunner">the <see cref="AppRunner"/> instance</param> /// <param name="resourcesOverride"> /// The resources to use. If this method is not called, /// <see cref="AppSettings"/>.<see cref="AppSettings.Localize"/> will be used if available.</param> /// <returns></returns> public static AppRunner UseSpectreResources(this AppRunner appRunner, Resources resourcesOverride) { return(appRunner.Configure(c => { c.Services.GetOrCreate <SpectreAppConfig>().ResourcesSet = true; Resources.A = resourcesOverride; })); }
/// <summary>Enables FluentValidation for <see cref="IArgumentModel"/>s</summary> /// <param name="appRunner">the <see cref="AppRunner"/></param> /// <param name="showHelpOnError">when true, help will be display for the target command after the validation errors</param> public static AppRunner UseFluentValidation(this AppRunner appRunner, bool showHelpOnError = false) { return(appRunner.Configure(c => { c.Services.Add(new Config(showHelpOnError)); c.UseMiddleware(Middleware, MiddlewareStages.PostBindValuesPreInvoke); })); }
public static AppRunner UseDataAnnotationValidations(this AppRunner appRunner, bool showHelpOnError = false) { return(appRunner.Configure(c => { c.UseMiddleware(DataAnnotationsValidation, MiddlewareSteps.DataAnnotations); c.Services.Add(new Config(showHelpOnError)); })); }
internal static AppRunner UseParseDirective(this AppRunner appRunner) { return(appRunner.Configure(c => { c.UseMiddleware(ConfigureParseReportByTokenTransform, MiddlewareStages.PreTokenize); c.UseMiddleware(ParseReportByArg, MiddlewareStages.BindValues, MiddlewareSteps.BindValues.Order + 100); })); }
internal static AppRunner UseDebugDirective(this AppRunner appRunner, bool?waitForDebuggerToAttach = null) { return(appRunner.Configure(c => { c.UseMiddleware(AttachDebugger, MiddlewareSteps.DebugDirective); c.Services.Add(new DebugDirectiveContext(waitForDebuggerToAttach ?? !InTestHarness)); })); }
internal static AppRunner UseVersionMiddleware(AppRunner appRunner) { return(appRunner.Configure(c => { c.UseMiddleware(DisplayVersionIfSpecified, MiddlewareSteps.Version); c.BuildEvents.OnCommandCreated += AddVersionOption; })); }
internal static AppRunner UseParseDirective(this AppRunner appRunner) { return(appRunner.Configure(c => { c.UseMiddleware(ConfigureReportHooks, MiddlewareStages.PreTokenize); c.UseMiddleware(ExitAfterTokenization, MiddlewareStages.Tokenize, MiddlewareSteps.CreateRootCommand.Order - 100); })); }
/// <summary>Enables FluentValidation for <see cref="IArgumentModel"/>s</summary> /// <param name="appRunner">the <see cref="AppRunner"/></param> /// <param name="showHelpOnError">when true, help will be display for the target command after the validation errors</param> public static AppRunner UseFluentValidation(this AppRunner appRunner, bool showHelpOnError = false) { return(appRunner.Configure(c => { c.UseMiddleware(FluentValidationForModels, MiddlewareSteps.FluentValidation); c.Services.Add(new Config(showHelpOnError)); })); }
internal static AppRunner UseHelpMiddleware(this AppRunner appRunner) { return(appRunner.Configure(c => { c.BuildEvents.OnCommandCreated += AddHelpOption; c.UseMiddleware(DisplayHelp, MiddlewareSteps.Help.Stage, MiddlewareSteps.Help.Order); })); }
internal static AppRunner AssertAfterRun(this AppRunner appRunner, Action <AppRunnerResult> assert) { return(appRunner.Configure(cfg => { var postRunActions = cfg.Services.GetOrAdd(() => new List <Action <AppRunnerResult> >()); postRunActions.Add(assert); })); }
internal static AppRunner UseCancellationHandlers(AppRunner appRunner) { return(appRunner.Configure(c => { c.UseMiddleware(AddCancellationTokens, MiddlewareSteps.CancellationHandler); c.OnRunCompleted += args => CancellationHandlers.EndRun(args.CommandContext); })); }
internal static AppRunner UseHelpMiddleware(this AppRunner appRunner) { return(appRunner.Configure(c => { c.BuildEvents.OnCommandCreated += AddHelpOption; c.UseMiddleware(CheckIfShouldShowHelp, MiddlewareSteps.Help.CheckIfShouldShowHelp); c.UseMiddleware(PrintHelp, MiddlewareSteps.Help.PrintHelpOnExit); })); }
private AppRunnerResult RunInMem(int carNumber, string ownerName, ExecutionMiddleware postBindValues = null, ExecutionMiddleware preBindValues = null) { var appRunner = new AppRunner <App>(); if (postBindValues != null) { appRunner.Configure(c => c.UseMiddleware(postBindValues, MiddlewareStages.PostBindValuesPreInvoke, int.MaxValue)); } if (preBindValues != null) { appRunner.Configure(c => c.UseMiddleware(preBindValues, MiddlewareStages.PostParseInputPreBindValues, int.MaxValue)); } var args = $"NotifyOwner --Number {carNumber} --owner {ownerName}".SplitArgs(); return(appRunner.RunInMem(args)); }
// This code is not covered by automation. I couldn't find a way to mimic and verify these events. // Tested manually using CancelMeApp in CommandDotNet.Examples internal static AppRunner UseCancellationHandlers(AppRunner appRunner) { var handlers = new Handlers(); return(appRunner.Configure(c => { c.CancellationToken = handlers.CancellationToken; c.OnRunCompleted += _ => handlers.RemoveHandlers(); })); }
public static AppRunner SetDefaults(this AppRunner appRunner, IDictionary <string, object> defaults) { // run before help command so help will display the updated defaults return(appRunner.Configure(c => { c.UseMiddleware((ctx, next) => SetDefaults(ctx, next, defaults), MiddlewareStages.PostParseInputPreBindValues, BeforeHelpMiddleware); })); }
/// <summary> /// Injects a middleware to capture state at specific point. <br/> /// This method does not prevent referenced objects from being mutated after capture. <br/> /// It is the responsibility of capture action to clone data to prevent mutation. /// </summary> public static AppRunner CaptureState(this AppRunner runner, Action <CommandContext> capture, MiddlewareStages middlewareStage, short?orderWithinStage = null, bool exitAfterCapture = false) { return(runner.Configure(b => b.UseMiddleware((context, next) => { capture(context); return exitAfterCapture ? ExitCodes.Success : next(context); }, middlewareStage, orderWithinStage))); }
public static AppRunner UseCancellationHandler(this AppRunner appRunner) { System.Console.CancelKeyPress += Console_CancelKeyPress; AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; AppDomain.CurrentDomain.ProcessExit += CurrentDomain_ProcessExit; return(appRunner.Configure(c => { c.CancellationToken = TokenSource.Token; })); }
/// <summary> /// Injects a middleware to capture state at specific point. <br/> /// This method does not prevent referenced objects from being mutated after capture. <br/> /// It is the responsibility of capture action to clone data to prevent mutation. /// </summary> public static AppRunner CaptureState(this AppRunner runner, Action <CommandContext> capture, MiddlewareStages middlewareStage, int?orderWithinStage = null, bool exitAfterCapture = false) { return(runner.Configure(b => b.UseMiddleware((context, next) => { capture(context); return exitAfterCapture ? Task.FromResult <int>(0) : next(context); }, middlewareStage, orderWithinStage))); }
internal static AppRunner UseClassDefMiddleware(this AppRunner appRunner, Type rootCommandType) { return(appRunner.Configure(c => { c.UseMiddleware(CreateRootCommand, MiddlewareSteps.CreateRootCommand); c.UseMiddleware(AssembleInvocationPipelineMiddleware, MiddlewareSteps.AssembleInvocationPipeline); c.UseMiddleware(BindValuesMiddleware.BindValues, MiddlewareSteps.BindValues); c.UseMiddleware(ResolveCommandClassesMiddleware.ResolveCommandClassInstances, MiddlewareSteps.ResolveCommandClasses); c.UseMiddleware(InvokeInvocationPipelineMiddleware, MiddlewareSteps.InvokeCommand); c.Services.Add(new Config(rootCommandType)); })); }
private static TestOutputs InjectTestOutputs(AppRunner runner) { var outputs = new TestOutputs(); runner.Configure(c => { c.Services.Add(outputs); c.UseMiddleware(InjectTestOutputs, MiddlewareStages.PostBindValuesPreInvoke); }); return(outputs); }