Sub-commands?
cocowalla opened this issue · 3 comments
I'm wondering if there is currently any supported way to use sub-commands?
I'm thinking of the way the Docker CLI works, for example:
docker container rm abc
docker volume ls
We can break down the first example like:
docker container rm abc
^ app ^command ^ sub-command ^ args
I thought perhaps command aliases could have a space in them, which could make this work:
[Description("List volumes", Name = "volume ls")]
public class ListVolumesCommand : OaktonAsyncCommand<ListVolumeInput>
Unfortunately this doesn't work, and I guess it would break handling of enumerable arguments.
You can use arguments to effect sub commands. Your Oakton command can vary on what it actually does by just doing a switch in the Execute on the argument. Oakton was originally built in the FubuCore days -- for better or worse -- as a way to build tools like the git cli
Do you mean using something like this:
[Description("Work with volumes", Name = "volume")]
public class VolumeCommand : OaktonAsyncCommand<VolumeInput>
{
private readonly AppConfig appConfig;
public VolumeCommand(AppConfig appConfig)
{
this.appConfig = appConfig;
Usage("Work with a volume").Arguments(x => x.Action, x => x.Name);
}
public override async Task<bool> Execute(VolumeInput input)
{
// Switch on input.Action here
}
}
public class VolumeInput
{
public CommandAction Action { get; set; } = VolumeAction.ls;
public string Name { get; set; };
public enum CommandAction
{
create,
ls,
inspect,
rm,
}
}
Let's say I also wanted a command my-app volume ls
, i.e. the ls action, but without any arguments - any idea how I could achieve this while still keeping the CommandUsage
from the above code working?
For reference, I worked around this by handling the top level commands myself, then building a CommandExecutor
for the specified command: Gist
@jeremydmiller BTW, I really like how simple yet well-featured this library is compared to the bigger ones!