Skip to content

Commit 569b913

Browse files
authored
fix: update help text to show allowed values from AllowedValues attribute instead of Enum values (#391)
1 parent 497f598 commit 569b913

File tree

2 files changed

+44
-10
lines changed

2 files changed

+44
-10
lines changed

src/CommandLineUtils/HelpText/DefaultHelpTextGenerator.cs

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -192,20 +192,28 @@ protected virtual void GenerateArguments(
192192

193193
foreach (var arg in visibleArguments)
194194
{
195-
var enumNames = ExtractNamesFromEnum(arg.UnderlyingType);
196-
var description = enumNames.Any()
197-
? $"{arg.Description}\nAllowed values are: {string.Join(", ", enumNames)}."
198-
: arg.Description;
195+
var description = arg.Description;
196+
var allowedValuesBeenSet = false;
199197

200198
foreach (var attributeValidator in arg.Validators.Cast<AttributeValidator>())
201199
{
202200
if (attributeValidator?.ValidationAttribute is AllowedValuesAttribute allowedValuesAttribute)
203201
{
204202
description += $"\nAllowed values are: {string.Join(", ", allowedValuesAttribute.AllowedValues)}.";
203+
allowedValuesBeenSet = true;
205204
break;
206205
}
207206
}
208207

208+
if (!allowedValuesBeenSet)
209+
{
210+
var enumNames = ExtractNamesFromEnum(arg.UnderlyingType);
211+
if (enumNames.Any())
212+
{
213+
description += $"\nAllowed values are: {string.Join(", ", enumNames)}.";
214+
}
215+
}
216+
209217
var wrappedDescription = IndentWriter?.Write(description);
210218
var message = string.Format(outputFormat, arg.Name, wrappedDescription);
211219

@@ -236,20 +244,28 @@ protected virtual void GenerateOptions(
236244

237245
foreach (var opt in visibleOptions)
238246
{
239-
var enumNames = ExtractNamesFromEnum(opt.UnderlyingType);
240-
var description = enumNames.Any()
241-
? $"{opt.Description}\nAllowed values are: {string.Join(", ", enumNames)}."
242-
: opt.Description;
247+
var description = opt.Description;
248+
var allowedValuesBeenSet = false;
243249

244250
foreach (var attributeValidator in opt.Validators.Cast<AttributeValidator>())
245251
{
246252
if (attributeValidator?.ValidationAttribute is AllowedValuesAttribute allowedValuesAttribute)
247253
{
248254
description += $"\nAllowed values are: {string.Join(", ", allowedValuesAttribute.AllowedValues)}.";
255+
allowedValuesBeenSet = true;
249256
break;
250257
}
251258
}
252259

260+
if (!allowedValuesBeenSet)
261+
{
262+
var enumNames = ExtractNamesFromEnum(opt.UnderlyingType);
263+
if (enumNames.Any())
264+
{
265+
description += $"\nAllowed values are: {string.Join(", ", enumNames)}.";
266+
}
267+
}
268+
253269
var wrappedDescription = IndentWriter?.Write(description);
254270
var message = string.Format(outputFormat, Format(opt), wrappedDescription);
255271

test/CommandLineUtils.Tests/DefaultHelpTextGeneratorTests.cs

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,19 +112,23 @@ public void ShowHelp()
112112
app.Option("--rStrOpt <E>", "restricted str option desc.", CommandOptionType.SingleValue, o => o.IsRequired().Accepts().Values("Foo", "Bar"));
113113
app.Option<int>("--intOpt <E>", "int option desc.", CommandOptionType.SingleValue);
114114
app.Option<SomeEnum>("--enumOpt <E>", "enum option desc.", CommandOptionType.SingleValue);
115+
app.Option<SomeEnum>("--rEnumOpt <E>", "restricted enum option desc.", CommandOptionType.SingleValue, o => o.Accepts().Values("None", "Normal"));
115116
app.Argument("SomeStringArgument", "string arg desc.");
116117
app.Argument("RestrictedStringArgument", "restricted string arg desc.", a => a.IsRequired().Accepts().Values("Foo", "Bar"));
117118
app.Argument<SomeEnum>("SomeEnumArgument", "enum arg desc.");
119+
app.Argument<SomeEnum>("RestrictedEnumArgument", "restricted enum arg desc.", a => a.Accepts().Values("None", "Normal"));
118120
var helpText = GetHelpText(app);
119121

120-
Assert.Equal(@"Usage: [options] <SomeStringArgument> <RestrictedStringArgument> <SomeEnumArgument>
122+
Assert.Equal(@"Usage: [options] <SomeStringArgument> <RestrictedStringArgument> <SomeEnumArgument> <RestrictedEnumArgument>
121123
122124
Arguments:
123125
SomeStringArgument string arg desc.
124126
RestrictedStringArgument restricted string arg desc.
125127
Allowed values are: Foo, Bar.
126128
SomeEnumArgument enum arg desc.
127129
Allowed values are: None, Normal, Extreme.
130+
RestrictedEnumArgument restricted enum arg desc.
131+
Allowed values are: None, Normal.
128132
129133
Options:
130134
-?|-h|--help Show help information.
@@ -134,6 +138,8 @@ SomeEnumArgument enum arg desc.
134138
--intOpt <E> int option desc.
135139
--enumOpt <E> enum option desc.
136140
Allowed values are: None, Normal, Extreme.
141+
--rEnumOpt <E> restricted enum option desc.
142+
Allowed values are: None, Normal.
137143
138144
",
139145
helpText,
@@ -148,14 +154,16 @@ public void ShowHelpFromAttributes()
148154
app.Conventions.UseDefaultConventions();
149155
var helpText = GetHelpText(app);
150156

151-
Assert.Equal(@"Usage: test [options] <SomeStringArgument> <RestrictedStringArgument> <SomeEnumArgument>
157+
Assert.Equal(@"Usage: test [options] <SomeStringArgument> <RestrictedStringArgument> <SomeEnumArgument> <RestrictedEnumArgument>
152158
153159
Arguments:
154160
SomeStringArgument string arg desc.
155161
RestrictedStringArgument restricted string arg desc.
156162
Allowed values are: Foo, Bar.
157163
SomeEnumArgument enum arg desc.
158164
Allowed values are: None, Normal, Extreme.
165+
RestrictedEnumArgument restricted enum arg desc.
166+
Allowed values are: None, Normal.
159167
160168
Options:
161169
-strOpt|--str-opt <STR_OPT> str option desc.
@@ -164,6 +172,8 @@ SomeEnumArgument enum arg desc.
164172
-intOpt|--int-opt <INT_OPT> int option desc.
165173
-enumOpt|--verbosity <VERBOSITY> enum option desc.
166174
Allowed values are: None, Normal, Extreme.
175+
-rEnumOpt|--verb2 <VERB2> restricted enum option desc.
176+
Allowed values are: None, Normal.
167177
-?|-h|--help Show help information.
168178
169179
",
@@ -187,6 +197,10 @@ public class MyApp
187197
[Option(ShortName = "enumOpt", Description = "enum option desc.")]
188198
public SomeEnum Verbosity { get; set; }
189199

200+
[Option(ShortName = "rEnumOpt", Description = "restricted enum option desc.")]
201+
[AllowedValues("None", "Normal")]
202+
public SomeEnum Verb2 { get; set; }
203+
190204
[Argument(0, Description = "string arg desc.")]
191205
public string SomeStringArgument { get; set; }
192206

@@ -197,6 +211,10 @@ public class MyApp
197211

198212
[Argument(2, Description = "enum arg desc.")]
199213
public SomeEnum SomeEnumArgument { get; set; }
214+
215+
[Argument(3, Description = "restricted enum arg desc.")]
216+
[AllowedValues("None", "Normal")]
217+
public SomeEnum RestrictedEnumArgument { get; set; }
200218
}
201219

202220
[Theory]

0 commit comments

Comments
 (0)