Skip to content

Commit dbc3781

Browse files
committed
fix #2628
1 parent 12473cd commit dbc3781

File tree

4 files changed

+31
-16
lines changed

4 files changed

+31
-16
lines changed

src/System.CommandLine.Tests/VersionOptionTests.cs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ public async Task When_the_version_option_is_specified_then_invocation_is_short_
3737
{
3838
var wasCalled = false;
3939
var rootCommand = new RootCommand();
40-
rootCommand.SetAction((_) => wasCalled = true);
40+
rootCommand.SetAction(_ => wasCalled = true);
4141

4242
var output = new StringWriter();
4343

@@ -46,6 +46,21 @@ public async Task When_the_version_option_is_specified_then_invocation_is_short_
4646
wasCalled.Should().BeFalse();
4747
}
4848

49+
[Fact] // https://github.com/dotnet/command-line-api/issues/2628
50+
public void When_the_version_option_is_specified_then_there_are_no_parse_errors_due_to_unspecified_subcommand()
51+
{
52+
Command subcommand = new("subcommand");
53+
RootCommand root = new()
54+
{
55+
subcommand
56+
};
57+
subcommand.SetAction(_ => 0);
58+
59+
var parseResult = root.Parse("--version");
60+
61+
parseResult.Errors.Should().BeEmpty();
62+
}
63+
4964
[Fact]
5065
public async Task Version_option_appears_in_help()
5166
{

src/System.CommandLine/ParserConfiguration.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
33

44
using System.CommandLine.Parsing;
5-
using System.Linq;
65

76
namespace System.CommandLine
87
{

src/System.CommandLine/Parsing/CommandResult.cs

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -43,17 +43,10 @@ internal CommandResult(
4343
internal override bool UseDefaultValueFor(ArgumentResult argumentResult)
4444
=> argumentResult.Argument.HasDefaultValue && argumentResult.Tokens.Count == 0;
4545

46-
/// <param name="completeValidation">Only the inner most command goes through complete validation.</param>
47-
internal void Validate(bool completeValidation)
46+
internal void Validate(bool isInnermostCommand)
4847
{
49-
if (completeValidation)
48+
if (isInnermostCommand)
5049
{
51-
if (Command.Action is null && Command.HasSubcommands)
52-
{
53-
SymbolResultTree.InsertFirstError(
54-
new ParseError(LocalizationResources.RequiredCommandWasNotProvided(), this));
55-
}
56-
5750
if (Command.HasValidators)
5851
{
5952
int errorCountBefore = SymbolResultTree.ErrorCount;
@@ -71,12 +64,12 @@ internal void Validate(bool completeValidation)
7164

7265
if (Command.HasOptions)
7366
{
74-
ValidateOptionsAndAddDefaultResults(completeValidation);
67+
ValidateOptionsAndAddDefaultResults(isInnermostCommand);
7568
}
7669

7770
if (Command.HasArguments)
7871
{
79-
ValidateArgumentsAndAddDefaultResults(completeValidation);
72+
ValidateArgumentsAndAddDefaultResults(isInnermostCommand);
8073
}
8174
}
8275

src/System.CommandLine/Parsing/ParseOperation.cs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ internal ParseResult Parse()
6363

6464
ValidateAndAddDefaultResults();
6565

66+
6667
if (_isHelpRequested)
6768
{
6869
_symbolResultTree.Errors?.Clear();
@@ -373,17 +374,24 @@ private void AddCurrentTokenToUnmatched()
373374

374375
private void ValidateAndAddDefaultResults()
375376
{
376-
// Only the inner most command goes through complete validation,
377+
// Only the innermost command goes through complete validation,
377378
// for other commands only a subset of options is checked.
378-
_innermostCommandResult.Validate(completeValidation: true);
379+
_innermostCommandResult.Validate(isInnermostCommand: true);
379380

380381
CommandResult? currentResult = _innermostCommandResult.Parent as CommandResult;
381382
while (currentResult is not null)
382383
{
383-
currentResult.Validate(completeValidation: false);
384+
currentResult.Validate(isInnermostCommand: false);
384385

385386
currentResult = currentResult.Parent as CommandResult;
386387
}
388+
389+
if (_primaryAction is null &&
390+
_innermostCommandResult is { Command: { Action: null, HasSubcommands: true } })
391+
{
392+
_symbolResultTree.InsertFirstError(
393+
new ParseError(LocalizationResources.RequiredCommandWasNotProvided(), _innermostCommandResult));
394+
}
387395
}
388396
}
389397
}

0 commit comments

Comments
 (0)