AutoSpectre.SourceGeneration
0.9.0
dotnet add package AutoSpectre.SourceGeneration --version 0.9.0
NuGet\Install-Package AutoSpectre.SourceGeneration -Version 0.9.0
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="AutoSpectre.SourceGeneration" Version="0.9.0" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add AutoSpectre.SourceGeneration --version 0.9.0
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
#r "nuget: AutoSpectre.SourceGeneration, 0.9.0"
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install AutoSpectre.SourceGeneration as a Cake Addin #addin nuget:?package=AutoSpectre.SourceGeneration&version=0.9.0 // Install AutoSpectre.SourceGeneration as a Cake Tool #tool nuget:?package=AutoSpectre.SourceGeneration&version=0.9.0
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
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
There are no supported framework assets in this package.
Learn more about Target Frameworks and .NET Standard.
-
.NETStandard 2.0
- AutoSpectre (>= 0.9.0)
- Microsoft.CodeAnalysis.CSharp.Workspaces (>= 4.8.0)
- Spectre.Console (>= 0.49.1)
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 | 146 | 7/2/2024 |
0.9.0-preview-0.6 | 65 | 7/1/2024 |
0.8.2 | 109 | 6/25/2024 |
0.8.2-preview-01 | 91 | 6/23/2024 |
0.8.1 | 160 | 2/5/2024 |
0.8.0 | 224 | 11/30/2023 |
0.8.0-preview.0.1 | 111 | 11/4/2023 |
0.7.0 | 305 | 10/3/2023 |
0.7.0-preview.0.8 | 95 | 10/2/2023 |
0.7.0-preview.0.7 | 75 | 10/2/2023 |
0.7.0-preview.0.6 | 88 | 10/1/2023 |
0.7.0-preview.0.5 | 83 | 9/26/2023 |
0.7.0-preview.0.4.2 | 82 | 9/20/2023 |
0.7.0-preview.0.3 | 65 | 9/18/2023 |
0.7.0-preview.0.2 | 84 | 9/15/2023 |
0.7.0-preview.0.1 | 94 | 9/14/2023 |
0.6.0 | 342 | 9/12/2023 |
0.6.0-preview.0.4 | 84 | 9/10/2023 |
0.6.0-preview.0.1 | 80 | 9/3/2023 |
0.5.3 | 319 | 8/28/2023 |
0.5.2 | 323 | 8/27/2023 |
0.5.1 | 326 | 8/25/2023 |
0.5.0 | 336 | 8/23/2023 |
0.4.0 | 354 | 8/15/2023 |
0.3.8 | 355 | 8/6/2023 |
0.3.7.2 | 218 | 7/29/2023 |
0.3.6.1 | 215 | 7/25/2023 |
0.3.5 | 178 | 7/24/2023 |
0.3.4 | 200 | 7/23/2023 |
0.3.3 | 187 | 7/23/2023 |
0.3.2 | 354 | 1/22/2023 |
0.3.1 | 360 | 1/16/2023 |
0.3.0 | 369 | 1/6/2023 |
0.2.0.2 | 358 | 12/14/2022 |
0.2.0.1 | 331 | 12/14/2022 |
0.1.6 | 393 | 12/2/2022 |
0.1.5 | 372 | 11/30/2022 |
Added EnsureSearch functionality. Begin deprecations of Dump related extension methods. Better nested class support