Skip to content

Commit 62a09ed

Browse files
committed
Migrate XPlat to System.CommandLine
1 parent 9f5248f commit 62a09ed

32 files changed

Lines changed: 1703 additions & 1867 deletions

src/NuGet.Core/NuGet.CommandLine.XPlat/Commands/CommandConstants.cs

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

44
#nullable enable
55

6-
namespace NuGet.CommandLine.XPlat
6+
namespace NuGet.CommandLine.XPlat.Commands
77
{
88
internal static class CommandConstants
99
{

src/NuGet.Core/NuGet.CommandLine.XPlat/Commands/CommandParsers.cs

Lines changed: 0 additions & 24 deletions
This file was deleted.

src/NuGet.Core/NuGet.CommandLine.XPlat/Commands/ConfigCommands/ConfigCommand.cs

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
using System.CommandLine;
88
using System.CommandLine.Help;
99
using System.Threading.Tasks;
10-
using Microsoft.Extensions.CommandLineUtils;
1110
using NuGet.CommandLine.XPlat.Commands;
1211
using NuGet.Common;
1312

@@ -78,15 +77,7 @@ internal static void LogException(Exception e, ILogger log)
7877
log.LogVerbose(e.ToString());
7978
}
8079

81-
internal static void Register(CommandLineApplication app)
82-
{
83-
app.Command("config", configCmd =>
84-
{
85-
configCmd.Description = Strings.Config_Description;
86-
});
87-
}
88-
89-
internal static Command Register(Command app, Func<ILogger> getLogger)
80+
internal static Command Register(Command app, Func<ILoggerWithColor> getLogger)
9081
{
9182
var ConfigCmd = new DocumentedCommand(name: "config", description: Strings.Config_Description, "https://aka.ms/dotnet/nuget/config");
9283
ConfigCmd.Options.Add(HelpOption);

src/NuGet.Core/NuGet.CommandLine.XPlat/Commands/DeleteCommand.cs

Lines changed: 81 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -4,94 +4,102 @@
44
#nullable disable
55

66
using System;
7+
using System.CommandLine;
78
using System.Globalization;
8-
using Microsoft.Extensions.CommandLineUtils;
99
using NuGet.Commands;
10-
using NuGet.Common;
1110
using NuGet.Configuration;
1211
using NuGet.Credentials;
1312

1413
namespace NuGet.CommandLine.XPlat
1514
{
1615
internal static class DeleteCommand
1716
{
18-
public static void Register(CommandLineApplication app, Func<ILogger> getLogger)
17+
private static readonly Option<string> SourceOption = new Option<string>("--source", "-s")
1918
{
20-
app.Command("delete", delete =>
19+
Arity = ArgumentArity.ZeroOrOne,
20+
Description = Strings.Source_Description,
21+
};
22+
23+
private static readonly Option<bool> NonInteractiveOption = new Option<bool>("--non-interactive")
24+
{
25+
Arity = ArgumentArity.Zero,
26+
Description = Strings.NonInteractive_Description,
27+
};
28+
29+
private static readonly Option<string> ApiKeyOption = new Option<string>("--api-key", "-k")
30+
{
31+
Arity = ArgumentArity.ZeroOrOne,
32+
Description = Strings.ApiKey_Description,
33+
};
34+
35+
private static readonly Option<bool> NoServiceEndpointOption = new Option<bool>("--no-service-endpoint")
36+
{
37+
Arity = ArgumentArity.Zero,
38+
Description = Strings.NoServiceEndpoint_Description,
39+
};
40+
41+
private static readonly Option<bool> InteractiveOption = new Option<bool>("--interactive")
42+
{
43+
Arity = ArgumentArity.Zero,
44+
Description = Strings.NuGetXplatCommand_Interactive,
45+
};
46+
47+
private static readonly Argument<string> PackageIdArgument = new Argument<string>("PackageId")
48+
{
49+
Arity = ArgumentArity.ExactlyOne,
50+
Description = Strings.Delete_PackageIdAndVersion_Description,
51+
};
52+
53+
private static readonly Argument<string> PackageVersionArgument = new Argument<string>("PackageVersion")
54+
{
55+
Arity = ArgumentArity.ExactlyOne,
56+
Description = Strings.Delete_PackageIdAndVersion_Description,
57+
};
58+
59+
internal static void Register(Command parent, Func<ILoggerWithColor> getLogger)
60+
{
61+
var deleteCmd = new Command("delete", Strings.Delete_Description);
62+
63+
deleteCmd.Options.Add(SourceOption);
64+
deleteCmd.Options.Add(NonInteractiveOption);
65+
deleteCmd.Options.Add(ApiKeyOption);
66+
deleteCmd.Options.Add(NoServiceEndpointOption);
67+
deleteCmd.Options.Add(InteractiveOption);
68+
deleteCmd.Arguments.Add(PackageIdArgument);
69+
deleteCmd.Arguments.Add(PackageVersionArgument);
70+
71+
deleteCmd.SetAction(async (parseResult, cancellationToken) =>
2172
{
22-
delete.Description = Strings.Delete_Description;
23-
delete.HelpOption(XPlatUtility.HelpOption);
24-
25-
delete.Option(
26-
CommandConstants.ForceEnglishOutputOption,
27-
Strings.ForceEnglishOutput_Description,
28-
CommandOptionType.NoValue);
29-
30-
var source = delete.Option(
31-
"-s|--source <source>",
32-
Strings.Source_Description,
33-
CommandOptionType.SingleValue);
34-
35-
var nonInteractive = delete.Option(
36-
"--non-interactive",
37-
Strings.NonInteractive_Description,
38-
CommandOptionType.NoValue);
39-
40-
var apikey = delete.Option(
41-
"-k|--api-key <apiKey>",
42-
Strings.ApiKey_Description,
43-
CommandOptionType.SingleValue);
44-
45-
var arguments = delete.Argument(
46-
"[root]",
47-
Strings.Delete_PackageIdAndVersion_Description,
48-
multipleValues: true);
49-
50-
var noServiceEndpointDescription = delete.Option(
51-
"--no-service-endpoint",
52-
Strings.NoServiceEndpoint_Description,
53-
CommandOptionType.NoValue);
54-
55-
var interactive = delete.Option(
56-
"--interactive",
57-
Strings.NuGetXplatCommand_Interactive,
58-
CommandOptionType.NoValue);
59-
60-
delete.OnExecute(async () =>
61-
{
62-
if (arguments.Values.Count < 2)
63-
{
64-
throw new ArgumentException(Strings.Delete_MissingArguments);
65-
}
66-
67-
string packageId = arguments.Values[0];
68-
string packageVersion = arguments.Values[1];
69-
string sourcePath = source.Value();
70-
string apiKeyValue = apikey.Value();
71-
bool nonInteractiveValue = nonInteractive.HasValue();
72-
bool noServiceEndpoint = noServiceEndpointDescription.HasValue();
73-
74-
DefaultCredentialServiceUtility.SetupDefaultCredentialService(getLogger(), !interactive.HasValue());
73+
string packageId = parseResult.GetValue(PackageIdArgument);
74+
string packageVersion = parseResult.GetValue(PackageVersionArgument);
75+
string sourcePath = parseResult.GetValue(SourceOption);
76+
string apiKeyValue = parseResult.GetValue(ApiKeyOption);
77+
bool nonInteractiveValue = parseResult.GetValue(NonInteractiveOption);
78+
bool noServiceEndpoint = parseResult.GetValue(NoServiceEndpointOption);
79+
bool interactiveValue = parseResult.GetValue(InteractiveOption);
80+
81+
DefaultCredentialServiceUtility.SetupDefaultCredentialService(getLogger(), !interactiveValue);
7582

7683
#pragma warning disable CS0618 // Type or member is obsolete
77-
PackageSourceProvider sourceProvider = new PackageSourceProvider(XPlatUtility.GetSettingsForCurrentWorkingDirectory(), enablePackageSourcesChangedEvent: false);
84+
PackageSourceProvider sourceProvider = new PackageSourceProvider(XPlatUtility.GetSettingsForCurrentWorkingDirectory(), enablePackageSourcesChangedEvent: false);
7885
#pragma warning restore CS0618 // Type or member is obsolete
7986

80-
await DeleteRunner.Run(
81-
sourceProvider.Settings,
82-
sourceProvider,
83-
packageId,
84-
packageVersion,
85-
sourcePath,
86-
apiKeyValue,
87-
nonInteractiveValue,
88-
noServiceEndpoint,
89-
Confirm,
90-
getLogger());
91-
92-
return 0;
93-
});
87+
await DeleteRunner.Run(
88+
sourceProvider.Settings,
89+
sourceProvider,
90+
packageId,
91+
packageVersion,
92+
sourcePath,
93+
apiKeyValue,
94+
nonInteractiveValue,
95+
noServiceEndpoint,
96+
Confirm,
97+
getLogger());
98+
99+
return 0;
94100
});
101+
102+
parent.Subcommands.Add(deleteCmd);
95103
}
96104

97105
private static bool Confirm(string description)
@@ -103,7 +111,7 @@ private static bool Confirm(string description)
103111
Console.ForegroundColor = ConsoleColor.Yellow;
104112
Console.WriteLine(string.Format(CultureInfo.CurrentCulture, Strings.ConsoleConfirmMessage, description));
105113
var result = Console.ReadLine();
106-
return result.StartsWith(Strings.ConsoleConfirmMessageAccept, StringComparison.OrdinalIgnoreCase);
114+
return result != null && result.StartsWith(Strings.ConsoleConfirmMessageAccept, StringComparison.OrdinalIgnoreCase);
107115
}
108116
finally
109117
{

src/NuGet.Core/NuGet.CommandLine.XPlat/Commands/LocalsCommand.cs

Lines changed: 61 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -4,79 +4,84 @@
44
#nullable enable
55

66
using System;
7+
using System.CommandLine;
8+
using System.Collections.Generic;
79
using System.Globalization;
8-
using Microsoft.Extensions.CommandLineUtils;
10+
using System.Threading.Tasks;
911
using NuGet.Commands;
10-
using NuGet.Common;
1112

1213
namespace NuGet.CommandLine.XPlat
1314
{
1415
internal static class LocalsCommand
1516
{
16-
public static void Register(CommandLineApplication app, Func<ILogger> getLogger)
17+
private static readonly Option<bool> ClearOption = new Option<bool>("--clear", "-c")
1718
{
18-
app.Command("locals", locals =>
19-
{
20-
locals.Description = Strings.LocalsCommand_Description;
21-
locals.HelpOption(XPlatUtility.HelpOption);
19+
Arity = ArgumentArity.Zero,
20+
Description = Strings.LocalsCommand_ClearDescription,
21+
};
2222

23-
locals.Option(
24-
CommandConstants.ForceEnglishOutputOption,
25-
Strings.ForceEnglishOutput_Description,
26-
CommandOptionType.NoValue);
23+
private static readonly Option<bool> ListOption = new Option<bool>("--list", "-l")
24+
{
25+
Arity = ArgumentArity.Zero,
26+
Description = Strings.LocalsCommand_ListDescription,
27+
};
2728

28-
var clear = locals.Option(
29-
"-c|--clear",
30-
Strings.LocalsCommand_ClearDescription,
31-
CommandOptionType.NoValue);
29+
private static readonly Argument<string> CacheLocationArgument = new Argument<string>("Cache Location(s)")
30+
{
31+
Arity = ArgumentArity.ZeroOrOne,
32+
Description = Strings.LocalsCommand_ArgumentDescription,
33+
};
3234

33-
var list = locals.Option(
34-
"-l|--list",
35-
Strings.LocalsCommand_ListDescription,
36-
CommandOptionType.NoValue);
35+
internal static void Register(Command parent, Func<ILoggerWithColor> getLogger)
36+
{
37+
var localsCmd = new Command("locals", Strings.LocalsCommand_Description);
3738

38-
var arguments = locals.Argument(
39-
"Cache Location(s)",
40-
Strings.LocalsCommand_ArgumentDescription,
41-
multipleValues: false);
39+
localsCmd.Options.Add(ClearOption);
40+
localsCmd.Options.Add(ListOption);
41+
localsCmd.Arguments.Add(CacheLocationArgument);
4242

43-
locals.OnExecute(() =>
44-
{
45-
var logger = getLogger();
46-
var setting = XPlatUtility.GetSettingsForCurrentWorkingDirectory();
43+
localsCmd.SetAction((parseResult, cancellationToken) =>
44+
{
45+
var logger = getLogger();
46+
var setting = XPlatUtility.GetSettingsForCurrentWorkingDirectory();
4747

48-
// Using both -clear and -list command options, or neither one of them, is not supported.
49-
// We use MinArgs = 0 even though the first argument is required,
50-
// to avoid throwing a command argument validation exception and
51-
// immediately show usage help for this command instead.
52-
if ((arguments.Values.Count < 1) || string.IsNullOrWhiteSpace(arguments.Values[0]))
53-
{
54-
throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Strings.LocalsCommand_NoArguments));
55-
}
56-
else if (clear.HasValue() && list.HasValue())
57-
{
58-
throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Strings.LocalsCommand_MultipleOperations));
59-
}
60-
else if (!clear.HasValue() && !list.HasValue())
61-
{
62-
throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Strings.LocalsCommand_NoOperation));
63-
}
64-
else
65-
{
66-
var localsArgs = new LocalsArgs(arguments.Values,
67-
setting,
68-
logger.LogInformation,
69-
logger.LogError,
70-
clear.HasValue(),
71-
list.HasValue());
48+
string? cacheLocation = parseResult.GetValue(CacheLocationArgument);
49+
bool clear = parseResult.GetValue(ClearOption);
50+
bool list = parseResult.GetValue(ListOption);
7251

73-
var localsCommandRunner = new LocalsCommandRunner();
74-
localsCommandRunner.ExecuteCommand(localsArgs);
75-
}
52+
// Using both -clear and -list command options, or neither one of them, is not supported.
53+
// We use MinArgs = 0 even though the first argument is required,
54+
// to avoid throwing a command argument validation exception and
55+
// immediately show usage help for this command instead.
56+
if (string.IsNullOrWhiteSpace(cacheLocation))
57+
{
58+
throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Strings.LocalsCommand_NoArguments));
59+
}
60+
else if (clear && list)
61+
{
62+
throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Strings.LocalsCommand_MultipleOperations));
63+
}
64+
else if (!clear && !list)
65+
{
66+
throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Strings.LocalsCommand_NoOperation));
67+
}
68+
else
69+
{
70+
var localsArgs = new LocalsArgs(new List<string> { cacheLocation },
71+
setting,
72+
logger.LogInformation,
73+
logger.LogError,
74+
clear,
75+
list);
76+
77+
var localsCommandRunner = new LocalsCommandRunner();
78+
localsCommandRunner.ExecuteCommand(localsArgs);
79+
}
7680

77-
return 0;
78-
});
81+
return Task.FromResult(0);
7982
});
83+
84+
parent.Subcommands.Add(localsCmd);
8085
}
8186
}
8287
}

0 commit comments

Comments
 (0)