MintPlayer.CliGenerator
13.0.0
dotnet add package MintPlayer.CliGenerator --version 13.0.0
NuGet\Install-Package MintPlayer.CliGenerator -Version 13.0.0
<PackageReference Include="MintPlayer.CliGenerator" Version="13.0.0"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> </PackageReference>
<PackageVersion Include="MintPlayer.CliGenerator" Version="13.0.0" />
<PackageReference Include="MintPlayer.CliGenerator"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> </PackageReference>
paket add MintPlayer.CliGenerator --version 13.0.0
#r "nuget: MintPlayer.CliGenerator, 13.0.0"
#:package MintPlayer.CliGenerator@13.0.0
#addin nuget:?package=MintPlayer.CliGenerator&version=13.0.0
#tool nuget:?package=MintPlayer.CliGenerator&version=13.0.0
CLI command generators
Create structured CLI applications with nested commands and dependency injection support using the CliCommand source generator.
Install both MintPlayer.CliGenerator and MintPlayer.CliGenerator.Attributes. The generator is a development dependency: a dotnet add package reference to it does not make the attributes compile (CS0246), so the attributes package must be referenced explicitly. The generated code uses Microsoft.Extensions.Hosting (IHost), so the project needs that package as well.
- Annotate your root command with
[CliRootCommand]and mark each command (and subcommand) with[CliCommand]. - Define command options with
[CliOption]and positional arguments with[CliArgument]on mutable properties. - Implement
MintPlayer.CliGenerator.Attributes.ICliCommandso each command exposes anExecute(CancellationToken)handler returning a task-based exit code. - Register the tree with the generated
Add{RootCommand}()extension onIServiceCollection, and run it withInvoke{RootCommand}Async(args)on the builtIHost(Build{RootCommand}()returns theSystem.CommandLineroot command). - Use
[CliParentCommand(typeof(ParentCommand))]on a non-nested partial command class to attach it under an existing command without nesting the type in code. This enables splitting large command trees across multiple files.
[CliRootCommand(Name = "demo", Description = "Sample CLI")]
public partial class DemoCommand : ICliCommand
{
[CliOption("--verbose", "-v")] public bool Verbose { get; set; }
public Task<int> Execute(CancellationToken cancellationToken)
{
if (Verbose)
{
Console.WriteLine("Verbose mode active");
}
return Task.FromResult(0);
}
}
// In another file:
[CliCommand("greet", Description = "Greets a person")]
[CliParentCommand(typeof(DemoCommand))]
public partial class Greet : ICliCommand
{
private readonly IGreetingService greetingService;
public Greet(IGreetingService greetingService) => this.greetingService = greetingService;
[CliArgument(0)] public string Name { get; set; } = "world";
[CliOption("--times", DefaultValue = 1)] public int Times { get; set; }
public async Task<int> Execute(CancellationToken cancellationToken)
{
for (var i = 0; i < Times; i++)
await greetingService.GreetAsync(Name, cancellationToken);
return 0;
}
}
var builder = Host.CreateApplicationBuilder(args);
builder.Services.AddDemoCommand();
builder.Services.AddSingleton<IGreetingService, GreetingService>();
var app = builder.Build();
return await app.InvokeDemoCommandAsync(args);
The generator creates:
- Scoped service registrations for all commands in the tree.
- Methods that build
System.CommandLinecommand hierarchies and wire options and arguments automatically. - A
{RootCommand}CliExtensionsclass withAdd{RootCommand}onIServiceCollection,Build{RootCommand}onIServiceProviderandInvoke{RootCommand}AsynconIHost, to register, build and execute the command tree. - Recognition of non-nested partial command classes linked via
[CliParentCommand].
A command can be a class or a record (record class), at top level or nested in a partial class, record,
struct, record struct or interface. Execute receives the invocation's cancellation token, which is cancelled
on Ctrl+C.
Commands the generator cannot generate for are reported instead of producing code that does not compile. Every rule is an error:
| ID | Reason |
|---|---|
| MINTCLI001 | The command does not implement ICliCommand |
| MINTCLI002 | The command is not partial |
| MINTCLI003 | The command is generic, or nested in a generic type |
| MINTCLI004 | The command is static |
| MINTCLI005 | A containing type is not partial |
| MINTCLI006 | The command, or a containing type, is file-local |
| MINTCLI007 | A root command is less accessible than internal |
| MINTCLI008 | A subcommand is not accessible from its parent command |
| MINTCLI009 | Two root commands share a type name, so their {Name}CliExtensions classes would collide |
Learn more about Target Frameworks and .NET Standard.
-
.NETStandard 2.0
- MintPlayer.CliGenerator.Attributes (>= 13.0.0)
- MintPlayer.ValueComparerGenerator.Attributes (>= 13.0.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 | |
|---|---|---|---|
| 13.0.0 | 51 | 10/11/2026 | |
| 12.2.0 | 50 | 10/11/2026 | |
| 12.1.1 | 89 | 10/2/2026 | |
| 12.1.0 | 108 | 9/26/2026 | |
| 12.0.1 | 110 | 9/25/2026 | |
| 12.0.0 | 109 | 9/25/2026 | |
| 11.0.0 | 109 | 9/25/2026 | |
| 10.21.1 | 128 | 9/3/2026 | |
| 10.21.0 | 109 | 8/27/2026 | |
| 10.20.1 | 106 | 8/27/2026 | |
| 10.20.0 | 296 | 6/5/2026 | |
| 10.19.0 | 148 | 4/3/2026 | |
| 10.14.0 | 147 | 1/19/2026 | |
| 10.13.0 | 135 | 1/19/2026 | |
| 10.10.1 | 141 | 1/12/2026 | |
| 10.10.0 | 147 | 1/12/2026 | |
| 10.9.0 | 140 | 1/12/2026 | |
| 10.8.0 | 267 | 11/14/2025 | |
| 10.7.0 | 318 | 11/13/2025 | |
| 10.5.0 | 319 | 11/11/2025 |