AutoSpectre.SourceGeneration
0.7.0-preview.0.8
See the version list below for details.
dotnet add package AutoSpectre.SourceGeneration --version 0.7.0-preview.0.8
NuGet\Install-Package AutoSpectre.SourceGeneration -Version 0.7.0-preview.0.8
<PackageReference Include="AutoSpectre.SourceGeneration" Version="0.7.0-preview.0.8" />
paket add AutoSpectre.SourceGeneration --version 0.7.0-preview.0.8
#r "nuget: AutoSpectre.SourceGeneration, 0.7.0-preview.0.8"
// Install AutoSpectre.SourceGeneration as a Cake Addin #addin nuget:?package=AutoSpectre.SourceGeneration&version=0.7.0-preview.0.8&prerelease // Install AutoSpectre.SourceGeneration as a Cake Tool #tool nuget:?package=AutoSpectre.SourceGeneration&version=0.7.0-preview.0.8&prerelease
AutoSpectre Source Generation
This allows you to decorate a class with the AutoSpectreForm
attribute and decorate properties on that class with:
TextPromptAttribute
SelectPromptAttribute
and void or Task methods with
TaskStepAttribute
and behind the scenes a Form (SpectreFactory) will be generated to request input using Spectre.Console
Example
Code
[AutoSpectreForm]
public class Example
{
[TextPrompt(Title = "Add item")] public int[] IntItems { get; set; } = Array.Empty<int>();
[TextPrompt(Title = "Enter first name", DefaultValueStyle = "bold")]
public string? FirstName { get; set; } = "John Doe"; // Default value in prompt
[TextPrompt(PromptStyle = "green bold")]
public bool LeftHanded { get; set; }
[TextPrompt(Title = "Choose your [red]value[/]" )]
public SomeEnum Other { get; set; }
[TextPrompt(Secret = true, Mask = '*')]
public string? Password { get; set; }
[TextPrompt] public OtherAutoSpectreFormClass ChildForm { get; set; } = new();
[TextPrompt]
public IReadOnlyList<OtherAutoSpectreFormClass> Investors { get; set; } = new List<OtherAutoSpectreFormClass>();
[TaskStep(UseStatus = true, StatusText = "This will take a while", SpinnerType = SpinnerKnownTypes.Christmas, SpinnerStyle = "green on yellow")]
public void DoSomething(IAnsiConsole console)
{
console.Write(new FigletText("A figlet text is needed"));
}
[SelectPrompt(WrapAround = true, PageSize = 3,
MoreChoicesText = "Press down to see more choices", HighlightStyle = "purple")]
//[SelectPrompt(Source = nameof(ItemSource))]
public string Item { get; set; } = string.Empty;
public List<string> ItemSource { get; } = new() { "Alpha", "Bravo", "Charlie" };
[SelectPrompt(InstructionsText = "Check the special items you want to select")]
//[SelectPrompt(Converter = nameof(SpecialProjectionConverter))]
public List<int> SpecialProjection { get; set; } = new();
public string SpecialProjectionConverter(int source) => $"Number {source}";
public List<int> SpecialProjectionSource { get; set; } = new() { 1, 2, 3, 4 };
[TextPrompt]
// [TextPrompt(Validator = nameof(EnterYearValidator))]
public int EnterYear { get; set; }
public string? EnterYearValidator(int year)
{
return year <= DateTime.Now.Year ? null : "Year cannot be larger than current year";
}
[TextPrompt] public HashSet<string> Names { get; set; } = new(StringComparer.OrdinalIgnoreCase);
public string? NamesValidator(List<string> items, string newItem)
{
if (newItem == "Foobar")
return "Cannot be Foobar";
if (items.Contains(newItem))
return $"{newItem} has already been added";
return null;
}
[TextPrompt] public bool AddExistingName { get; set; }
[TextPrompt(Condition = nameof(AddExistingName))]
public string? ExistingName { get; set; }
[TextPrompt(Condition = nameof(AddExistingName), NegateCondition = true)]
public string? NewName { get; set; }
}
Output
/// <summary>
/// Helps create and fill <see cref = "Example"/> with values
/// </summary>
public interface IExampleSpectreFactory
{
Example Get(Example destination = null);
}
/// <summary>
/// Helps create and fill <see cref = "Example"/> with values
/// </summary>
public class ExampleSpectreFactory : IExampleSpectreFactory
{
public Example Get(Example destination = null)
{
IOtherAutoSpectreFormClassSpectreFactory OtherAutoSpectreFormClassSpectreFactory = new OtherAutoSpectreFormClassSpectreFactory();
destination ??= new ConsoleApp1.Example();
// Prompt for values for destination.IntItems
{
List<int> items = new List<int>();
bool continuePrompting = true;
do
{
var item = AnsiConsole.Prompt(new TextPrompt<int>("Add item"));
items.Add(item);
continuePrompting = AnsiConsole.Confirm("Add more items?");
}
while (continuePrompting);
int[] result = items.ToArray();
destination.IntItems = result;
}
destination.FirstName = AnsiConsole.Prompt(new TextPrompt<string?>("Enter first name").AllowEmpty().DefaultValue("John Doe").DefaultValueStyle("bold"));
destination.LeftHanded = AnsiConsole.Confirm("Enter [green]LeftHanded[/]");
destination.Other = AnsiConsole.Prompt(new SelectionPrompt<SomeEnum>().Title("Choose your [red]value[/]").PageSize(10).AddChoices(Enum.GetValues<SomeEnum>()));
destination.Password = AnsiConsole.Prompt(new TextPrompt<string?>("Enter [green]Password[/]").AllowEmpty().Secret('*'));
{
AnsiConsole.MarkupLine("Enter [green]ChildForm[/]");
var item = OtherAutoSpectreFormClassSpectreFactory.Get();
destination.ChildForm = item;
}
// Prompt for values for destination.Investors
{
List<OtherAutoSpectreFormClass> items = new List<OtherAutoSpectreFormClass>();
bool continuePrompting = true;
do
{
{
AnsiConsole.MarkupLine("Enter [green]Investors[/]");
var newItem = OtherAutoSpectreFormClassSpectreFactory.Get();
items.Add(newItem);
}
continuePrompting = AnsiConsole.Confirm("Add more items?");
}
while (continuePrompting);
System.Collections.Generic.IReadOnlyList<ConsoleApp1.OtherAutoSpectreFormClass> result = items;
destination.Investors = result;
}
AnsiConsole.MarkupLine("Calling method [green]DoSomething[/]");
AnsiConsole.Status().SpinnerStyle("green on yellow").Spinner(Spinner.Known.Christmas).Start("This will take a while", ctx =>
{
destination.DoSomething(AnsiConsole.Console);
});
destination.Item = AnsiConsole.Prompt(new SelectionPrompt<string>().Title("Enter [green]Item[/]").PageSize(3).WrapAround(true).MoreChoicesText("Press down to see more choices").HighlightStyle("purple").AddChoices(destination.ItemSource.ToArray()));
destination.SpecialProjection = AnsiConsole.Prompt(new MultiSelectionPrompt<int>().Title("Enter [green]SpecialProjection[/]").UseConverter(destination.SpecialProjectionConverter).PageSize(10).InstructionsText("Check the special items you want to select").AddChoices(destination.SpecialProjectionSource.ToArray()));
destination.EnterYear = AnsiConsole.Prompt(new TextPrompt<int>("Enter [green]EnterYear[/]").Validate(ctx =>
{
var result = destination.EnterYearValidator(ctx);
return result == null ? ValidationResult.Success() : ValidationResult.Error(result);
}));
// Prompt for values for destination.Names
{
List<string> items = new List<string>();
bool continuePrompting = true;
do
{
bool valid = false;
while (!valid)
{
var item = AnsiConsole.Prompt(new TextPrompt<string>("Enter [green]Names[/]"));
var validationResult = destination.NamesValidator(items, item);
if (validationResult is { } error)
{
AnsiConsole.MarkupLine($"[red]{error}[/]");
valid = false;
}
else
{
valid = true;
items.Add(item);
}
}
continuePrompting = AnsiConsole.Confirm("Add more items?");
}
while (continuePrompting);
System.Collections.Generic.HashSet<string> result = new System.Collections.Generic.HashSet<string>(items);
destination.Names = result;
}
destination.AddExistingName = AnsiConsole.Confirm("Enter [green]AddExistingName[/]");
if (destination.AddExistingName == true)
{
destination.ExistingName = AnsiConsole.Prompt(new TextPrompt<string?>("Enter [green]ExistingName[/]").AllowEmpty());
}
if (destination.AddExistingName == false)
{
destination.NewName = AnsiConsole.Prompt(new TextPrompt<string?>("Enter [green]NewName[/]").AllowEmpty());
}
return destination;
}
}
Credits
Learn more about Target Frameworks and .NET Standard.
-
.NETStandard 2.0
- AutoSpectre (>= 0.7.0-preview.0.5)
- Microsoft.CodeAnalysis.CSharp.Workspaces (>= 4.7.0)
- Spectre.Console (>= 0.47.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last updated |
---|---|---|
0.9.0 | 132 | 7/2/2024 |
0.9.0-preview-0.6 | 59 | 7/1/2024 |
0.8.2 | 101 | 6/25/2024 |
0.8.2-preview-01 | 87 | 6/23/2024 |
0.8.1 | 155 | 2/5/2024 |
0.8.0 | 219 | 11/30/2023 |
0.8.0-preview.0.1 | 108 | 11/4/2023 |
0.7.0 | 298 | 10/3/2023 |
0.7.0-preview.0.8 | 90 | 10/2/2023 |
0.7.0-preview.0.7 | 72 | 10/2/2023 |
0.7.0-preview.0.6 | 85 | 10/1/2023 |
0.7.0-preview.0.5 | 80 | 9/26/2023 |
0.7.0-preview.0.4.2 | 79 | 9/20/2023 |
0.7.0-preview.0.3 | 60 | 9/18/2023 |
0.7.0-preview.0.2 | 81 | 9/15/2023 |
0.7.0-preview.0.1 | 91 | 9/14/2023 |
0.6.0 | 337 | 9/12/2023 |
0.6.0-preview.0.4 | 81 | 9/10/2023 |
0.6.0-preview.0.1 | 77 | 9/3/2023 |
0.5.3 | 314 | 8/28/2023 |
0.5.2 | 318 | 8/27/2023 |
0.5.1 | 321 | 8/25/2023 |
0.5.0 | 331 | 8/23/2023 |
0.4.0 | 349 | 8/15/2023 |
0.3.8 | 350 | 8/6/2023 |
0.3.7.2 | 213 | 7/29/2023 |
0.3.6.1 | 210 | 7/25/2023 |
0.3.5 | 171 | 7/24/2023 |
0.3.4 | 195 | 7/23/2023 |
0.3.3 | 182 | 7/23/2023 |
0.3.2 | 346 | 1/22/2023 |
0.3.1 | 355 | 1/16/2023 |
0.3.0 | 364 | 1/6/2023 |
0.2.0.2 | 353 | 12/14/2022 |
0.2.0.1 | 326 | 12/14/2022 |
0.1.6 | 388 | 12/2/2022 |
0.1.5 | 367 | 11/30/2022 |
Added support for setting Choices on the TextPromptAttribute. Rewrote logic for DefaultValue. Retired old default value solution. Added support for defining source that point to fields. Allowed sources to point to static. Add for Default