v2.0.0
Features
Introduce Minimal API (#43, #45)
This release introduces ASP.NET Core-like Minimal API. It's an enhancement for .NET 6 and C# 10.
Minimal API supports most of the expressions that were possible with the previous Class-based style.
Please refer to the updated documentation for more details and see CoconaSample.MinimalApi.InAction.
CoconaApp.Run
and CoconaApp.RunAsync
Run
and RunAsync
is a shortcut that makes it easy to build command line applications.
await CoconaApp.RunAsync((string? name) => Console.WriteLine($"Hello {(name ?? "Guest")}!"));
This is equivalent to the following code using Minimal API Builder.
var builder = CoconaApp.CreateBuilder(args);
var app = builder.Build();
app.AddCommand((string? name) => Console.WriteLine($"Hello {(name ?? "Guest")}!"));
app.Run();
CoconaApp.CreateBuilder()
and CoconaApp.Create()
CreateBuilder
and Create
provide builders to configure services and register/configure multiple commands.
var builder = CoconaApp.CreateBuilder();
builder.Services.AddTransient<IMyService, MyService>();
builder.Configuration.AddJsonFile("path/to/additonalsettings.json");
var app = builder.Build();
app.AddCommand("hello", (string? name) => Console.WriteLine($"Hello {(name ?? "Guest")}!"));
app.AddSubCommand("server", x =>
{
x.UseFilter(new RequirePrivilege());
x.AddCommand("start", () => Console.WriteLine("Start"));
x.AddCommand("stop", () => Console.WriteLine("Stop"));
});
app.AddSubCommand("client", x =>
{
x.AddCommand("connect", () => Console.WriteLine("Connect"));
x.AddCommand("disconnect", () => Console.WriteLine("Disconnect"));
});
app.AddComands<CommandType>();
await app.RunAsync();
Add a command and configure using the builder
var app = CoconaApp.Create(); // Shorthand for CoconaApp.CreateBuilder().Build();
// Add a command and configure.
app.AddCommand("hello", (string? name) => Console.WriteLine($"Hello {(name ?? "Guest")}!"))
// Sets a description to the command.
.WithDescription("Say hello");
// Sets aliases to the command.
.WithAliases(new[] { "hey" })
// Sets a metadata (attribute) to the command.
.WithMetadata(new HiddenAttribute());
// Use a user-defined command filter.
app.UseFilter(new MyFilterAttribute());
// Configure filters per command.
app.AddCommand("konnichiwa", (string name) => Console.WriteLine($"Konnichiwa {name}!"))
.WithFilter(new MyFilterAttribute())
.WithFilter(async (ctx, next) =>
{
if (Environment.UserName != "Administrator")
{
throw new CommandExitedException("Insufficient Permissions");
}
return next(ctx);
})
.CommandLikeOption(x =>
{
// CommandLikeOption: konnichiwa --info
x.Add("info", () => Console.WriteLine("Show Information"));
});
New APIs
CoconaAppBuilder
Services
Build()
CoconaApp
(ICoconaCommandsBuilder
)- Static methods
Create
: Shorthand forCoconaApp.CreateBuilder().Build()
CreateBuilder
: CreatesCoconaAppBuilder
instance.CreateHostBuilder
: CreatesCoconaAppHostBuilder
instance. (formerCoconaApp.Create()
)
- Instance methods
AddCommand(Delegate)
AddCommand(string, Delegate)
AddCommands(Type)
AddCommands<T>()
AddSubCommand(string, Action<ICoconaCommandsBuilder>)
UseFilter
Run
/RunAsync
- Static methods
Introduce [Option(StopParsingOptions = true)]
(#36)
[Option(StopParsingOptions = true)]
enables to stop parsing options after a option on a command line.
public void A([Option]int a, [Option(StopParsingOptions = true)]string b, [Argument]string arg0, [Argument]string[] args)
{
// $ ./myapp --a 123 --b valueB -c -d --e f
// a = 123
// b = "valueB"
// arg0 = "-c"
// args = new [] { "d", "--e", "f" }
}
Handle shutdown timeout (#57)
Cocona waits for a timeout before shutting down when canceling with Ctrl+C. This will allow you to perform a graceful shutdown.
Applied to Cocona
var builder = CoconaApp.CreateBuilder();
builder.Services.Configure<HostOptions>(options =>
{
options.ShutdownTimeout = TimeSpan.FromSeconds(15);
});
Applied to Cocona.Lite
CoconaLiteApp.Create(options =>
{
options.ShutdownTimeout = TimeSpan.FromSecond(15);
});
Localization (#44)
This release introduces localization mechanism for user-defined commands and add built-in ja-jp localization of messages.
New APIs
ICoconaLocalizer
interface: Provides a localized description of the command. (see CoconaSample.Advanced.Localization)
Help Wanted: Contributions are welcome! 🤝
- English: Since I (@mayuki) am not a native English speaker, this project has some problems such as lack of documentation and grammatical errors. Contributions of XML Doc comments, exception messages and README improvements would be welcome!
- Non-English: Contributions of non-English language (ja-jp, ko-kr, ...) resources are also welcome!
Breaking changes
Disable support for shell completion by default (#50)
Support for Shell completion feature is now disabled by default.
If you want to continue to enable it, set the EnableShellCompletionSupport
option to true
.
CoconaApp Host APIs (#43)
- Rename
CoconaApp.Create()
->CoconaApp.CreateHostBuilder()
- Rename
IHostBuilder.UseCocona
->IHostBuilder.ConfigureCocona
- Remove
CommandTypes
fromCoconaAppOptions
andCoconaLiteAppOptions
Changes
Improvements
- Adopt to .NET 6 (#41)
- Add scope support for ServiceProvider (#56)
- Handle static methods marked as commands. (#35)
Fixes
- Update NuGet package info (#55)
- Throw exceptions in Run when building the application (#51)
- Throw an exception if a sub-command name is duplicated (#52)
Full Changelog: v1.6.0...v2.0.0