Skip to content

Commit 28ad8f7

Browse files
baronfeljonsequitur
authored andcommitted
Only show help arguments for Options/Arguments with an Arity greater than zero
1 parent 0aaa253 commit 28ad8f7

File tree

2 files changed

+49
-14
lines changed

2 files changed

+49
-14
lines changed

src/System.CommandLine.Tests/Help/HelpBuilderTests.cs

Lines changed: 39 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -720,7 +720,7 @@ public void Command_arguments_show_argument_name_in_first_column()
720720
new Argument<bool>("boolArgument") { Description = "Some value" },
721721
new Argument<int>("intArgument") { Description = "Another value" },
722722
};
723-
723+
724724
var helpBuilder = GetHelpBuilder(SmallMaxWidth);
725725

726726
helpBuilder.Write(command, _console);
@@ -777,16 +777,16 @@ public void Help_describes_default_value_for_argument()
777777

778778
help.Should().Contain("[default: the-arg-value]");
779779
}
780-
780+
781781
[Fact]
782782
public void Help_does_not_show_default_value_for_argument_when_default_value_is_empty()
783783
{
784784
var argument = new Argument<string>("the-arg")
785-
{
785+
{
786786
Description = "The argument description",
787787
DefaultValueFactory = (_) => ""
788788
};
789-
789+
790790
var command = new Command("the-command", "The command description")
791791
{
792792
argument
@@ -824,6 +824,38 @@ public void Help_does_not_show_default_value_for_option_when_default_value_is_em
824824
help.Should().NotContain("[default");
825825
}
826826

827+
[Flags]
828+
public enum Letters
829+
{
830+
A = 1,
831+
B = 2
832+
}
833+
834+
[Fact]
835+
public void Help_does_not_show_arguments_for_enum_backed_option_when_arity_is_zero()
836+
{
837+
var option = new Option<Letters>("--all")
838+
{
839+
Description = "Passes both A and B",
840+
Arity = ArgumentArity.Zero,
841+
CustomParser = _ => Letters.A | Letters.B
842+
};
843+
844+
var command = new Command("the-command", "The command description")
845+
{
846+
option
847+
};
848+
849+
var helpBuilder = GetHelpBuilder(SmallMaxWidth);
850+
851+
helpBuilder.Write(command, _console);
852+
853+
var help = _console.ToString();
854+
855+
help.Should().NotContain("--all <A|B>");
856+
}
857+
858+
827859
[Fact]
828860
public void Command_arguments_default_value_provided()
829861
{
@@ -864,7 +896,7 @@ public void Command_arguments_with_default_values_that_are_enumerable_display_pi
864896
new Argument<List<int>>("filter-size")
865897
{
866898
DefaultValueFactory = (_) => new List<int>() { 0, 2, 4 }
867-
}
899+
}
868900
};
869901

870902
_helpBuilder.Write(command, _console);
@@ -905,7 +937,7 @@ public void Command_shared_arguments_with_one_or_more_arity_are_displayed_as_bei
905937

906938
_console.ToString().Should().Contain(expected);
907939
}
908-
940+
909941
#endregion Arguments
910942

911943
#region Options
@@ -1491,7 +1523,7 @@ public void Help_describes_default_value_for_subcommand_with_arguments_and_only_
14911523
{
14921524
Hidden = true
14931525
};
1494-
argument.DefaultValueFactory = _ => "the-arg-value";
1526+
argument.DefaultValueFactory = _ => "the-arg-value";
14951527
otherArgumentHidden.DefaultValueFactory = _ => "the-other-hidden-arg-value";
14961528

14971529
var command = new Command("outer", "outer command help")

src/System.CommandLine/Help/HelpBuilder.Default.cs

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -50,19 +50,22 @@ public static string GetArgumentUsageLabel(Symbol parameter)
5050
// By default Option.Name == Argument.Name, don't repeat it
5151
return parameter switch
5252
{
53-
Argument argument => GetUsageLabel(argument.HelpName, argument.ValueType, argument.CompletionSources, argument) ?? $"<{argument.Name}>",
54-
Option option => GetUsageLabel(option.HelpName, option.ValueType, option.CompletionSources, option) ?? "",
53+
Argument argument => GetUsageLabel(argument.HelpName, argument.ValueType, argument.CompletionSources, argument, argument.Arity) ?? $"<{argument.Name}>",
54+
Option option => GetUsageLabel(option.HelpName, option.ValueType, option.CompletionSources, option, option.Arity) ?? "",
5555
_ => throw new InvalidOperationException()
5656
};
5757

58-
static string? GetUsageLabel(string? helpName, Type valueType, List<Func<CompletionContext, IEnumerable<CompletionItem>>> completionSources, Symbol symbol)
58+
static string? GetUsageLabel(string? helpName, Type valueType, List<Func<CompletionContext, IEnumerable<CompletionItem>>> completionSources, Symbol symbol, ArgumentArity arity)
5959
{
6060
// Argument.HelpName is always first choice
6161
if (!string.IsNullOrWhiteSpace(helpName))
6262
{
6363
return $"<{helpName}>";
6464
}
65-
else if (!(valueType == typeof(bool) || valueType == typeof(bool?)) && completionSources.Count > 0)
65+
else if (
66+
!(valueType == typeof(bool) || valueType == typeof(bool?))
67+
&& arity.MaximumNumberOfValues > 0 // allowing zero arguments means we don't need to show usage
68+
&& completionSources.Count > 0)
6669
{
6770
IEnumerable<string> completions = symbol
6871
.GetCompletions(CompletionContext.Empty)
@@ -94,9 +97,9 @@ public static string GetOptionUsageLabel(Option symbol)
9497

9598
private static string GetIdentifierSymbolUsageLabel(Symbol symbol, ICollection<string>? aliasSet)
9699
{
97-
var aliases = aliasSet is null
98-
? new [] { symbol.Name }
99-
: new [] {symbol.Name}.Concat(aliasSet)
100+
var aliases = aliasSet is null
101+
? new[] { symbol.Name }
102+
: new[] { symbol.Name }.Concat(aliasSet)
100103
.Select(r => r.SplitPrefix())
101104
.OrderBy(r => r.Prefix, StringComparer.OrdinalIgnoreCase)
102105
.ThenBy(r => r.Alias, StringComparer.OrdinalIgnoreCase)

0 commit comments

Comments
 (0)