Skip to content

Commit 6524142

Browse files
authored
Parent search bug fix (#2030)
1 parent daec22f commit 6524142

File tree

4 files changed

+64
-11
lines changed

4 files changed

+64
-11
lines changed

src/System.CommandLine.Tests/CompletionTests.cs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,20 +57,25 @@ public void Command_GetCompletions_returns_available_option_aliases()
5757
[Fact] // https://github.com/dotnet/command-line-api/issues/1563
5858
public void Command_GetCompletions_returns_available_option_aliases_for_global_options()
5959
{
60-
var subcommand = new Command("command")
60+
var subcommand2 = new Command("command2")
6161
{
6262
new Option<string>("--one", "option one"),
6363
new Option<string>("--two", "option two")
6464
};
6565

66+
var subcommand1 = new Command("command1")
67+
{
68+
subcommand2
69+
};
70+
6671
var rootCommand = new RootCommand
6772
{
68-
subcommand
73+
subcommand1
6974
};
7075

7176
rootCommand.AddGlobalOption(new Option<string>("--three", "option three"));
7277

73-
var completions = subcommand.GetCompletions(CompletionContext.Empty);
78+
var completions = subcommand2.GetCompletions(CompletionContext.Empty);
7479

7580
completions
7681
.Select(item => item.Label)

src/System.CommandLine.Tests/ParseResultTests.cs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
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.Linq;
45
using System.CommandLine.Parsing;
56
using FluentAssertions;
67
using Xunit;
@@ -83,5 +84,42 @@ public void Command_will_not_accept_a_command_if_a_sibling_command_has_already_b
8384
result2.CommandResult.Command.Name.Should().Be("inner-two");
8485
result2.Errors.Count.Should().Be(1);
8586
}
87+
88+
[Fact] // https://github.com/dotnet/command-line-api/pull/2030#issuecomment-1400275332
89+
public void ParseResult_GetCompletions_returns_global_options_of_given_command_only()
90+
{
91+
var leafCommand = new Command("leafCommand")
92+
{
93+
new Option<string>("--one", "option one"),
94+
new Option<string>("--two", "option two")
95+
};
96+
97+
var midCommand1 = new Command("midCommand1")
98+
{
99+
leafCommand
100+
};
101+
midCommand1.AddGlobalOption(new Option<string>("--three1", "option three 1"));
102+
103+
var midCommand2 = new Command("midCommand2")
104+
{
105+
leafCommand
106+
};
107+
midCommand2.AddGlobalOption(new Option<string>("--three2", "option three 2"));
108+
109+
var rootCommand = new Command("root")
110+
{
111+
midCommand1,
112+
midCommand2
113+
};
114+
115+
var result = new Parser(rootCommand).Parse("root midCommand2 leafCommand --");
116+
117+
var completions = result.GetCompletions();
118+
119+
completions
120+
.Select(item => item.Label)
121+
.Should()
122+
.BeEquivalentTo("--one", "--two", "--three2");
123+
}
86124
}
87125
}

src/System.CommandLine/Command.cs

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -192,20 +192,28 @@ public override IEnumerable<CompletionItem> GetCompletions(CompletionContext con
192192
ParentNode? parent = FirstParent;
193193
while (parent is not null)
194194
{
195-
if (parent.Symbol is Command parentCommand && parentCommand.HasOptions)
195+
Command parentCommand = (Command)parent.Symbol;
196+
197+
if (context.IsEmpty || context.ParseResult.FindResultFor(parentCommand) is not null)
196198
{
197-
for (var i = 0; i < parentCommand.Options.Count; i++)
199+
if (parentCommand.HasOptions)
198200
{
199-
var option = parentCommand.Options[i];
200-
201-
if (option.IsGlobal)
201+
for (var i = 0; i < parentCommand.Options.Count; i++)
202202
{
203-
AddCompletionsFor(option);
203+
var option = parentCommand.Options[i];
204+
205+
if (option.IsGlobal)
206+
{
207+
AddCompletionsFor(option);
208+
}
204209
}
205210
}
211+
parent = parent.Symbol.FirstParent;
212+
}
213+
else
214+
{
215+
parent = parent.Next;
206216
}
207-
208-
parent = parent.Next;
209217
}
210218
}
211219

src/System.CommandLine/Completions/CompletionContext.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ internal CompletionContext(ParseResult parseResult, string wordToComplete)
3131
/// <remarks>Can be used for testing purposes.</remarks>
3232
public static CompletionContext Empty => _empty ??= new TokenCompletionContext(ParseResult.Empty());
3333

34+
internal bool IsEmpty => ReferenceEquals(this, _empty);
35+
3436
/// <summary>
3537
/// Gets the text to be matched for completion, which can be used to filter a list of completions.
3638
/// </summary>

0 commit comments

Comments
 (0)