Skip to content

Commit d638310

Browse files
committed
Merge branch 'Athari-disable-auto-options' into develop
2 parents 47269dd + 0db898d commit d638310

11 files changed

+180
-15
lines changed

src/CommandLine/Core/InstanceBuilder.cs

+3-1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ public static ParserResult<T> Build<T>(
2323
StringComparer nameComparer,
2424
bool ignoreValueCase,
2525
CultureInfo parsingCulture,
26+
bool autoHelp,
27+
bool autoVersion,
2628
IEnumerable<ErrorType> nonFatalErrors)
2729
{
2830
var typeInfo = factory.MapValueOrDefault(f => f().GetType(), typeof(T));
@@ -139,7 +141,7 @@ from sp in spv.DefaultIfEmpty()
139141

140142
var preprocessorErrors = (
141143
argumentsList.Any()
142-
? argumentsList.Preprocess(PreprocessorGuards.Lookup(nameComparer))
144+
? arguments.Preprocess(PreprocessorGuards.Lookup(nameComparer, autoHelp, autoVersion))
143145
: Enumerable.Empty<Error>()
144146
).Memorize();
145147

src/CommandLine/Core/InstanceChooser.cs

+9-3
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ public static ParserResult<object> Choose(
1919
StringComparer nameComparer,
2020
bool ignoreValueCase,
2121
CultureInfo parsingCulture,
22+
bool autoHelp,
23+
bool autoVersion,
2224
IEnumerable<ErrorType> nonFatalErrors)
2325
{
2426
Func<ParserResult<object>> choose = () =>
@@ -31,13 +33,13 @@ public static ParserResult<object> Choose(
3133

3234
var verbs = Verb.SelectFromTypes(types);
3335

34-
return preprocCompare("help")
36+
return (autoHelp && preprocCompare("help"))
3537
? MakeNotParsed(types,
3638
MakeHelpVerbRequestedError(verbs,
3739
arguments.Skip(1).FirstOrDefault() ?? string.Empty, nameComparer))
38-
: preprocCompare("version")
40+
: (autoVersion && preprocCompare("version"))
3941
? MakeNotParsed(types, new VersionRequestedError())
40-
: MatchVerb(tokenizer, verbs, arguments, nameComparer, ignoreValueCase, parsingCulture, nonFatalErrors);
42+
: MatchVerb(tokenizer, verbs, arguments, nameComparer, ignoreValueCase, parsingCulture, autoHelp, autoVersion, nonFatalErrors);
4143
};
4244

4345
return arguments.Any()
@@ -52,6 +54,8 @@ private static ParserResult<object> MatchVerb(
5254
StringComparer nameComparer,
5355
bool ignoreValueCase,
5456
CultureInfo parsingCulture,
57+
bool autoHelp,
58+
bool autoVersion,
5559
IEnumerable<ErrorType> nonFatalErrors)
5660
{
5761
return verbs.Any(a => nameComparer.Equals(a.Item1.Name, arguments.First()))
@@ -64,6 +68,8 @@ private static ParserResult<object> MatchVerb(
6468
nameComparer,
6569
ignoreValueCase,
6670
parsingCulture,
71+
autoHelp,
72+
autoVersion,
6773
nonFatalErrors)
6874
: MakeNotParsed(verbs.Select(v => v.Item2), new BadVerbSelectedError(arguments.First()));
6975
}

src/CommandLine/Core/PreprocessorGuards.cs

+7-6
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,14 @@ namespace CommandLine.Core
99
static class PreprocessorGuards
1010
{
1111
public static IEnumerable<Func<IEnumerable<string>, IEnumerable<Error>>>
12-
Lookup(StringComparer nameComparer)
12+
Lookup(StringComparer nameComparer, bool autoHelp, bool autoVersion)
1313
{
14-
return new List<Func<IEnumerable<string>, IEnumerable<Error>>>
15-
{
16-
HelpCommand(nameComparer),
17-
VersionCommand(nameComparer)
18-
};
14+
var list = new List<Func<IEnumerable<string>, IEnumerable<Error>>>();
15+
if (autoHelp)
16+
list.Add(HelpCommand(nameComparer));
17+
if (autoVersion)
18+
list.Add(VersionCommand(nameComparer));
19+
return list;
1920
}
2021

2122
public static Func<IEnumerable<string>, IEnumerable<Error>> HelpCommand(StringComparer nameComparer)

src/CommandLine/Parser.cs

+6
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,8 @@ public ParserResult<T> ParseArguments<T>(IEnumerable<string> args)
9999
settings.NameComparer,
100100
settings.CaseInsensitiveEnumValues,
101101
settings.ParsingCulture,
102+
settings.AutoHelp,
103+
settings.AutoVersion,
102104
HandleUnknownArguments(settings.IgnoreUnknownArguments)),
103105
settings);
104106
}
@@ -128,6 +130,8 @@ public ParserResult<T> ParseArguments<T>(Func<T> factory, IEnumerable<string> ar
128130
settings.NameComparer,
129131
settings.CaseInsensitiveEnumValues,
130132
settings.ParsingCulture,
133+
settings.AutoHelp,
134+
settings.AutoVersion,
131135
HandleUnknownArguments(settings.IgnoreUnknownArguments)),
132136
settings);
133137
}
@@ -158,6 +162,8 @@ public ParserResult<object> ParseArguments(IEnumerable<string> args, params Type
158162
settings.NameComparer,
159163
settings.CaseInsensitiveEnumValues,
160164
settings.ParsingCulture,
165+
settings.AutoHelp,
166+
settings.AutoVersion,
161167
HandleUnknownArguments(settings.IgnoreUnknownArguments)),
162168
settings);
163169
}

