Command-line-api: Was not obvious to me how to get an argument passed to a handler

Created on 24 May 2019  路  12Comments  路  Source: dotnet/command-line-api

I eventually figured out that giving the argument a name was the key thing, but it would be helpful to add an example and perhaps mention this somewhere.

Area-Documentation

Most helpful comment

The code needs to be a lot less forgiving in my opinion. I wrestled with this for a while and believe I would have saved time if the CommandHandler complained if I had arguments in the passed lambda with names that did not match any known arguments or options.

All 12 comments

I still can't figure out how to do this via the System.CommandLine API :(

Here's what I ended up doing. The argument name is set and matches up with the parameter name on the helper delegate.
```c#
Command countCommand = new Command("COUNT");
{
countCommand.Description = "Count the number of types and methods in an assembly.";
countCommand.AddAlias("count");

        Argument<string> assemblyArgument = new Argument<string>();
        assemblyArgument.Arity = ArgumentArity.ExactlyOne;
        assemblyArgument.Name = "assemblyName";             // this name 
        assemblyArgument.Description = "Assembly file to process";
        countCommand.AddArgument(assemblyArgument);
                                                            // matches this name
        countCommand.Handler = CommandHandler.Create<string>((assemblyName) =>
        {
            if (File.Exists(assemblyName))
            {
                Visitor v = new Counter();
                Worker w = new Worker(v, false);
                return w.Work(assemblyName);
            }

            Console.WriteLine($"Failed: assembly '{assemblyName}' does not exist");
            return 101;
        });
    }

```

This is a common gotcha and we're looking for suggestion to improve it.

FYI, you should only need to set the arity of an argument in very specialized circumstances, e.g. custom conversion logic. It's inferred based on the type.

I was having some trouble with a command with multiple args and options and thought it might be arity related, so I was setting everything explicitly there for a while.

Let me see if I can get you a repro.

I spent a lot of time to figure this out
If the name doesn't match you will receive null as the argument value
If you don't set the arity the command won't work:

'arg' was not matched. Did you mean 'help'?
Unrecognized command or argument 'arg'

You need both the name to match and set the arity

@ctyar Can you post an example? You should not need to set the arity in most cases.

Ah, of course. I wasn't thinking about the non-generic Argument class. I'll clarify my previous statement to say, You should not need to set the arity in most cases _if you are using Argument<T> or setting Argument.ArgumentType_. The argument's type is used to infer the arity and will typically be correct.

So, reasons to set arity:

  • Argument.ArgumentType is not set (meaning all binding is done lazily)
  • Argument.ArgumentType is an enumerable type and the argument is one of multiple command arguments but not the final one.
  • A custom parse delegate is being used and the standard inferred arity is not correct for your Argument.ArgumentType.

I was under the assumption that here CommandHandler.Create<string>(Add) is where I define my argument types.
So I need to match this with an Argument<string>.
Thanks, that clarifies it.

The code needs to be a lot less forgiving in my opinion. I wrestled with this for a while and believe I would have saved time if the CommandHandler complained if I had arguments in the passed lambda with names that did not match any known arguments or options.

872 is a proposal to address this. I'd appreciate your thoughts on it.

Potential solution: #1012. Please comment.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

shaggygi picture shaggygi  路  5Comments

DualBrain picture DualBrain  路  3Comments

divinebovine picture divinebovine  路  3Comments

SirJosh3917 picture SirJosh3917  路  3Comments

mariopasquali picture mariopasquali  路  4Comments