private async Task <bool> RunContinuously(ProjectionInput input, DocumentStore store) { var shards = input.BuildShards(store); if (input.InteractiveFlag) { var all = store.Options.Projections.All.Where(x => x.Lifecycle != ProjectionLifecycle.Live).SelectMany(x => x.AsyncProjectionShards(store)) .Select(x => x.Name.Identity).ToArray(); var prompt = new MultiSelectionPrompt <string>() .Title("Choose projection shards to run continuously") .AddChoices(all); var selections = AnsiConsole.Prompt(prompt); shards = store.Options.Projections.All.SelectMany(x => x.AsyncProjectionShards(store)) .Where(x => selections.Contains(x.Name.Identity)).ToList(); } if (!shards.Any()) { Console.WriteLine(input.ProjectionFlag.IsEmpty() ? "No projections are registered with an asynchronous life cycle." : $"No projection or projection shards match the requested filter '{input.ProjectionFlag}'"); Console.WriteLine(); WriteProjectionTable(store); return(true); } var assembly = Assembly.GetEntryAssembly(); AssemblyLoadContext.GetLoadContext(assembly).Unloading += context => Shutdown(); Console.CancelKeyPress += (sender, eventArgs) => { Shutdown(); eventArgs.Cancel = true; }; var shutdownMessage = "Press CTRL + C to quit"; Console.WriteLine(shutdownMessage); var daemon = store.BuildProjectionDaemon(); daemon.Tracker.Subscribe(new ProjectionWatcher(_completion.Task, shards)); foreach (var shard in shards) { await daemon.StartShard(shard, _cancellation.Token); } await _completion.Task; return(false); }
/// <summary> /// Sets a value indicating whether or not at least one choice must be selected. /// </summary> /// <typeparam name="T">The prompt result type.</typeparam> /// <param name="obj">The prompt.</param> /// <param name="required">Whether or not at least one choice must be selected.</param> /// <returns>The same instance so that multiple calls can be chained.</returns> public static MultiSelectionPrompt <T> Required <T>(this MultiSelectionPrompt <T> obj, bool required) where T : notnull { if (obj is null) { throw new ArgumentNullException(nameof(obj)); } obj.Required = required; return(obj); }
/// <summary> /// Sets the selection mode. /// </summary> /// <typeparam name="T">The prompt result type.</typeparam> /// <param name="obj">The prompt.</param> /// <param name="mode">The selection mode.</param> /// <returns>The same instance so that multiple calls can be chained.</returns> public static MultiSelectionPrompt <T> Mode <T>(this MultiSelectionPrompt <T> obj, SelectionMode mode) where T : notnull { if (obj is null) { throw new ArgumentNullException(nameof(obj)); } obj.Mode = mode; return(obj); }
/// <summary> /// Sets the text that instructs the user of how to select items. /// </summary> /// <typeparam name="T">The prompt result type.</typeparam> /// <param name="obj">The prompt.</param> /// <param name="text">The text to display.</param> /// <returns>The same instance so that multiple calls can be chained.</returns> public static MultiSelectionPrompt <T> InstructionsText <T>(this MultiSelectionPrompt <T> obj, string?text) where T : notnull { if (obj is null) { throw new ArgumentNullException(nameof(obj)); } obj.InstructionsText = text; return(obj); }
/// <summary> /// Sets the highlight style of the selected choice. /// </summary> /// <typeparam name="T">The prompt result type.</typeparam> /// <param name="obj">The prompt.</param> /// <param name="highlightStyle">The highlight style of the selected choice.</param> /// <returns>The same instance so that multiple calls can be chained.</returns> public static MultiSelectionPrompt <T> HighlightStyle <T>(this MultiSelectionPrompt <T> obj, Style highlightStyle) where T : notnull { if (obj is null) { throw new ArgumentNullException(nameof(obj)); } obj.HighlightStyle = highlightStyle; return(obj); }
/// <summary> /// Sets the title. /// </summary> /// <typeparam name="T">The prompt result type.</typeparam> /// <param name="obj">The prompt.</param> /// <param name="title">The title markup text.</param> /// <returns>The same instance so that multiple calls can be chained.</returns> public static MultiSelectionPrompt <T> Title <T>(this MultiSelectionPrompt <T> obj, string?title) where T : notnull { if (obj is null) { throw new ArgumentNullException(nameof(obj)); } obj.Title = title; return(obj); }
public void Should_Not_Mark_Item_As_Selected_By_Default() { // Given var prompt = new MultiSelectionPrompt <int>(); // When var choice = prompt.AddChoice(32); // Then choice.IsSelected.ShouldBeFalse(); }
/// <summary> /// Sets the function to create a display string for a given choice. /// </summary> /// <typeparam name="T">The prompt type.</typeparam> /// <param name="obj">The prompt.</param> /// <param name="displaySelector">The function to get a display string for a given choice.</param> /// <returns>The same instance so that multiple calls can be chained.</returns> public static MultiSelectionPrompt <T> UseConverter <T>(this MultiSelectionPrompt <T> obj, Func <T, string>?displaySelector) where T : notnull { if (obj is null) { throw new ArgumentNullException(nameof(obj)); } obj.Converter = displaySelector; return(obj); }
public void Should_Mark_Item_As_Selected() { // Given var prompt = new MultiSelectionPrompt <int>(); var choice = prompt.AddChoice(32); // When prompt.Select(32); // Then choice.IsSelected.ShouldBeTrue(); }
public void Should_Throw_When_Getting_Parents_Of_Non_Existing_Node() { // Given var prompt = new MultiSelectionPrompt <string>(); prompt.AddChoice("root").AddChild("level-1").AddChild("level-2").AddChild("item"); // When Action action = () => prompt.GetParents("non-existing"); // Then action.ShouldThrow <ArgumentOutOfRangeException>(); }
public void Should_Get_Null_As_Direct_Parent_Of_Root_Node() { // Given var prompt = new MultiSelectionPrompt <string>(); prompt.AddChoice("root"); // When var actual = prompt.GetParent("root"); // Then actual.ShouldBeNull(); }
public void Should_Get_The_Direct_Parent() { // Given var prompt = new MultiSelectionPrompt <string>(); prompt.AddChoice("root").AddChild("level-1").AddChild("level-2").AddChild("item"); // When var actual = prompt.GetParent("item"); // Then actual.ShouldBe("level-2"); }
public void Should_Get_The_List_Of_All_Parents() { // Given var prompt = new MultiSelectionPrompt <string>(); prompt.AddChoice("root").AddChild("level-1").AddChild("level-2").AddChild("item"); // When var actual = prompt.GetParents("item"); // Then actual.ShouldBe(new [] { "root", "level-1", "level-2" }); }
public void Should_Get_An_Empty_List_Of_Parents_For_Root_Node() { // Given var prompt = new MultiSelectionPrompt <string>(); prompt.AddChoice("root"); // When var actual = prompt.GetParents("root"); // Then actual.ShouldBeEmpty(); }
/// <summary> /// Marks an item as selected. /// </summary> /// <typeparam name="T">The prompt result type.</typeparam> /// <param name="obj">The prompt.</param> /// <param name="item">The item to select.</param> /// <returns>The same instance so that multiple calls can be chained.</returns> public static MultiSelectionPrompt <T> Select <T>(this MultiSelectionPrompt <T> obj, T item) where T : notnull { if (obj is null) { throw new ArgumentNullException(nameof(obj)); } var node = obj.Tree.Find(item); node?.Select(); return(obj); }
/// <summary> /// Adds multiple choices. /// </summary> /// <typeparam name="T">The prompt result type.</typeparam> /// <param name="obj">The prompt.</param> /// <param name="choices">The choices to add.</param> /// <returns>The same instance so that multiple calls can be chained.</returns> public static MultiSelectionPrompt <T> AddChoices <T>(this MultiSelectionPrompt <T> obj, IEnumerable <T> choices) where T : notnull { if (obj is null) { throw new ArgumentNullException(nameof(obj)); } foreach (var choice in choices) { obj.AddChoice(choice); } return(obj); }
public void Should_Mark_Custom_Item_As_Selected_If_The_Same_Reference_Is_Used() { // Given var prompt = new MultiSelectionPrompt <CustomItem>(); var item = new CustomItem { X = 18, Y = 32 }; var choice = prompt.AddChoice(item); // When prompt.Select(item); // Then choice.IsSelected.ShouldBeTrue(); }
/// <summary> /// Sets how many choices that are displayed to the user. /// </summary> /// <typeparam name="T">The prompt result type.</typeparam> /// <param name="obj">The prompt.</param> /// <param name="pageSize">The number of choices that are displayed to the user.</param> /// <returns>The same instance so that multiple calls can be chained.</returns> public static MultiSelectionPrompt <T> PageSize <T>(this MultiSelectionPrompt <T> obj, int pageSize) where T : notnull { if (obj is null) { throw new ArgumentNullException(nameof(obj)); } if (pageSize <= 2) { throw new ArgumentException("Page size must be greater or equal to 3.", nameof(pageSize)); } obj.PageSize = pageSize; return(obj); }
public void Should_Mark_Custom_Item_As_Selected_If_A_Comparer_Is_Provided() { // Given var prompt = new MultiSelectionPrompt <CustomItem>(new CustomItem.Comparer()); var choice = prompt.AddChoice(new CustomItem { X = 18, Y = 32 }); // When prompt.Select(new CustomItem { X = 18, Y = 32 }); // Then choice.IsSelected.ShouldBeTrue(); }
/// <summary> /// Adds multiple grouped choices. /// </summary> /// <typeparam name="T">The prompt result type.</typeparam> /// <param name="obj">The prompt.</param> /// <param name="group">The group.</param> /// <param name="choices">The choices to add.</param> /// <returns>The same instance so that multiple calls can be chained.</returns> public static MultiSelectionPrompt <T> AddChoiceGroup <T>(this MultiSelectionPrompt <T> obj, T group, params T[] choices) where T : notnull { if (obj is null) { throw new ArgumentNullException(nameof(obj)); } var root = obj.AddChoice(group); foreach (var choice in choices) { root.AddChild(choice); } return(obj); }
/// <summary> /// Adds a choice. /// </summary> /// <typeparam name="T">The prompt result type.</typeparam> /// <param name="obj">The prompt.</param> /// <param name="choice">The choice to add.</param> /// <param name="configurator">The configurator for the choice.</param> /// <returns>The same instance so that multiple calls can be chained.</returns> public static MultiSelectionPrompt <T> AddChoices <T>(this MultiSelectionPrompt <T> obj, T choice, Action <IMultiSelectionItem <T> > configurator) where T : notnull { if (obj is null) { throw new ArgumentNullException(nameof(obj)); } if (configurator is null) { throw new ArgumentNullException(nameof(configurator)); } var result = obj.AddChoice(choice); configurator(result); return(obj); }
public virtual ICollection <string> PromptForArgumentValues( CommandContext ctx, IArgument argument, out bool isCancellationRequested) { isCancellationRequested = false; var argumentName = _getPromptTextCallback?.Invoke(ctx, argument) ?? argument.Name; var promptText = $"{argumentName} ({argument.TypeInfo.DisplayName})"; var isPassword = argument.TypeInfo.UnderlyingType == typeof(Password); var defaultValue = argument.Default?.Value; var ansiConsole = ctx.Services.GetOrThrow <IAnsiConsole>(); // https://spectreconsole.net/prompts/ if (argument.Arity.AllowsMany()) { if (argument.AllowedValues.Any()) { // TODO: how to show default? is it the first choice? var p = new MultiSelectionPrompt <string> { MoreChoicesText = Resources.A.Selection_paging_instructions(argument.Name), InstructionsText = Resources.A.MultiSelection_selection_instructions(argument.Name) } .Title(promptText) .AddChoices(argument.AllowedValues) .PageSize(_pageSize); return(ansiConsole.Prompt(p)); } else { return(MultiPrompt(ansiConsole, promptText)); } } else { if (argument.TypeInfo.Type == typeof(bool)) { var result = defaultValue != null ? ansiConsole.Confirm(promptText, (bool)defaultValue) : ansiConsole.Confirm(promptText); return(new[] { result.ToString() }); } if (argument.AllowedValues.Any()) { var p = new SelectionPrompt <string>() { Title = promptText, PageSize = _pageSize, MoreChoicesText = Resources.A.Selection_paging_instructions(argument.Name) } .AddChoices(argument.AllowedValues); // TODO: how to show default? is it the first choice? return(new [] { ansiConsole.Prompt(p) }); } else { var p = new TextPrompt <string>(promptText) { IsSecret = isPassword, AllowEmpty = argument.Arity.RequiresNone(), ShowDefaultValue = true }; if (defaultValue != null) { p.DefaultValue(defaultValue.ToString() !); } return(new[] { ansiConsole.Prompt(p) }); } } }
/// <summary> /// Requires a choice to be selected. /// </summary> /// <typeparam name="T">The prompt result type.</typeparam> /// <param name="obj">The prompt.</param> /// <returns>The same instance so that multiple calls can be chained.</returns> public static MultiSelectionPrompt <T> Required <T>(this MultiSelectionPrompt <T> obj) where T : notnull { return(Required(obj, true)); }
public override async Task <bool> Execute(DescribeInput input) { input.HostBuilder.ConfigureServices(x => x.AddTransient <IDescribedSystemPart, ConfigurationPreview>()); using (var host = input.BuildHost()) { var config = host.Services.GetRequiredService <IConfiguration>(); var hosting = host.Services.GetService <IHostEnvironment>(); var about = new AboutThisAppPart(hosting, config); var factories = host.Services.GetServices <IDescribedSystemPartFactory>(); var parts = host.Services.GetServices <IDescribedSystemPart>() .Concat(factories.SelectMany(x => x.Parts())) .Concat(new IDescribedSystemPart[] { about, new ReferencedAssemblies() }).ToArray(); foreach (var partWithServices in parts.OfType <IRequiresServices>()) { partWithServices.Resolve(host.Services); } if (input.ListFlag) { Console.WriteLine("The registered system parts are"); foreach (var part in parts) { Console.WriteLine("* " + part.Title); } return(true); } if (input.TitleFlag.IsNotEmpty()) { parts = parts.Where(x => x.Title == input.TitleFlag).ToArray(); } else if (input.InteractiveFlag) { var prompt = new MultiSelectionPrompt <string>() .Title("What part(s) of your application do you wish to view?") .PageSize(10) .AddChoices(parts.Select(x => x.Title)); var titles = AnsiConsole.Prompt(prompt); parts = parts.Where(x => titles.Contains(x.Title)).ToArray(); } if (!input.SilentFlag) { await WriteToConsole(parts); } if (input.FileFlag.IsNotEmpty()) { using (var stream = new FileStream(input.FileFlag, FileMode.CreateNew, FileAccess.Write)) { var writer = new StreamWriter(stream); await WriteText(parts, writer); await writer.FlushAsync(); } Console.WriteLine("Wrote system description to file " + input.FileFlag); } return(true); } }