src/CommandLine/ParserSettings.cs

+22
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ public class ParserSettings : IDisposable
2020
private bool caseInsensitiveEnumValues;
2121
private TextWriter helpWriter;
2222
private bool ignoreUnknownArguments;
23+
private bool autoHelp;
24+
private bool autoVersion;
2325
private CultureInfo parsingCulture;
2426
private bool enableDashDash;
2527
private int maximumDisplayWidth;
@@ -31,6 +33,8 @@ public ParserSettings()
3133
{
3234
caseSensitive = true;
3335
caseInsensitiveEnumValues = false;
36+
autoHelp = true;
37+
autoVersion = true;
3438
parsingCulture = CultureInfo.InvariantCulture;
3539
try
3640
{
@@ -122,6 +126,24 @@ public bool IgnoreUnknownArguments
122126
set { PopsicleSetter.Set(Consumed, ref ignoreUnknownArguments, value); }
123127
}
124128

129+
/// <summary>
130+
/// Gets or sets a value indicating whether implicit option or verb 'help' should be supported.
131+
/// </summary>
132+
public bool AutoHelp
133+
{
134+
get { return autoHelp; }
135+
set { PopsicleSetter.Set(Consumed, ref autoHelp, value); }
136+
}
137+
138+
/// <summary>
139+
/// Gets or sets a value indicating whether implicit option or verb 'version' should be supported.
140+
/// </summary>
141+
public bool AutoVersion
142+
{
143+
get { return autoVersion; }
144+
set { PopsicleSetter.Set(Consumed, ref autoVersion, value); }
145+
}
146+
125147
/// <summary>
126148
/// Gets or sets a value indicating whether enable double dash '--' syntax,
127149
/// that forces parsing of all subsequent tokens as values.

src/CommandLine/Text/HelpText.cs

+34-4
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ public class HelpText
3131
private StringBuilder optionsHelp;
3232
private bool addDashesToOption;
3333
private bool addEnumValuesToHelpText;
34+
private bool autoHelp;
35+
private bool autoVersion;
3436

3537
/// <summary>
3638
/// Initializes a new instance of the <see cref="CommandLine.Text.HelpText"/> class.
@@ -117,6 +119,8 @@ public HelpText(SentenceBuilder sentenceBuilder, string heading, string copyrigh
117119
this.sentenceBuilder = sentenceBuilder;
118120
this.heading = heading;
119121
this.copyright = copyright;
122+
this.autoHelp = true;
123+
this.autoVersion = true;
120124
}
121125

122126
/// <summary>
@@ -187,6 +191,24 @@ public bool AddEnumValuesToHelpText
187191
set { addEnumValuesToHelpText = value; }
188192
}
189193

