bilal-fazlani / commanddotnet

A modern framework for building modern CLI apps
https://commanddotnet.bilal-fazlani.com
MIT License
560 stars 32 forks source link

Help provider per method #472

Open SebastianStehle opened 1 year ago

SebastianStehle commented 1 year ago

Hi,

inside my command, I have a list of "targets" that I run, e.g. a target is described by:

interface ITarget
{
   string Name { get; }
   void Run();
}

I have an option -t to define, which targets to run.

[Option('t', "targets", Description = "The targets to sync, e.g. schemas, workflows, app, rules.")]
public string[] Targets { get; set; }

I would like to have a method to describe the targets. Perhaps something like "DescriptionMethod" where I can define which method to invoke when the description is generated.

e.g.

[Option('t', "targets", DescriptionMethod = nameof(DescribeTargets))]
public string[] Targets { get; set; }

private static string DescribeTargets(....) {

}

Would be also great for other descriptions

drewburlingame commented 1 year ago

Hi @SebastianStehle, I like the idea. I won't have time to implement this in the near future but would except it as a PR.

In the meantime, I can think of two ways to implement this if you need it soon.

The first is to create a [DescriptionMethod(nameof(DescribeTargets)] attribute and put it on the option. Then create a custom help provider by inheriting from HelpTextProvider and overriding ArgumentDescription. In that method, you can use argument.GetCustomAttribute<DescriptionMethodAttribute>() and use that attribute if it exists, else fall back to the base method. Since it's the only method you'd need to override, this should be a pretty small effort.

The second is to create a middleware component that will get the targeted command and assign the description to the argument. This would be more work than the custom help provider, but I can describe it if you're interested.