Skip to content

Commit 174878a

Browse files
committed
Upgrade to System.CommandLine 2.0.0 and remove NamingConventionBinder
1 parent 9581c09 commit 174878a

18 files changed

+225
-113
lines changed

developer-cli/Commands/BuildCommand.cs

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
using System.CommandLine;
2-
using System.CommandLine.NamingConventionBinder;
32
using System.Diagnostics;
43
using PlatformPlatform.DeveloperCli.Installation;
54
using PlatformPlatform.DeveloperCli.Utilities;
@@ -11,13 +10,19 @@ public class BuildCommand : Command
1110
{
1211
public BuildCommand() : base("build", "Builds a self-contained system")
1312
{
14-
Handler = CommandHandler.Create<bool, bool, string?>(Execute);
13+
var backendOption = new Option<bool>("--backend", "-b") { Description = "Run only backend build" };
14+
var frontendOption = new Option<bool>("--frontend", "-f") { Description = "Run only frontend build" };
15+
var solutionNameOption = new Option<string?>("<solution-name>", "--solution-name", "-s") { Description = "The name of the self-contained system to build (only used for backend builds)" };
1516

16-
AddOption(new Option<bool?>(["--backend", "-b"], "Run only backend build"));
17-
AddOption(new Option<bool?>(["--frontend", "-f"], "Run only frontend build"));
18-
AddOption(new Option<string?>(["<solution-name>", "--solution-name", "-s"], "The name of the self-contained system to build (only used for backend builds)"));
17+
Options.Add(backendOption);
18+
Options.Add(frontendOption);
19+
Options.Add(solutionNameOption);
1920

20-
Handler = CommandHandler.Create<bool, bool, string?>(Execute);
21+
this.SetAction(parseResult => Execute(
22+
parseResult.GetValue(backendOption),
23+
parseResult.GetValue(frontendOption),
24+
parseResult.GetValue(solutionNameOption)
25+
));
2126
}
2227

2328
private static void Execute(bool backend, bool frontend, string? solutionName)

developer-cli/Commands/CheckCommand.cs

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
using System.CommandLine;
2-
using System.CommandLine.NamingConventionBinder;
2+
using System.CommandLine.Invocation;
33
using System.Diagnostics;
44
using PlatformPlatform.DeveloperCli.Installation;
55
using PlatformPlatform.DeveloperCli.Utilities;
@@ -11,13 +11,25 @@ public class CheckCommand : Command
1111
{
1212
public CheckCommand() : base("check", "Performs all checks including build, test, format, and inspect for backend and frontend code")
1313
{
14-
AddOption(new Option<bool?>(["--backend", "-b"], "Run only backend checks"));
15-
AddOption(new Option<bool?>(["--frontend", "-f"], "Run only frontend checks"));
16-
AddOption(new Option<string?>(["<solution-name>", "--solution-name", "-s"], "The name of the self-contained system to check (only used for backend checks)"));
17-
AddOption(new Option<bool>(["--skip-format"], () => false, "Skip the backend format step which can be time consuming"));
18-
AddOption(new Option<bool>(["--skip-inspect"], () => false, "Skip the backend inspection step which can be time consuming"));
14+
var backendOption = new Option<bool>("--backend", "-b") { Description = "Run only backend checks" };
15+
var frontendOption = new Option<bool>("--frontend", "-f") { Description = "Run only frontend checks" };
16+
var solutionNameOption = new Option<string?>("<solution-name>", "--solution-name", "-s") { Description = "The name of the self-contained system to check (only used for backend checks)" };
17+
var skipFormatOption = new Option<bool>("--skip-format") { Description = "Skip the backend format step which can be time consuming" };
18+
var skipInspectOption = new Option<bool>("--skip-inspect") { Description = "Skip the backend inspection step which can be time consuming" };
1919

20-
Handler = CommandHandler.Create<bool, bool, string?, bool, bool>(Execute);
20+
Options.Add(backendOption);
21+
Options.Add(frontendOption);
22+
Options.Add(solutionNameOption);
23+
Options.Add(skipFormatOption);
24+
Options.Add(skipInspectOption);
25+
26+
this.SetAction(parseResult => Execute(
27+
parseResult.GetValue(backendOption),
28+
parseResult.GetValue(frontendOption),
29+
parseResult.GetValue(solutionNameOption),
30+
parseResult.GetValue(skipFormatOption),
31+
parseResult.GetValue(skipInspectOption)
32+
));
2133
}
2234

2335
private static void Execute(bool backend, bool frontend, string? solutionName, bool skipFormat, bool skipInspect)
@@ -67,24 +79,24 @@ private static void RunBackendChecks(string? solutionName, bool skipFormat, bool
6779
{
6880
string[] solutionArgs = solutionName is not null ? ["--solution-name", solutionName] : [];
6981

70-
new BuildCommand().InvokeAsync([.. solutionArgs, "--backend"]);
71-
new TestCommand().InvokeAsync([.. solutionArgs, "--no-build"]);
82+
new BuildCommand().Parse([.. solutionArgs, "--backend"]).Invoke();
83+
new TestCommand().Parse([.. solutionArgs, "--no-build"]).Invoke();
7284

7385
if (!skipFormat)
7486
{
75-
new FormatCommand().InvokeAsync([.. solutionArgs, "--backend"]);
87+
new FormatCommand().Parse([.. solutionArgs, "--backend"]).Invoke();
7688
}
7789

7890
if (!skipInspect)
7991
{
80-
new InspectCommand().InvokeAsync([.. solutionArgs, "--backend", "--no-build"]);
92+
new InspectCommand().Parse([.. solutionArgs, "--backend", "--no-build"]).Invoke();
8193
}
8294
}
8395

8496
private static void RunFrontendChecks()
8597
{
86-
new BuildCommand().InvokeAsync(["--frontend"]);
87-
new FormatCommand().InvokeAsync(["--frontend"]);
88-
new InspectCommand().InvokeAsync(["--frontend"]);
98+
new BuildCommand().Parse(["--frontend"]).Invoke();
99+
new FormatCommand().Parse(["--frontend"]).Invoke();
100+
new InspectCommand().Parse(["--frontend"]).Invoke();
89101
}
90102
}

developer-cli/Commands/CoAuthorCommand.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
using System.CommandLine;
2-
using System.CommandLine.NamingConventionBinder;
32
using PlatformPlatform.DeveloperCli.Installation;
43
using PlatformPlatform.DeveloperCli.Utilities;
54
using Spectre.Console;
@@ -12,7 +11,7 @@ public sealed class CoAuthorCommand : Command
1211

1312
public CoAuthorCommand() : base("coauthor", "Amends the current commit and adds you as a co-author")
1413
{
15-
Handler = CommandHandler.Create(Execute);
14+
this.SetAction(_ => Execute());
1615
}
1716

1817
private static void Execute()

developer-cli/Commands/ConfigureContinuousDeploymentsCommand.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
using System.CommandLine;
2-
using System.CommandLine.NamingConventionBinder;
32
using System.Diagnostics;
43
using System.Reflection;
54
using System.Text;
@@ -26,9 +25,11 @@ public ConfigureContinuousDeploymentsCommand() : base(
2625
"Set up trust between Azure and GitHub for passwordless deployments using OpenID Connect"
2726
)
2827
{
29-
AddOption(new Option<bool>(["--verbose-logging"], "Print Azure and GitHub CLI commands and output"));
28+
var verboseLoggingOption = new Option<bool>("--verbose-logging") { Description = "Print Azure and GitHub CLI commands and output" };
3029

31-
Handler = CommandHandler.Create<bool>(Execute);
30+
Options.Add(verboseLoggingOption);
31+
32+
this.SetAction(parseResult => Execute(parseResult.GetValue(verboseLoggingOption)));
3233
}
3334

3435
private void Execute(bool verboseLogging = false)

developer-cli/Commands/CoverageCommand.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
using System.CommandLine;
2-
using System.CommandLine.NamingConventionBinder;
32
using PlatformPlatform.DeveloperCli.Installation;
43
using PlatformPlatform.DeveloperCli.Utilities;
54
using Spectre.Console;
@@ -10,9 +9,11 @@ public class CoverageCommand : Command
109
{
1110
public CoverageCommand() : base("coverage", "Run JetBrains Code Coverage")
1211
{
13-
AddOption(new Option<string?>(["<solution-name>", "--solution-name", "-s"], "The name of the self-contained system to build"));
12+
var solutionNameOption = new Option<string?>("<solution-name>", "--solution-name", "-s") { Description = "The name of the self-contained system to build" };
1413

15-
Handler = CommandHandler.Create(Execute);
14+
Options.Add(solutionNameOption);
15+
16+
this.SetAction(parseResult => Execute(parseResult.GetValue(solutionNameOption)));
1617
}
1718

1819
private static void Execute(string? solutionName)

developer-cli/Commands/End2EndCommand.cs

Lines changed: 65 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
using System.CommandLine;
2-
using System.CommandLine.NamingConventionBinder;
32
using System.Diagnostics;
43
using PlatformPlatform.DeveloperCli.Installation;
54
using PlatformPlatform.DeveloperCli.Utilities;
@@ -16,30 +15,71 @@ public class End2EndCommand : Command
1615

1716
public End2EndCommand() : base("e2e", "Run end-to-end tests using Playwright")
1817
{
19-
// Add argument for search term or test file patterns
20-
AddArgument(new Argument<string[]>("search-terms", () => [], "Search terms for test filtering (e.g., 'user management', '@smoke', 'smoke', 'comprehensive', 'user-management-flows.spec.ts')"));
21-
22-
// All options in alphabetical order
23-
AddOption(new Option<string>(["--browser", "-b"], () => "all", "Browser to use for tests (chromium, firefox, webkit, safari, all)"));
24-
AddOption(new Option<bool>(["--debug"], () => false, "Start with Playwright Inspector for debugging (automatically enables headed mode)"));
25-
AddOption(new Option<bool>(["--debug-timing"], () => false, "Show step timing output with color coding during test execution"));
26-
AddOption(new Option<bool>(["--headed"], () => false, "Show browser UI while running tests (automatically enables sequential execution)"));
27-
AddOption(new Option<bool>(["--include-slow"], () => false, "Include tests marked as @slow"));
28-
AddOption(new Option<bool>(["--last-failed"], () => false, "Only re-run the failures"));
29-
AddOption(new Option<bool>(["--only-changed"], () => false, "Only run test files that have uncommitted changes"));
30-
AddOption(new Option<bool>(["--quiet"], () => false, "Suppress all output including terminal output and automatic report opening"));
31-
AddOption(new Option<int?>(["--repeat-each"], "Number of times to repeat each test"));
32-
AddOption(new Option<bool>(["--delete-artifacts"], () => false, "Delete all test artifacts and exit"));
33-
AddOption(new Option<int?>(["--retries"], "Maximum retry count for flaky tests, zero for no retries"));
34-
AddOption(new Option<string?>(["<self-contained-system>", "--self-contained-system", "-s"], $"The name of the self-contained system to test ({string.Join(", ", AvailableSelfContainedSystems)}, etc.)"));
35-
AddOption(new Option<bool>(["--show-report"], () => false, "Always show HTML report after test run"));
36-
AddOption(new Option<bool>(["--slow-mo"], () => false, "Run tests in slow motion (automatically enables headed mode)"));
37-
AddOption(new Option<bool>(["--smoke"], () => false, "Run only smoke tests"));
38-
AddOption(new Option<bool>(["--stop-on-first-failure", "-x"], () => false, "Stop after the first failure"));
39-
AddOption(new Option<bool>(["--ui"], () => false, "Run tests in interactive UI mode with time-travel debugging"));
40-
AddOption(new Option<int?>(["--workers", "-w"], "Number of worker processes to use for running tests"));
41-
42-
Handler = CommandHandler.Create(Execute);
18+
var searchTermsArgument = new Argument<string[]>("search-terms") { Description = "Search terms for test filtering (e.g., 'user management', '@smoke', 'smoke', 'comprehensive', 'user-management-flows.spec.ts')", DefaultValueFactory = _ => [] };
19+
var browserOption = new Option<string>("--browser", "-b") { Description = "Browser to use for tests (chromium, firefox, webkit, safari, all)", DefaultValueFactory = _ => "all" };
20+
var debugOption = new Option<bool>("--debug") { Description = "Start with Playwright Inspector for debugging (automatically enables headed mode)" };
21+
var debugTimingOption = new Option<bool>("--debug-timing") { Description = "Show step timing output with color coding during test execution" };
22+
var headedOption = new Option<bool>("--headed") { Description = "Show browser UI while running tests (automatically enables sequential execution)" };
23+
var includeSlowOption = new Option<bool>("--include-slow") { Description = "Include tests marked as @slow" };
24+
var lastFailedOption = new Option<bool>("--last-failed") { Description = "Only re-run the failures" };
25+
var onlyChangedOption = new Option<bool>("--only-changed") { Description = "Only run test files that have uncommitted changes" };
26+
var quietOption = new Option<bool>("--quiet") { Description = "Suppress all output including terminal output and automatic report opening" };
27+
var repeatEachOption = new Option<int?>("--repeat-each") { Description = "Number of times to repeat each test" };
28+
var deleteArtifactsOption = new Option<bool>("--delete-artifacts") { Description = "Delete all test artifacts and exit" };
29+
var retriesOption = new Option<int?>("--retries") { Description = "Maximum retry count for flaky tests, zero for no retries" };
30+
var selfContainedSystemOption = new Option<string?>("<self-contained-system>", "--self-contained-system", "-s") { Description = $"The name of the self-contained system to test ({string.Join(", ", AvailableSelfContainedSystems)}, etc.)" };
31+
var showReportOption = new Option<bool>("--show-report") { Description = "Always show HTML report after test run" };
32+
var slowMoOption = new Option<bool>("--slow-mo") { Description = "Run tests in slow motion (automatically enables headed mode)" };
33+
var smokeOption = new Option<bool>("--smoke") { Description = "Run only smoke tests" };
34+
var stopOnFirstFailureOption = new Option<bool>("--stop-on-first-failure", "-x") { Description = "Stop after the first failure" };
35+
var uiOption = new Option<bool>("--ui") { Description = "Run tests in interactive UI mode with time-travel debugging" };
36+
var workersOption = new Option<int?>("--workers", "-w") { Description = "Number of worker processes to use for running tests" };
37+
38+
Arguments.Add(searchTermsArgument);
39+
Options.Add(browserOption);
40+
Options.Add(debugOption);
41+
Options.Add(debugTimingOption);
42+
Options.Add(headedOption);
43+
Options.Add(includeSlowOption);
44+
Options.Add(lastFailedOption);
45+
Options.Add(onlyChangedOption);
46+
Options.Add(quietOption);
47+
Options.Add(repeatEachOption);
48+
Options.Add(deleteArtifactsOption);
49+
Options.Add(retriesOption);
50+
Options.Add(selfContainedSystemOption);
51+
Options.Add(showReportOption);
52+
Options.Add(slowMoOption);
53+
Options.Add(smokeOption);
54+
Options.Add(stopOnFirstFailureOption);
55+
Options.Add(uiOption);
56+
Options.Add(workersOption);
57+
58+
// SetHandler only supports up to 8 parameters, so we use SetAction for this complex command
59+
this.SetAction(parseResult =>
60+
{
61+
Execute(
62+
parseResult.GetValue(searchTermsArgument)!,
63+
parseResult.GetValue(browserOption)!,
64+
parseResult.GetValue(debugOption),
65+
parseResult.GetValue(debugTimingOption),
66+
parseResult.GetValue(headedOption),
67+
parseResult.GetValue(includeSlowOption),
68+
parseResult.GetValue(lastFailedOption),
69+
parseResult.GetValue(onlyChangedOption),
70+
parseResult.GetValue(quietOption),
71+
parseResult.GetValue(repeatEachOption),
72+
parseResult.GetValue(deleteArtifactsOption),
73+
parseResult.GetValue(retriesOption),
74+
parseResult.GetValue(selfContainedSystemOption),
75+
parseResult.GetValue(showReportOption),
76+
parseResult.GetValue(slowMoOption),
77+
parseResult.GetValue(smokeOption),
78+
parseResult.GetValue(stopOnFirstFailureOption),
79+
parseResult.GetValue(uiOption),
80+
parseResult.GetValue(workersOption)
81+
);
82+
});
4383
}
4484

4585
private static string BaseUrl => Environment.GetEnvironmentVariable("PUBLIC_URL") ?? "https://localhost:9000";

developer-cli/Commands/FormatCommand.cs

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
using System.CommandLine;
2-
using System.CommandLine.NamingConventionBinder;
32
using System.Diagnostics;
43
using System.Text.Json;
54
using System.Xml.Linq;
@@ -13,11 +12,19 @@ public class FormatCommand : Command
1312
{
1413
public FormatCommand() : base("format", "Formats code to match code styling rules")
1514
{
16-
AddOption(new Option<bool?>(["--backend", "-b"], "Only format backend code"));
17-
AddOption(new Option<bool?>(["--frontend", "-f"], "Only format frontend code"));
18-
AddOption(new Option<string?>(["<solution-name>", "--solution-name", "-s"], "The name of the self-contained system to format (only used for backend code)"));
19-
20-
Handler = CommandHandler.Create<bool, bool, string?>(Execute);
15+
var backendOption = new Option<bool>("--backend", "-b") { Description = "Only format backend code" };
16+
var frontendOption = new Option<bool>("--frontend", "-f") { Description = "Only format frontend code" };
17+
var solutionNameOption = new Option<string?>("<solution-name>", "--solution-name", "-s") { Description = "The name of the self-contained system to format (only used for backend code)" };
18+
19+
Options.Add(backendOption);
20+
Options.Add(frontendOption);
21+
Options.Add(solutionNameOption);
22+
23+
this.SetAction(parseResult => Execute(
24+
parseResult.GetValue(backendOption),
25+
parseResult.GetValue(frontendOption),
26+
parseResult.GetValue(solutionNameOption)
27+
));
2128
}
2229

2330
private static void Execute(bool backend, bool frontend, string? solutionName)

developer-cli/Commands/InspectCommand.cs

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
using System.CommandLine;
2-
using System.CommandLine.NamingConventionBinder;
32
using System.Diagnostics;
43
using PlatformPlatform.DeveloperCli.Installation;
54
using PlatformPlatform.DeveloperCli.Utilities;
@@ -11,12 +10,22 @@ public class InspectCommand : Command
1110
{
1211
public InspectCommand() : base("inspect", "Run code inspections for frontend and backend code")
1312
{
14-
AddOption(new Option<bool?>(["--backend", "-b"], "Run only backend inspections"));
15-
AddOption(new Option<bool?>(["--frontend", "-f"], "Run only frontend inspections"));
16-
AddOption(new Option<string?>(["<solution-name>", "--solution-name", "-s"], "The name of the self-contained system to inspect (only used for backend inspections)"));
17-
AddOption(new Option<bool>(["--no-build"], () => false, "Skip building and restoring the solution before running inspections"));
13+
var backendOption = new Option<bool>("--backend", "-b") { Description = "Run only backend inspections" };
14+
var frontendOption = new Option<bool>("--frontend", "-f") { Description = "Run only frontend inspections" };
15+
var solutionNameOption = new Option<string?>("<solution-name>", "--solution-name", "-s") { Description = "The name of the self-contained system to inspect (only used for backend inspections)" };
16+
var noBuildOption = new Option<bool>("--no-build") { Description = "Skip building and restoring the solution before running inspections" };
1817

19-
Handler = CommandHandler.Create<bool, bool, string?, bool>(Execute);
18+
Options.Add(backendOption);
19+
Options.Add(frontendOption);
20+
Options.Add(solutionNameOption);
21+
Options.Add(noBuildOption);
22+
23+
this.SetAction(parseResult => Execute(
24+
parseResult.GetValue(backendOption),
25+
parseResult.GetValue(frontendOption),
26+
parseResult.GetValue(solutionNameOption),
27+
parseResult.GetValue(noBuildOption)
28+
));
2029
}
2130

2231
private static void Execute(bool backend, bool frontend, string? solutionName, bool noBuild)

developer-cli/Commands/InstallCommand.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
using System.CommandLine;
2-
using System.CommandLine.NamingConventionBinder;
32
using PlatformPlatform.DeveloperCli.Installation;
43
using Spectre.Console;
54

@@ -41,7 +40,7 @@ public InstallCommand() : base(
4140
$"This will register the alias {Configuration.AliasName} so it will be available everywhere"
4241
)
4342
{
44-
Handler = CommandHandler.Create(Execute);
43+
this.SetAction(_ => Execute());
4544
}
4645

4746
private static void Execute()

0 commit comments

Comments
 (0)