Merge pull request #9294 from peterhuene/fix-completion
Improve command completion.
This commit is contained in:
commit
b5b47dd40d
8 changed files with 271 additions and 116 deletions
|
@ -3,14 +3,23 @@
|
||||||
|
|
||||||
using Microsoft.DotNet.Cli.CommandLine;
|
using Microsoft.DotNet.Cli.CommandLine;
|
||||||
using Microsoft.DotNet.Tools.Help;
|
using Microsoft.DotNet.Tools.Help;
|
||||||
|
using Microsoft.DotNet.Tools.New;
|
||||||
using static System.Environment;
|
using static System.Environment;
|
||||||
using static Microsoft.DotNet.Cli.CommandLine.LocalizableStrings;
|
using static Microsoft.DotNet.Cli.CommandLine.LocalizableStrings;
|
||||||
using LocalizableStrings = Microsoft.DotNet.Tools.Run.LocalizableStrings;
|
using LocalizableStrings = Microsoft.DotNet.Tools.Run.LocalizableStrings;
|
||||||
|
using NewCommandParser = Microsoft.TemplateEngine.Cli.CommandParsing.CommandParserSupport;
|
||||||
|
|
||||||
namespace Microsoft.DotNet.Cli
|
namespace Microsoft.DotNet.Cli
|
||||||
{
|
{
|
||||||
public static class Parser
|
public static class Parser
|
||||||
{
|
{
|
||||||
|
// This is used for descriptions of commands and options that are only defined for `dotnet complete` (i.e. command line completion).
|
||||||
|
// For example, a NuGet assembly handles parsing the `nuget` command and options.
|
||||||
|
// To get completion for such a command, we have to define a parser that is used for the completion.
|
||||||
|
// Command and option help text cannot be empty, otherwise the parser will hide them from the completion list.
|
||||||
|
// The value of `-` has no special meaning; it simply prevents these commands and options from being hidden.
|
||||||
|
internal const string CompletionOnlyDescription = "-";
|
||||||
|
|
||||||
static Parser()
|
static Parser()
|
||||||
{
|
{
|
||||||
ConfigureCommandLineLocalizedStrings();
|
ConfigureCommandLineLocalizedStrings();
|
||||||
|
@ -35,7 +44,7 @@ namespace Microsoft.DotNet.Cli
|
||||||
options: Create.Command("dotnet",
|
options: Create.Command("dotnet",
|
||||||
".NET Command Line Tools",
|
".NET Command Line Tools",
|
||||||
Accept.NoArguments(),
|
Accept.NoArguments(),
|
||||||
NewCommandParser.New(),
|
NewCommandParser.CreateNewCommandWithoutTemplateInfo(NewCommandShim.CommandName),
|
||||||
RestoreCommandParser.Restore(),
|
RestoreCommandParser.Restore(),
|
||||||
BuildCommandParser.Build(),
|
BuildCommandParser.Build(),
|
||||||
PublishCommandParser.Publish(),
|
PublishCommandParser.Publish(),
|
||||||
|
@ -51,15 +60,17 @@ namespace Microsoft.DotNet.Cli
|
||||||
NuGetCommandParser.NuGet(),
|
NuGetCommandParser.NuGet(),
|
||||||
StoreCommandParser.Store(),
|
StoreCommandParser.Store(),
|
||||||
HelpCommandParser.Help(),
|
HelpCommandParser.Help(),
|
||||||
Create.Command("msbuild", ""),
|
Create.Command("msbuild", CompletionOnlyDescription),
|
||||||
Create.Command("vstest", ""),
|
Create.Command("vstest", CompletionOnlyDescription),
|
||||||
CompleteCommandParser.Complete(),
|
CompleteCommandParser.Complete(),
|
||||||
InternalReportinstallsuccessCommandParser.InternalReportinstallsuccess(),
|
InternalReportinstallsuccessCommandParser.InternalReportinstallsuccess(),
|
||||||
ToolCommandParser.Tool(),
|
ToolCommandParser.Tool(),
|
||||||
BuildServerCommandParser.CreateCommand(),
|
BuildServerCommandParser.CreateCommand(),
|
||||||
CommonOptions.HelpOption(),
|
CommonOptions.HelpOption(),
|
||||||
Create.Option("--info", ""),
|
Create.Option("--info", CompletionOnlyDescription),
|
||||||
Create.Option("-d", ""),
|
Create.Option("-d|--diagnostics", CompletionOnlyDescription),
|
||||||
Create.Option("--debug", "")));
|
Create.Option("--version", CompletionOnlyDescription),
|
||||||
|
Create.Option("--list-sdks", CompletionOnlyDescription),
|
||||||
|
Create.Option("--list-runtimes", CompletionOnlyDescription)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,16 @@ namespace Microsoft.DotNet.Cli
|
||||||
{
|
{
|
||||||
public static int Run(string[] args)
|
public static int Run(string[] args)
|
||||||
{
|
{
|
||||||
|
return RunWithReporter(args, Reporter.Output);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int RunWithReporter(string [] args, IReporter reporter)
|
||||||
|
{
|
||||||
|
if (reporter == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(reporter));
|
||||||
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
DebugHelper.HandleDebugSwitch(ref args);
|
DebugHelper.HandleDebugSwitch(ref args);
|
||||||
|
@ -28,7 +38,7 @@ namespace Microsoft.DotNet.Cli
|
||||||
|
|
||||||
foreach (var suggestion in suggestions)
|
foreach (var suggestion in suggestions)
|
||||||
{
|
{
|
||||||
Console.WriteLine(suggestion);
|
reporter.WriteLine(suggestion);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception)
|
||||||
|
|
|
@ -10,7 +10,8 @@ namespace Microsoft.DotNet.Cli
|
||||||
{
|
{
|
||||||
public static Command InternalReportinstallsuccess() =>
|
public static Command InternalReportinstallsuccess() =>
|
||||||
Create.Command(
|
Create.Command(
|
||||||
"internal-reportinstallsuccess", "internal only",
|
"internal-reportinstallsuccess",
|
||||||
|
"",
|
||||||
Accept.ExactlyOneArgument());
|
Accept.ExactlyOneArgument());
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,39 +0,0 @@
|
||||||
// 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 Microsoft.DotNet.Cli.CommandLine;
|
|
||||||
|
|
||||||
namespace Microsoft.DotNet.Cli
|
|
||||||
{
|
|
||||||
internal static class NewCommandParser
|
|
||||||
{
|
|
||||||
public static Command New() =>
|
|
||||||
Create.Command("new",
|
|
||||||
"Initialize .NET projects.",
|
|
||||||
Accept
|
|
||||||
.ExactlyOneArgument()
|
|
||||||
.WithSuggestionsFrom(
|
|
||||||
"console",
|
|
||||||
"classlib",
|
|
||||||
"mstest",
|
|
||||||
"xunit",
|
|
||||||
"web",
|
|
||||||
"mvc",
|
|
||||||
"webapi",
|
|
||||||
"sln"),
|
|
||||||
Create.Option("-l|--list",
|
|
||||||
"List templates containing the specified name."),
|
|
||||||
Create.Option("-lang|--language",
|
|
||||||
"Specifies the language of the template to create",
|
|
||||||
Accept.WithSuggestionsFrom("C#", "F#")
|
|
||||||
.With(defaultValue: () => "C#")),
|
|
||||||
Create.Option("-n|--name",
|
|
||||||
"The name for the output being created. If no name is specified, the name of the current directory is used."),
|
|
||||||
Create.Option("-o|--output",
|
|
||||||
"Location to place the generated output."),
|
|
||||||
Create.Option("-h|--help",
|
|
||||||
"Displays help for this command."),
|
|
||||||
Create.Option("-all|--show-all",
|
|
||||||
"Shows all templates"));
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -24,8 +24,8 @@ namespace Microsoft.DotNet.Tools.New
|
||||||
{
|
{
|
||||||
internal class NewCommandShim
|
internal class NewCommandShim
|
||||||
{
|
{
|
||||||
|
public const string CommandName = "new";
|
||||||
private const string HostIdentifier = "dotnetcli";
|
private const string HostIdentifier = "dotnetcli";
|
||||||
private const string CommandName = "new";
|
|
||||||
|
|
||||||
public static int Run(string[] args)
|
public static int Run(string[] args)
|
||||||
{
|
{
|
||||||
|
|
|
@ -5,74 +5,52 @@ using Microsoft.DotNet.Cli.CommandLine;
|
||||||
|
|
||||||
namespace Microsoft.DotNet.Cli
|
namespace Microsoft.DotNet.Cli
|
||||||
{
|
{
|
||||||
|
// This parser is used for completion and telemetry.
|
||||||
|
// See https://github.com/NuGet/NuGet.Client for the actual implementation.
|
||||||
internal static class NuGetCommandParser
|
internal static class NuGetCommandParser
|
||||||
{
|
{
|
||||||
public static Command NuGet() =>
|
public static Command NuGet() =>
|
||||||
Create.Command("nuget",
|
Create.Command(
|
||||||
"NuGet Command Line 4.0.0.0",
|
"nuget",
|
||||||
CommonOptions.HelpOption(),
|
Parser.CompletionOnlyDescription,
|
||||||
Create.Option("--version",
|
Create.Option("-h|--help", Parser.CompletionOnlyDescription),
|
||||||
"Show version information"),
|
Create.Option("--version", Parser.CompletionOnlyDescription),
|
||||||
Create.Option("-v|--verbosity",
|
Create.Option("-v|--verbosity", Parser.CompletionOnlyDescription, Accept.ExactlyOneArgument()),
|
||||||
"The verbosity of logging to use. Allowed values: Debug, Verbose, Information, Minimal, Warning, Error.",
|
Create.Command(
|
||||||
Accept.ExactlyOneArgument()
|
"delete",
|
||||||
.With(name: "verbosity")),
|
Parser.CompletionOnlyDescription,
|
||||||
Create.Command("delete",
|
Accept.OneOrMoreArguments(),
|
||||||
"Deletes a package from the server.",
|
Create.Option("-h|--help", Parser.CompletionOnlyDescription),
|
||||||
Accept.ExactlyOneArgument()
|
Create.Option("--force-english-output", Parser.CompletionOnlyDescription),
|
||||||
.With(name: "root",
|
Create.Option("-s|--source", Parser.CompletionOnlyDescription, Accept.ExactlyOneArgument()),
|
||||||
description: "The Package Id and version."),
|
Create.Option("--non-interactive", Parser.CompletionOnlyDescription),
|
||||||
CommonOptions.HelpOption(),
|
Create.Option("-k|--api-key", Parser.CompletionOnlyDescription, Accept.ExactlyOneArgument()),
|
||||||
Create.Option("--force-english-output",
|
Create.Option("--no-service-endpoint", Parser.CompletionOnlyDescription)),
|
||||||
"Forces the application to run using an invariant, English-based culture."),
|
Create.Command(
|
||||||
Create.Option("-s|--source",
|
"locals",
|
||||||
"Specifies the server URL",
|
Parser.CompletionOnlyDescription,
|
||||||
Accept.ExactlyOneArgument()
|
Accept.AnyOneOf(
|
||||||
.With(name: "source")),
|
"all",
|
||||||
Create.Option("--non-interactive",
|
"http-cache",
|
||||||
"Do not prompt for user input or confirmations."),
|
"global-packages",
|
||||||
Create.Option("-k|--api-key",
|
"temp"),
|
||||||
"The API key for the server.",
|
Create.Option("-h|--help", Parser.CompletionOnlyDescription),
|
||||||
Accept.ExactlyOneArgument()
|
Create.Option("--force-english-output", Parser.CompletionOnlyDescription),
|
||||||
.With(name: "apiKey"))),
|
Create.Option("-c|--clear", Parser.CompletionOnlyDescription),
|
||||||
Create.Command("locals",
|
Create.Option("-l|--list", Parser.CompletionOnlyDescription)),
|
||||||
"Clears or lists local NuGet resources such as http requests cache, packages cache or machine-wide global packages folder.",
|
Create.Command(
|
||||||
Accept.AnyOneOf(@"all",
|
"push",
|
||||||
@"http-cache",
|
Parser.CompletionOnlyDescription,
|
||||||
@"global-packages",
|
Accept.OneOrMoreArguments(),
|
||||||
@"temp")
|
Create.Option("-h|--help", Parser.CompletionOnlyDescription),
|
||||||
.With(description: "Cache Location(s) Specifies the cache location(s) to list or clear."),
|
Create.Option("--force-english-output", Parser.CompletionOnlyDescription),
|
||||||
CommonOptions.HelpOption(),
|
Create.Option("-s|--source", Parser.CompletionOnlyDescription, Accept.ExactlyOneArgument()),
|
||||||
Create.Option("--force-english-output",
|
Create.Option("-ss|--symbol-source", Parser.CompletionOnlyDescription, Accept.ExactlyOneArgument()),
|
||||||
"Forces the application to run using an invariant, English-based culture."),
|
Create.Option("-t|--timeout", Parser.CompletionOnlyDescription, Accept.ExactlyOneArgument()),
|
||||||
Create.Option("-c|--clear", "Clear the selected local resources or cache location(s)."),
|
Create.Option("-k|--api-key", Parser.CompletionOnlyDescription, Accept.ExactlyOneArgument()),
|
||||||
Create.Option("-l|--list", "List the selected local resources or cache location(s).")),
|
Create.Option("-sk|--symbol-api-key", Parser.CompletionOnlyDescription, Accept.ExactlyOneArgument()),
|
||||||
Create.Command("push",
|
Create.Option("-d|--disable-buffering", Parser.CompletionOnlyDescription),
|
||||||
"Pushes a package to the server and publishes it.",
|
Create.Option("-n|--no-symbols", Parser.CompletionOnlyDescription),
|
||||||
CommonOptions.HelpOption(),
|
Create.Option("--no-service-endpoint", Parser.CompletionOnlyDescription)));
|
||||||
Create.Option("--force-english-output",
|
|
||||||
"Forces the application to run using an invariant, English-based culture."),
|
|
||||||
Create.Option("-s|--source",
|
|
||||||
"Specifies the server URL",
|
|
||||||
Accept.ExactlyOneArgument()
|
|
||||||
.With(name: "source")),
|
|
||||||
Create.Option("-ss|--symbol-source",
|
|
||||||
"Specifies the symbol server URL. If not specified, nuget.smbsrc.net is used when pushing to nuget.org.",
|
|
||||||
Accept.ExactlyOneArgument()
|
|
||||||
.With(name: "source")),
|
|
||||||
Create.Option("-t|--timeout",
|
|
||||||
"Specifies the timeout for pushing to a server in seconds. Defaults to 300 seconds (5 minutes).",
|
|
||||||
Accept.ExactlyOneArgument()
|
|
||||||
.With(name: "timeout")),
|
|
||||||
Create.Option("-k|--api-key", "The API key for the server.",
|
|
||||||
Accept.ExactlyOneArgument()
|
|
||||||
.With(name: "apiKey")),
|
|
||||||
Create.Option("-sk|--symbol-api-key", "The API key for the symbol server.",
|
|
||||||
Accept.ExactlyOneArgument()
|
|
||||||
.With(name: "apiKey")),
|
|
||||||
Create.Option("-d|--disable-buffering",
|
|
||||||
"Disable buffering when pushing to an HTTP(S) server to decrease memory usage."),
|
|
||||||
Create.Option("-n|--no-symbols",
|
|
||||||
"If a symbols package exists, it will not be pushed to a symbols server.")));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
194
test/dotnet.Tests/CommandTests/CompleteCommandTests.cs
Normal file
194
test/dotnet.Tests/CommandTests/CompleteCommandTests.cs
Normal file
|
@ -0,0 +1,194 @@
|
||||||
|
// 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;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using FluentAssertions;
|
||||||
|
using Microsoft.DotNet.Cli;
|
||||||
|
using Microsoft.DotNet.Tools.Test.Utilities;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Microsoft.DotNet.Tests.Commands
|
||||||
|
{
|
||||||
|
public class CompleteCommandTests : TestBase
|
||||||
|
{
|
||||||
|
[Fact]
|
||||||
|
public void GivenOnlyDotnetItSuggestsTopLevelCommandsAndOptions()
|
||||||
|
{
|
||||||
|
var expected = new string[] {
|
||||||
|
"--diagnostics",
|
||||||
|
"--help",
|
||||||
|
"--info",
|
||||||
|
"--list-runtimes",
|
||||||
|
"--list-sdks",
|
||||||
|
"--version",
|
||||||
|
"-d",
|
||||||
|
"-h",
|
||||||
|
"add",
|
||||||
|
"build",
|
||||||
|
"build-server",
|
||||||
|
"clean",
|
||||||
|
"help",
|
||||||
|
"list",
|
||||||
|
"migrate",
|
||||||
|
"msbuild",
|
||||||
|
"new",
|
||||||
|
"nuget",
|
||||||
|
"pack",
|
||||||
|
"publish",
|
||||||
|
"remove",
|
||||||
|
"restore",
|
||||||
|
"run",
|
||||||
|
"sln",
|
||||||
|
"store",
|
||||||
|
"test",
|
||||||
|
"tool",
|
||||||
|
"vstest"
|
||||||
|
};
|
||||||
|
|
||||||
|
var reporter = new BufferedReporter();
|
||||||
|
CompleteCommand.RunWithReporter(new[] { "dotnet " }, reporter).Should().Be(0);
|
||||||
|
reporter.Lines.Should().Equal(expected.OrderBy(c => c));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void GivenASlashItSuggestsTopLevelOptions()
|
||||||
|
{
|
||||||
|
var expected = new string[] {
|
||||||
|
"--diagnostics",
|
||||||
|
"--help",
|
||||||
|
"--info",
|
||||||
|
"--list-runtimes",
|
||||||
|
"--list-sdks",
|
||||||
|
"--version",
|
||||||
|
"-d",
|
||||||
|
"-h",
|
||||||
|
"build-server" // This should be removed when completion is based on "starts with" rather than "contains".
|
||||||
|
// See https://github.com/dotnet/cli/issues/8958.
|
||||||
|
};
|
||||||
|
|
||||||
|
var reporter = new BufferedReporter();
|
||||||
|
CompleteCommand.RunWithReporter(new[] { "dotnet -" }, reporter).Should().Be(0);
|
||||||
|
reporter.Lines.Should().Equal(expected.OrderBy(c => c));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void GivenNewCommandItDisplaysCompletions()
|
||||||
|
{
|
||||||
|
var expected = new string[] {
|
||||||
|
"--force",
|
||||||
|
"--help",
|
||||||
|
"--install",
|
||||||
|
"--language",
|
||||||
|
"--list",
|
||||||
|
"--name",
|
||||||
|
"--nuget-source",
|
||||||
|
"--output",
|
||||||
|
"--type",
|
||||||
|
"--uninstall",
|
||||||
|
"-h",
|
||||||
|
"-i",
|
||||||
|
"-l",
|
||||||
|
"-lang",
|
||||||
|
"-n",
|
||||||
|
"-o",
|
||||||
|
"-u"
|
||||||
|
};
|
||||||
|
|
||||||
|
var reporter = new BufferedReporter();
|
||||||
|
CompleteCommand.RunWithReporter(new[] { "dotnet new " }, reporter).Should().Be(0);
|
||||||
|
reporter.Lines.Should().Equal(expected.OrderBy(c => c));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void GivenNuGetCommandItDisplaysCompletions()
|
||||||
|
{
|
||||||
|
var expected = new string[] {
|
||||||
|
"--help",
|
||||||
|
"--verbosity",
|
||||||
|
"--version",
|
||||||
|
"-h",
|
||||||
|
"-v",
|
||||||
|
"delete",
|
||||||
|
"locals",
|
||||||
|
"push",
|
||||||
|
};
|
||||||
|
|
||||||
|
var reporter = new BufferedReporter();
|
||||||
|
CompleteCommand.RunWithReporter(new[] { "dotnet nuget " }, reporter).Should().Be(0);
|
||||||
|
reporter.Lines.Should().Equal(expected.OrderBy(c => c));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void GivenNuGetDeleteCommandItDisplaysCompletions()
|
||||||
|
{
|
||||||
|
var expected = new string[] {
|
||||||
|
"--api-key",
|
||||||
|
"--force-english-output",
|
||||||
|
"--help",
|
||||||
|
"--no-service-endpoint",
|
||||||
|
"--non-interactive",
|
||||||
|
"--source",
|
||||||
|
"-h",
|
||||||
|
"-k",
|
||||||
|
"-s"
|
||||||
|
};
|
||||||
|
|
||||||
|
var reporter = new BufferedReporter();
|
||||||
|
CompleteCommand.RunWithReporter(new[] { "dotnet nuget delete " }, reporter).Should().Be(0);
|
||||||
|
reporter.Lines.Should().Equal(expected.OrderBy(c => c));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void GivenNuGetLocalsCommandItDisplaysCompletions()
|
||||||
|
{
|
||||||
|
var expected = new string[] {
|
||||||
|
"--clear",
|
||||||
|
"--force-english-output",
|
||||||
|
"--help",
|
||||||
|
"--list",
|
||||||
|
"-c",
|
||||||
|
"-h",
|
||||||
|
"-l",
|
||||||
|
"all",
|
||||||
|
"global-packages",
|
||||||
|
"http-cache",
|
||||||
|
"temp"
|
||||||
|
};
|
||||||
|
|
||||||
|
var reporter = new BufferedReporter();
|
||||||
|
CompleteCommand.RunWithReporter(new[] { "dotnet nuget locals " }, reporter).Should().Be(0);
|
||||||
|
reporter.Lines.Should().Equal(expected.OrderBy(c => c));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void GivenNuGetPushCommandItDisplaysCompletions()
|
||||||
|
{
|
||||||
|
var expected = new string[] {
|
||||||
|
"--api-key",
|
||||||
|
"--disable-buffering",
|
||||||
|
"--force-english-output",
|
||||||
|
"--help",
|
||||||
|
"--no-service-endpoint",
|
||||||
|
"--no-symbols",
|
||||||
|
"--source",
|
||||||
|
"--symbol-api-key",
|
||||||
|
"--symbol-source",
|
||||||
|
"--timeout",
|
||||||
|
"-d",
|
||||||
|
"-h",
|
||||||
|
"-k",
|
||||||
|
"-n",
|
||||||
|
"-s",
|
||||||
|
"-sk",
|
||||||
|
"-ss",
|
||||||
|
"-t"
|
||||||
|
};
|
||||||
|
|
||||||
|
var reporter = new BufferedReporter();
|
||||||
|
CompleteCommand.RunWithReporter(new[] { "dotnet nuget push " }, reporter).Should().Be(0);
|
||||||
|
reporter.Lines.Should().Equal(expected.OrderBy(c => c));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -163,7 +163,7 @@ namespace Microsoft.DotNet.Tests
|
||||||
{
|
{
|
||||||
const string argumentToSend = "push";
|
const string argumentToSend = "push";
|
||||||
|
|
||||||
string[] args = { "nuget", argumentToSend };
|
string[] args = { "nuget", argumentToSend, "path" };
|
||||||
|
|
||||||
Cli.Program.ProcessArgs(args);
|
Cli.Program.ProcessArgs(args);
|
||||||
_fakeTelemetry
|
_fakeTelemetry
|
||||||
|
|
Loading…
Add table
Reference in a new issue