command-line-api icon indicating copy to clipboard operation
command-line-api copied to clipboard

Completions for Enum values provide all enum names instead of provided

Open lennybacon opened this issue 11 months ago • 2 comments

I have an enum type:

  public enum JsonWebSignatureAlgorithmType
  {
    Unsupported = 0,
    Hs256 = 1,
    Hs384 = 2,
    Hs512 = 3,
    Rs256 = 10, 
    Rs384 = 11, 
    Rs512 = 12, 
    Ps256 = 20, 
    Ps384 = 21, 
    Ps512 = 22, 
    Es256 = 30, 
    Es384 = 31, 
    Es512 = 32, 
  }

And use that to create an option:

      var option = new Option<JsonWebSignatureAlgorithmType>(
        "-algorithm",
        "The algorithm."
        ) {
          Arity = ArgumentArity.ExactlyOne,
          IsRequired = true
        };
      option.GetArgument().Completions.Clear();
      var names = Enum.GetNames(typeof(JsonWebSignatureAlgorithmType))
        .Where(
          n =>
            !n.Equals(nameof(JsonWebSignatureAlgorithmType.Unsupported), StringComparison.OrdinalIgnoreCase)
            && !n.StartsWith("HS", StringComparison.OrdinalIgnoreCase)
            && !n.StartsWith("PS", StringComparison.OrdinalIgnoreCase))
        .ToArray();
      option.AddCompletions(names);
      // same behavior with
      //option.FromAmong(names);

Now I call the executable with the --help argument.

Expected behavior: The output looks like this - The filtered names:

 -algorithm                                                  The algorithm.
  <Es256|Es384|Es512|Hs256|Hs384|Hs512|Ps256|Ps384|Ps512|Rs256> (REQUIRED)

Actual behavior: The output looks like this - The un-filtered names:

  -algorithm                                                  The algorithm.
  <Es256|Es384|Es512|Hs256|Hs384|Hs512|Ps256|Ps384|Ps512|Rs2
  56|Rs384|Rs512|Unsupported> (REQUIRED)

Workaround: As the Argument is a internal member I can only access It by doing dirty and unwanted reflection to clear the completions collection.

...
var optionType = typeof(Option);
var argumentProperty =
      _s_optionType.GetProperty(
        "Argument",
        BindingFlags.Instance | BindingFlags.NonPublic);
var argument = argumentProperty .GetValue(option) as Argument;
argument.Completions.Clear();

** Wishlist** At least the FromAmong-call should clear the collections for validation and completion, or provide a boolean argument (force), which will do so (more explicit).

lennybacon avatar Mar 12 '25 13:03 lennybacon

Completely agree here - I think I've done the same by hand in the dotnet CLI.

baronfel avatar Mar 12 '25 13:03 baronfel