JasperFx/oakton

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!