194+
/// <summary>
195+
/// Gets or sets a value indicating whether implicit option or verb 'help' should be supported.
196+
/// </summary>
197+
public bool AutoHelp
198+
{
199+
get { return autoHelp; }
200+
set { autoHelp = value; }
201+
}
202+
203+
/// <summary>
204+
/// Gets or sets a value indicating whether implicit option or verb 'version' should be supported.
205+
/// </summary>
206+
public bool AutoVersion
207+
{
208+
get { return autoVersion; }
209+
set { autoVersion = value; }
210+
}
211+
190212
/// <summary>
191213
/// Gets the <see cref="SentenceBuilder"/> instance specified in constructor.
192214
/// </summary>
@@ -680,8 +702,11 @@ private IEnumerable<Specification> GetSpecificationsFromType(Type type)
680702
{
681703
var specs = type.GetSpecifications(Specification.FromProperty);
682704
var optionSpecs = specs
683-
.OfType<OptionSpecification>()
684-
.Concat(new[] { MakeHelpEntry(), MakeVersionEntry() });
705+
.OfType<OptionSpecification>();
706+
if (autoHelp)
707+
optionSpecs = optionSpecs.Concat(new [] { MakeHelpEntry() });
708+
if (autoVersion)
709+
optionSpecs = optionSpecs.Concat(new [] { MakeVersionEntry() });
685710
var valueSpecs = specs
686711
.OfType<ValueSpecification>()
687712
.OrderBy(v => v.Index);
@@ -711,15 +736,20 @@ private static Maybe<Tuple<UsageAttribute, IEnumerable<Example>>> GetUsageFromTy
711736

712737
private IEnumerable<Specification> AdaptVerbsToSpecifications(IEnumerable<Type> types)
713738
{
714-
return (from verbTuple in Verb.SelectFromTypes(types)
739+
var optionSpecs = from verbTuple in Verb.SelectFromTypes(types)
715740
select
716741
OptionSpecification.NewSwitch(
717742
string.Empty,
718743
verbTuple.Item1.Name,
719744
false,
720745
verbTuple.Item1.HelpText,
721746
string.Empty,
722-
verbTuple.Item1.Hidden)).Concat(new[] { MakeHelpEntry(), MakeVersionEntry() });
747+
verbTuple.Item1.Hidden);
748+
if (autoHelp)
749+
optionSpecs = optionSpecs.Concat(new [] { MakeHelpEntry() });
750+
if (autoVersion)
751+
optionSpecs = optionSpecs.Concat(new [] { MakeVersionEntry() });
752+
return optionSpecs;
723753
}
724754

725755
private HelpText AddOptionsImpl(

tests/CommandLine.Tests/CommandLine.Tests.csproj

+2
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@
5959
</Compile>
6060
<Compile Include="CultureInfoExtensions.cs" />
6161
<Compile Include="Fakes\Hidden_Option.cs" />
62+
<Compile Include="Fakes\Options_With_Custom_Help_Option.cs" />
63+
<Compile Include="Fakes\Options_With_Custom_Version_Option.cs" />
6264
<Compile Include="Fakes\Options_With_Default_Set_To_Sequence.cs" />
6365
<Compile Include="Fakes\Options_With_Guid.cs" />
6466
<Compile Include="Fakes\Options_With_Option_And_Value_Of_String_Type.cs" />
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
namespace CommandLine.Tests.Fakes
2+
{
3+
class Options_With_Custom_Help_Option : Simple_Options
4+
{
5+
[Option('h', "help")]
6+
public bool Help { get; set; }
7+
}
8+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
namespace CommandLine.Tests.Fakes
2+
{
3+
class Options_With_Custom_Version_Option : Simple_Options
4+
{
5+
[Option('v', "version")]
6+
public bool MyVersion { get; set; }
7+
}
8+
}

tests/CommandLine.Tests/Unit/Core/InstanceBuilderTests.cs

+79-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ namespace CommandLine.Tests.Unit.Core
1919
{
2020
public class InstanceBuilderTests
2121
{
22-
private static ParserResult<T> InvokeBuild<T>(string[] arguments)
22+
private static ParserResult<T> InvokeBuild<T>(string[] arguments, bool autoHelp = true, bool autoVersion = true)
2323
where T : new()
2424
{
2525
return InstanceBuilder.Build(
@@ -29,6 +29,8 @@ private static ParserResult<T> InvokeBuild<T>(string[] arguments)
2929
StringComparer.Ordinal,
3030
false,
3131
CultureInfo.InvariantCulture,
32+
autoHelp,
33+
autoVersion,
3234
Enumerable.Empty<ErrorType>());
3335
}
3436

@@ -42,6 +44,8 @@ private static ParserResult<T> InvokeBuildEnumValuesCaseIgnore<T>(string[] argum
4244
StringComparer.Ordinal,
4345
true,
4446
CultureInfo.InvariantCulture,
47+
true,
48+
true,
4549
Enumerable.Empty<ErrorType>());
4650
}
4751

@@ -54,6 +58,8 @@ private static ParserResult<T> InvokeBuildImmutable<T>(string[] arguments)
5458
StringComparer.Ordinal,
5559
false,
5660
CultureInfo.InvariantCulture,
61+
true,
62+
true,
5763
Enumerable.Empty<ErrorType>());
5864
}
5965

@@ -451,6 +457,8 @@ public void Double_dash_force_subsequent_arguments_as_values()
451457
StringComparer.Ordinal,
452458
false,
453459
CultureInfo.InvariantCulture,
460+
true,
461+
true,
454462
Enumerable.Empty<ErrorType>());
455463

