From ca825411cce2e2ee873b60cb652e8910fc16ca0c Mon Sep 17 00:00:00 2001 From: Jan Kotas Date: Mon, 21 Mar 2022 15:36:51 -0700 Subject: [PATCH] Update to latest System.CommandLine package (#66929) --- eng/Version.Details.xml | 4 + eng/Versions.props | 3 +- src/coreclr/tools/ILVerify/Program.cs | 161 +++-- .../tools/r2rdump/CommandLineOptions.cs | 234 ++++++- src/coreclr/tools/r2rdump/R2RDump.cs | 79 +-- src/coreclr/tools/r2rtest/BuildOptions.cs | 44 +- .../tools/r2rtest/CommandLineOptions.cs | 617 ++++++++++-------- src/coreclr/tools/r2rtest/Program.cs | 21 - 8 files changed, 679 insertions(+), 484 deletions(-) delete mode 100644 src/coreclr/tools/r2rtest/Program.cs diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 8a6a8096ae592..5a8f02b8b08e8 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -48,6 +48,10 @@ https://github.com/dotnet/llvm-project f17917e8d6a2e3ba069cddeab873554706d502a5 + + https://github.com/dotnet/command-line-api + 021ec68a4cb510c2cc125c6ebb78b9cfd4e3847a + diff --git a/eng/Versions.props b/eng/Versions.props index 9006c1f20d539..d4c3214f4e06c 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -138,9 +138,8 @@ 1.0.0-prerelease.22121.2 16.9.0-beta1.21055.5 - 2.0.0-beta1.20253.1 + 2.0.0-beta3.22114.1 2.0.65 - 2.2.0 2.1.0 2.0.3 1.0.4-preview6.19326.1 diff --git a/src/coreclr/tools/ILVerify/Program.cs b/src/coreclr/tools/ILVerify/Program.cs index 44759eac3f399..851f9d9da8a06 100644 --- a/src/coreclr/tools/ILVerify/Program.cs +++ b/src/coreclr/tools/ILVerify/Program.cs @@ -4,7 +4,9 @@ using System; using System.Collections.Generic; using System.CommandLine; +using System.CommandLine.Builder; using System.CommandLine.Invocation; +using System.CommandLine.Parsing; using System.IO; using System.Linq; using System.Reflection; @@ -43,42 +45,6 @@ public static IReadOnlyList StringPatternsToRegexList(IReadOnlyList("input-file-path", "Input file(s)") { Arity = new ArgumentArity(1, Int32.MaxValue) }); - command.AddOption(new Option(new[] { "--reference", "-r" }, "Reference metadata from the specified assembly")); - command.AddOption(new Option(new[] { "--system-module", "-s" }, "System module name (default: mscorlib)")); - command.AddOption(new Option(new[] { "--sanity-checks", "-c" }, "Check for valid constructs that are likely mistakes")); - command.AddOption(new Option(new[] { "--include", "-i" }, "Use only methods/types/namespaces, which match the given regular expression(s)")); - command.AddOption(new Option(new[] { "--include-file" }, "Same as --include, but the regular expression(s) are declared line by line in the specified file.").ExistingOnly()); - command.AddOption(new Option(new[] { "--exclude", "-e" }, "Skip methods/types/namespaces, which match the given regular expression(s)")); - command.AddOption(new Option(new[] { "--exclude-file" }, "Same as --exclude, but the regular expression(s) are declared line by line in the specified file.").ExistingOnly()); - command.AddOption(new Option(new[] { "--ignore-error", "-g" }, "Ignore errors, which match the given regular expression(s)")); - command.AddOption(new Option(new[] { "--ignore-error-file" }, "Same as --ignore-error, but the regular expression(s) are declared line by line in the specified file.").ExistingOnly()); - command.AddOption(new Option(new[] { "--statistics" }, "Print verification statistics")); - command.AddOption(new Option(new[] { "--verbose", "-v" }, "Verbose output")); - command.AddOption(new Option(new[] { "--tokens", "-t" }, "Include metadata tokens in error messages")); - return command; - } - private Program(Options options) { _options = options; @@ -489,29 +455,118 @@ public PEReader Resolve(string simpleName) return null; } - private static int Run(Options options) + // + // Command line parsing + // + + private class ILVerifyRootCommand : RootCommand { - try - { - return new Program(options).Run(); - } - catch (CommandLineException e) - { - Console.WriteLine("Error: " + e.Message); - return 1; - } - catch (Exception e) + public Argument InputFilePath { get; } = + new("input-file-path", "Input file(s)") { Arity = ArgumentArity.OneOrMore }; + public Option Reference { get; } = + new(new[] { "--reference", "-r" }, "Reference metadata from the specified assembly"); + public Option SystemModule { get; } = + new(new[] { "--system-module", "-s" }, "System module name (default: mscorlib)"); + public Option SanityChecks { get; } = + new(new[] { "--sanity-checks", "-c" }, "Check for valid constructs that are likely mistakes"); + public Option Include { get; } = + new(new[] { "--include", "-i" }, "Use only methods/types/namespaces, which match the given regular expression(s)"); + public Option IncludeFile { get; } = + new Option(new[] { "--include-file" }, "Same as --include, but the regular expression(s) are declared line by line in the specified file.").ExistingOnly(); + public Option Exclude { get; } = + new(new[] { "--exclude", "-e" }, "Skip methods/types/namespaces, which match the given regular expression(s)"); + public Option ExcludeFile { get; } = + new Option(new[] { "--exclude-file" }, "Same as --exclude, but the regular expression(s) are declared line by line in the specified file.").ExistingOnly(); + public Option IgnoreError { get; } = + new(new[] { "--ignore-error", "-g" }, "Ignore errors, which match the given regular expression(s)"); + public Option IgnoreErrorFile { get; } = + new Option(new[] { "--ignore-error-file" }, "Same as --ignore-error, but the regular expression(s) are declared line by line in the specified file.").ExistingOnly(); + public Option Statistics { get; } = + new(new[] { "--statistics" }, "Print verification statistics"); + public Option Verbose { get; } = + new(new[] { "--verbose", "-v" }, "Verbose output"); + public Option Tokens { get; } = + new(new[] { "--tokens", "-t" }, "Include metadata tokens in error messages"); + + public ILVerifyRootCommand() + : base("Tool for verifying MSIL code based on ECMA-335.") { - Console.WriteLine("Error: " + e.ToString()); - return 1; + AddArgument(InputFilePath); + AddOption(Reference); + AddOption(SystemModule); + AddOption(SanityChecks); + AddOption(Include); + AddOption(IncludeFile); + AddOption(Exclude); + AddOption(ExcludeFile); + AddOption(IgnoreError); + AddOption(IgnoreErrorFile); + AddOption(Statistics); + AddOption(Verbose); + AddOption(Tokens); + + this.SetHandler((InvocationContext context) => + { + try + { + context.ExitCode = new Program(new Options(this, context.ParseResult)).Run(); + } + catch (Exception e) + { + Console.ResetColor(); + Console.ForegroundColor = ConsoleColor.Red; + + // Omit the stacktrace from the error (different from the default System.CommandLine exception handler) + Console.Error.WriteLine("Error: " + e.Message); + + Console.ResetColor(); + + context.ExitCode = 1; + } + }); } } - private static async Task Main(string[] args) + private class Options { - var command = RootCommand(); - command.Handler = CommandHandler.Create(Run); - return await command.InvokeAsync(args); + public Options(ILVerifyRootCommand cmd, ParseResult res) + { + InputFilePath = res.GetValueForArgument(cmd.InputFilePath); + Reference = res.GetValueForOption(cmd.Reference); + SystemModule = res.GetValueForOption(cmd.SystemModule); + SanityChecks = res.GetValueForOption(cmd.SanityChecks); + Include = res.GetValueForOption(cmd.Include); + IncludeFile = res.GetValueForOption(cmd.IncludeFile); + Exclude = res.GetValueForOption(cmd.Exclude); + ExcludeFile = res.GetValueForOption(cmd.ExcludeFile); + IgnoreError = res.GetValueForOption(cmd.IgnoreError); + IgnoreErrorFile = res.GetValueForOption(cmd.IgnoreErrorFile); + Statistics = res.GetValueForOption(cmd.Statistics); + Verbose = res.GetValueForOption(cmd.Verbose); + Tokens = res.GetValueForOption(cmd.Tokens); + } + + public string[] InputFilePath { get; } + public string[] Reference { get; } + public string SystemModule { get; } + public bool SanityChecks { get; } + public string[] Include { get; } + public FileInfo IncludeFile { get; } + public string[] Exclude { get; } + public FileInfo ExcludeFile { get; } + public string[] IgnoreError { get; } + public FileInfo IgnoreErrorFile { get; } + public bool Statistics { get; } + public bool Verbose { get; } + public bool Tokens { get; } } + + private static int Main(string[] args) => + new CommandLineBuilder(new ILVerifyRootCommand()) + .UseVersionOption() + .UseHelp() + .UseParseErrorReporting() + .Build() + .Invoke(args); } } diff --git a/src/coreclr/tools/r2rdump/CommandLineOptions.cs b/src/coreclr/tools/r2rdump/CommandLineOptions.cs index 9a1296bdbd65d..f0b6f71a58ed4 100644 --- a/src/coreclr/tools/r2rdump/CommandLineOptions.cs +++ b/src/coreclr/tools/r2rdump/CommandLineOptions.cs @@ -2,46 +2,212 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.CommandLine; +using System.CommandLine.Invocation; +using System.CommandLine.Parsing; using System.IO; namespace R2RDump { - internal static class CommandLineOptions + public class R2RDumpRootCommand : RootCommand { - public static RootCommand RootCommand() + public Option In { get; } = + new(new[] { "--in", "-i" }, "Input file(s) to dump. Expects them to by ReadyToRun images"); + public Option Out { get; } = + new(new[] { "--out", "-o" }, "Output file path. Dumps everything to the specified file except for help message and exception messages"); + public Option Raw { get; } = + new(new[] { "--raw" }, "Dump the raw bytes of each section or runtime function"); + public Option Header { get; } = + new(new[] { "--header" }, "Dump R2R header"); + public Option Disasm { get; } = + new(new[] { "--disasm", "-d" }, "Show disassembly of methods or runtime functions"); + public Option Naked { get; } = + new(new[] { "--naked" }, "Naked dump suppresses most compilation details like placement addresses"); + public Option HideOffsets { get; } = + new(new[] { "--hide-offsets", "--ho" }, "Hide offsets in naked disassembly"); + + public Option Query { get; } = + new(new[] { "--query", "-q" }, "Query method by exact name, signature, row ID or token"); + public Option Keyword { get; } = + new(new[] { "--keyword", "-k" }, "Search method by keyword"); + public Option RuntimeFunction { get; } = + new(new[] { "--runtimefunction", "-f" }, "Get one runtime function by id or relative virtual address"); + public Option Section { get; } = + new(new[] { "--section", "-s" }, "Get section by keyword"); + + public Option Unwind { get; } = + new(new[] { "--unwind" }, "Dump unwindInfo"); + public Option GC { get; } = + new(new[] { "--gc" }, "Dump gcInfo and slot table"); + public Option Pgo { get; } = + new(new[] { "--pgo" }, "Dump embedded pgo instrumentation data"); + public Option SectionContents { get; } = + new(new[] { "--sectionContents", "--sc" }, "Dump section contents"); + public Option EntryPoints { get; } = + new(new[] { "--entrypoints", "-e" }, "Dump list of method / instance entrypoints in the R2R file"); + public Option Normalize { get; } = + new(new[] { "--normalize", "-n" }, "Normalize dump by sorting the various tables and methods (default = unsorted i.e. file order)"); + public Option HideTransitions { get; } = + new(new[] { "--hide-transitions", "--ht" }, "Don't include GC transitions in disassembly output"); + public Option Verbose { get; } = + new(new[] { "--verbose", "-v" }, "Dump disassembly, unwindInfo, gcInfo and sectionContents"); + public Option Diff { get; } = + new(new[] { "--diff" }, "Compare two R2R images"); + public Option DiffHideSameDisasm { get; } = + new(new[] { "--diff-hide-same-disasm" }, "In matching method diff dump, hide functions with identical disassembly"); + + public Option CreatePDB { get; } = + new(new[] { "--create-pdb" }, "Create PDB"); + public Option PdbPath { get; } = + new(new[] { "--pdb-path" }, "PDB output path for --create-pdb"); + + public Option CreatePerfmap { get; } = + new(new[] { "--create-perfmap" }, "Create PerfMap"); + public Option PerfmapPath { get; } = + new(new[] { "--perfmap-path" }, "PerfMap output path for --create-perfmap"); + public Option PerfmapFormatVersion { get; } = + new(new[] { "--perfmap-format-version" }, () => ILCompiler.Diagnostics.PerfMapWriter.CurrentFormatVersion, "PerfMap format version for --create-perfmap"); + + public Option Reference { get; } = + new(new[] { "--reference", "-r" }, "Explicit reference assembly files"); + public Option ReferencePath { get; } = + new(new[] { "--referencePath", "--rp" }, "Search paths for reference assemblies"); + + public Option SignatureBinary { get; } = + new(new[] { "--signatureBinary", "--sb" }, "Append signature binary to its textual representation"); + public Option InlineSignatureBinary { get; } = + new(new[] { "--inlineSignatureBinary", "--isb" }, "Embed binary signature into its textual representation"); + + public R2RDumpRootCommand() + : base("Parses and outputs the contents of a ReadyToRun image") { - RootCommand command = new RootCommand(); - command.AddOption(new Option(new[] { "--in", "-i" }, "Input file(s) to dump. Expects them to by ReadyToRun images")); - command.AddOption(new Option(new[] { "--out", "-o" }, "Output file path. Dumps everything to the specified file except for help message and exception messages")); - command.AddOption(new Option(new[] { "--raw" }, "Dump the raw bytes of each section or runtime function")); - command.AddOption(new Option(new[] { "--header" }, "Dump R2R header")); - command.AddOption(new Option(new[] { "--disasm", "-d" }, "Show disassembly of methods or runtime functions")); - command.AddOption(new Option(new[] { "--naked" }, "Naked dump suppresses most compilation details like placement addresses")); - command.AddOption(new Option(new[] { "--hide-offsets", "--ho" }, "Hide offsets in naked disassembly")); - command.AddOption(new Option(new[] { "--query", "-q" }, "Query method by exact name, signature, row ID or token")); - command.AddOption(new Option(new[] { "--keyword", "-k" }, "Search method by keyword")); - command.AddOption(new Option(new[] { "--runtimefunction", "-f" }, "Get one runtime function by id or relative virtual address")); - command.AddOption(new Option(new[] { "--section", "-s" }, "Get section by keyword")); - command.AddOption(new Option(new[] { "--unwind" }, "Dump unwindInfo")); - command.AddOption(new Option(new[] { "--gc" }, "Dump gcInfo and slot table")); - command.AddOption(new Option(new[] { "--pgo" }, "Dump embedded pgo instrumentation data")); - command.AddOption(new Option(new[] { "--sectionContents", "--sc" }, "Dump section contents")); - command.AddOption(new Option(new[] { "--entrypoints", "-e" }, "Dump list of method / instance entrypoints in the R2R file")); - command.AddOption(new Option(new[] { "--normalize", "-n" }, "Normalize dump by sorting the various tables and methods (default = unsorted i.e. file order)")); - command.AddOption(new Option(new[] { "--hide-transitions", "--ht" }, "Don't include GC transitions in disassembly output")); - command.AddOption(new Option(new[] { "--verbose", "-v" }, "Dump disassembly, unwindInfo, gcInfo and sectionContents")); - command.AddOption(new Option(new[] { "--diff" }, "Compare two R2R images")); - command.AddOption(new Option(new[] { "--diff-hide-same-disasm" }, "In matching method diff dump, hide functions with identical disassembly")); - command.AddOption(new Option(new[] { "--reference", "-r" }, "Explicit reference assembly files")); - command.AddOption(new Option(new[] { "--referencePath", "--rp" }, "Search paths for reference assemblies")); - command.AddOption(new Option(new[] { "--inlineSignatureBinary", "--isb" }, "Embed binary signature into its textual representation")); - command.AddOption(new Option(new[] { "--signatureBinary", "--sb" }, "Append signature binary to its textual representation")); - command.AddOption(new Option(new[] { "--create-pdb" }, "Create PDB")); - command.AddOption(new Option(new[] { "--pdb-path" }, "PDB output path for --create-pdb")); - command.AddOption(new Option(new[] { "--create-perfmap" }, "Create PerfMap")); - command.AddOption(new Option(new[] { "--perfmap-path" }, "PerfMap output path for --create-perfmap")); - command.AddOption(new Option(new[] { "--perfmap-format-version" }, "PerfMap format version for --create-perfmap")); - return command; + AddOption(In); + AddOption(Out); + AddOption(Raw); + AddOption(Header); + AddOption(Disasm); + AddOption(Naked); + AddOption(HideOffsets); + + AddOption(Query); + AddOption(Keyword); + AddOption(RuntimeFunction); + AddOption(Section); + + AddOption(Unwind); + AddOption(GC); + AddOption(Pgo); + AddOption(SectionContents); + AddOption(EntryPoints); + AddOption(Normalize); + AddOption(HideTransitions); + AddOption(Verbose); + AddOption(Diff); + AddOption(DiffHideSameDisasm); + + AddOption(CreatePDB); + AddOption(PdbPath); + + AddOption(CreatePerfmap); + AddOption(PerfmapPath); + AddOption(PerfmapFormatVersion); + + AddOption(Reference); + AddOption(ReferencePath); + + AddOption(SignatureBinary); + AddOption(InlineSignatureBinary); + + this.SetHandler((InvocationContext context) => + context.ExitCode = new R2RDump(new DumpOptions(this, context.ParseResult)).Run()); + } + } + + public partial class DumpOptions + { + public FileInfo[] In { get; } + public FileInfo Out { get; } + public bool Raw { get; } + public bool Header { get; } + public bool Disasm { get; } + public bool Naked { get; } + public bool HideOffsets { get; } + + public string[] Query { get; } + public string[] Keyword { get; } + public string[] RuntimeFunction { get; } + public string[] Section { get; } + + public bool Unwind { get; } + public bool GC { get; } + public bool Pgo { get; } + public bool SectionContents { get; } + public bool EntryPoints { get; } + public bool Normalize { get; } + public bool HideTransitions { get; } + public bool Verbose { get; } + public bool Diff { get; } + public bool DiffHideSameDisasm { get; } + + public bool CreatePDB { get; } + public string PdbPath { get; } + + public bool CreatePerfmap { get; } + public string PerfmapPath { get; } + public int PerfmapFormatVersion { get; } + + public FileInfo[] Reference { get; } + public DirectoryInfo[] ReferencePath { get; } + + public bool SignatureBinary { get; } + public bool InlineSignatureBinary { get; } + + public DumpOptions(R2RDumpRootCommand cmd, ParseResult res) + { + In = res.GetValueForOption(cmd.In); + Out = res.GetValueForOption(cmd.Out); + Raw = res.GetValueForOption(cmd.Raw); + Header = res.GetValueForOption(cmd.Header); + Disasm = res.GetValueForOption(cmd.Disasm); + Naked = res.GetValueForOption(cmd.Naked); + HideOffsets = res.GetValueForOption(cmd.HideOffsets); + + Query = res.GetValueForOption(cmd.Query); + Keyword = res.GetValueForOption(cmd.Keyword); + RuntimeFunction = res.GetValueForOption(cmd.RuntimeFunction); + Section = res.GetValueForOption(cmd.Section); + + Unwind = res.GetValueForOption(cmd.Unwind); + GC = res.GetValueForOption(cmd.GC); + Pgo = res.GetValueForOption(cmd.Pgo); + SectionContents = res.GetValueForOption(cmd.SectionContents); + EntryPoints = res.GetValueForOption(cmd.EntryPoints); + Normalize = res.GetValueForOption(cmd.Normalize); + HideTransitions = res.GetValueForOption(cmd.HideTransitions); + Verbose = res.GetValueForOption(cmd.Verbose); + Diff = res.GetValueForOption(cmd.Diff); + DiffHideSameDisasm = res.GetValueForOption(cmd.DiffHideSameDisasm); + + CreatePDB = res.GetValueForOption(cmd.CreatePDB); + PdbPath = res.GetValueForOption(cmd.PdbPath); + + CreatePerfmap = res.GetValueForOption(cmd.CreatePerfmap); + PerfmapPath = res.GetValueForOption(cmd.PerfmapPath); + PerfmapFormatVersion = res.GetValueForOption(cmd.PerfmapFormatVersion); + + Reference = res.GetValueForOption(cmd.Reference); + ReferencePath = res.GetValueForOption(cmd.ReferencePath); + + SignatureBinary = res.GetValueForOption(cmd.SignatureBinary); + InlineSignatureBinary = res.GetValueForOption(cmd.InlineSignatureBinary); + + if (Verbose) + { + Disasm = true; + Unwind = true; + GC = true; + Pgo = true; + SectionContents = true; + } } } } diff --git a/src/coreclr/tools/r2rdump/R2RDump.cs b/src/coreclr/tools/r2rdump/R2RDump.cs index 6b7d192da59a6..3a8e7f99f46f5 100644 --- a/src/coreclr/tools/r2rdump/R2RDump.cs +++ b/src/coreclr/tools/r2rdump/R2RDump.cs @@ -5,7 +5,9 @@ using System.Collections.Generic; using System.Collections.Immutable; using System.CommandLine; +using System.CommandLine.Builder; using System.CommandLine.Invocation; +using System.CommandLine.Parsing; using System.IO; using System.Linq; using System.Reflection.Metadata; @@ -26,54 +28,10 @@ namespace R2RDump { - public class DumpOptions : IAssemblyResolver + public partial class DumpOptions : IAssemblyResolver { - public FileInfo[] In { get; set; } - public FileInfo Out { get; set; } - public bool Raw { get; set; } - public bool Header { get; set; } - public bool Disasm { get; set; } - public bool Naked { get; set; } - public bool HideOffsets { get; set; } - - public string[] Query { get; set; } - public string[] Keyword { get; set; } - public string[] RuntimeFunction { get; set; } - public string[] Section { get; set; } - - public bool Unwind { get; set; } - public bool GC { get; set; } - public bool Pgo { get; set; } - public bool SectionContents { get; set; } - public bool EntryPoints { get; set; } - public bool Normalize { get; set; } - public bool HideTransitions { get; set; } - public bool Verbose { get; set; } - public bool Diff { get; set; } - public bool DiffHideSameDisasm { get; set; } - public bool IgnoreSensitive { get; set; } - - public bool CreatePDB { get; set; } - public string PdbPath { get; set; } - - public bool CreatePerfmap { get; set; } - public string PerfmapPath { get; set; } - public int PerfmapFormatVersion { get; set; } - - - public FileInfo[] Reference { get; set; } - public DirectoryInfo[] ReferencePath { get; set; } - - public bool SignatureBinary { get; set; } - public bool InlineSignatureBinary { get; set; } - private SignatureFormattingOptions signatureFormattingOptions; - public DumpOptions() - { - PerfmapFormatVersion = PerfMapWriter.CurrentFormatVersion; - } - /// /// Probing extensions to use when looking up assemblies under reference paths. /// @@ -232,7 +190,7 @@ public IEnumerable NormalizedMethods() public Disassembler Disassembler => _disassembler; } - class R2RDump + public class R2RDump { private readonly DumpOptions _options; private readonly Dictionary _selectedSections = new Dictionary(); @@ -240,20 +198,11 @@ class R2RDump private readonly TextWriter _writer; private Dumper _dumper; - private R2RDump(DumpOptions options) + public R2RDump(DumpOptions options) { _options = options; _encoding = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false, throwOnInvalidBytes: false); - if (_options.Verbose) - { - _options.Disasm = true; - _options.Unwind = true; - _options.GC = true; - _options.Pgo = true; - _options.SectionContents = true; - } - if (_options.Out != null) { _writer = new StreamWriter(_options.Out.FullName, append: false, _encoding); @@ -606,7 +555,7 @@ public RuntimeFunction FindRuntimeFunction(ReadyToRunReader r2r, int rtfQuery) return null; } - private int Run() + public int Run() { Disassembler disassembler = null; @@ -678,11 +627,15 @@ private int Run() return 0; } - public static async Task Main(string[] args) - { - var command = CommandLineOptions.RootCommand(); - command.Handler = CommandHandler.Create((DumpOptions options) => new R2RDump(options).Run()); - return await command.InvokeAsync(args); - } + // + // Command line parsing + // + + public static int Main(string[] args) => + new CommandLineBuilder(new R2RDumpRootCommand()) + .UseHelp() + .UseParseErrorReporting() + .Build() + .Invoke(args); } } diff --git a/src/coreclr/tools/r2rtest/BuildOptions.cs b/src/coreclr/tools/r2rtest/BuildOptions.cs index 5c3dd68b20369..9c7deffe42e0d 100644 --- a/src/coreclr/tools/r2rtest/BuildOptions.cs +++ b/src/coreclr/tools/r2rtest/BuildOptions.cs @@ -8,50 +8,10 @@ namespace R2RTest { - public class BuildOptions + public partial class BuildOptions { - public DirectoryInfo InputDirectory { get; set; } - public DirectoryInfo OutputDirectory { get; set; } - public DirectoryInfo CoreRootDirectory { get; set; } - public FileInfo Crossgen2Path { get; set; } - public bool VerifyTypeAndFieldLayout { get; set; } - public string TargetArch { get; set; } - public bool Exe { get; set; } - public bool NoJit { get; set; } - public bool NoCrossgen2 { get; set; } - public bool NoExe { get; set; } - public bool NoEtw { get; set; } - public bool NoCleanup { get; set; } - public bool Map { get; set; } - public bool Pdb { get; set; } - - public bool Perfmap { get; set; } - public int PerfmapFormatVersion { get; set; } = 1; - public FileInfo PackageList { get; set; } - public int DegreeOfParallelism { get; set; } - public bool Sequential { get; set; } - public int Iterations { get; set; } = 1; - public bool Framework { get; set; } - public bool UseFramework { get; set; } - public bool Release { get; set; } - public bool LargeBubble { get; set; } - public bool Composite { get; set; } - public int Crossgen2Parallelism { get; set; } - public FileInfo Crossgen2JitPath { get; set; } - public int CompilationTimeoutMinutes { get; set; } - public int ExecutionTimeoutMinutes { get; set; } - public DirectoryInfo[] ReferencePath { get; set; } - public FileInfo[] IssuesPath { get; set; } - public FileInfo R2RDumpPath { get; set; } - public FileInfo CrossgenResponseFile { get; set; } - public DirectoryInfo[] RewriteOldPath { get; set; } - public DirectoryInfo[] RewriteNewPath { get; set; } - public DirectoryInfo AspNetPath { get; set; } - public bool MeasurePerf { get; set; } - public string InputFileSearchString { get; set; } public string ConfigurationSuffix => (Release ? "-ret.out" : "-chk.out"); - public string GCStress { get; set; } - public FileInfo[] MibcPath { get; set; } + public string DotNetCli { get diff --git a/src/coreclr/tools/r2rtest/CommandLineOptions.cs b/src/coreclr/tools/r2rtest/CommandLineOptions.cs index 404aa63428fc4..79865a164c534 100644 --- a/src/coreclr/tools/r2rtest/CommandLineOptions.cs +++ b/src/coreclr/tools/r2rtest/CommandLineOptions.cs @@ -5,316 +5,395 @@ using System.CommandLine; using System.CommandLine.Builder; using System.CommandLine.Invocation; +using System.CommandLine.Parsing; using System.IO; namespace R2RTest { - internal static class CommandLineOptions + public class R2RTestRootCommand : RootCommand { - public static CommandLineBuilder Build() + void CreateCommand(string name, string description, Option[] options, Func action) { - var parser = new CommandLineBuilder() - .AddCommand(CompileFolder()) - .AddCommand(CompileSubtree()) - .AddCommand(CompileFramework()) - .AddCommand(CompileNugetPackages()) - .AddCommand(CompileSerp()); - - return parser; - - Command CreateCommand(string name, string description, Option[] options, Func action) - { - Command command = new Command(name, description); - foreach (var option in GetCommonOptions()) - command.AddOption(option); - foreach (var option in options) - command.AddOption(option); - command.Handler = CommandHandler.Create(action); - return command; - } - - Option[] GetCommonOptions() => new[] { CoreRootDirectory(), DotNetCli() }; - - Command CompileFolder() => - CreateCommand("compile-directory", "Compile all assemblies in directory", - new Option[] - { - InputDirectory(), - OutputDirectory(), - Crossgen2Path(), - TargetArch(), - VerifyTypeAndFieldLayout(), - NoJit(), - NoCrossgen2(), - Exe(), - NoExe(), - NoEtw(), - NoCleanup(), - Map(), - Pdb(), - Perfmap(), - PerfmapFormatVersion(), - DegreeOfParallelism(), - Sequential(), - Iterations(), - Framework(), - UseFramework(), - Release(), - LargeBubble(), - Composite(), - Crossgen2Parallelism(), - Crossgen2JitPath(), - ReferencePath(), - IssuesPath(), - CompilationTimeoutMinutes(), - ExecutionTimeoutMinutes(), - R2RDumpPath(), - MeasurePerf(), - InputFileSearchString(), - MibcPath(), - }, - CompileDirectoryCommand.CompileDirectory); - - Command CompileSubtree() => - CreateCommand("compile-subtree", "Build each directory in a given subtree containing any managed assemblies as a separate app", - new Option[] - { - InputDirectory(), - OutputDirectory(), - Crossgen2Path(), - TargetArch(), - VerifyTypeAndFieldLayout(), - NoJit(), - NoCrossgen2(), - Exe(), - NoExe(), - NoEtw(), - NoCleanup(), - Map(), - Pdb(), - Perfmap(), - PerfmapFormatVersion(), - DegreeOfParallelism(), - Sequential(), - Iterations(), - Framework(), - UseFramework(), - Release(), - LargeBubble(), - Composite(), - Crossgen2Parallelism(), - Crossgen2JitPath(), - ReferencePath(), - IssuesPath(), - CompilationTimeoutMinutes(), - ExecutionTimeoutMinutes(), - R2RDumpPath(), - GCStress(), - MibcPath(), - }, - CompileSubtreeCommand.CompileSubtree); - - Command CompileFramework() => - CreateCommand("compile-framework", "Compile managed framework assemblies in Core_Root", - new Option[] - { - Crossgen2Path(), - TargetArch(), - VerifyTypeAndFieldLayout(), - NoCrossgen2(), - NoCleanup(), - Map(), - Pdb(), - Perfmap(), - PerfmapFormatVersion(), - Crossgen2Parallelism(), - Crossgen2JitPath(), - DegreeOfParallelism(), - Sequential(), - Iterations(), - Release(), - LargeBubble(), - Composite(), - ReferencePath(), - IssuesPath(), - CompilationTimeoutMinutes(), - R2RDumpPath(), - MeasurePerf(), - InputFileSearchString(), - OutputDirectory(), - MibcPath(), - }, - CompileFrameworkCommand.CompileFramework); - - Command CompileNugetPackages() => - CreateCommand("compile-nuget", "Restore a list of Nuget packages into an empty console app, publish, and optimize with Crossgen / CPAOT", - new Option[] - { - R2RDumpPath(), - InputDirectory(), - OutputDirectory(), - PackageList(), - NoCleanup(), - Map(), - Pdb(), - Perfmap(), - PerfmapFormatVersion(), - DegreeOfParallelism(), - CompilationTimeoutMinutes(), - ExecutionTimeoutMinutes(), - MibcPath(), - }, - CompileNugetCommand.CompileNuget); - - Command CompileSerp() => - CreateCommand("compile-serp", "Compile existing application", - new Option[] - { - InputDirectory(), - DegreeOfParallelism(), - AspNetPath(), - Composite(), - Map(), - Pdb(), - Perfmap(), - PerfmapFormatVersion(), - CompilationTimeoutMinutes(), - Crossgen2Path(), - MibcPath(), - }, - options => - { - var compileSerp = new CompileSerpCommand(options); - return compileSerp.CompileSerpAssemblies(); - }); - - // Todo: Input / Output directories should be required arguments to the command when they're made available to handlers - // https://github.com/dotnet/command-line-api/issues/297 - Option InputDirectory() => - new Option(new[] { "--input-directory", "-in" }, "Folder containing assemblies to optimize").ExistingOnly(); - - Option OutputDirectory() => - new Option(new[] { "--output-directory", "-out" }, "Folder to emit compiled assemblies").LegalFilePathsOnly(); - - Option CoreRootDirectory() => - new Option(new[] { "--core-root-directory", "-cr" }, "Location of the CoreCLR CORE_ROOT folder") + Command command = new Command(name, description); + foreach (var option in GetCommonOptions()) + command.AddOption(option); + foreach (var option in options) + command.AddOption(option); + command.SetHandler((InvocationContext context) => + context.ExitCode = action(new BuildOptions(this, context.ParseResult))); + AddCommand(command); + } + + Option[] GetCommonOptions() => new Option[] { CoreRootDirectory, DotNetCli }; + + R2RTestRootCommand() + { + CreateCommand("compile-directory", "Compile all assemblies in directory", + new Option[] + { + InputDirectory, + OutputDirectory, + Crossgen2Path, + TargetArch, + VerifyTypeAndFieldLayout, + NoJit, + NoCrossgen2, + Exe, + NoExe, + NoEtw, + NoCleanup, + Map, + Pdb, + Perfmap, + PerfmapFormatVersion, + DegreeOfParallelism, + Sequential, + Iterations, + Framework, + UseFramework, + Release, + LargeBubble, + Composite, + Crossgen2Parallelism, + Crossgen2JitPath, + ReferencePath, + IssuesPath, + CompilationTimeoutMinutes, + ExecutionTimeoutMinutes, + R2RDumpPath, + MeasurePerf, + InputFileSearchString, + MibcPath, + }, + CompileDirectoryCommand.CompileDirectory); + + CreateCommand("compile-subtree", "Build each directory in a given subtree containing any managed assemblies as a separate app", + new Option[] + { + InputDirectory, + OutputDirectory, + Crossgen2Path, + TargetArch, + VerifyTypeAndFieldLayout, + NoJit, + NoCrossgen2, + Exe, + NoExe, + NoEtw, + NoCleanup, + Map, + Pdb, + Perfmap, + PerfmapFormatVersion, + DegreeOfParallelism, + Sequential, + Iterations, + Framework, + UseFramework, + Release, + LargeBubble, + Composite, + Crossgen2Parallelism, + Crossgen2JitPath, + ReferencePath, + IssuesPath, + CompilationTimeoutMinutes, + ExecutionTimeoutMinutes, + R2RDumpPath, + GCStress, + MibcPath, + }, + CompileSubtreeCommand.CompileSubtree); + + CreateCommand("compile-framework", "Compile managed framework assemblies in Core_Root", + new Option[] { - Required = true - }.ExistingOnly(); + Crossgen2Path, + TargetArch, + VerifyTypeAndFieldLayout, + NoCrossgen2, + NoCleanup, + Map, + Pdb, + Perfmap, + PerfmapFormatVersion, + Crossgen2Parallelism, + Crossgen2JitPath, + DegreeOfParallelism, + Sequential, + Iterations, + Release, + LargeBubble, + Composite, + ReferencePath, + IssuesPath, + CompilationTimeoutMinutes, + R2RDumpPath, + MeasurePerf, + InputFileSearchString, + OutputDirectory, + MibcPath, + }, + CompileFrameworkCommand.CompileFramework); + + CreateCommand("compile-nuget", "Restore a list of Nuget packages into an empty console app, publish, and optimize with Crossgen / CPAOT", + new Option[] + { + R2RDumpPath, + InputDirectory, + OutputDirectory, + PackageList, + NoCleanup, + Map, + Pdb, + Perfmap, + PerfmapFormatVersion, + DegreeOfParallelism, + CompilationTimeoutMinutes, + ExecutionTimeoutMinutes, + MibcPath, + }, + CompileNugetCommand.CompileNuget); + + CreateCommand("compile-serp", "Compile existing application", + new Option[] + { + InputDirectory, + DegreeOfParallelism, + AspNetPath, + Composite, + Map, + Pdb, + Perfmap, + PerfmapFormatVersion, + CompilationTimeoutMinutes, + Crossgen2Path, + MibcPath, + }, + options => + { + var compileSerp = new CompileSerpCommand(options); + return compileSerp.CompileSerpAssemblies(); + }); + } + + // Todo: Input / Output directories should be required arguments to the command when they're made available to handlers + // https://github.com/dotnet/command-line-api/issues/297 + public Option InputDirectory { get; } = + new Option(new[] { "--input-directory", "-in" }, "Folder containing assemblies to optimize").ExistingOnly(); - Option ReferencePath() => - new Option(new[] { "--reference-path", "-r" }, "Folder containing assemblies to reference during compilation") - { Argument = new Argument() { Arity = ArgumentArity.ZeroOrMore }.ExistingOnly() }; + public Option OutputDirectory { get; } = + new Option(new[] { "--output-directory", "-out" }, "Folder to emit compiled assemblies").LegalFilePathsOnly(); - Option MibcPath() => - new Option(new[] { "--mibc-path", "-m" }, "Mibc files to use in compilation") - { Argument = new Argument() { Arity = ArgumentArity.ZeroOrMore }.ExistingOnly() }; + public Option CoreRootDirectory { get; } = + new Option(new[] { "--core-root-directory", "-cr" }, "Location of the CoreCLR CORE_ROOT folder") + { Arity = ArgumentArity.ExactlyOne }.ExistingOnly(); - Option Crossgen2Path() => - new Option(new[] { "--crossgen2-path", "-c2p" }, "Explicit Crossgen2 path (useful for cross-targeting)").ExistingOnly(); + public Option ReferencePath { get; } = + new Option(new[] { "--reference-path", "-r" }, "Folder containing assemblies to reference during compilation") + { Arity = ArgumentArity.ZeroOrMore }.ExistingOnly(); - Option VerifyTypeAndFieldLayout() => - new Option(new[] { "--verify-type-and-field-layout" }, "Verify that struct type layout and field offsets match between compile time and runtime. Use only for diagnostic purposes."); + public Option MibcPath { get; } = + new Option(new[] { "--mibc-path", "-m" }, "Mibc files to use in compilation") + { Arity = ArgumentArity.ZeroOrMore }.ExistingOnly(); - Option NoJit() => - new Option(new[] { "--nojit" }, "Don't run tests in JITted mode"); + public Option Crossgen2Path { get; } = + new Option(new[] { "--crossgen2-path", "-c2p" }, "Explicit Crossgen2 path (useful for cross-targeting)").ExistingOnly(); - Option NoCrossgen2() => - new Option(new[] { "--nocrossgen2" }, "Don't run tests in Crossgen2 mode"); + public Option VerifyTypeAndFieldLayout { get; } = + new(new[] { "--verify-type-and-field-layout" }, "Verify that struct type layout and field offsets match between compile time and runtime. Use only for diagnostic purposes."); - Option Exe() => - new Option(new[] { "--exe" }, "Don't compile tests, just execute them"); + public Option NoJit { get; } = + new(new[] { "--nojit" }, "Don't run tests in JITted mode"); - Option NoExe() => - new Option(new[] { "--noexe" }, "Compilation-only mode (don't execute the built apps)"); + public Option NoCrossgen2 { get; } = + new(new[] { "--nocrossgen2" }, "Don't run tests in Crossgen2 mode"); - Option NoEtw() => - new Option(new[] { "--noetw" }, "Don't capture jitted methods using ETW"); + public Option Exe { get; } = + new(new[] { "--exe" }, "Don't compile tests, just execute them"); - Option NoCleanup() => - new Option(new[] { "--nocleanup" }, "Don't clean up compilation artifacts after test runs"); + public Option NoExe { get; } = + new(new[] { "--noexe" }, "Compilation-only mode (don't execute the built apps)"); - Option Map() => - new Option(new[] { "--map" }, "Generate a map file (Crossgen2)"); + public Option NoEtw { get; } = + new(new[] { "--noetw" }, "Don't capture jitted methods using ETW"); - Option Pdb() => - new Option(new[] { "--pdb" }, "Generate PDB symbol information (Crossgen2 / Windows only)"); + public Option NoCleanup { get; } = + new(new[] { "--nocleanup" }, "Don't clean up compilation artifacts after test runs"); - Option Perfmap() => - new Option(new[] { "--perfmap" }, "Generate perfmap symbol information"); + public Option Map { get; } = + new(new[] { "--map" }, "Generate a map file (Crossgen2)"); - Option PerfmapFormatVersion() => - new Option(new[] { "--perfmap-format-version" }, "Perfmap format version to generate"); + public Option Pdb { get; } = + new(new[] { "--pdb" }, "Generate PDB symbol information (Crossgen2 / Windows only)"); - Option DegreeOfParallelism() => - new Option(new[] { "--degree-of-parallelism", "-dop" }, "Override default compilation / execution DOP (default = logical processor count)"); + public Option Perfmap { get; } = + new(new[] { "--perfmap" }, "Generate perfmap symbol information"); - Option Sequential() => - new Option(new[] { "--sequential" }, "Run tests sequentially"); + public Option PerfmapFormatVersion { get; } = + new(new[] { "--perfmap-format-version" }, () => 1, "Perfmap format version to generate"); - Option Iterations() => - new Option(new[] { "--iterations" }, "Number of iterations for each test execution"); + public Option DegreeOfParallelism { get; } = + new(new[] { "--degree-of-parallelism", "-dop" }, "Override default compilation / execution DOP (default = logical processor count)"); - Option Framework() => - new Option(new[] { "--framework" }, "Precompile and use native framework"); + public Option Sequential { get; } = + new(new[] { "--sequential" }, "Run tests sequentially"); - Option UseFramework() => - new Option(new[] { "--use-framework" }, "Use native framework (don't precompile, assume previously compiled)"); + public Option Iterations { get; } = + new(new[] { "--iterations" }, () => 1, "Number of iterations for each test execution"); - Option Release() => - new Option(new[] { "--release" }, "Build the tests in release mode"); + public Option Framework { get; } = + new(new[] { "--framework" }, "Precompile and use native framework"); - Option LargeBubble() => - new Option(new[] { "--large-bubble" }, "Assume all input files as part of one version bubble"); + public Option UseFramework { get; } = + new(new[] { "--use-framework" }, "Use native framework (don't precompile, assume previously compiled)"); - Option Composite() => - new Option(new[] { "--composite" }, "Compile tests in composite R2R mode"); + public Option Release { get; } = + new(new[] { "--release" }, "Build the tests in release mode"); - Option Crossgen2Parallelism() => - new Option(new[] { "--crossgen2-parallelism" }, "Max number of threads to use in Crossgen2 (default = logical processor count)"); - - Option Crossgen2JitPath() => - new Option(new[] { "--crossgen2-jitpath" }, "Jit path to use for crossgen2"); + public Option LargeBubble { get; } = + new(new[] { "--large-bubble" }, "Assume all input files as part of one version bubble"); - Option IssuesPath() => - new Option(new[] { "--issues-path", "-ip" }, "Path to issues.targets") - { Argument = new Argument() { Arity = ArgumentArity.ZeroOrMore } }; + public Option Composite { get; } = + new(new[] { "--composite" }, "Compile tests in composite R2R mode"); - Option CompilationTimeoutMinutes() => - new Option(new[] { "--compilation-timeout-minutes", "-ct" }, "Compilation timeout (minutes)"); + public Option Crossgen2Parallelism { get; } = + new(new[] { "--crossgen2-parallelism" }, "Max number of threads to use in Crossgen2 (default = logical processor count)"); - Option ExecutionTimeoutMinutes() => - new Option(new[] { "--execution-timeout-minutes", "-et" }, "Execution timeout (minutes)"); + public Option Crossgen2JitPath { get; } = + new(new[] { "--crossgen2-jitpath" }, "Jit path to use for crossgen2"); - Option R2RDumpPath() => - new Option(new[] { "--r2r-dump-path" }, "Path to R2RDump.exe/dll").ExistingOnly(); + public Option IssuesPath { get; } = + new Option(new[] { "--issues-path", "-ip" }, "Path to issues.targets") + { Arity = ArgumentArity.ZeroOrMore }; - Option MeasurePerf() => - new Option(new[] { "--measure-perf" }, "Print out compilation time"); + public Option CompilationTimeoutMinutes { get; } = + new(new[] { "--compilation-timeout-minutes", "-ct" }, "Compilation timeout (minutes)"); - Option InputFileSearchString() => - new Option(new[] { "--input-file-search-string", "-input-file" }, "Search string for input files in the input directory"); + public Option ExecutionTimeoutMinutes { get; } = + new(new[] { "--execution-timeout-minutes", "-et" }, "Execution timeout (minutes)"); - Option GCStress() => - new Option(new[] { "--gcstress" }, "Run tests with the specified GC stress level enabled (the argument value is in hex)"); + public Option R2RDumpPath { get; } = + new Option(new[] { "--r2r-dump-path" }, "Path to R2RDump.exe/dll").ExistingOnly(); - Option DotNetCli() => - new Option(new [] { "--dotnet-cli", "-cli" }, "For dev box testing, point at .NET 5 dotnet.exe or /dotnet.cmd."); + public Option MeasurePerf { get; } = + new(new[] { "--measure-perf" }, "Print out compilation time"); - Option TargetArch() => - new Option(new[] { "--target-arch" }, "Target architecture for crossgen2"); + public Option InputFileSearchString { get; } = + new(new[] { "--input-file-search-string", "-input-file" }, "Search string for input files in the input directory"); - // - // compile-nuget specific options - // - Option PackageList() => - new Option(new[] { "--package-list", "-pl" }, "Text file containing a package name on each line").ExistingOnly(); + public Option GCStress { get; } = + new(new[] { "--gcstress" }, "Run tests with the specified GC stress level enabled (the argument value is in hex)"); - // - // compile-serp specific options - // - Option AspNetPath() => - new Option(new[] { "--asp-net-path", "-asp" }, "Path to SERP's ASP.NET Core folder").ExistingOnly(); + public Option DotNetCli { get; } = + new(new [] { "--dotnet-cli", "-cli" }, "For dev box testing, point at .NET 5 dotnet.exe or /dotnet.cmd."); + + public Option TargetArch { get; } = + new(new[] { "--target-arch" }, "Target architecture for crossgen2"); + + // + // compile-nuget specific options + // + public Option PackageList { get; } = + new Option(new[] { "--package-list", "-pl" }, "Text file containing a package name on each line").ExistingOnly(); + + // + // compile-serp specific options + // + public Option AspNetPath { get; } = + new Option(new[] { "--asp-net-path", "-asp" }, "Path to SERP's ASP.NET Core folder").ExistingOnly(); + + static int Main(string[] args) + { + return new CommandLineBuilder(new R2RTestRootCommand()) + .UseHelp() + .UseParseErrorReporting() + .Build() + .Invoke(args); } } + + public partial class BuildOptions + { + public BuildOptions(R2RTestRootCommand cmd, ParseResult res) + { + InputDirectory = res.GetValueForOption(cmd.InputDirectory); + OutputDirectory = res.GetValueForOption(cmd.OutputDirectory); + CoreRootDirectory = res.GetValueForOption(cmd.CoreRootDirectory); + Crossgen2Path = res.GetValueForOption(cmd.Crossgen2Path); + VerifyTypeAndFieldLayout = res.GetValueForOption(cmd.VerifyTypeAndFieldLayout); + TargetArch = res.GetValueForOption(cmd.TargetArch); + Exe = res.GetValueForOption(cmd.Exe); + NoJit = res.GetValueForOption(cmd.NoJit); + NoCrossgen2 = res.GetValueForOption(cmd.NoCrossgen2); + NoExe = res.GetValueForOption(cmd.NoExe); + NoEtw = res.GetValueForOption(cmd.NoEtw); + NoCleanup = res.GetValueForOption(cmd.NoCleanup); + Map = res.GetValueForOption(cmd.Map); + Pdb = res.GetValueForOption(cmd.Pdb); + + Perfmap = res.GetValueForOption(cmd.Perfmap); + PerfmapFormatVersion = res.GetValueForOption(cmd.PerfmapFormatVersion); + PackageList = res.GetValueForOption(cmd.PackageList); + DegreeOfParallelism = res.GetValueForOption(cmd.DegreeOfParallelism); + Sequential = res.GetValueForOption(cmd.Sequential); + Iterations = res.GetValueForOption(cmd.Iterations); + Framework = res.GetValueForOption(cmd.Framework); + UseFramework = res.GetValueForOption(cmd.UseFramework); + Release = res.GetValueForOption(cmd.Release); + LargeBubble = res.GetValueForOption(cmd.LargeBubble); + Composite = res.GetValueForOption(cmd.Composite); + Crossgen2Parallelism = res.GetValueForOption(cmd.Crossgen2Parallelism); + Crossgen2JitPath = res.GetValueForOption(cmd.Crossgen2JitPath); + CompilationTimeoutMinutes = res.GetValueForOption(cmd.CompilationTimeoutMinutes); + ExecutionTimeoutMinutes = res.GetValueForOption(cmd.ExecutionTimeoutMinutes); + ReferencePath = res.GetValueForOption(cmd.ReferencePath); + IssuesPath = res.GetValueForOption(cmd.IssuesPath); + R2RDumpPath = res.GetValueForOption(cmd.R2RDumpPath); + AspNetPath = res.GetValueForOption(cmd.AspNetPath); + MeasurePerf = res.GetValueForOption(cmd.MeasurePerf); + InputFileSearchString = res.GetValueForOption(cmd.InputFileSearchString); + GCStress = res.GetValueForOption(cmd.GCStress); + MibcPath = res.GetValueForOption(cmd.MibcPath); + } + + public DirectoryInfo InputDirectory { get; set; } + public DirectoryInfo OutputDirectory { get; set; } + public DirectoryInfo CoreRootDirectory { get; } + public FileInfo Crossgen2Path { get; } + public bool VerifyTypeAndFieldLayout { get; } + public string TargetArch { get; } + public bool Exe { get; } + public bool NoJit { get; set; } + public bool NoCrossgen2 { get; } + public bool NoExe { get; set; } + public bool NoEtw { get; set; } + public bool NoCleanup { get; } + public bool Map { get; } + public bool Pdb { get; } + + public bool Perfmap { get; } + public int PerfmapFormatVersion { get; } + public FileInfo PackageList { get; } + public int DegreeOfParallelism { get; set; } + public bool Sequential { get; } + public int Iterations { get; } + public bool Framework { get; set; } + public bool UseFramework { get; } + public bool Release { get; set; } + public bool LargeBubble { get; } + public bool Composite { get; } + public int Crossgen2Parallelism { get; } + public FileInfo Crossgen2JitPath { get; } + public int CompilationTimeoutMinutes { get; } + public int ExecutionTimeoutMinutes { get; } + public DirectoryInfo[] ReferencePath { get; } + public FileInfo[] IssuesPath { get; } + public FileInfo R2RDumpPath { get; } + public DirectoryInfo AspNetPath { get; } + public bool MeasurePerf { get; } + public string InputFileSearchString { get; } + public string GCStress { get; } + public FileInfo[] MibcPath { get; } + } } diff --git a/src/coreclr/tools/r2rtest/Program.cs b/src/coreclr/tools/r2rtest/Program.cs deleted file mode 100644 index 86cb14e240a43..0000000000000 --- a/src/coreclr/tools/r2rtest/Program.cs +++ /dev/null @@ -1,21 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.CommandLine; -using System.CommandLine.Builder; -using System.CommandLine.Parsing; -using System.Threading.Tasks; - -namespace R2RTest -{ - class Program - { - static async Task Main(string[] args) - { - var parser = CommandLineOptions.Build().UseDefaults().Build(); - - return await parser.InvokeAsync(args); - } - } -}