Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for showing Subgroups / Subcommands in Help print #123

Open
BlackPhlox opened this issue Jun 15, 2024 · 7 comments
Open

Support for showing Subgroups / Subcommands in Help print #123

BlackPhlox opened this issue Jun 15, 2024 · 7 comments

Comments

@BlackPhlox
Copy link

Hi there 👋
Thanks for creating this awesome framework and putting effort into maintaining it!
I'm currently working on a CLI and using this framework when I stumbled upon a limitation:

When implementing subcommands in ones CLI, it can feel overwhelming and cluttered that all commands including all sub-commands being shown in the help print, when in my opinion, the help should only show first level of the hierarchy. Which is usually the case for CLI's with many commands such as Azure's CLI az, which have something called subgroups, which is a group of commands under a command. ConsoleAppFramework should allow to express the this type of hierarchy as well.

Related StackOverflow question by Stephen Gilboy:
https://stackoverflow.com/questions/72913198/in-cysharp-consoleappframework-how-can-i-create-a-sub-sub-command

How it is currently

Given:

// Program.cs
var app = ConsoleApp.Create();
app.Add<KeyVaultCommands>("kv");
app.Run(args);

// ... 
public class KeyVaultCommands
{
    /// <summary>KeyVault - Manage Azure Key Vault Secrets</summary>
    /// <param name="msg">-m, Message to show.</param>
    [Command("")]
    public void Root(string msg) => Console.WriteLine(msg);

    /// <summary>
    /// Prompts installs for the nessary cli to interact with Azure KeyVault
    /// </summary>
    /// <param name="msg"></param>
    [Command("setup")]
    public void Setup(string msg) => Console.WriteLine(msg);
}

Produces result:

> MyCLI.exe
Usage: [command] [-h|--help] [--version]

Commands:
  kv          KeyVault - Manage Azure Key Vault Secrets
  kv setup    Prompts installs for the nessary cli to interact with Azure KeyVault

Notice how the setup command is not shown here, even though they start with the same command keyword:

> MyCLI.exe kv
Usage: kv  [options...] [-h|--help] [--version]

KeyVault - Manage Azure Key Vault Secrets

Options:
  -m|--msg <string>    Message to show. (Required)

How it could look like:

// Program.cs
var app = ConsoleApp.Create();
app.Add<KeyVaultCommands>("kv");
app.Run(args);

// ... 
public class KeyVaultCommands
{
    /// <summary>KeyVault - Manage Azure Key Vault Secrets</summary>
    /// <param name="msg">-m, Message to show.</param>
    [Command("")]
    public void Root(string msg) => Console.WriteLine(msg);

    /// <summary>
    /// Prompts installs for the nessary cli to interact with Azure KeyVault
    /// </summary>
    /// <param name="msg"></param>
    [Command("setup", CommandType.Hidden )] // More enum types could be: Default (Current behaviour), Hidden (The showcase behavior in this issue), Indented (Show as an ASCII tree of the hierarchy of its command parent)
    public void Setup(string msg) => Console.WriteLine(msg);
}
> MyCLI.exe
Usage: [command] [-h|--help] [--version]

Commands:
  kv          KeyVault - Manage Azure Key Vault Secrets

Here below at Commands: it could also be called Subgroups: or the like. Note: I'm also unsure of how the Usage: syntax should look like, currently I've just added a | to indicate or:

>MyCLI.exe kv
Usage: kv [command] | [options...] [-h|--help] [--version]

KeyVault - Manage Azure Key Vault Secrets

Commands:
  setup    Prompts installs for the nessary cli to interact with Azure KeyVault

Options:
  -m|--msg <string>    Message to show. (Required)

If able, please let me know if there's any edgecases or something that I havn't considered due to how the framework is structured.
I'll might take a crack at in the next week or so.

@neuecc
Copy link
Member

neuecc commented Jun 15, 2024

Thank you, I agree that this feature is necessary!
Regarding the display of help, I am using Cocona as a reference, so I think it would be good if we can have a similar display.
https://github.com/mayuki/Cocona

The current problem is that when a Root command does not exist, there is no way to set the Description for the Group.
Also, we may not want to add too many features to the CommandAttribute.

@BlackPhlox
Copy link
Author

@neuecc Thank you for responding so quick, yes framework alignment is properly for the best. Are you thinking a separate attribute would be the best choice or something entirely different?

@BlackPhlox
Copy link
Author

BlackPhlox commented Jun 15, 2024

Regarding Description when no Root command exists, the documentation on the class could be extrapolated, no?

@neuecc
Copy link
Member

neuecc commented Jun 15, 2024

Ah, you're right, it does seem like a good idea to take it from the class documentation!
As for the Attribute, I think a separate one would be better, but in the first place, I don't really understand what the CommandType is supposed to indicate.

@BlackPhlox
Copy link
Author

@neuecc Here's what my idea was:

Default:

> MyCLI.exe
Usage: [command] [-h|--help] [--version]

Commands:
  kv          KeyVault - Manage Azure Key Vault Secrets
  kv setup    Prompts installs for the nessary cli to interact with Azure KeyVault

Hidden, only shown setup when calling > MyCLI.exe kv setup :

> MyCLI.exe
Usage: [command] [-h|--help] [--version]

Commands:
  kv         KeyVault - Manage Azure Key Vault Secrets

Indented:

> MyCLI.exe
Usage: [command] [-h|--help] [--version]

Commands:
  kv          KeyVault - Manage Azure Key Vault Secrets
  └─ setup    Prompts installs for the nessary cli to interact with Azure KeyVault

@neuecc
Copy link
Member

neuecc commented Jun 18, 2024

I see.
I don't think it's a good idea to configure on a per-command basis.
If you want to be able to configure it, the whole thing should be default or hidden, I guess.

@christianklauss
Copy link

christianklauss commented Sep 23, 2024

Just stumbled over this while creating CLI tool with sub-commands. From my personal experience I would expect the default behaviour to be that sub-commands are hidden and only shown when the user requests them on the particular level with --help.

I agree that this should probably be not configured on a per-(sub-)command basis but on a global level. My first idea would be an enumeration that defines this behaviour and can be set as a static property on the ConsoleApp class (to keep in line with the current pattern of the Framework).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants