Open shaggygi opened 2 years ago
Could you say a bit more about what you're wanting to do?
One hint that might or might not be relevant: If you keep a reference to the Option
from the outset, you can use ParseResult.FindResultFor
and ParseResult.GetValueOrDefault
. It's more performant than traversing the hierarchy.
Let's say I have the following:
rootCommand subCommand1 subCommand2 subCommand3
subCommand1 has a GlobalOption. When executing subCommand3, I need to find out what the GlobalOption is within subCommand1.
There is probably a better way, but below is similar to what I'm trying...
public static Command? FindAncestorCommand(Command command, string commandName)
{
foreach (Command parentCommand in command.Parents)
{
if (parentCommand.Name == commandName)
{
return parentCommand;
}
else
{
Command? nextParent = FindAncestorCommand(parentCommand, commandName);
if (nextParent is not null)
{
return nextParent;
}
}
}
return null;
}
Then call within my SetHandler...
if (CommandHelper.FindAncestorCommand(command, "subCommand1") is not SubCommand1 subCommand1)
{
throw new Exception($"Invalid command. {command}");
}
string optionValue = context.ParseResult.GetValueForOption(subCommand1.GetMyOption());
Also note, I have all my Commands and some Options separated into own classes. Not one big setup with Program.cs.
Instead of I'm here since I may want to convert some python utilities that use Click, specifically Click's Nested Handling and Contexts, to dotnet, and happened to find this issue. I'm following the example in #1537 to use custom bindings --- shouldn't I be I be able to get a command's ancestor's custom bound options, and not re-process the individual options and arguments as suggested above? In Click's world, I'd be setting a context object that gets passed down to the subcommand.
We don't currently have APIs to find ancestors or descendants directly, only parents and children. But it's a simple enough thing to do with a helper method so I'm not sure we'd add this kind of convenience method to the surface area of the library.
Here's an example of how we traverse all ancestors using an internal method FlattenBreadthFirst
:
Similar to Children, it seems like Commands could also have Ancestors. Unless there is a better approach, I have to scan each Command's Parents (and each one of their Parents and so on) until I find the one that includes a GlobalOption needed.
Thoughts?
Thx