Skip to content

Parent search bug fix #2030

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jan 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 8 additions & 3 deletions src/System.CommandLine.Tests/CompletionTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,20 +57,25 @@ public void Command_GetCompletions_returns_available_option_aliases()
[Fact] // https://github.com/dotnet/command-line-api/issues/1563
public void Command_GetCompletions_returns_available_option_aliases_for_global_options()
{
var subcommand = new Command("command")
var subcommand2 = new Command("command2")
{
new Option<string>("--one", "option one"),
new Option<string>("--two", "option two")
};

var subcommand1 = new Command("command1")
{
subcommand2
};

var rootCommand = new RootCommand
{
subcommand
subcommand1
};

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

var completions = subcommand.GetCompletions(CompletionContext.Empty);
var completions = subcommand2.GetCompletions(CompletionContext.Empty);

completions
.Select(item => item.Label)
Expand Down
38 changes: 38 additions & 0 deletions src/System.CommandLine.Tests/ParseResultTests.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright (c) .NET Foundation and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System.Linq;
using System.CommandLine.Parsing;
using FluentAssertions;
using Xunit;
Expand Down Expand Up @@ -83,5 +84,42 @@ public void Command_will_not_accept_a_command_if_a_sibling_command_has_already_b
result2.CommandResult.Command.Name.Should().Be("inner-two");
result2.Errors.Count.Should().Be(1);
}

[Fact] // https://github.com/dotnet/command-line-api/pull/2030#issuecomment-1400275332
public void ParseResult_GetCompletions_returns_global_options_of_given_command_only()
{
var leafCommand = new Command("leafCommand")
{
new Option<string>("--one", "option one"),
new Option<string>("--two", "option two")
};

var midCommand1 = new Command("midCommand1")
{
leafCommand
};
midCommand1.AddGlobalOption(new Option<string>("--three1", "option three 1"));

var midCommand2 = new Command("midCommand2")
{
leafCommand
};
midCommand2.AddGlobalOption(new Option<string>("--three2", "option three 2"));

var rootCommand = new Command("root")
{
midCommand1,
midCommand2
};

var result = new Parser(rootCommand).Parse("root midCommand2 leafCommand --");

var completions = result.GetCompletions();

completions
.Select(item => item.Label)
.Should()
.BeEquivalentTo("--one", "--two", "--three2");
}
}
}
24 changes: 16 additions & 8 deletions src/System.CommandLine/Command.cs
Original file line number Diff line number Diff line change
Expand Up @@ -192,20 +192,28 @@ public override IEnumerable<CompletionItem> GetCompletions(CompletionContext con
ParentNode? parent = FirstParent;
while (parent is not null)
{
if (parent.Symbol is Command parentCommand && parentCommand.HasOptions)
Command parentCommand = (Command)parent.Symbol;

if (context.IsEmpty || context.ParseResult.FindResultFor(parentCommand) is not null)
{
for (var i = 0; i < parentCommand.Options.Count; i++)
if (parentCommand.HasOptions)
{
var option = parentCommand.Options[i];

if (option.IsGlobal)
for (var i = 0; i < parentCommand.Options.Count; i++)
{
AddCompletionsFor(option);
var option = parentCommand.Options[i];

if (option.IsGlobal)
{
AddCompletionsFor(option);
}
}
}
parent = parent.Symbol.FirstParent;
}
else
{
parent = parent.Next;
}

parent = parent.Next;
}
}

Expand Down
2 changes: 2 additions & 0 deletions src/System.CommandLine/Completions/CompletionContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ internal CompletionContext(ParseResult parseResult, string wordToComplete)
/// <remarks>Can be used for testing purposes.</remarks>
public static CompletionContext Empty => _empty ??= new TokenCompletionContext(ParseResult.Empty());

internal bool IsEmpty => ReferenceEquals(this, _empty);

/// <summary>
/// Gets the text to be matched for completion, which can be used to filter a list of completions.
/// </summary>
Expand Down