Subcommands#
You can nest commands. Let's take git
for example
git
has a command called stash. When you execute git stash
, it stashes all the changes. But stash has further commands like, git stash pop
, git stash list
, etc.
Let's mimic the same behavior using CommandDotNet:
Subcommand as a property#
[Command(Description = "Fake git application")]
public class Program
{
static int Main(string[] args) => AppRunner.Run(args);
public static AppRunner AppRunner =>
new AppRunner<Program>().UseNameCasing(Case.KebabCase);
// Properties decorated with the [Subcommand] attribute will be subcommands of the host
[Subcommand]
public Stash Stash { get; set; }
[Command(Description = "Commits all staged changes")]
public void Commit(IConsole console, [Option('m', null)] string? commitMessage)
{
console.WriteLine("Commit successful");
}
}
[Command(Description = "Stashes all changes when executed without any arguments")]
[Subcommand]
public class Stash
{
[DefaultCommand]
public void StashImpl(IConsole console)
{
console.WriteLine("changes stashed");
}
[Command(Description = "Applies last stashed changes")]
public void Pop(IConsole console)
{
console.WriteLine("stash popped");
}
[Command(Description = "Lists all stashed changes")]
public void List(IConsole console)
{
console.WriteLine("here's the list of stash");
}
}
Notice the Stash
property decorated with the [SubCommand]
attribute.
The help will generate as:
$ git.exe -h
Fake git application
Usage: git.exe [command]
Commands:
commit Commits all staged changes
stash Stashes all changes when executed without any arguments
Use "git.exe [command] --help" for more information about a command.
Here's how the interaction looks like:
$ git.exe commit -m "some refactoring"
Commit successful
$ git.exe stash
changes stashed
$ git.exe stash -h
Stashes all changes when executed without any arguments
Usage: git.exe stash [command]
Commands:
list Lists all stashed changes
pop Applies last stashed changes
Use "git.exe stash [command] --help" for more information about a command.
$ git.exe stash pop
stash popped
Tip
See Nullable Reference Types for avoiding "Non-nullable property is uninitialized" warnings for subcommand properties
Subcommand as a nested class#
The same git stash command could be modelled as a nested class.
[Command(Description = "Fake git application")]
public class Program
{
static int Main(string[] args) => AppRunner.Run(args);
public static AppRunner AppRunner =>
new AppRunner<Program>()
.UseNameCasing(Case.KebabCase);
[Command(Description = "Commits all staged changes")]
public void Commit(IConsole console, [Option('m')] string? commitMessage)
{
console.WriteLine("Commit successful");
}
[Command(Description = "Stashes all changes when executed without any arguments")]
[Subcommand]
public class Stash
{
[DefaultCommand]
public void StashImpl(IConsole console)
{
console.WriteLine("changes stashed");
}
[Command(Description = "Applies last stashed changes")]
public void Pop(IConsole console)
{
console.WriteLine("stash popped");
}
[Command(Description = "Lists all stashed changes")]
public void List(IConsole console)
{
console.WriteLine("here's the list of stash");
}
}
}