Skip to content

Commit 4213a18

Browse files
committed
no error for missing subcommand when HelpOption is present
1 parent 04b19c9 commit 4213a18

File tree

4 files changed

+64
-42
lines changed

4 files changed

+64
-42
lines changed

src/System.CommandLine.Tests/UseHelpTests.cs

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using System.CommandLine.Invocation;
66
using System.CommandLine.IO;
77
using System.CommandLine.Parsing;
8+
using System.IO;
89
using System.Threading.Tasks;
910
using FluentAssertions;
1011
using Xunit;
@@ -109,12 +110,12 @@ public void There_are_no_parse_errors_when_help_is_invoked_on_root_command()
109110
[Fact]
110111
public void There_are_no_parse_errors_when_help_is_invoked_on_subcommand()
111112
{
112-
var command = new RootCommand
113+
var root = new RootCommand
113114
{
114115
new Command("subcommand")
115116
};
116117

117-
var parser = new CommandLineBuilder(command)
118+
var parser = new CommandLineBuilder(root)
118119
.UseHelp()
119120
.Build();
120121

@@ -125,6 +126,23 @@ public void There_are_no_parse_errors_when_help_is_invoked_on_subcommand()
125126
.BeEmpty();
126127
}
127128

129+
[Fact]
130+
public void There_are_no_parse_errors_when_help_is_invoked_on_a_command_with_subcommands()
131+
{
132+
var root = new RootCommand
133+
{
134+
new Command("subcommand")
135+
};
136+
137+
var parser = new CommandLineBuilder(root)
138+
.UseHelp()
139+
.Build();
140+
141+
var result = parser.Parse("-h");
142+
143+
result.Errors.Should().BeEmpty();
144+
}
145+
128146
[Theory]
129147
[InlineData("-h")]
130148
[InlineData("inner -h")]

src/System.CommandLine/Builder/CommandLineBuilderExtensions.cs

Lines changed: 1 addition & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
// Copyright (c) .NET Foundation and contributors. All rights reserved.
22
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
33

4-
using System.Collections.Generic;
54
using System.CommandLine.Binding;
65
using System.CommandLine.Help;
76
using System.CommandLine.Invocation;
@@ -268,9 +267,7 @@ void Default(Exception exception, InvocationContext context)
268267

269268
public static CommandLineBuilder UseHelp(this CommandLineBuilder builder)
270269
{
271-
var helpOption = new HelpOption();
272-
273-
return builder.UseHelp(helpOption);
270+
return builder.UseHelp(new HelpOption());
274271
}
275272

276273
internal static CommandLineBuilder UseHelp(
@@ -296,41 +293,6 @@ internal static CommandLineBuilder UseHelp(
296293
return builder;
297294
}
298295

299-
private class HelpOption : Option
300-
{
301-
public HelpOption() : base(new[]
302-
{
303-
"-h",
304-
"/h",
305-
"--help",
306-
"-?",
307-
"/?"
308-
}, "Show help and usage information")
309-
{
310-
}
311-
312-
public override Argument Argument
313-
{
314-
get => Argument.None;
315-
set => throw new NotSupportedException();
316-
}
317-
318-
protected bool Equals(HelpOption other)
319-
{
320-
return other != null;
321-
}
322-
323-
public override bool Equals(object obj)
324-
{
325-
return obj is HelpOption;
326-
}
327-
328-
public override int GetHashCode()
329-
{
330-
return typeof(HelpOption).GetHashCode();
331-
}
332-
}
333-
334296
public static TBuilder UseHelpBuilder<TBuilder>(this TBuilder builder, Func<BindingContext, IHelpBuilder> getHelpBuilder)
335297
where TBuilder : CommandLineBuilder
336298
{
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// Copyright (c) .NET Foundation and contributors. All rights reserved.
2+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
3+
4+
namespace System.CommandLine.Help
5+
{
6+
internal class HelpOption : Option
7+
{
8+
public HelpOption() : base(new[]
9+
{
10+
"-h",
11+
"/h",
12+
"--help",
13+
"-?",
14+
"/?"
15+
}, "Show help and usage information")
16+
{
17+
}
18+
19+
public override Argument Argument
20+
{
21+
get => Argument.None;
22+
set => throw new NotSupportedException();
23+
}
24+
25+
protected bool Equals(HelpOption other)
26+
{
27+
return other != null;
28+
}
29+
30+
public override bool Equals(object obj)
31+
{
32+
return obj is HelpOption;
33+
}
34+
35+
public override int GetHashCode()
36+
{
37+
return typeof(HelpOption).GetHashCode();
38+
}
39+
}
40+
}

src/System.CommandLine/Parsing/ParseResultVisitor.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
using System.Collections.Generic;
55
using System.CommandLine.Binding;
6+
using System.CommandLine.Help;
67
using System.Linq;
78

89
namespace System.CommandLine.Parsing
@@ -227,7 +228,8 @@ private void ValidateCommandHandler()
227228
{
228229
if (_innermostCommandResult.Command is Command cmd &&
229230
cmd.Handler == null &&
230-
cmd.Children.OfType<ICommand>().Any())
231+
cmd.Children.OfType<ICommand>().Any() &&
232+
!cmd.Options.OfType<HelpOption>().Any())
231233
{
232234
_errors.Insert(0,
233235
new ParseError(

0 commit comments

Comments
 (0)