diff --git a/src/System.CommandLine.Tests/Help/HelpBuilderTests.cs b/src/System.CommandLine.Tests/Help/HelpBuilderTests.cs index 4b8c9263b5..89fb9fca8a 100644 --- a/src/System.CommandLine.Tests/Help/HelpBuilderTests.cs +++ b/src/System.CommandLine.Tests/Help/HelpBuilderTests.cs @@ -720,7 +720,7 @@ public void Command_arguments_show_argument_name_in_first_column() new Argument("boolArgument") { Description = "Some value" }, new Argument("intArgument") { Description = "Another value" }, }; - + var helpBuilder = GetHelpBuilder(SmallMaxWidth); helpBuilder.Write(command, _console); @@ -777,16 +777,16 @@ public void Help_describes_default_value_for_argument() help.Should().Contain("[default: the-arg-value]"); } - + [Fact] public void Help_does_not_show_default_value_for_argument_when_default_value_is_empty() { var argument = new Argument("the-arg") - { + { Description = "The argument description", DefaultValueFactory = (_) => "" }; - + var command = new Command("the-command", "The command description") { argument @@ -824,6 +824,38 @@ public void Help_does_not_show_default_value_for_option_when_default_value_is_em help.Should().NotContain("[default"); } + [Flags] + public enum Letters + { + A = 1, + B = 2 + } + + [Fact] + public void Help_does_not_show_arguments_for_enum_backed_option_when_arity_is_zero() + { + var option = new Option("--all") + { + Description = "Passes both A and B", + Arity = ArgumentArity.Zero, + CustomParser = _ => Letters.A | Letters.B + }; + + var command = new Command("the-command", "The command description") + { + option + }; + + var helpBuilder = GetHelpBuilder(SmallMaxWidth); + + helpBuilder.Write(command, _console); + + var help = _console.ToString(); + + help.Should().NotContain("--all "); + } + + [Fact] public void Command_arguments_default_value_provided() { @@ -864,7 +896,7 @@ public void Command_arguments_with_default_values_that_are_enumerable_display_pi new Argument>("filter-size") { DefaultValueFactory = (_) => new List() { 0, 2, 4 } - } + } }; _helpBuilder.Write(command, _console); @@ -905,7 +937,7 @@ public void Command_shared_arguments_with_one_or_more_arity_are_displayed_as_bei _console.ToString().Should().Contain(expected); } - + #endregion Arguments #region Options @@ -1491,7 +1523,7 @@ public void Help_describes_default_value_for_subcommand_with_arguments_and_only_ { Hidden = true }; - argument.DefaultValueFactory = _ => "the-arg-value"; + argument.DefaultValueFactory = _ => "the-arg-value"; otherArgumentHidden.DefaultValueFactory = _ => "the-other-hidden-arg-value"; var command = new Command("outer", "outer command help") diff --git a/src/System.CommandLine/Help/HelpBuilder.Default.cs b/src/System.CommandLine/Help/HelpBuilder.Default.cs index 0325a44402..23199dab53 100644 --- a/src/System.CommandLine/Help/HelpBuilder.Default.cs +++ b/src/System.CommandLine/Help/HelpBuilder.Default.cs @@ -50,19 +50,22 @@ public static string GetArgumentUsageLabel(Symbol parameter) // By default Option.Name == Argument.Name, don't repeat it return parameter switch { - Argument argument => GetUsageLabel(argument.HelpName, argument.ValueType, argument.CompletionSources, argument) ?? $"<{argument.Name}>", - Option option => GetUsageLabel(option.HelpName, option.ValueType, option.CompletionSources, option) ?? "", + Argument argument => GetUsageLabel(argument.HelpName, argument.ValueType, argument.CompletionSources, argument, argument.Arity) ?? $"<{argument.Name}>", + Option option => GetUsageLabel(option.HelpName, option.ValueType, option.CompletionSources, option, option.Arity) ?? "", _ => throw new InvalidOperationException() }; - static string? GetUsageLabel(string? helpName, Type valueType, List>> completionSources, Symbol symbol) + static string? GetUsageLabel(string? helpName, Type valueType, List>> completionSources, Symbol symbol, ArgumentArity arity) { // Argument.HelpName is always first choice if (!string.IsNullOrWhiteSpace(helpName)) { return $"<{helpName}>"; } - else if (!(valueType == typeof(bool) || valueType == typeof(bool?)) && completionSources.Count > 0) + else if ( + !(valueType == typeof(bool) || valueType == typeof(bool?)) + && arity.MaximumNumberOfValues > 0 // allowing zero arguments means we don't need to show usage + && completionSources.Count > 0) { IEnumerable completions = symbol .GetCompletions(CompletionContext.Empty) @@ -94,9 +97,9 @@ public static string GetOptionUsageLabel(Option symbol) private static string GetIdentifierSymbolUsageLabel(Symbol symbol, ICollection? aliasSet) { - var aliases = aliasSet is null - ? new [] { symbol.Name } - : new [] {symbol.Name}.Concat(aliasSet) + var aliases = aliasSet is null + ? new[] { symbol.Name } + : new[] { symbol.Name }.Concat(aliasSet) .Select(r => r.SplitPrefix()) .OrderBy(r => r.Prefix, StringComparer.OrdinalIgnoreCase) .ThenBy(r => r.Alias, StringComparer.OrdinalIgnoreCase)