Binding arguments - adambajguz/Typin GitHub Wiki

Commands can be configured to take input from command line arguments. To do that, we need to add properties to the command and annotate them with special attributes.

In Typin, there are two types of argument bindings: parameters and options. Parameters are positional arguments that are identified by the order they appear in, while options are arguments identified by their names.

Here's an example command that calculates a logarithm of a value, which uses both a parameter and an option:

[Command]
public class LogCommand : ICommand
{
    [CommandParameter(0, Description = "Value whose logarithm is to be found.")]
    public double Value { get; set; }

    [CommandOption("base", 'b', Description = "Logarithm base.")]
    public double Base { get; set; } = 10;

    public ValueTask ExecuteAsync(IConsole console)
    {
        var result = Math.Log(Value, Base);
        console.Output.WriteLine(result);

        return default;
    }
}

The above command has two inputs:

  • Value which is a parameter with order 0.
  • Base which is an option with name base and short name b.

Let's try running --help to see how this command is supposed to be used:

> myapp.exe --help

MyApp v1.0

Usage
  myapp.exe <value> [options]

Parameters
* value             Value whose logarithm is to be found.

Options
  -b|--base         Logarithm base. Default: "10".
  -h|--help         Shows help text.
  --version         Shows version information.

As we can see, in order to execute this command, at a minimum, the user has to supply a value:

> myapp.exe 10000

4

They can also set the base option to override the default logarithm base of 10:

> myapp.exe 729 -b 3

6
> myapp.exe 123 --base 4.5

3.199426017362198

On the other hand, if the user fails to provide the required parameter, they will get an error:

> myapp.exe -b 10

Missing value for parameter <value>.

Differences between parameters and options

Property Parameters Options
Order Parameters are identified by their relative order. Options are identified by two dashes followed by their name, or a single dash followed by their short name (single character). All options in command must have different names (comparison is case-sensitive). If this isn't specified, kebab-cased property name is used instead.
Required Always - can't be optional. Yes/No - options are usually optional (as evident by the name), but can be configured to be required as well.
Name Only used in help. Used to identify options while binding arguments. Must be longer than a single character (case-sensitive).
Short name Not supported. Option short name (single character) can be optionally defined (case-sensitive).
Value fallback Not supported. Options can be configured to use the value of a variable from IOptionFallbackProvider as a fallback.
Multiple values Yes, but such a parameter must be last in order to avoid ambiguity. Options are not limited in this aspect. Yes

When name isn't specified, kebab-cased property name is used instead.

Which one to use?

As a general guideline, prefer to use parameters for required inputs that the command can't work without. Use options for non-required inputs, or when the command has too many required inputs, or when specifying the option name explicitly provides a better user experience.

⚠️ **GitHub.com Fallback** ⚠️