All commands are always optional when using hosting
In the example bellow I was expecting that running cli without specifying a subcommand would fail with the error "Required command was not provided." as it happens without using the host
var root = new Command("cli")
{
Subcommands = { new Command("cmd") }
};
var configuration = new CommandLineConfiguration(root).UseHost(
_ => Host.CreateDefaultBuilder(),
cfg => cfg.UseInvocationLifetime());
await configuration.InvokeAsync(args);
However, it works fine and no errors pop up. It seems that UseHost calls HostingAction.SetHandlers extensions on the root command and it sets actions to all commands in the chain. As a result, this validation never sets the error.
https://github.com/dotnet/command-line-api/blob/b7f0d1c4f0da129f7a115e32b21f0b773e60805b/src/System.CommandLine/Parsing/CommandResult.cs#L46-L55
Was it made intentionally? As a workaround I can use Validators and check that there are tokens provided in the arguments list, but it would be nice to keep the same behaviour as it works without using a host.
I worked around this by throwing an exception when there are unmatched tokens passed to the hostBuilderFactory.
var config = new CommandLineConfiguration(rootCommand);
config.UseHost(
hostBuilderFactory: unmatchedArgs =>
{
if (unmatchedArgs.Length > 0)
{
var helpBuilder = new HelpBuilder();
var stringWriter = new StringWriter();
helpBuilder.Write(rootCommand, stringWriter);
Console.WriteLine(stringWriter.ToString());
throw new InvalidOperationException($"Unmatched tokens: {string.Join(" ", unmatchedArgs)}");
}
return Host.CreateDefaultBuilder();
},
configureHost: host => host.ConfigureServices(services =>
{
// register your services
})
);
return await config.InvokeAsync(args);
This is with version 2.0.0-beta5.25210.1
https://github.com/lbussell/dotnet-docker/commit/961459765997a1f5d570cac45623a495ea57f77e