command-line-api icon indicating copy to clipboard operation
command-line-api copied to clipboard

Provide a better way to hook custom help

Open blowdart opened this issue 6 months ago • 2 comments

Having to define internal sealed class CustomHelpAction(HelpAction action) : SynchronousCommandLineAction and then loop through Options on the rootCommand looking for is HelpOption is a lot of ceremony.

Could we have something like

var rootCommand = new RootCommand("RootCommand")
{
  myArgument,
  myOption1,
  myOption2,
  HelpAction => () { Console.Writeline("Easy help!") }
};

or

rootCommand.SetHelp((cancellationToken) =>
{
   Console.Writeline("Easy help!")
}

blowdart avatar Jun 23 '25 17:06 blowdart

I would rather have the old HelpBuilder made public once again. I used that feature extensively in one of my projects that I need to update with the new System.CommandLine library that was just released, but now, I cannot customize the help anymore! Lame! All I can do is add text before/after the main help output, but I can't actually change the main help output in any way other than setting a description on options and setting a HelpName property. This is not sufficient for modifying help output. Using the (still existing, albeit now internal) HelpBuilder was easy and painless. This is a reduction in useful functionality.

fourpastmidnight avatar Nov 12 '25 17:11 fourpastmidnight

So, there's not too much entanglement from "internal" or "private" only things in System.CommandLine with respect to help. So, I'm forced to basically copy HelpBuilder and HelpContext and other associated classes, including the localization resources--but after doing all of that, and restoring the OnCustomize property of the HelpBuilder, the old functionality is back and working just like before. The main difference being that all the action is kicked off in a new HelpAction class, that itself is really a SynchronousCommandAction object. So, implementing a new one of those and assigning my own implementation to HelpOption is the biggest change, but that change was trivial.

I'm not really sure why this was taken "private". The only thing I can think of is there are planned bigger changes around help, and limiting people's dependence on this component could make it easier for these changes to occur without breaking more people? That's the only plausible reason I can see for this bizarre change. I mean, the HelpBuilder is a bit convoluted and not really extensible, so, there's that. And I would applaud a more extensible design of the help system within System.CommandLine. Other than that, I really need this functionality. So I'm glad to have a "workaround", albeit a desperate one.

fourpastmidnight avatar Nov 14 '25 13:11 fourpastmidnight