Tyrrrz / CliFx

Class-first framework for building command-line interfaces
MIT License
1.5k stars 61 forks source link

Show valid values of an enum option in help #18

Closed Tyrrrz closed 4 years ago

domn1995 commented 4 years ago

I've got this working on a sandbox branch. What's the output format we're looking for here? Here's some ideas:

Code

public enum DummyEnum
{
   Foo, Bar, Baz,
}

[Command("enum")]
public class ShowValidEnumValuesCommand : ICommand
{
    [CommandOption("option", 'o', Description = "Enum option description.")]
    public DummyEnum Option { get; set; } = DummyEnum.Bar;

    public ValueTask ExecuteAsync(IConsole console) => default;
}

Option 1 - Append valid values to the description

Usage
  app enum [options]

Options
  -o,--option       Enum option description. Valid values: foo|bar|baz
  -h|--help         Shows help text.

Option 2 - Append valid values to the option name - Short Name

Usage
  app enum [options]

Options
  -o [foo|bar|baz]  Enum option description.
  -h|--help         Shows help text.

Option 2 - Append valid values to the option name - Short and Long Name

Usage
  app enum [options]

Options
  -o,--option[=foo|bar|baz] Enum option description.
  -h|--help         Shows help text.

Option 3 - Append valid values below option name - Short Name

Usage
  app enum [options]

Options
  -o                Enum option description.
  [foo|bar|baz]
  -h|--help         Shows help text.

Option 3 - Append valid values below option name - Short and Long Name

Usage
  app enum [options]

Options
  -o,--option       Enum option description.
  [=foo|bar|baz]
  -h|--help         Shows help text.

@Tyrrrz, I'd love your input! Once I hear back, I'll submit a PR :)

Tyrrrz commented 4 years ago

I really like option 2 but I'm afraid it won't scale well when there are many enum fields. Otherwise option 1 is the best.

Could you try option 1 and option 2 on enums that have more fields or just longer names? Maybe make a screenshot to compare.

domn1995 commented 4 years ago

Agreed that option 2 seems ideal. Here's some more examples (and ideas) with more options which should cause text wrapping on most terminals:

Code

public enum DummyEnum
{
    Option1, Option2, Option3, Option4, Option5, Option6,
    Option7, Option8, Option9, Option10, Option11, Option12,
}

[Command("enum")]
public class ShowValidEnumValuesCommand : ICommand
{
    [CommandOption("option", 'o', Description = "Enum option.")]
    public DummyEnum Option { get; set; } = DummyEnum.Option1;
    public ValueTask ExecuteAsync(IConsole console) => default;
}

Option 1 - Appended to Description

Usage
  app enum [options]

Options
  -o|--option       Enum option. Valid values: option1, option2, option3, 
option4, option5, option6, option7, option8, option9, option10, option11, 
option12. (Default: option1)
  -h|--help         Shows help text.

Option 2 - Appended to Option, Don't Wrap Description

Usage
  app enum [options]

Options
  -o|--option[=(option1|option2|option3|option4|option5|option6|option7|o
ption8|option9|option10|option11|option12)] Enum option. (Default: option
1)
  -h|--help         Shows help text.

Option 3 - Appended to Option, Wrap Description If Not Aligned with Others

Usage
  app enum [options]

Options
  -o|--option[=(option1|option2|option3|option4|option5|option6|option7|o
ption8|option9|option10|option11|option12)] 
                    Enum option. (Default: option1)
  -h|--help         Shows help text.

The above is how git works whenever an option's definition goes past the start of the description.

I think option1 is the cleanest when you consider also displaying default values. But option3 is pretty clean as well if we wrap to keep descriptions aligned nicely.

Tyrrrz commented 4 years ago

Just by looking at it, I personally feel option 1 is the best. I need to focus pretty hard to parse out the information in option 2 and option 3. So let's go with option 1. :tada:

rcdailey commented 3 years ago

This doesn't work when the option type is List<DummyEnum>