From d29392edce6bee3fb178ea6275222cc2ae69b18f Mon Sep 17 00:00:00 2001
From: Adeel Mujahid <3840695+am11@users.noreply.github.com>
Date: Fri, 27 Mar 2026 12:40:14 +0000
Subject: [PATCH] Migrate remaining tools to modern commandline
---
eng/build.yml | 2 +-
src/AnalyzeAsm/AnalyzeAsm.csproj | 1 -
src/Directory.Build.props | 15 ++
src/cijobs/CIJobsRootCommand.cs | 33 ++--
src/cijobs/Program.cs | 12 +-
src/cijobs/cijobs.csproj | 3 -
.../instructions-retired-explorer.csproj | 3 -
src/jit-analyze/Program.cs | 7 +-
src/jit-analyze/jit-analyze.csproj | 3 -
src/jit-dasm-pmi/Program.cs | 7 +-
src/jit-dasm-pmi/jit-dasm-pmi.csproj | 3 -
src/jit-dasm/Program.cs | 7 +-
src/jit-dasm/jit-dasm.csproj | 3 -
.../jit-decisions-analyze.csproj | 3 -
src/jit-diff/JitDiffRootCommand.cs | 149 ++++++++++++++++
src/jit-diff/jit-diff.cs | 168 ++++++++----------
src/jit-diff/jit-diff.csproj | 3 -
src/jit-format/JitFormatRootCommand.cs | 65 +++++++
src/jit-format/jit-format.cs | 58 +++---
src/jit-format/jit-format.csproj | 3 -
src/jit-include.props | 11 --
src/jit-rl-cse/MLCSE.csproj | 3 -
src/jit-tp-analyze/Program.cs | 7 +-
src/jit-tp-analyze/jit-tp-analyze.csproj | 3 -
src/mutate-test/MutateTestRootCommand.cs | 32 ++--
src/mutate-test/Program.cs | 12 +-
src/mutate-test/mutate-test.csproj | 3 -
.../performance-explorer.csproj | 3 -
src/pmi/pmi.csproj | 2 -
src/superpmi/superpmicollect.csproj | 2 -
src/target-framework.props | 9 -
src/wasm-spmi-filter/wasm-spmi-filter.csproj | 1 -
32 files changed, 399 insertions(+), 237 deletions(-)
create mode 100644 src/Directory.Build.props
create mode 100644 src/jit-diff/JitDiffRootCommand.cs
create mode 100644 src/jit-format/JitFormatRootCommand.cs
delete mode 100644 src/jit-include.props
delete mode 100644 src/target-framework.props
diff --git a/eng/build.yml b/eng/build.yml
index 9f7588ae..ba3779bb 100644
--- a/eng/build.yml
+++ b/eng/build.yml
@@ -13,7 +13,7 @@ jobs:
displayName: 'Install .NET Core SDK'
inputs:
packageType: sdk
- version: 8.x
+ version: 10.x
installationPath: $(Agent.ToolsDirectory)/dotnet
- ${{ if eq(parameters.agentOs, 'Windows_NT') }}:
diff --git a/src/AnalyzeAsm/AnalyzeAsm.csproj b/src/AnalyzeAsm/AnalyzeAsm.csproj
index 74954604..6a70a1ab 100644
--- a/src/AnalyzeAsm/AnalyzeAsm.csproj
+++ b/src/AnalyzeAsm/AnalyzeAsm.csproj
@@ -2,7 +2,6 @@
Exe
- net6.0
diff --git a/src/Directory.Build.props b/src/Directory.Build.props
new file mode 100644
index 00000000..0422e1b6
--- /dev/null
+++ b/src/Directory.Build.props
@@ -0,0 +1,15 @@
+
+
+
+ net10.0
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/cijobs/CIJobsRootCommand.cs b/src/cijobs/CIJobsRootCommand.cs
index e566a403..df9c44af 100644
--- a/src/cijobs/CIJobsRootCommand.cs
+++ b/src/cijobs/CIJobsRootCommand.cs
@@ -5,38 +5,37 @@
using System;
using System.Collections.Generic;
using System.CommandLine;
-using System.CommandLine.Invocation;
using System.Threading.Tasks;
namespace ManagedCodeGen
{
- internal sealed class CIJobsRootCommand : CliRootCommand
+ internal sealed class CIJobsRootCommand : RootCommand
{
- public CliOption Server { get; } =
+ public Option Server { get; } =
new("--server", "-s") { Description = "Url of the server. Defaults to https://ci.dot.net/" };
- public CliOption JobName { get; } =
+ public Option JobName { get; } =
new("--job", "-j") { Description = "Name of the job." };
- public CliOption BranchName { get; } =
+ public Option BranchName { get; } =
new("--branch", "-b") { DefaultValueFactory = _ => "master", Description = "Name of the branch." };
- public CliOption RepoName { get; } =
+ public Option RepoName { get; } =
new("--repo", "-r") { DefaultValueFactory = _ => "dotnet_coreclr", Description = "Name of the repo (e.g. dotnet_corefx or dotnet_coreclr)." };
- public CliOption MatchPattern { get; } =
+ public Option MatchPattern { get; } =
new("--match", "-m") { Description = "Regex pattern used to select jobs output." };
- public CliOption JobNumber { get; } =
+ public Option JobNumber { get; } =
new("--number", "-n") { Description = "Job number." };
- public CliOption ShowLastSuccessful { get; } =
+ public Option ShowLastSuccessful { get; } =
new("--last-successful", "-l") { Description = "Show last successful build." };
- public CliOption Commit { get; } =
+ public Option Commit { get; } =
new("--commit", "-c") { Description = "List build at this commit." };
- public CliOption ShowArtifacts { get; } =
+ public Option ShowArtifacts { get; } =
new("--artifacts", "-a") { Description = "Show job artifacts on server." };
- public CliOption OutputPath { get; } =
+ public Option OutputPath { get; } =
new("--output", "-o") { Description = "The path where output will be placed." };
- public CliOption OutputRoot { get; } =
+ public Option OutputRoot { get; } =
new("--output-root") { Description = "The root directory where output will be placed. A subdirectory named by job and build number will be created within this to store the output." };
- public CliOption Unzip { get; } =
+ public Option Unzip { get; } =
new("--unzip", "-u") { Description = "Unzip copied artifacts" };
- public CliOption ContentPath { get; } =
+ public Option ContentPath { get; } =
new("--ContentPath", "-p") { Description = "Relative product zip path. Default is artifact/bin/Product/*zip*/Product.zip" };
public ParseResult Result;
@@ -45,7 +44,7 @@ public CIJobsRootCommand(string[] args) : base("Continuous integration build job
{
List errors = new();
- CliCommand listCommand = new("list", "List jobs on ci.dot.net for the repo.")
+ Command listCommand = new("list", "List jobs on ci.dot.net for the repo.")
{
Server,
JobName,
@@ -104,7 +103,7 @@ public CIJobsRootCommand(string[] args) : base("Continuous integration build job
Subcommands.Add(listCommand);
- CliCommand copyCommand = new("copy", @"Copies job artifacts from ci.dot.net. This
+ Command copyCommand = new("copy", @"Copies job artifacts from ci.dot.net. This
command copies a zip of artifacts from a repo (defaulted to
dotnet_coreclr). The default location of the zips is the
Product sub-directory, though that can be changed using the
diff --git a/src/cijobs/Program.cs b/src/cijobs/Program.cs
index 73b01e18..24626b0e 100755
--- a/src/cijobs/Program.cs
+++ b/src/cijobs/Program.cs
@@ -69,13 +69,13 @@ public async Task RunAsync(string name)
return await CopyAsync(cic);
}
- private T Get(CliOption option) => _command.Result.GetValue(option);
+ private T Get(Option option) => _command.Result.GetValue(option);
- private static Task Main(string[] args) =>
- new CliConfiguration(new CIJobsRootCommand(args).UseVersion())
- {
- EnableParseErrorReporting = true
- }.InvokeAsync(args);
+ private static Task Main(string[] args)
+ {
+ var command = new CIJobsRootCommand(args).UseVersion();
+ return command.Parse(args).InvokeAsync();
+ }
// List jobs and their details from the given project on .NETCI Jenkins instance.
// List functionality:
diff --git a/src/cijobs/cijobs.csproj b/src/cijobs/cijobs.csproj
index 036eb0f1..87773400 100644
--- a/src/cijobs/cijobs.csproj
+++ b/src/cijobs/cijobs.csproj
@@ -1,8 +1,5 @@
-
-
-
Exe
diff --git a/src/instructions-retired-explorer/instructions-retired-explorer.csproj b/src/instructions-retired-explorer/instructions-retired-explorer.csproj
index 4539b1d1..fc32fc7d 100644
--- a/src/instructions-retired-explorer/instructions-retired-explorer.csproj
+++ b/src/instructions-retired-explorer/instructions-retired-explorer.csproj
@@ -1,8 +1,5 @@
-
-
-
Exe
diff --git a/src/jit-analyze/Program.cs b/src/jit-analyze/Program.cs
index 2d334f85..cc791ca9 100644
--- a/src/jit-analyze/Program.cs
+++ b/src/jit-analyze/Program.cs
@@ -908,8 +908,11 @@ public static Dictionary DiffInText(string diffPath, string basePat
private T Get(Option option) => _command.Result.GetValue(option);
- private static int Main(string[] args) =>
- new CommandLineConfiguration(new JitAnalyzeRootCommand(args).UseVersion()).Invoke(args);
+ private static int Main(string[] args)
+ {
+ var command = new JitAnalyzeRootCommand(args).UseVersion();
+ return command.Parse(args).Invoke();
+ }
public int Run()
{
diff --git a/src/jit-analyze/jit-analyze.csproj b/src/jit-analyze/jit-analyze.csproj
index 036eb0f1..87773400 100644
--- a/src/jit-analyze/jit-analyze.csproj
+++ b/src/jit-analyze/jit-analyze.csproj
@@ -1,8 +1,5 @@
-
-
-
Exe
diff --git a/src/jit-dasm-pmi/Program.cs b/src/jit-dasm-pmi/Program.cs
index 16cf6c50..904bbba3 100644
--- a/src/jit-dasm-pmi/Program.cs
+++ b/src/jit-dasm-pmi/Program.cs
@@ -75,8 +75,11 @@ public int Run()
private T Get(Option option) => _command.Result.GetValue(option);
private T Get(Argument arg) => _command.Result.GetValue(arg);
- private static int Main(string[] args) =>
- new CommandLineConfiguration(new JitDasmPmiRootCommand(args).UseVersion()).Invoke(args);
+ private static int Main(string[] args)
+ {
+ var command = new JitDasmPmiRootCommand(args).UseVersion();
+ return command.Parse(args).Invoke();
+ }
public List GenerateAssemblyWorklist()
{
diff --git a/src/jit-dasm-pmi/jit-dasm-pmi.csproj b/src/jit-dasm-pmi/jit-dasm-pmi.csproj
index 036eb0f1..87773400 100644
--- a/src/jit-dasm-pmi/jit-dasm-pmi.csproj
+++ b/src/jit-dasm-pmi/jit-dasm-pmi.csproj
@@ -1,8 +1,5 @@
-
-
-
Exe
diff --git a/src/jit-dasm/Program.cs b/src/jit-dasm/Program.cs
index dc24baa8..77755cd1 100644
--- a/src/jit-dasm/Program.cs
+++ b/src/jit-dasm/Program.cs
@@ -84,8 +84,11 @@ public int Run()
private T Get(Option option) => _command.Result.GetValue(option);
private T Get(Argument arg) => _command.Result.GetValue(arg);
- private static int Main(string[] args) =>
- new CommandLineConfiguration(new JitDasmRootCommand(args).UseVersion()).Invoke(args);
+ private static int Main(string[] args)
+ {
+ var command = new JitDasmRootCommand(args).UseVersion();
+ return command.Parse(args).Invoke();
+ }
public List GenerateAssemblyWorklist()
{
diff --git a/src/jit-dasm/jit-dasm.csproj b/src/jit-dasm/jit-dasm.csproj
index 036eb0f1..87773400 100644
--- a/src/jit-dasm/jit-dasm.csproj
+++ b/src/jit-dasm/jit-dasm.csproj
@@ -1,8 +1,5 @@
-
-
-
Exe
diff --git a/src/jit-decisions-analyze/jit-decisions-analyze.csproj b/src/jit-decisions-analyze/jit-decisions-analyze.csproj
index 036eb0f1..87773400 100644
--- a/src/jit-decisions-analyze/jit-decisions-analyze.csproj
+++ b/src/jit-decisions-analyze/jit-decisions-analyze.csproj
@@ -1,8 +1,5 @@
-
-
-
Exe
diff --git a/src/jit-diff/JitDiffRootCommand.cs b/src/jit-diff/JitDiffRootCommand.cs
new file mode 100644
index 00000000..9048517e
--- /dev/null
+++ b/src/jit-diff/JitDiffRootCommand.cs
@@ -0,0 +1,149 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+using System.Collections.Generic;
+using System.CommandLine;
+using System.CommandLine.Parsing;
+
+namespace ManagedCodeGen
+{
+ internal sealed class JitDiffRootCommand : RootCommand
+ {
+ public Option BasePath { get; } =
+ new("--base", "-b") { Description = "The base compiler directory or tag. Will use crossgen, corerun, or clrjit from this directory.", Arity = ArgumentArity.ZeroOrOne };
+ public Option DiffPath { get; } =
+ new("--diff", "-d") { Description = "The diff compiler directory or tag. Will use crossgen, corerun, or clrjit from this directory.", Arity = ArgumentArity.ZeroOrOne };
+ public Option CrossgenExe { get; } =
+ new("--crossgen") { Description = "The crossgen or crossgen2 compiler exe. When this is specified, will use clrjit from the --base and --diff directories with this crossgen." };
+ public Option OutputPath { get; } =
+ new("--output", "-o") { Description = "The output path." };
+ public Option NoAnalyze { get; } =
+ new("--noanalyze") { Description = "Do not analyze resulting base, diff dasm directories. (By default, the directories are analyzed for diffs.)" };
+ public Option Sequential { get; } =
+ new("--sequential", "-s") { Description = "Run sequentially; don't do parallel compiles." };
+ public Option Tag { get; } =
+ new("--tag", "-t") { Description = "Name of root in output directory. Allows for many sets of output." };
+ public Option CoreLib { get; } =
+ new("--corelib", "-c") { Description = "Diff System.Private.CoreLib.dll." };
+ public Option Frameworks { get; } =
+ new("--frameworks", "-f") { Description = "Diff frameworks." };
+ public Option Metric { get; } =
+ new("--metrics", "-m") { Description = "Comma-separated metric to use for diff computations. Available metrics: CodeSize(default), PerfScore, PrologSize, InstrCount, AllocSize, ExtraAllocBytes, DebugClauseCount, DebugVarCount" };
+ public Option Benchmarks { get; } =
+ new("--benchmarks") { Description = "Diff core benchmarks." };
+ public Option Tests { get; } =
+ new("--tests") { Description = "Diff all tests." };
+ public Option GCInfo { get; } =
+ new("--gcinfo") { Description = "Add GC info to the disasm output." };
+ public Option DebugInfo { get; } =
+ new("--debuginfo") { Description = "Add Debug info to the disasm output." };
+ public Option Verbose { get; } =
+ new("--verbose", "-v") { Description = "Enable verbose output." };
+ public Option NoDiffable { get; } =
+ new("--nodiffable") { Description = "Generate non-diffable asm (pointer values will be left in output)." };
+ public Option CoreRoot { get; } =
+ new("--core_root") { Description = "Path to test CORE_ROOT." };
+ public Option TestRoot { get; } =
+ new("--test_root") { Description = "Path to test tree. Use with --benchmarks or --tests." };
+ public Option BaseRoot { get; } =
+ new("--base_root") { Description = "Path to root of base dotnet/runtime repo." };
+ public Option DiffRoot { get; } =
+ new("--diff_root") { Description = "Path to root of diff dotnet/runtime repo." };
+ public Option Arch { get; } =
+ new("--arch") { Description = "Architecture to diff (x86, x64)." };
+ public Option Build { get; } =
+ new("--build") { Description = "Build flavor to diff (Checked, Debug)." };
+ public Option AltJit { get; } =
+ new("--altjit") { Description = "If set, the name of the altjit to use (e.g., clrjit_win_arm64_x64.dll)." };
+ public Option Pmi { get; } =
+ new("--pmi") { Description = "Run asm diffs via pmi." };
+ public Option Cctors { get; } =
+ new("--cctors") { Description = "With --pmi, jit and run cctors before jitting other methods" };
+ public Option> AssemblyList { get; } =
+ new("--assembly") { Description = "Run asm diffs on a given set of assemblies. An individual item can be an assembly or a directory tree containing assemblies." };
+ public Option Tsv { get; } =
+ new("--tsv") { Description = "Dump analysis data to diffs.tsv in output directory." };
+ public Option Tier0 { get; } =
+ new("--tier0") { Description = "Diff tier0 codegen where possible." };
+ public Option Count { get; } =
+ new("--count") { Description = "Provide the count parameter to jit-analyze (default 20)." };
+
+ public Option JobName { get; } =
+ new("--job", "-j") { Description = "Name of the job." };
+ public Option Number { get; } =
+ new("--number", "-n") { Description = "Job number." };
+ public Option LastSuccessful { get; } =
+ new("--last_successful", "-l") { Description = "Last successful build." };
+ public Option BranchName { get; } =
+ new("--branch", "-b") { Description = "Name of branch." };
+
+ public ParseResult Result { get; private set; }
+ public jitdiff.Commands SelectedCommand { get; private set; }
+
+ public JitDiffRootCommand(string[] args) : base("Managed codegen diff orchestrator")
+ {
+ Command diffCommand = new("diff", "Run asm diffs via crossgen.")
+ {
+ BasePath, DiffPath, CrossgenExe, OutputPath, NoAnalyze, Sequential, Tag, CoreLib, Frameworks, Metric,
+ Benchmarks, Tests, GCInfo, DebugInfo, Verbose, NoDiffable, CoreRoot, TestRoot, BaseRoot, DiffRoot,
+ Arch, Build, AltJit, Pmi, Cctors, AssemblyList, Tsv, Tier0, Count
+ };
+ diffCommand.SetAction(result => Execute(result, jitdiff.Commands.Diff));
+ Subcommands.Add(diffCommand);
+
+ Command listCommand = new("list", "List defaults and available tools in config.json.")
+ {
+ Verbose
+ };
+ listCommand.SetAction(result => Execute(result, jitdiff.Commands.List));
+ Subcommands.Add(listCommand);
+
+ Command installCommand = new("install", "Install tool in config.json.")
+ {
+ JobName, Number, LastSuccessful, BranchName, Verbose
+ };
+ installCommand.SetAction(result => Execute(result, jitdiff.Commands.Install));
+ Subcommands.Add(installCommand);
+
+ Command uninstallCommand = new("uninstall", "Uninstall tool from config.json.")
+ {
+ Tag
+ };
+ uninstallCommand.SetAction(result => Execute(result, jitdiff.Commands.Uninstall));
+ Subcommands.Add(uninstallCommand);
+ }
+
+ private int Execute(ParseResult result, jitdiff.Commands command)
+ {
+ Result = result;
+ SelectedCommand = command;
+
+ try
+ {
+ jitdiff.Config config = new(this);
+ return config.DoCommand switch
+ {
+ jitdiff.Commands.Diff => jitdiff.DiffTool.DiffCommand(config),
+ jitdiff.Commands.PmiDiff => jitdiff.DiffTool.DiffCommand(config),
+ jitdiff.Commands.List => config.ListCommand(),
+ jitdiff.Commands.Install => jitdiff.InstallCommand(config),
+ jitdiff.Commands.Uninstall => jitdiff.UninstallCommand(config),
+ _ => 1,
+ };
+ }
+ catch (Exception e)
+ {
+ Console.ResetColor();
+ Console.ForegroundColor = ConsoleColor.Red;
+
+ Console.Error.WriteLine("Error: " + e.Message);
+ Console.Error.WriteLine(e.ToString());
+
+ Console.ResetColor();
+ return 1;
+ }
+ }
+ }
+}
diff --git a/src/jit-diff/jit-diff.cs b/src/jit-diff/jit-diff.cs
index 9430d637..c395c112 100755
--- a/src/jit-diff/jit-diff.cs
+++ b/src/jit-diff/jit-diff.cs
@@ -5,6 +5,7 @@
using System;
using System.Collections.Generic;
using System.CommandLine;
+using System.CommandLine.Parsing;
using System.IO;
using System.Linq;
using System.Text.Json;
@@ -113,7 +114,6 @@ private static string GetConfigurationArtifactDir(string platformMoniker, string
public class Config
{
- private ArgumentSyntax _syntaxResult;
private Commands _command = Commands.Diff;
private bool _baseSpecified = false; // True if user specified "--base" or "--base " or "--base "
private bool _diffSpecified = false; // True if user specified "--diff" or "--diff " or "--diff "
@@ -158,77 +158,80 @@ public class Config
private bool _noJitUtilsRoot = false;
private bool _validationError = false;
- public Config(string[] args)
+ internal Config(JitDiffRootCommand command)
{
- // Get configuration values from JIT_UTILS_ROOT/config.json
+ // Get configuration values from JIT_UTILS_ROOT/config.json.
LoadFileConfig();
- _syntaxResult = ArgumentSyntax.Parse(args, syntax =>
+ ParseResult result = command.Result;
+ _command = command.SelectedCommand;
+
+ bool IsSpecified(Option option) => result.GetResult(option) != null;
+ T Get(Option option) => result.GetValue(option);
+
+ if (_command == Commands.Diff)
{
- // Diff command section.
- syntax.DefineCommand("diff", ref _command, Commands.Diff, "Run asm diffs via crossgen.");
-
- var baseOption = syntax.DefineOption("b|base", ref _basePath, false,
- "The base compiler directory or tag. Will use crossgen, corerun, or clrjit from this directory.");
- var diffOption = syntax.DefineOption("d|diff", ref _diffPath, false,
- "The diff compiler directory or tag. Will use crossgen, corerun, or clrjit from this directory.");
- syntax.DefineOption("crossgen", ref _crossgenExe,
- "The crossgen or crossgen2 compiler exe. When this is specified, will use clrjit from the --base and " +
- "--diff directories with this crossgen.");
- syntax.DefineOption("o|output", ref _outputPath, "The output path.");
- syntax.DefineOption("noanalyze", ref _noanalyze, "Do not analyze resulting base, diff dasm directories. (By default, the directories are analyzed for diffs.)");
- syntax.DefineOption("s|sequential", ref _sequential, "Run sequentially; don't do parallel compiles.");
- syntax.DefineOption("t|tag", ref _tag, "Name of root in output directory. Allows for many sets of output.");
- syntax.DefineOption("c|corelib", ref _corelib, "Diff System.Private.CoreLib.dll.");
- syntax.DefineOption("f|frameworks", ref _frameworks, "Diff frameworks.");
- syntax.DefineOption("m|metrics", ref _metric, false, "Comma-separated metric to use for diff computations. Available metrics: CodeSize(default), PerfScore, PrologSize, InstrCount, AllocSize, ExtraAllocBytes, DebugClauseCount, DebugVarCount");
- syntax.DefineOption("benchmarks", ref _benchmarks, "Diff core benchmarks.");
- syntax.DefineOption("tests", ref _tests, "Diff all tests.");
- syntax.DefineOption("gcinfo", ref _gcinfo, "Add GC info to the disasm output.");
- syntax.DefineOption("debuginfo", ref _debuginfo, "Add Debug info to the disasm output.");
- syntax.DefineOption("v|verbose", ref _verbose, "Enable verbose output.");
- syntax.DefineOption("nodiffable", ref _noDiffable, "Generate non-diffable asm (pointer values will be left in output).");
- syntax.DefineOption("core_root", ref _platformPath, "Path to test CORE_ROOT.");
- syntax.DefineOption("test_root", ref _testPath, "Path to test tree. Use with --benchmarks or --tests.");
- syntax.DefineOption("base_root", ref _baseRoot, "Path to root of base dotnet/runtime repo.");
- syntax.DefineOption("diff_root", ref _diffRoot, "Path to root of diff dotnet/runtime repo.");
- syntax.DefineOption("arch", ref _arch, "Architecture to diff (x86, x64).");
- syntax.DefineOption("build", ref _build, "Build flavor to diff (Checked, Debug).");
- syntax.DefineOption("altjit", ref _altjit, "If set, the name of the altjit to use (e.g., clrjit_win_arm64_x64.dll).");
- var pmiOption = syntax.DefineOption("pmi", ref _pmi, "Run asm diffs via pmi.");
- syntax.DefineOption("cctors", ref _cctors, "With --pmi, jit and run cctors before jitting other methods");
- syntax.DefineOptionList("assembly", ref _assemblyList, "Run asm diffs on a given set of assemblies. An individual item can be an assembly or a directory tree containing assemblies.");
- syntax.DefineOption("tsv", ref _tsv, "Dump analysis data to diffs.tsv in output directory.");
- syntax.DefineOption("tier0", ref _tier0, "Diff tier0 codegen where possible.");
-
- // used by jit-analyze
- syntax.DefineOption("count", ref _count, "provide the count parameter to jit-analyze (default 20)");
-
- // List command section.
- syntax.DefineCommand("list", ref _command, Commands.List,
- "List defaults and available tools in " + s_configFileName + ".");
- syntax.DefineOption("v|verbose", ref _verbose, "Enable verbose output.");
-
- // Install command section.
- syntax.DefineCommand("install", ref _command, Commands.Install, "Install tool in " + s_configFileName + ".");
- syntax.DefineOption("j|job", ref _jobName, "Name of the job.");
- syntax.DefineOption("n|number", ref _number, "Job number.");
- syntax.DefineOption("l|last_successful", ref _lastSuccessful, "Last successful build.");
- syntax.DefineOption("b|branch", ref _branchName, "Name of branch.");
- syntax.DefineOption("v|verbose", ref _verbose, "Enable verbose output.");
-
- // Uninstall command section.s
- syntax.DefineCommand("uninstall", ref _command, Commands.Uninstall, "Uninstall tool from " + s_configFileName + ".");
- syntax.DefineOption("t|tag", ref _tag, "Name of tool tag in config file.");
-
- _baseSpecified = baseOption.IsSpecified;
- _diffSpecified = diffOption.IsSpecified;
-
- if (pmiOption.IsSpecified)
+ _baseSpecified = IsSpecified(command.BasePath);
+ if (_baseSpecified)
+ {
+ _basePath = Get(command.BasePath);
+ }
+
+ _diffSpecified = IsSpecified(command.DiffPath);
+ if (_diffSpecified)
+ {
+ _diffPath = Get(command.DiffPath);
+ }
+
+ if (IsSpecified(command.CrossgenExe)) _crossgenExe = Get(command.CrossgenExe);
+ if (IsSpecified(command.OutputPath)) _outputPath = Get(command.OutputPath);
+ if (IsSpecified(command.NoAnalyze)) _noanalyze = Get(command.NoAnalyze);
+ if (IsSpecified(command.Sequential)) _sequential = Get(command.Sequential);
+ if (IsSpecified(command.Tag)) _tag = Get(command.Tag);
+ if (IsSpecified(command.CoreLib)) _corelib = Get(command.CoreLib);
+ if (IsSpecified(command.Frameworks)) _frameworks = Get(command.Frameworks);
+ if (IsSpecified(command.Metric)) _metric = Get(command.Metric);
+ if (IsSpecified(command.Benchmarks)) _benchmarks = Get(command.Benchmarks);
+ if (IsSpecified(command.Tests)) _tests = Get(command.Tests);
+ if (IsSpecified(command.GCInfo)) _gcinfo = Get(command.GCInfo);
+ if (IsSpecified(command.DebugInfo)) _debuginfo = Get(command.DebugInfo);
+ if (IsSpecified(command.Verbose)) _verbose = Get(command.Verbose);
+ if (IsSpecified(command.NoDiffable)) _noDiffable = Get(command.NoDiffable);
+ if (IsSpecified(command.CoreRoot)) _platformPath = Get(command.CoreRoot);
+ if (IsSpecified(command.TestRoot)) _testPath = Get(command.TestRoot);
+ if (IsSpecified(command.BaseRoot)) _baseRoot = Get(command.BaseRoot);
+ if (IsSpecified(command.DiffRoot)) _diffRoot = Get(command.DiffRoot);
+ if (IsSpecified(command.Arch)) _arch = Get(command.Arch);
+ if (IsSpecified(command.Build)) _build = Get(command.Build);
+ if (IsSpecified(command.AltJit)) _altjit = Get(command.AltJit);
+ if (IsSpecified(command.Pmi)) _pmi = Get(command.Pmi);
+ if (IsSpecified(command.Cctors)) _cctors = Get(command.Cctors);
+ if (IsSpecified(command.AssemblyList)) _assemblyList = Get(command.AssemblyList);
+ if (IsSpecified(command.Tsv)) _tsv = Get(command.Tsv);
+ if (IsSpecified(command.Tier0)) _tier0 = Get(command.Tier0);
+ if (IsSpecified(command.Count)) _count = Get(command.Count);
+
+ if (_pmi)
{
_command = Commands.PmiDiff;
}
- });
+ }
+ else if (_command == Commands.List)
+ {
+ if (IsSpecified(command.Verbose)) _verbose = Get(command.Verbose);
+ }
+ else if (_command == Commands.Install)
+ {
+ if (IsSpecified(command.JobName)) _jobName = Get(command.JobName);
+ if (IsSpecified(command.Number)) _number = Get(command.Number);
+ if (IsSpecified(command.LastSuccessful)) _lastSuccessful = Get(command.LastSuccessful);
+ if (IsSpecified(command.BranchName)) _branchName = Get(command.BranchName);
+ if (IsSpecified(command.Verbose)) _verbose = Get(command.Verbose);
+ }
+ else if (_command == Commands.Uninstall)
+ {
+ if (IsSpecified(command.Tag)) _tag = Get(command.Tag);
+ }
SetRID();
@@ -776,7 +779,8 @@ private void Validate()
private void DisplayUsageMessage()
{
Console.Error.WriteLine("");
- Console.Error.Write(_syntaxResult.GetHelpText(100));
+ Console.Error.WriteLine("Usage: jit-diff [options]");
+ Console.Error.WriteLine("Run 'jit-diff --help' for command-specific options.");
if (_command == Commands.Diff)
{
@@ -1348,36 +1352,8 @@ public int ListCommand()
public static int Main(string[] args)
{
- Config config = new Config(args);
- int ret = 0;
-
- switch (config.DoCommand)
- {
- case Commands.Diff:
- case Commands.PmiDiff:
- {
- ret = DiffTool.DiffCommand(config);
- }
- break;
- case Commands.List:
- {
- // List command: list loaded configuration
- ret = config.ListCommand();
- }
- break;
- case Commands.Install:
- {
- ret = InstallCommand(config);
- }
- break;
- case Commands.Uninstall:
- {
- ret = UninstallCommand(config);
- }
- break;
- }
-
- return ret;
+ var command = new JitDiffRootCommand(args).UseVersion();
+ return command.Parse(args).Invoke();
}
}
}
diff --git a/src/jit-diff/jit-diff.csproj b/src/jit-diff/jit-diff.csproj
index 7c7b258e..87773400 100644
--- a/src/jit-diff/jit-diff.csproj
+++ b/src/jit-diff/jit-diff.csproj
@@ -1,14 +1,11 @@
-
-
Exe
-
diff --git a/src/jit-format/JitFormatRootCommand.cs b/src/jit-format/JitFormatRootCommand.cs
new file mode 100644
index 00000000..2d3c4d3d
--- /dev/null
+++ b/src/jit-format/JitFormatRootCommand.cs
@@ -0,0 +1,65 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System.Collections.Generic;
+using System.CommandLine;
+using System.CommandLine.Parsing;
+
+namespace ManagedCodeGen
+{
+ internal sealed class JitFormatRootCommand : RootCommand
+ {
+ public Option Arch { get; } =
+ new("--arch", "-a") { Description = "The architecture of the build (options: arm64, x64, x86)" };
+ public Option OS { get; } =
+ new("--os", "-o") { Description = "The operating system of the build (options: windows, osx, linux, etc.)" };
+ public Option Build { get; } =
+ new("--build", "-b") { Description = "The build type of the build (options: Release, Checked, Debug)" };
+ public Option RuntimePath { get; } =
+ new("--runtime", "-r") { Description = "Full path to runtime directory" };
+ public Option CompileCommands { get; } =
+ new("--compile-commands") { Description = "Full path to compile_commands.json" };
+ public Option Verbose { get; } =
+ new("--verbose") { Description = "Enable verbose output." };
+ public Option Untidy { get; } =
+ new("--untidy") { Description = "Do not run clang-tidy" };
+ public Option NoFormat { get; } =
+ new("--noformat") { Description = "Do not run clang-format" };
+ public Option Cross { get; } =
+ new("--cross") { Description = "If on Linux, run the configure build as a cross build." };
+ public Option Fix { get; } =
+ new("--fix", "-f") { Description = "Fix formatting errors discovered by clang-format and clang-tidy." };
+ public Option IgnoreErrors { get; } =
+ new("--ignore-errors", "-i") { Description = "Ignore clang-tidy errors" };
+ public Option> Projects { get; } =
+ new("--projects") { Description = "List of build projects clang-tidy should consider (e.g. dll, standalone, protojit, etc.). Default: dll" };
+ public Argument> Filenames { get; } =
+ new("filenames") { Description = "Optional list of files that should be formatted." };
+
+ public ParseResult Result { get; private set; }
+
+ public JitFormatRootCommand(string[] args) : base("JIT formatting tool")
+ {
+ Options.Add(Arch);
+ Options.Add(OS);
+ Options.Add(Build);
+ Options.Add(RuntimePath);
+ Options.Add(CompileCommands);
+ Options.Add(Verbose);
+ Options.Add(Untidy);
+ Options.Add(NoFormat);
+ Options.Add(Cross);
+ Options.Add(Fix);
+ Options.Add(IgnoreErrors);
+ Options.Add(Projects);
+ Arguments.Add(Filenames);
+
+ SetAction(result =>
+ {
+ Result = result;
+ return jitformat.Execute(this);
+ });
+ }
+ }
+}
diff --git a/src/jit-format/jit-format.cs b/src/jit-format/jit-format.cs
index 104017e8..4d7ca752 100644
--- a/src/jit-format/jit-format.cs
+++ b/src/jit-format/jit-format.cs
@@ -10,6 +10,7 @@
using System;
using System.Collections.Generic;
using System.CommandLine;
+using System.CommandLine.Parsing;
using System.Diagnostics;
using System.IO;
using System.Linq;
@@ -30,7 +31,6 @@ public class Config
private static string s_configFileName = "config.json";
private static string s_configFileRootKey = "format";
- private ArgumentSyntax _syntaxResult;
private string _arch = null;
private string _os = null;
private string _build = null;
@@ -51,27 +51,29 @@ public class Config
private JsonObject _jObj;
private string _jitUtilsRoot = null;
- public Config(string[] args)
+ internal Config(JitFormatRootCommand command)
{
LoadFileConfig();
- _syntaxResult = ArgumentSyntax.Parse(args, syntax =>
- {
- syntax.DefineOption("a|arch", ref _arch, "The architecture of the build (options: arm64, x64, x86)");
- syntax.DefineOption("o|os", ref _os, "The operating system of the build (options: windows, osx, linux, etc.)");
- syntax.DefineOption("b|build", ref _build, "The build type of the build (options: Release, Checked, Debug)");
- syntax.DefineOption("r|runtime", ref _runtimePath, "Full path to runtime directory");
- syntax.DefineOption("compile-commands", ref _compileCommands, "Full path to compile_commands.json");
- syntax.DefineOption("v|verbose", ref _verbose, "Enable verbose output.");
- syntax.DefineOption("untidy", ref _untidy, "Do not run clang-tidy");
- syntax.DefineOption("noformat", ref _noformat, "Do not run clang-format");
- syntax.DefineOption("cross", ref _cross, "If on Linux, run the configure build as a cross build.");
- syntax.DefineOption("f|fix", ref _fix, "Fix formatting errors discovered by clang-format and clang-tidy.");
- syntax.DefineOption("i|ignore-errors", ref _ignoreErrors, "Ignore clang-tidy errors");
- syntax.DefineOptionList("projects", ref _projects, "List of build projects clang-tidy should consider (e.g. dll, standalone, protojit, etc.). Default: dll");
-
- syntax.DefineParameterList("filenames", ref _filenames, "Optional list of files that should be formatted.");
- });
+ ParseResult result = command.Result;
+
+ bool IsSpecified(Option option) => result.GetResult(option) != null;
+ T Get(Option option) => result.GetValue(option);
+ List GetArgument(Argument> arg) => result.GetValue(arg);
+
+ if (IsSpecified(command.Arch)) _arch = Get(command.Arch);
+ if (IsSpecified(command.OS)) _os = Get(command.OS);
+ if (IsSpecified(command.Build)) _build = Get(command.Build);
+ if (IsSpecified(command.RuntimePath)) _runtimePath = Get(command.RuntimePath);
+ if (IsSpecified(command.CompileCommands)) _compileCommands = Get(command.CompileCommands);
+ if (IsSpecified(command.Verbose)) _verbose = Get(command.Verbose);
+ if (IsSpecified(command.Untidy)) _untidy = Get(command.Untidy);
+ if (IsSpecified(command.NoFormat)) _noformat = Get(command.NoFormat);
+ if (IsSpecified(command.Cross)) _cross = Get(command.Cross);
+ if (IsSpecified(command.Fix)) _fix = Get(command.Fix);
+ if (IsSpecified(command.IgnoreErrors)) _ignoreErrors = Get(command.IgnoreErrors);
+ if (IsSpecified(command.Projects)) _projects = Get(command.Projects);
+ _filenames = GetArgument(command.Filenames);
// Run validation code on parsed input to ensure we have a sensible scenario.
@@ -241,7 +243,7 @@ private void validate()
if (!_untidy && ((_arch == null) || (_os == null) || (_build == null)))
{
- _syntaxResult.ReportError("Specify --arch, --os, and --build for clang-tidy run.");
+ throw new Exception("Specify --arch, --os, and --build for clang-tidy run.");
}
if (_runtimePath == null)
@@ -253,7 +255,7 @@ private void validate()
_runtimePath = Utility.GetRepoRoot(_verbose);
if (_runtimePath == null)
{
- _syntaxResult.ReportError("Specify --runtime");
+ throw new Exception("Specify --runtime");
}
else
{
@@ -265,12 +267,12 @@ private void validate()
if (!Directory.Exists(_coreclrPath))
{
// If _coreclrPath doesn't exist, it is an invalid path
- _syntaxResult.ReportError("Invalid path to runtime directory. Specify with --runtime");
+ throw new Exception("Invalid path to runtime directory. Specify with --runtime");
}
else if (!File.Exists(Path.Combine(_coreclrPath, "build-runtime.cmd")) || !File.Exists(Path.Combine(_coreclrPath, "build-runtime.sh")) || !File.Exists(Path.Combine(_coreclrPath, "clr.featuredefines.props")))
{
// Doesn't look like the coreclr directory.
- _syntaxResult.ReportError("Invalid path to coreclr directory. Specify with --runtime");
+ throw new Exception("Invalid path to coreclr directory. Specify with --runtime");
}
// Check that we can find compile_commands.json on windows
@@ -491,10 +493,10 @@ public CompileCommand(string dir, string cmd, string filename)
}
}
- public static int Main(string[] args)
+ internal static int Execute(JitFormatRootCommand command)
{
// Parse and store comand line options.
- var config = new Config(args);
+ var config = new Config(command);
int returncode = 0;
bool verbose = config.DoVerboseOutput;
@@ -625,6 +627,12 @@ public static int Main(string[] args)
return returncode;
}
+ public static int Main(string[] args)
+ {
+ var command = new JitFormatRootCommand(args).UseVersion();
+ return command.Parse(args).Invoke();
+ }
+
// This method reads in a compile_command.json file, and writes a new json file with only the entries
// commands for files found in the project specified. For example, if project is dll, it will write a
// new compile_commands file (called compile_commands_dll.json) with only the entries whose directory
diff --git a/src/jit-format/jit-format.csproj b/src/jit-format/jit-format.csproj
index 7c7b258e..87773400 100644
--- a/src/jit-format/jit-format.csproj
+++ b/src/jit-format/jit-format.csproj
@@ -1,14 +1,11 @@
-
-
Exe
-
diff --git a/src/jit-include.props b/src/jit-include.props
deleted file mode 100644
index e4a0fd5d..00000000
--- a/src/jit-include.props
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/jit-rl-cse/MLCSE.csproj b/src/jit-rl-cse/MLCSE.csproj
index c5357bb9..65779695 100644
--- a/src/jit-rl-cse/MLCSE.csproj
+++ b/src/jit-rl-cse/MLCSE.csproj
@@ -1,8 +1,5 @@
-
-
-
Exe
enable
diff --git a/src/jit-tp-analyze/Program.cs b/src/jit-tp-analyze/Program.cs
index ae9acac5..2fdc5fae 100644
--- a/src/jit-tp-analyze/Program.cs
+++ b/src/jit-tp-analyze/Program.cs
@@ -124,8 +124,11 @@ private static double GetPercentageDiff(double baseValue, double diffValue) =>
private static string FormatPercentageDiff(double value, string precision = "00") =>
(value > 0 ? "+" : "") + value.ToString($"0.{precision}") + "%";
- private static void Main(string[] args) =>
- new CommandLineConfiguration(new JitTpAnalyzeRootCommand().UseVersion()).Invoke(args);
+ private static void Main(string[] args)
+ {
+ var command = new JitTpAnalyzeRootCommand().UseVersion();
+ command.Parse(args).Invoke();
+ }
private struct FunctionDiff
{
diff --git a/src/jit-tp-analyze/jit-tp-analyze.csproj b/src/jit-tp-analyze/jit-tp-analyze.csproj
index fe8dbbe8..6a70a1ab 100644
--- a/src/jit-tp-analyze/jit-tp-analyze.csproj
+++ b/src/jit-tp-analyze/jit-tp-analyze.csproj
@@ -1,8 +1,5 @@
-
-
-
Exe
diff --git a/src/mutate-test/MutateTestRootCommand.cs b/src/mutate-test/MutateTestRootCommand.cs
index e6ed26b5..bb14301c 100644
--- a/src/mutate-test/MutateTestRootCommand.cs
+++ b/src/mutate-test/MutateTestRootCommand.cs
@@ -7,35 +7,35 @@
namespace MutateTest
{
- internal sealed class MutateTestRootCommand : CliRootCommand
+ internal sealed class MutateTestRootCommand : RootCommand
{
- public CliArgument InputFilePath { get; } =
- new("input-test-case") { Description = "Input test case file or directory (for --recursive)", Arity = ArgumentArity.OneOrMore };
- public CliOption EHStress { get; } =
+ public Argument InputFilePath { get; } =
+ new("input-test-case") { Description = "Input test case file or directory (for --recursive)", Arity = ArgumentArity.ExactlyOne };
+ public Option EHStress { get; } =
new("--ehStress") { Description = "Add EH to methods" };
- public CliOption StructStress { get; } =
+ public Option StructStress { get; } =
new("--structStress") { Description = "Replace locals with structs" };
- public CliOption ShowResults { get; } =
+ public Option ShowResults { get; } =
new("--showResults") { Description = "Add EH to methods" };
- public CliOption Verbose { get; } =
+ public Option Verbose { get; } =
new("--verbose") { Description = "Describe each transformation" };
- public CliOption Quiet { get; } =
+ public Option Quiet { get; } =
new("--quiet") { Description = "Produce minimal output" };
- public CliOption Recursive { get; } =
+ public Option Recursive { get; } =
new("--recursive") { Description = "Process each file recursively" };
- public CliOption Seed { get; } =
+ public Option Seed { get; } =
new("--seed") { DefaultValueFactory = _ => 42, Description = "Random seed" };
- public CliOption StopAtFirstFailure { get; } =
+ public Option StopAtFirstFailure { get; } =
new("--stopAtFirstFailure") { Description = "Stop each test at first failure" };
- public CliOption EmptyBlocks { get; } =
+ public Option EmptyBlocks { get; } =
new("--emptyBlocks") { Description = "Transform empty blocks" };
- public CliOption SizeLimit { get; } =
+ public Option SizeLimit { get; } =
new("--sizeLimit") { DefaultValueFactory = _ => 10000, Description = "Don't process programs larger than this size" };
- public CliOption TimeLimit { get; } =
+ public Option TimeLimit { get; } =
new("--timeLimit") { DefaultValueFactory = _ => 10000, Description = "Don't stress programs where compile + run takes more than this many milliseconds" };
- public CliOption Projects { get; } =
+ public Option Projects { get; } =
new("--projects") { Description = "Look for .csproj files instead of .cs files when doing recursive exploration" };
- public CliOption OnlyFailures { get; } =
+ public Option OnlyFailures { get; } =
new("--onlyFailures") { Description = "Only emit output for cases that fail at runtime" };
public ParseResult Result { get; private set; }
diff --git a/src/mutate-test/Program.cs b/src/mutate-test/Program.cs
index 212a8ba1..6006e466 100644
--- a/src/mutate-test/Program.cs
+++ b/src/mutate-test/Program.cs
@@ -232,13 +232,13 @@ public Program(MutateTestRootCommand command)
private static bool isFirstRun = true;
- private T Get(CliOption option) => _command.Result.GetValue(option);
+ private T Get(Option option) => _command.Result.GetValue(option);
- private static int Main(string[] args) =>
- new CliConfiguration(new MutateTestRootCommand(args).UseVersion())
- {
- EnableParseErrorReporting = true
- }.Invoke(args);
+ private static int Main(string[] args)
+ {
+ var command = new MutateTestRootCommand(args).UseVersion();
+ return command.Parse(args).Invoke();
+ }
public int Run()
{
diff --git a/src/mutate-test/mutate-test.csproj b/src/mutate-test/mutate-test.csproj
index bd600f3a..c09eb2da 100644
--- a/src/mutate-test/mutate-test.csproj
+++ b/src/mutate-test/mutate-test.csproj
@@ -1,10 +1,7 @@
-
-
Exe
- net6.0
Mutate
Mutate
diff --git a/src/performance-explorer/performance-explorer.csproj b/src/performance-explorer/performance-explorer.csproj
index 036eb0f1..87773400 100644
--- a/src/performance-explorer/performance-explorer.csproj
+++ b/src/performance-explorer/performance-explorer.csproj
@@ -1,8 +1,5 @@
-
-
-
Exe
diff --git a/src/pmi/pmi.csproj b/src/pmi/pmi.csproj
index 344ce4c0..89ff5527 100644
--- a/src/pmi/pmi.csproj
+++ b/src/pmi/pmi.csproj
@@ -4,8 +4,6 @@
Exe
-
-
diff --git a/src/superpmi/superpmicollect.csproj b/src/superpmi/superpmicollect.csproj
index 95fdbc0d..52e6553d 100644
--- a/src/superpmi/superpmicollect.csproj
+++ b/src/superpmi/superpmicollect.csproj
@@ -4,6 +4,4 @@
Exe
-
-
diff --git a/src/target-framework.props b/src/target-framework.props
deleted file mode 100644
index c5a6fefa..00000000
--- a/src/target-framework.props
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
-
-
- net8.0
-
-
-
diff --git a/src/wasm-spmi-filter/wasm-spmi-filter.csproj b/src/wasm-spmi-filter/wasm-spmi-filter.csproj
index 19d1338a..553d71b4 100644
--- a/src/wasm-spmi-filter/wasm-spmi-filter.csproj
+++ b/src/wasm-spmi-filter/wasm-spmi-filter.csproj
@@ -2,7 +2,6 @@
Exe
- net10.0
wasm_spmi_filter
enable
enable