456464
// Verify outcome
@@ -1024,6 +1032,76 @@ public void Parse_string_with_dashes_except_in_beginning(string[] arguments, str
10241032
// Teardown
10251033
}
10261034

1035+
[Theory]
1036+
[InlineData(new[] { "--help" }, ErrorType.UnknownOptionError)]
1037+
public void Parse_without_auto_help_should_not_recognize_help_option(string[] arguments, ErrorType errorType)
1038+
{
1039+
// Fixture setup in attributes
1040+
1041+
// Exercize system
1042+
var result = InvokeBuild<Simple_Options>(arguments, autoHelp: false);
1043+
1044+
// Verify outcome
1045+
result.Should().BeOfType<NotParsed<Simple_Options>>()
1046+
.Which.Errors.Should().ContainSingle()
1047+
.Which.Tag.Should().Be(errorType);
1048+
1049+
// Teardown
1050+
}
1051+
1052+
[Theory]
1053+
[InlineData(new[] { "--help" }, true)]
1054+
[InlineData(new[] { "-h" }, true)]
1055+
[InlineData(new[] { "-x" }, false)]
1056+
public void Parse_with_custom_help_option(string[] arguments, bool isHelp)
1057+
{
1058+
// Fixture setup in attributes
1059+
1060+
// Exercize system
1061+
var result = InvokeBuild<Options_With_Custom_Help_Option>(arguments, autoHelp: false);
1062+
1063+
// Verify outcome
1064+
result.Should().BeOfType<Parsed<Options_With_Custom_Help_Option>>()
1065+
.Which.Value.Help.Should().Be(isHelp);
1066+
1067+
// Teardown
1068+
}
1069+
1070+
[Theory]
1071+
[InlineData(new[] { "--version" }, ErrorType.UnknownOptionError)]
1072+
public void Parse_without_auto_version_should_not_recognize_version_option(string[] arguments, ErrorType errorType)
1073+
{
1074+
// Fixture setup in attributes
1075+
1076+
// Exercize system
1077+
var result = InvokeBuild<Simple_Options>(arguments, autoVersion: false);
1078+
1079+
// Verify outcome
1080+
result.Should().BeOfType<NotParsed<Simple_Options>>()
1081+
.Which.Errors.Should().ContainSingle()
1082+
.Which.Tag.Should().Be(errorType);
1083+
1084+
// Teardown
1085+
}
1086+
1087+
[Theory]
1088+
[InlineData(new[] { "--version" }, true)]
1089+
[InlineData(new[] { "-v" }, true)]
1090+
[InlineData(new[] { "-s", "s" }, false)]
1091+
public void Parse_with_custom_version_option(string[] arguments, bool isVersion)
1092+
{
1093+
// Fixture setup in attributes
1094+
1095+
// Exercize system
1096+
var result = InvokeBuild<Options_With_Custom_Version_Option>(arguments, autoVersion: false);
1097+
1098+
// Verify outcome
1099+
result.Should().BeOfType<Parsed<Options_With_Custom_Version_Option>>()
1100+
.Which.Value.MyVersion.Should().Be(isVersion);
1101+
1102+
// Teardown
1103+
}
1104+
10271105
[Theory]
10281106
[MemberData("GuidData")]
10291107
public void Parse_Guid(string[] arguments, Options_With_Guid expected)

tests/CommandLine.Tests/Unit/Core/InstanceChooserTests.cs

+2
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ private static ParserResult<object> InvokeChoose(
2424
StringComparer.Ordinal,
2525
false,
2626
CultureInfo.InvariantCulture,
27+
true,
28+
true,
2729
Enumerable.Empty<ErrorType>());
2830
}
2931

0 commit comments

Comments
 (0)