未验证 提交 c5b27d63 编写于 作者: A Adeel Mujahid 提交者: GitHub

Update System.CommandLine version (#84229)

上级 299a8c9c
......@@ -76,13 +76,13 @@
<Uri>https://github.com/dotnet/llvm-project</Uri>
<Sha>76f334f354eb653a7b409a5319b591ea09df5a43</Sha>
</Dependency>
<Dependency Name="System.CommandLine" Version="2.0.0-beta4.22564.1">
<Dependency Name="System.CommandLine" Version="2.0.0-beta4.23307.1">
<Uri>https://github.com/dotnet/command-line-api</Uri>
<Sha>8374d5fca634a93458c84414b1604c12f765d1ab</Sha>
<Sha>02fe27cd6a9b001c8feb7938e6ef4b3799745759</Sha>
</Dependency>
<Dependency Name="Microsoft.SourceBuild.Intermediate.command-line-api" Version="0.1.356401">
<Dependency Name="Microsoft.SourceBuild.Intermediate.command-line-api" Version="0.1.430701">
<Uri>https://github.com/dotnet/command-line-api</Uri>
<Sha>8374d5fca634a93458c84414b1604c12f765d1ab</Sha>
<Sha>02fe27cd6a9b001c8feb7938e6ef4b3799745759b</Sha>
<SourceBuild RepoName="command-line-api" ManagedOnly="true" />
</Dependency>
<Dependency Name="Microsoft.DotNet.Cecil" Version="0.11.4-alpha.23327.1">
......
......@@ -161,7 +161,7 @@
<optimizationPGOCoreCLRVersion>1.0.0-prerelease.23326.3</optimizationPGOCoreCLRVersion>
<!-- Not auto-updated. -->
<MicrosoftDiaSymReaderNativeVersion>16.11.27-beta1.23180.1</MicrosoftDiaSymReaderNativeVersion>
<SystemCommandLineVersion>2.0.0-beta4.22564.1</SystemCommandLineVersion>
<SystemCommandLineVersion>2.0.0-beta4.23307.1</SystemCommandLineVersion>
<TraceEventVersion>3.0.3</TraceEventVersion>
<NETStandardLibraryRefVersion>2.1.0</NETStandardLibraryRefVersion>
<NetStandardLibraryVersion>2.0.3</NetStandardLibraryVersion>
......
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System.CommandLine.Help;
using System.Collections.Generic;
using System.CommandLine.Binding;
using System.CommandLine.Parsing;
using System.IO;
using System.IO.Compression;
......@@ -24,11 +24,11 @@ internal static partial class Helpers
{
public const string DefaultSystemModule = "System.Private.CoreLib";
public static Dictionary<string, string> BuildPathDictionary(IReadOnlyList<Token> tokens, bool strict)
public static Dictionary<string, string> BuildPathDictionary(IReadOnlyList<CliToken> tokens, bool strict)
{
Dictionary<string, string> dictionary = new(StringComparer.OrdinalIgnoreCase);
foreach (Token token in tokens)
foreach (CliToken token in tokens)
{
AppendExpandedPaths(dictionary, token.Value, strict);
}
......@@ -36,11 +36,11 @@ internal static partial class Helpers
return dictionary;
}
public static List<string> BuildPathList(IReadOnlyList<Token> tokens)
public static List<string> BuildPathList(IReadOnlyList<CliToken> tokens)
{
List<string> paths = new();
Dictionary<string, string> dictionary = new(StringComparer.OrdinalIgnoreCase);
foreach (Token token in tokens)
foreach (CliToken token in tokens)
{
AppendExpandedPaths(dictionary, token.Value, false);
foreach (string file in dictionary.Values)
......@@ -113,6 +113,36 @@ public static TargetArchitecture GetTargetArchitecture(string token)
}
}
public static CliRootCommand UseVersion(this CliRootCommand command)
{
for (int i = 0; i < command.Options.Count; i++)
{
if (command.Options[i] is VersionOption)
{
command.Options[i] = new VersionOption("--version", "-v");
break;
}
}
return command;
}
public static CliRootCommand UseExtendedHelp(this CliRootCommand command, Func<HelpContext, IEnumerable<Action<HelpContext>>> customizer)
{
foreach (CliOption option in command.Options)
{
if (option is HelpOption helpOption)
{
HelpBuilder builder = new();
builder.CustomizeLayout(customizer);
helpOption.Action = new HelpAction { Builder = builder };
break;
}
}
return command;
}
public static void MakeReproPackage(string makeReproPath, string outputFilePath, string[] args, ParseResult res, IEnumerable<string> inputOptions, IEnumerable<string> outputOptions = null)
{
Directory.CreateDirectory(makeReproPath);
......@@ -177,16 +207,16 @@ public static void MakeReproPackage(string makeReproPath, string outputFilePath,
Dictionary<string, string> outputToReproPackageFileName = new();
List<string> rspFile = new List<string>();
foreach (var option in res.CommandResult.Command.Options)
foreach (CliOption option in res.CommandResult.Command.Options)
{
if (!res.HasOption(option) || option.Name == "make-repro-path")
OptionResult optionResult = res.GetResult(option);
if (optionResult is null || option.Name == "make-repro-path")
{
continue;
}
IValueDescriptor descriptor = option;
object val = res.CommandResult.GetValue(option);
if (val is not null && !(descriptor.HasDefaultValue && descriptor.GetDefaultValue().Equals(val)))
object val = optionResult.GetValueOrDefault<object>();
if (val is not null && !optionResult.Implicit)
{
if (val is IEnumerable<string> || val is IDictionary<string, string>)
{
......@@ -234,9 +264,15 @@ public static void MakeReproPackage(string makeReproPath, string outputFilePath,
}
}
foreach (var argument in res.CommandResult.Command.Arguments)
foreach (CliArgument argument in res.CommandResult.Command.Arguments)
{
object val = res.CommandResult.GetValue(argument);
ArgumentResult argumentResult = res.GetResult(argument);
if (argumentResult is null)
{
continue;
}
object val = argumentResult.GetValueOrDefault<object>();
if (val is IEnumerable<string> || val is IDictionary<string, string>)
{
if (val is not IEnumerable<string> values)
......
......@@ -8,61 +8,61 @@
namespace ILVerify
{
internal sealed class ILVerifyRootCommand : RootCommand
internal sealed class ILVerifyRootCommand : CliRootCommand
{
public Argument<Dictionary<string, string>> InputFilePath { get; } =
new("input-file-path", result => Helpers.BuildPathDictionary(result.Tokens, true), false, "Input file(s)") { Arity = ArgumentArity.OneOrMore };
public Option<Dictionary<string, string>> Reference { get; } =
new(new[] { "--reference", "-r" }, result => Helpers.BuildPathDictionary(result.Tokens, false), false, "Reference metadata from the specified assembly");
public Option<string> SystemModule { get; } =
new(new[] { "--system-module", "-s" }, "System module name (default: mscorlib)");
public Option<bool> SanityChecks { get; } =
new(new[] { "--sanity-checks", "-c" }, "Check for valid constructs that are likely mistakes");
public Option<string[]> Include { get; } =
new(new[] { "--include", "-i" }, "Use only methods/types/namespaces, which match the given regular expression(s)");
public Option<FileInfo> IncludeFile { get; } =
new Option<FileInfo>(new[] { "--include-file" }, "Same as --include, but the regular expression(s) are declared line by line in the specified file.").AcceptExistingOnly();
public Option<string[]> Exclude { get; } =
new(new[] { "--exclude", "-e" }, "Skip methods/types/namespaces, which match the given regular expression(s)");
public Option<FileInfo> ExcludeFile { get; } =
new Option<FileInfo>(new[] { "--exclude-file" }, "Same as --exclude, but the regular expression(s) are declared line by line in the specified file.").AcceptExistingOnly();
public Option<string[]> IgnoreError { get; } =
new(new[] { "--ignore-error", "-g" }, "Ignore errors, which match the given regular expression(s)");
public Option<FileInfo> IgnoreErrorFile { get; } =
new Option<FileInfo>(new[] { "--ignore-error-file" }, "Same as --ignore-error, but the regular expression(s) are declared line by line in the specified file.").AcceptExistingOnly();
public Option<bool> Statistics { get; } =
new(new[] { "--statistics" }, "Print verification statistics");
public Option<bool> Verbose { get; } =
new(new[] { "--verbose" }, "Verbose output");
public Option<bool> Tokens { get; } =
new(new[] { "--tokens", "-t" }, "Include metadata tokens in error messages");
public CliArgument<Dictionary<string, string>> InputFilePath { get; } =
new("input-file-path") { CustomParser = result => Helpers.BuildPathDictionary(result.Tokens, true), Description = "Input file(s)", Arity = ArgumentArity.OneOrMore };
public CliOption<Dictionary<string, string>> Reference { get; } =
new("--reference", "-r") { CustomParser = result => Helpers.BuildPathDictionary(result.Tokens, false), Description = "Reference metadata from the specified assembly" };
public CliOption<string> SystemModule { get; } =
new("--system-module", "-s") { Description = "System module name (default: mscorlib)" };
public CliOption<bool> SanityChecks { get; } =
new("--sanity-checks", "-c") { Description = "Check for valid constructs that are likely mistakes" };
public CliOption<string[]> Include { get; } =
new("--include", "-i") { Description = "Use only methods/types/namespaces, which match the given regular expression(s)" };
public CliOption<FileInfo> IncludeFile { get; } =
new CliOption<FileInfo>("--include-file") { Description = "Same as --include, but the regular expression(s) are declared line by line in the specified file." }.AcceptExistingOnly();
public CliOption<string[]> Exclude { get; } =
new("--exclude", "-e") { Description = "Skip methods/types/namespaces, which match the given regular expression(s)" };
public CliOption<FileInfo> ExcludeFile { get; } =
new CliOption<FileInfo>("--exclude-file") { Description = "Same as --exclude, but the regular expression(s) are declared line by line in the specified file." }.AcceptExistingOnly();
public CliOption<string[]> IgnoreError { get; } =
new("--ignore-error", "-g") { Description = "Ignore errors, which match the given regular expression(s)" };
public CliOption<FileInfo> IgnoreErrorFile { get; } =
new CliOption<FileInfo>("--ignore-error-file") { Description = "Same as --ignore-error, but the regular expression(s) are declared line by line in the specified file." }.AcceptExistingOnly();
public CliOption<bool> Statistics { get; } =
new("--statistics") { Description = "Print verification statistics" };
public CliOption<bool> Verbose { get; } =
new("--verbose") { Description = "Verbose output" };
public CliOption<bool> Tokens { get; } =
new("--tokens", "-t") { Description = "Include metadata tokens in error messages" };
public ParseResult Result;
public ILVerifyRootCommand()
: base("Tool for verifying MSIL code based on ECMA-335.")
{
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);
Arguments.Add(InputFilePath);
Options.Add(Reference);
Options.Add(SystemModule);
Options.Add(SanityChecks);
Options.Add(Include);
Options.Add(IncludeFile);
Options.Add(Exclude);
Options.Add(ExcludeFile);
Options.Add(IgnoreError);
Options.Add(IgnoreErrorFile);
Options.Add(Statistics);
Options.Add(Verbose);
Options.Add(Tokens);
this.SetHandler(context =>
this.SetAction(result =>
{
Result = context.ParseResult;
Result = result;
try
{
context.ExitCode = new Program(this).Run();
return new Program(this).Run();
}
catch (Exception e)
{
......@@ -73,9 +73,9 @@ public ILVerifyRootCommand()
Console.Error.WriteLine(e.ToString());
Console.ResetColor();
context.ExitCode = 1;
}
return 1;
});
}
}
......
......@@ -450,16 +450,14 @@ public PEReader Resolve(string simpleName)
return null;
}
private T Get<T>(Option<T> option) => _command.Result.GetValue(option);
private T Get<T>(Argument<T> argument) => _command.Result.GetValue(argument);
private T Get<T>(CliOption<T> option) => _command.Result.GetValue(option);
private T Get<T>(CliArgument<T> argument) => _command.Result.GetValue(argument);
private static int Main(string[] args) =>
new CommandLineBuilder(new ILVerifyRootCommand())
.UseTokenReplacer(Helpers.TryReadResponseFile)
.UseVersionOption("--version", "-v")
.UseHelp()
.UseParseErrorReporting()
.Build()
.Invoke(args);
new CliConfiguration(new ILVerifyRootCommand().UseVersion())
{
ResponseFileTokenReplacer = Helpers.TryReadResponseFile,
EnableParseErrorReporting = true
}.Invoke(args);
}
}
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System.CommandLine;
using System.IO;
var binOption = new Option<FileInfo>(
name: "--bin",
description: "Binary data to attach to the image");
var imageOption = new Option<FileInfo>(
name: "--image",
description: "PE image to add the binary resource into");
var nameOption = new Option<string>(
name: "--name",
description: "Resource name");
var rootCommand = new RootCommand("Inject native resources into a Portable Executable image");
rootCommand.AddOption(binOption);
rootCommand.AddOption(imageOption);
rootCommand.AddOption(nameOption);
CliOption<FileInfo> binOption = new("--bin") { Description = "Binary data to attach to the image" };
CliOption<FileInfo> imageOption = new("--image") { Description = "PE image to add the binary resource into" };
CliOption<string> nameOption = new("--name") { Description = "Resource name" };
CliRootCommand rootCommand = new("Inject native resources into a Portable Executable image");
rootCommand.Options.Add(binOption);
rootCommand.Options.Add(imageOption);
rootCommand.Options.Add(nameOption);
rootCommand.SetHandler((FileInfo binaryData, FileInfo peImage, string name) =>
{
using ResourceUpdater updater = new(peImage);
updater.AddBinaryResource(name, File.ReadAllBytes(binaryData.FullName));
},
binOption,
imageOption,
nameOption);
rootCommand.SetAction(result =>
{
using ResourceUpdater updater = new(result.GetValue(imageOption)!);
updater.AddBinaryResource(result.GetValue(nameOption)!, File.ReadAllBytes(result.GetValue(binOption)!.FullName));
});
return rootCommand.Invoke(args);
return new CliConfiguration(rootCommand).Invoke(args);
......@@ -698,15 +698,15 @@ private static IEnumerable<int> ProcessWarningCodes(IEnumerable<string> warningC
}
}
private T Get<T>(Option<T> option) => _command.Result.GetValue(option);
private T Get<T>(CliOption<T> option) => _command.Result.GetValue(option);
private static int Main(string[] args) =>
new CommandLineBuilder(new ILCompilerRootCommand(args))
.UseTokenReplacer(Helpers.TryReadResponseFile)
.UseVersionOption("--version", "-v")
.UseHelp(context => context.HelpBuilder.CustomizeLayout(ILCompilerRootCommand.GetExtendedHelp))
.UseParseErrorReporting()
.Build()
.Invoke(args);
new CliConfiguration(new ILCompilerRootCommand(args)
.UseVersion()
.UseExtendedHelp(ILCompilerRootCommand.GetExtendedHelp))
{
ResponseFileTokenReplacer = Helpers.TryReadResponseFile,
EnableParseErrorReporting = true
}.Invoke(args);
}
}
......@@ -908,15 +908,15 @@ internal static bool IsValidPublicKey(byte[] blob)
return true;
}
private T Get<T>(Option<T> option) => _command.Result.GetValue(option);
private T Get<T>(CliOption<T> option) => _command.Result.GetValue(option);
private static int Main(string[] args) =>
new CommandLineBuilder(new Crossgen2RootCommand(args))
.UseTokenReplacer(Helpers.TryReadResponseFile)
.UseVersionOption("--version", "-v")
.UseHelp(context => context.HelpBuilder.CustomizeLayout(Crossgen2RootCommand.GetExtendedHelp))
.UseParseErrorReporting()
.Build()
.Invoke(args);
new CliConfiguration(new Crossgen2RootCommand(args)
.UseVersion()
.UseExtendedHelp(Crossgen2RootCommand.GetExtendedHelp))
{
ResponseFileTokenReplacer = Helpers.TryReadResponseFile,
EnableParseErrorReporting = true
}.Invoke(args);
}
}
......@@ -13,76 +13,57 @@
namespace Microsoft.Diagnostics.Tools.Pgo
{
internal sealed class PgoRootCommand : RootCommand
internal sealed class PgoRootCommand : CliRootCommand
{
public Option<List<string>> InputFilesToMerge { get; } =
new(new[] { "--input", "-i" }, result => Helpers.BuildPathList(result.Tokens), false, "Input .mibc files to be merged. Multiple input arguments are specified as --input file1.mibc --input file2.mibc") { IsRequired = true, Arity = ArgumentArity.OneOrMore };
public Option<string[]> InputFilesToCompare { get; } =
new(new[] { "--input", "-i" }, "The input .mibc files to be compared. Specify as --input file1.mibc --input file2.mibc") { IsRequired = true, Arity = new ArgumentArity(2, 2) /* exactly two */ };
public Option<string> InputFileToDump { get; } =
new(new[] { "--input", "-i" }, "Name of the input mibc file to dump") { IsRequired = true, Arity = ArgumentArity.ExactlyOne };
public Option<string> TraceFilePath { get; } =
new(new[] { "--trace", "-t" }, "Specify the trace file to be parsed");
public Option<string> OutputFilePath { get; } =
new(new[] { "--output", "-o" }, "Specify the output filename to be created");
public Option<string> PreciseDebugInfoFile { get; } =
new(new[] { "--precise-debug-info-file" }, "Name of file of newline separated JSON objects containing precise debug info");
public Option<int> Pid { get; } =
new(new[] { "--pid" }, "The pid within the trace of the process to examine. If this is a multi-process trace, at least one of --pid or --process-name must be specified");
public Option<string> ProcessName { get; } =
new(new[] { "--process-name" }, "The process name within the trace of the process to examine. If this is a multi-process trace, at least one of --pid or --process-name must be specified");
public Option<List<string>> Reference =
new(new[] { "--reference", "-r" }, result => Helpers.BuildPathList(result.Tokens), true, "If a reference is not located on disk at the same location as used in the process, it may be specified with a --reference parameter. Multiple --reference parameters may be specified. The wild cards * and ? are supported by this option");
public Option<int> ClrInstanceId { get; } =
new("--clr-instance-id", "If the process contains multiple .NET runtimes, the instance ID must be specified");
public Option<bool> Spgo { get; } =
new("--spgo", "Base profile on samples in the input. Uses last branch records if available and otherwise raw IP samples");
public Option<int> SpgoMinSamples { get; } =
new("--spgo-min-samples", () => 50, "The minimum number of total samples a function must have before generating profile data for it with SPGO. Default: 50");
public Option<bool> IncludeFullGraphs { get; } =
new("--include-full-graphs", "Include all blocks and edges in the written .mibc file, regardless of profile counts");
public Option<double> ExcludeEventsBefore { get; } =
new("--exclude-events-before", () => Double.MinValue, "Exclude data from events before specified time. Time is specified as milliseconds from the start of the trace");
public Option<double> ExcludeEventsAfter { get; } =
new("--exclude-events-after", () => Double.MaxValue, "Exclude data from events after specified time. Time is specified as milliseconds from the start of the trace");
public Option<bool> Compressed { get; } =
new("--compressed", () => true, "Generate compressed mibc");
public Option<int> DumpWorstOverlapGraphs { get; } =
new("--dump-worst-overlap-graphs", () => -1, "Number of graphs to dump to .dot format in dump-worst-overlap-graphs-to directory");
public Option<string> DumpWorstOverlapGraphsTo { get; } =
new("--dump-worst-overlap-graphs-to", "Number of graphs to dump to .dot format in dump-worst-overlap-graphs-to directory");
public Option<bool> AutomaticReferences { get; } =
new("--automatic-references", () => true, "Attempt to find references by using paths embedded in the trace file. Defaults to true");
public Option<AssemblyName[]> IncludedAssemblies { get; } =
new("--include-reference", result =>
{
if (result.Tokens.Count > 0)
{
var includedAssemblies = new List<AssemblyName>();
foreach (Token token in result.Tokens)
{
try
{
includedAssemblies.Add(new AssemblyName(token.Value));
}
catch
{
throw new FormatException($"Unable to parse '{token.Value}' as an Assembly Name.");
}
}
}
return Array.Empty<AssemblyName>();
}, true, "If specified, include in Mibc file only references to the specified assemblies. Assemblies are specified as assembly names, not filenames. For instance, `System.Private.CoreLib` not `System.Private.CoreLib.dll`. Multiple --include-reference options may be specified.");
private Option<bool> _includeReadyToRun { get; } =
new("--includeReadyToRun", "Include ReadyToRun methods in the trace file");
private Option<Verbosity> _verbosity { get; } =
new(new[] { "--verbose" }, () => Verbosity.normal, "Adjust verbosity level. Supported levels are minimal, normal, detailed, and diagnostic");
private Option<bool> _isSorted { get; } =
new("--sorted", "Generate sorted output.");
private Option<bool> _showTimestamp { get; } =
new("--showtimestamp", "Show timestamps in output");
public CliOption<List<string>> InputFilesToMerge { get; } =
new("--input", "-i") { CustomParser = result => Helpers.BuildPathList(result.Tokens), Description = "Input .mibc files to be merged. Multiple input arguments are specified as --input file1.mibc --input file2.mibc", Required = true, Arity = ArgumentArity.OneOrMore };
public CliOption<string[]> InputFilesToCompare { get; } =
new("--input", "-i") { Description = "The input .mibc files to be compared. Specify as --input file1.mibc --input file2.mibc", Required = true, Arity = new ArgumentArity(2, 2) /* exactly two */ };
public CliOption<string> InputFileToDump { get; } =
new("--input", "-i") { Description = "Name of the input mibc file to dump", Required = true, Arity = ArgumentArity.ExactlyOne };
public CliOption<string> TraceFilePath { get; } =
new("--trace", "-t") { Description = "Specify the trace file to be parsed" };
public CliOption<string> OutputFilePath { get; } =
new("--output", "-o") { Description = "Specify the output filename to be created" };
public CliOption<string> PreciseDebugInfoFile { get; } =
new("--precise-debug-info-file") { Description = "Name of file of newline separated JSON objects containing precise debug info" };
public CliOption<int> Pid { get; } =
new("--pid") { Description = "The pid within the trace of the process to examine. If this is a multi-process trace, at least one of --pid or --process-name must be specified" };
public CliOption<string> ProcessName { get; } =
new("--process-name") { Description = "The process name within the trace of the process to examine. If this is a multi-process trace, at least one of --pid or --process-name must be specified" };
public CliOption<List<string>> Reference =
new("--reference", "-r") { CustomParser = result => Helpers.BuildPathList(result.Tokens), DefaultValueFactory = result => Helpers.BuildPathList(result.Tokens), Description = "If a reference is not located on disk at the same location as used in the process, it may be specified with a --reference parameter. Multiple --reference parameters may be specified. The wild cards * and ? are supported by this option" };
public CliOption<int> ClrInstanceId { get; } =
new("--clr-instance-id") { Description = "If the process contains multiple .NET runtimes, the instance ID must be specified" };
public CliOption<bool> Spgo { get; } =
new("--spgo") { Description = "Base profile on samples in the input. Uses last branch records if available and otherwise raw IP samples" };
public CliOption<int> SpgoMinSamples { get; } =
new("--spgo-min-samples") { DefaultValueFactory = _ => 50, Description = "The minimum number of total samples a function must have before generating profile data for it with SPGO. Default: 50" };
public CliOption<bool> IncludeFullGraphs { get; } =
new("--include-full-graphs") { Description = "Include all blocks and edges in the written .mibc file, regardless of profile counts" };
public CliOption<double> ExcludeEventsBefore { get; } =
new("--exclude-events-before") { DefaultValueFactory = _ => Double.MinValue, Description = "Exclude data from events before specified time. Time is specified as milliseconds from the start of the trace" };
public CliOption<double> ExcludeEventsAfter { get; } =
new("--exclude-events-after") { DefaultValueFactory = _ => Double.MaxValue, Description = "Exclude data from events after specified time. Time is specified as milliseconds from the start of the trace" };
public CliOption<bool> Compressed { get; } =
new("--compressed") { DefaultValueFactory = _ => true, Description = "Generate compressed mibc" };
public CliOption<int> DumpWorstOverlapGraphs { get; } =
new("--dump-worst-overlap-graphs") { DefaultValueFactory = _ => -1, Description = "Number of graphs to dump to .dot format in dump-worst-overlap-graphs-to directory" };
public CliOption<string> DumpWorstOverlapGraphsTo { get; } =
new("--dump-worst-overlap-graphs-to") { Description = "Number of graphs to dump to .dot format in dump-worst-overlap-graphs-to directory" };
public CliOption<bool> AutomaticReferences { get; } =
new("--automatic-references") { DefaultValueFactory = _ => true, Description = "Attempt to find references by using paths embedded in the trace file. Defaults to true" };
public CliOption<AssemblyName[]> IncludedAssemblies { get; } =
new("--include-reference") { CustomParser = MakeAssemblyNameArray, DefaultValueFactory = MakeAssemblyNameArray, Description = "If specified, include in Mibc file only references to the specified assemblies. Assemblies are specified as assembly names, not filenames. For instance, `System.Private.CoreLib` not `System.Private.CoreLib.dll`. Multiple --include-reference options may be specified." };
private CliOption<bool> _includeReadyToRun { get; } =
new("--includeReadyToRun") { Description = "Include ReadyToRun methods in the trace file" };
private CliOption<Verbosity> _verbosity { get; } =
new("--verbose") { DefaultValueFactory = _ => Verbosity.normal, Description = "Adjust verbosity level. Supported levels are minimal, normal, detailed, and diagnostic" };
private CliOption<bool> _isSorted { get; } =
new("--sorted") { Description = "Generate sorted output." };
private CliOption<bool> _showTimestamp { get; } =
new("--showtimestamp") { Description = "Show timestamps in output" };
public PgoFileType? FileType;
public bool ProcessJitEvents;
......@@ -108,7 +89,7 @@ private enum Verbosity
public PgoRootCommand(string[] args) : base(".NET PGO Tool")
{
Command createMbicCommand = new("create-mibc", "Transform a trace file into a Mibc profile data file")
CliCommand createMbicCommand = new("create-mibc", "Transform a trace file into a Mibc profile data file")
{
TraceFilePath,
OutputFilePath,
......@@ -127,7 +108,7 @@ public PgoRootCommand(string[] args) : base(".NET PGO Tool")
IncludeFullGraphs
};
createMbicCommand.SetHandler(context =>
createMbicCommand.SetAction(result =>
{
FileType = PgoFileType.mibc;
GenerateCallGraph = true;
......@@ -139,14 +120,14 @@ public PgoRootCommand(string[] args) : base(".NET PGO Tool")
ValidateOutputFile = false;
#endif
TryExecuteWithContext(context, true);
return ExecuteWithContext(result, true);
});
AddCommand(createMbicCommand);
Subcommands.Add(createMbicCommand);
JitTraceOptions = JitTraceOptions.none;
#if DEBUG
Command createJitTraceCommand = new("create-jittrace","Transform a trace file into a jittrace runtime file")
CliCommand createJitTraceCommand = new("create-jittrace","Transform a trace file into a jittrace runtime file")
{
TraceFilePath,
OutputFilePath,
......@@ -163,30 +144,30 @@ public PgoRootCommand(string[] args) : base(".NET PGO Tool")
_includeReadyToRun
};
createJitTraceCommand.SetHandler(context =>
createJitTraceCommand.SetAction(result =>
{
FileType = PgoFileType.jittrace;
ProcessJitEvents = true;
ValidateOutputFile = false;
ProcessR2REvents = context.ParseResult.GetValue(_includeReadyToRun);
ProcessR2REvents = result.GetValue(_includeReadyToRun);
if (context.ParseResult.GetValue(_isSorted))
if (result.GetValue(_isSorted))
{
JitTraceOptions |= JitTraceOptions.sorted;
}
if (context.ParseResult.GetValue(_showTimestamp))
if (result.GetValue(_showTimestamp))
{
JitTraceOptions |= JitTraceOptions.showtimestamp;
}
TryExecuteWithContext(context, true);
return ExecuteWithContext(result, true);
});
AddCommand(createJitTraceCommand);
Subcommands.Add(createJitTraceCommand);
#endif
Command mergeCommand = new("merge", "Merge multiple Mibc profile data files into one file")
CliCommand mergeCommand = new("merge", "Merge multiple Mibc profile data files into one file")
{
InputFilesToMerge,
OutputFilePath,
......@@ -195,7 +176,7 @@ public PgoRootCommand(string[] args) : base(".NET PGO Tool")
Compressed
};
mergeCommand.SetHandler(context =>
mergeCommand.SetAction(result =>
{
#if DEBUG
ValidateOutputFile = true;
......@@ -203,44 +184,44 @@ public PgoRootCommand(string[] args) : base(".NET PGO Tool")
ValidateOutputFile = false;
#endif
TryExecuteWithContext(context, true);
return ExecuteWithContext(result, true);
});
AddCommand(mergeCommand);
Subcommands.Add(mergeCommand);
Command dumpCommand = new("dump", "Dump the contents of a Mibc file")
CliCommand dumpCommand = new("dump", "Dump the contents of a Mibc file")
{
_verbosity,
InputFileToDump,
OutputFilePath,
};
dumpCommand.SetHandler(context =>
dumpCommand.SetAction(result =>
{
DumpMibc = true;
TryExecuteWithContext(context, true);
return ExecuteWithContext(result, true);
});
AddCommand(dumpCommand);
Subcommands.Add(dumpCommand);
Command compareMbicCommand = new Command("compare-mibc", "Compare two .mibc files")
CliCommand compareMbicCommand = new("compare-mibc", "Compare two .mibc files")
{
InputFilesToCompare,
DumpWorstOverlapGraphs,
DumpWorstOverlapGraphsTo
};
compareMbicCommand.SetHandler(context => TryExecuteWithContext(context, false));
compareMbicCommand.SetAction(result => ExecuteWithContext(result, false));
AddCommand(compareMbicCommand);
Subcommands.Add(compareMbicCommand);
void TryExecuteWithContext(InvocationContext context, bool setVerbosity)
int ExecuteWithContext(ParseResult result, bool setVerbosity)
{
Result = context.ParseResult;
Result = result;
if (setVerbosity)
{
Verbosity verbosity = context.ParseResult.GetValue(_verbosity);
Verbosity verbosity = Result.GetValue(_verbosity);
BasicProgressMessages = (int)verbosity >= (int)Verbosity.normal;
Warnings = (int)verbosity >= (int)Verbosity.normal;
VerboseWarnings = (int)verbosity >= (int)Verbosity.detailed;
......@@ -250,7 +231,7 @@ void TryExecuteWithContext(InvocationContext context, bool setVerbosity)
try
{
context.ExitCode = new Program(this).Run();
return new Program(this).Run();
}
catch (Exception e)
{
......@@ -261,9 +242,9 @@ void TryExecuteWithContext(InvocationContext context, bool setVerbosity)
Console.Error.WriteLine(e.ToString());
Console.ResetColor();
context.ExitCode = 1;
}
return 1;
}
}
......@@ -290,5 +271,27 @@ public static IEnumerable<Action<HelpContext>> GetExtendedHelp(HelpContext conte
};
}
}
private static AssemblyName[] MakeAssemblyNameArray(ArgumentResult result)
{
if (result.Tokens.Count > 0)
{
var includedAssemblies = new List<AssemblyName>();
foreach (CliToken token in result.Tokens)
{
try
{
includedAssemblies.Add(new AssemblyName(token.Value));
}
catch
{
throw new FormatException($"Unable to parse '{token.Value}' as an Assembly Name.");
}
}
return includedAssemblies.ToArray();
}
return Array.Empty<AssemblyName>();
}
}
}
......@@ -155,18 +155,18 @@ public Program(PgoRootCommand command)
_inputFilesToCompare = Get(command.InputFilesToCompare);
}
private T Get<T>(Option<T> option) => _command.Result.GetValue(option);
private T Get<T>(Argument<T> argument) => _command.Result.GetValue(argument);
private bool IsSet<T>(Option<T> option) => _command.Result.FindResultFor(option) != null;
private T Get<T>(CliOption<T> option) => _command.Result.GetValue(option);
private T Get<T>(CliArgument<T> argument) => _command.Result.GetValue(argument);
private bool IsSet<T>(CliOption<T> option) => _command.Result.GetResult(option) != null;
private static int Main(string[] args) =>
new CommandLineBuilder(new PgoRootCommand(args))
.UseTokenReplacer(Helpers.TryReadResponseFile)
.UseVersionOption("--version", "-v")
.UseHelp(context => context.HelpBuilder.CustomizeLayout(PgoRootCommand.GetExtendedHelp))
.UseParseErrorReporting()
.Build()
.Invoke(args);
new CliConfiguration(new PgoRootCommand(args)
.UseVersion()
.UseExtendedHelp(PgoRootCommand.GetExtendedHelp))
{
ResponseFileTokenReplacer = Helpers.TryReadResponseFile,
EnableParseErrorReporting = true
}.Invoke(args);
public static void PrintWarning(string warning)
{
......
......@@ -494,15 +494,13 @@ public int Run()
return 0;
}
private T Get<T>(Option<T> option) => _command.Result.GetValue(option);
private T Get<T>(CliOption<T> option) => _command.Result.GetValue(option);
public static int Main(string[] args) =>
new CommandLineBuilder(new R2RDumpRootCommand())
.UseTokenReplacer(Helpers.TryReadResponseFile)
.UseVersionOption("--version", "-v")
.UseHelp()
.UseParseErrorReporting()
.Build()
.Invoke(args);
new CliConfiguration(new R2RDumpRootCommand().UseVersion())
{
ResponseFileTokenReplacer = Helpers.TryReadResponseFile,
EnableParseErrorReporting = true
}.Invoke(args);
}
}
......@@ -8,127 +8,127 @@
namespace R2RDump
{
internal sealed class R2RDumpRootCommand : RootCommand
internal sealed class R2RDumpRootCommand : CliRootCommand
{
public Option<List<string>> In { get; } =
new(new[] { "--in", "-i" }, result => Helpers.BuildPathList(result.Tokens), true, "Input file(s) to dump. Expects them to by ReadyToRun images");
public Option<FileInfo> Out { get; } =
new(new[] { "--out", "-o" }, "Output file path. Dumps everything to the specified file except for help message and exception messages");
public Option<bool> Raw { get; } =
new(new[] { "--raw" }, "Dump the raw bytes of each section or runtime function");
public Option<bool> Header { get; } =
new(new[] { "--header" }, "Dump R2R header");
public Option<bool> Disasm { get; } =
new(new[] { "--disasm", "-d" }, "Show disassembly of methods or runtime functions");
public Option<bool> Naked { get; } =
new(new[] { "--naked" }, "Naked dump suppresses most compilation details like placement addresses");
public Option<bool> HideOffsets { get; } =
new(new[] { "--hide-offsets", "--ho" }, "Hide offsets in naked disassembly");
public Option<string[]> Query { get; } =
new(new[] { "--query", "-q" }, "Query method by exact name, signature, row ID or token");
public Option<string[]> Keyword { get; } =
new(new[] { "--keyword", "-k" }, "Search method by keyword");
public Option<string[]> RuntimeFunction { get; } =
new(new[] { "--runtimefunction", "-f" }, "Get one runtime function by id or relative virtual address");
public Option<string[]> Section { get; } =
new(new[] { "--section", "-s" }, "Get section by keyword");
public Option<bool> Unwind { get; } =
new(new[] { "--unwind" }, "Dump unwindInfo");
public Option<bool> GC { get; } =
new(new[] { "--gc" }, "Dump gcInfo and slot table");
public Option<bool> Pgo { get; } =
new(new[] { "--pgo" }, "Dump embedded pgo instrumentation data");
public Option<bool> SectionContents { get; } =
new(new[] { "--sectionContents", "--sc" }, "Dump section contents");
public Option<bool> EntryPoints { get; } =
new(new[] { "--entrypoints", "-e" }, "Dump list of method / instance entrypoints in the R2R file");
public Option<bool> Normalize { get; } =
new(new[] { "--normalize", "-n" }, "Normalize dump by sorting the various tables and methods (default = unsorted i.e. file order)");
public Option<bool> HideTransitions { get; } =
new(new[] { "--hide-transitions", "--ht" }, "Don't include GC transitions in disassembly output");
public Option<bool> Verbose { get; } =
new(new[] { "--verbose" }, "Dump disassembly, unwindInfo, gcInfo and sectionContents");
public Option<bool> Diff { get; } =
new(new[] { "--diff" }, "Compare two R2R images");
public Option<bool> DiffHideSameDisasm { get; } =
new(new[] { "--diff-hide-same-disasm" }, "In matching method diff dump, hide functions with identical disassembly");
public Option<bool> CreatePDB { get; } =
new(new[] { "--create-pdb" }, "Create PDB");
public Option<string> PdbPath { get; } =
new(new[] { "--pdb-path" }, "PDB output path for --create-pdb");
public Option<bool> CreatePerfmap { get; } =
new(new[] { "--create-perfmap" }, "Create PerfMap");
public Option<string> PerfmapPath { get; } =
new(new[] { "--perfmap-path" }, "PerfMap output path for --create-perfmap");
public Option<int> PerfmapFormatVersion { get; } =
new(new[] { "--perfmap-format-version" }, () => ILCompiler.Diagnostics.PerfMapWriter.CurrentFormatVersion, "PerfMap format version for --create-perfmap");
public Option<List<string>> Reference { get; } =
new(new[] { "--reference", "-r" }, result => Helpers.BuildPathList(result.Tokens), true, "Explicit reference assembly files");
public Option<DirectoryInfo[]> ReferencePath { get; } =
new(new[] { "--referencePath", "--rp" }, "Search paths for reference assemblies");
public Option<bool> SignatureBinary { get; } =
new(new[] { "--signatureBinary", "--sb" }, "Append signature binary to its textual representation");
public Option<bool> InlineSignatureBinary { get; } =
new(new[] { "--inlineSignatureBinary", "--isb" }, "Embed binary signature into its textual representation");
public Option<bool> ValidateDebugInfo { get; } =
new(new[] { "--validateDebugInfo", "--val" }, "Validate functions reported debug info.");
public CliOption<List<string>> In { get; } =
new("--in", "-i") { CustomParser = result => Helpers.BuildPathList(result.Tokens), DefaultValueFactory = result => Helpers.BuildPathList(result.Tokens), Description = "Input file(s) to dump. Expects them to by ReadyToRun images" };
public CliOption<FileInfo> Out { get; } =
new("--out", "-o") { Description = "Output file path. Dumps everything to the specified file except for help message and exception messages" };
public CliOption<bool> Raw { get; } =
new("--raw") { Description = "Dump the raw bytes of each section or runtime function" };
public CliOption<bool> Header { get; } =
new("--header") { Description = "Dump R2R header" };
public CliOption<bool> Disasm { get; } =
new("--disasm", "-d") { Description = "Show disassembly of methods or runtime functions" };
public CliOption<bool> Naked { get; } =
new("--naked") { Description = "Naked dump suppresses most compilation details like placement addresses" };
public CliOption<bool> HideOffsets { get; } =
new("--hide-offsets", "--ho") { Description = "Hide offsets in naked disassembly" };
public CliOption<string[]> Query { get; } =
new("--query", "-q") { Description = "Query method by exact name, signature, row ID or token" };
public CliOption<string[]> Keyword { get; } =
new("--keyword", "-k") { Description = "Search method by keyword" };
public CliOption<string[]> RuntimeFunction { get; } =
new("--runtimefunction", "-f") { Description = "Get one runtime function by id or relative virtual address" };
public CliOption<string[]> Section { get; } =
new("--section", "-s") { Description = "Get section by keyword" };
public CliOption<bool> Unwind { get; } =
new("--unwind") { Description = "Dump unwindInfo" };
public CliOption<bool> GC { get; } =
new("--gc") { Description = "Dump gcInfo and slot table" };
public CliOption<bool> Pgo { get; } =
new("--pgo") { Description = "Dump embedded pgo instrumentation data" };
public CliOption<bool> SectionContents { get; } =
new("--sectionContents", "--sc") { Description = "Dump section contents" };
public CliOption<bool> EntryPoints { get; } =
new("--entrypoints", "-e") { Description = "Dump list of method / instance entrypoints in the R2R file" };
public CliOption<bool> Normalize { get; } =
new("--normalize", "-n") { Description = "Normalize dump by sorting the various tables and methods (default = unsorted i.e. file order)" };
public CliOption<bool> HideTransitions { get; } =
new("--hide-transitions", "--ht") { Description = "Don't include GC transitions in disassembly output" };
public CliOption<bool> Verbose { get; } =
new("--verbose") { Description = "Dump disassembly, unwindInfo, gcInfo and sectionContents" };
public CliOption<bool> Diff { get; } =
new("--diff") { Description = "Compare two R2R images" };
public CliOption<bool> DiffHideSameDisasm { get; } =
new("--diff-hide-same-disasm") { Description = "In matching method diff dump, hide functions with identical disassembly" };
public CliOption<bool> CreatePDB { get; } =
new("--create-pdb") { Description = "Create PDB" };
public CliOption<string> PdbPath { get; } =
new("--pdb-path") { Description = "PDB output path for --create-pdb" };
public CliOption<bool> CreatePerfmap { get; } =
new("--create-perfmap") { Description = "Create PerfMap" };
public CliOption<string> PerfmapPath { get; } =
new("--perfmap-path") { Description = "PerfMap output path for --create-perfmap" };
public CliOption<int> PerfmapFormatVersion { get; } =
new("--perfmap-format-version") { DefaultValueFactory = _ => ILCompiler.Diagnostics.PerfMapWriter.CurrentFormatVersion, Description = "PerfMap format version for --create-perfmap" };
public CliOption<List<string>> Reference { get; } =
new("--reference", "-r") { CustomParser = result => Helpers.BuildPathList(result.Tokens), DefaultValueFactory = result => Helpers.BuildPathList(result.Tokens), Description = "Explicit reference assembly files" };
public CliOption<DirectoryInfo[]> ReferencePath { get; } =
new("--referencePath", "--rp") { Description = "Search paths for reference assemblies" };
public CliOption<bool> SignatureBinary { get; } =
new("--signatureBinary", "--sb") { Description = "Append signature binary to its textual representation" };
public CliOption<bool> InlineSignatureBinary { get; } =
new("--inlineSignatureBinary", "--isb") { Description = "Embed binary signature into its textual representation" };
public CliOption<bool> ValidateDebugInfo { get; } =
new("--validateDebugInfo", "--val") { Description = "Validate functions reported debug info." };
public ParseResult Result;
public R2RDumpRootCommand()
: base("Parses and outputs the contents of a ReadyToRun image")
{
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);
AddOption(ValidateDebugInfo);
this.SetHandler(context =>
Options.Add(In);
Options.Add(Out);
Options.Add(Raw);
Options.Add(Header);
Options.Add(Disasm);
Options.Add(Naked);
Options.Add(HideOffsets);
Options.Add(Query);
Options.Add(Keyword);
Options.Add(RuntimeFunction);
Options.Add(Section);
Options.Add(Unwind);
Options.Add(GC);
Options.Add(Pgo);
Options.Add(SectionContents);
Options.Add(EntryPoints);
Options.Add(Normalize);
Options.Add(HideTransitions);
Options.Add(Verbose);
Options.Add(Diff);
Options.Add(DiffHideSameDisasm);
Options.Add(CreatePDB);
Options.Add(PdbPath);
Options.Add(CreatePerfmap);
Options.Add(PerfmapPath);
Options.Add(PerfmapFormatVersion);
Options.Add(Reference);
Options.Add(ReferencePath);
Options.Add(SignatureBinary);
Options.Add(InlineSignatureBinary);
Options.Add(ValidateDebugInfo);
SetAction(parseResult =>
{
Result = context.ParseResult;
Result = parseResult;
try
{
context.ExitCode = new Program(this).Run();
return new Program(this).Run();
}
catch (Exception e)
{
......@@ -140,7 +140,7 @@ public R2RDumpRootCommand()
Console.ResetColor();
context.ExitCode = 1;
return 1;
}
});
}
......
......@@ -8,26 +8,27 @@
namespace R2RTest
{
public class R2RTestRootCommand : RootCommand
public class R2RTestRootCommand : CliRootCommand
{
void CreateCommand(string name, string description, Option[] options, Func<BuildOptions, int> action)
void CreateCommand(string name, string description, CliOption[] options, Func<BuildOptions, int> action)
{
Command command = new Command(name, description);
CliCommand command = new(name, description);
foreach (var option in GetCommonOptions())
command.AddOption(option);
command.Options.Add(option);
foreach (var option in options)
command.AddOption(option);
command.SetHandler(context =>
context.ExitCode = action(new BuildOptions(this, context.ParseResult)));
AddCommand(command);
command.Options.Add(option);
command.SetAction(result => action(new BuildOptions(this, result)));
Subcommands.Add(command);
}
Option[] GetCommonOptions() => new Option[] { CoreRootDirectory, DotNetCli };
CliOption[] GetCommonOptions() => new CliOption[] { CoreRootDirectory, DotNetCli };
R2RTestRootCommand()
{
OutputDirectory.AcceptLegalFilePathsOnly();
CreateCommand("compile-directory", "Compile all assemblies in directory",
new Option[]
new CliOption[]
{
InputDirectory,
OutputDirectory,
......@@ -66,7 +67,7 @@ void CreateCommand(string name, string description, Option[] options, Func<Build
CompileDirectoryCommand.CompileDirectory);
CreateCommand("compile-subtree", "Build each directory in a given subtree containing any managed assemblies as a separate app",
new Option[]
new CliOption[]
{
InputDirectory,
OutputDirectory,
......@@ -104,7 +105,7 @@ void CreateCommand(string name, string description, Option[] options, Func<Build
CompileSubtreeCommand.CompileSubtree);
CreateCommand("compile-framework", "Compile managed framework assemblies in Core_Root",
new Option[]
new CliOption[]
{
Crossgen2Path,
TargetArch,
......@@ -135,7 +136,7 @@ void CreateCommand(string name, string description, Option[] options, Func<Build
CompileFrameworkCommand.CompileFramework);
CreateCommand("compile-nuget", "Restore a list of Nuget packages into an empty console app, publish, and optimize with Crossgen / CPAOT",
new Option[]
new CliOption[]
{
R2RDumpPath,
InputDirectory,
......@@ -154,7 +155,7 @@ void CreateCommand(string name, string description, Option[] options, Func<Build
CompileNugetCommand.CompileNuget);
CreateCommand("compile-serp", "Compile existing application",
new Option[]
new CliOption[]
{
InputDirectory,
DegreeOfParallelism,
......@@ -177,137 +178,131 @@ void CreateCommand(string name, string description, Option[] options, Func<Build
// 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<DirectoryInfo> InputDirectory { get; } =
new Option<DirectoryInfo>(new[] { "--input-directory", "-in" }, "Folder containing assemblies to optimize").AcceptExistingOnly();
public CliOption<DirectoryInfo> InputDirectory { get; } =
new CliOption<DirectoryInfo>("--input-directory", "-in") { Description = "Folder containing assemblies to optimize" }.AcceptExistingOnly();
public Option<DirectoryInfo> OutputDirectory { get; } =
new Option<DirectoryInfo>(new[] { "--output-directory", "-out" }, "Folder to emit compiled assemblies").AcceptLegalFilePathsOnly();
public CliOption<DirectoryInfo> OutputDirectory { get; } =
new CliOption<DirectoryInfo>("--output-directory", "-out") { Description = "Folder to emit compiled assemblies" };
public Option<DirectoryInfo> CoreRootDirectory { get; } =
new Option<DirectoryInfo>(new[] { "--core-root-directory", "-cr" }, "Location of the CoreCLR CORE_ROOT folder")
{ Arity = ArgumentArity.ExactlyOne }.AcceptExistingOnly();
public CliOption<DirectoryInfo> CoreRootDirectory { get; } =
new CliOption<DirectoryInfo>("--core-root-directory", "-cr") { Description = "Location of the CoreCLR CORE_ROOT folder", Arity = ArgumentArity.ExactlyOne }.AcceptExistingOnly();
public Option<DirectoryInfo[]> ReferencePath { get; } =
new Option<DirectoryInfo[]>(new[] { "--reference-path", "-r" }, "Folder containing assemblies to reference during compilation")
{ Arity = ArgumentArity.ZeroOrMore }.AcceptExistingOnly();
public CliOption<DirectoryInfo[]> ReferencePath { get; } =
new CliOption<DirectoryInfo[]>("--reference-path", "-r") { Description = "Folder containing assemblies to reference during compilation", Arity = ArgumentArity.ZeroOrMore }.AcceptExistingOnly();
public Option<FileInfo[]> MibcPath { get; } =
new Option<FileInfo[]>(new[] { "--mibc-path", "-m" }, "Mibc files to use in compilation")
{ Arity = ArgumentArity.ZeroOrMore }.AcceptExistingOnly();
public CliOption<FileInfo[]> MibcPath { get; } =
new CliOption<FileInfo[]>("--mibc-path", "-m") { Description = "Mibc files to use in compilation", Arity = ArgumentArity.ZeroOrMore }.AcceptExistingOnly();
public Option<FileInfo> Crossgen2Path { get; } =
new Option<FileInfo>(new[] { "--crossgen2-path", "-c2p" }, "Explicit Crossgen2 path (useful for cross-targeting)").AcceptExistingOnly();
public CliOption<FileInfo> Crossgen2Path { get; } =
new CliOption<FileInfo>("--crossgen2-path", "-c2p") { Description = "Explicit Crossgen2 path (useful for cross-targeting)" }.AcceptExistingOnly();
public Option<bool> 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.");
public CliOption<bool> VerifyTypeAndFieldLayout { get; } =
new("--verify-type-and-field-layout") { Description = "Verify that struct type layout and field offsets match between compile time and runtime. Use only for diagnostic purposes." };
public Option<bool> NoJit { get; } =
new(new[] { "--nojit" }, "Don't run tests in JITted mode");
public CliOption<bool> NoJit { get; } =
new("--nojit") { Description = "Don't run tests in JITted mode" };
public Option<bool> NoCrossgen2 { get; } =
new(new[] { "--nocrossgen2" }, "Don't run tests in Crossgen2 mode");
public CliOption<bool> NoCrossgen2 { get; } =
new("--nocrossgen2") { Description = "Don't run tests in Crossgen2 mode" };
public Option<bool> Exe { get; } =
new(new[] { "--exe" }, "Don't compile tests, just execute them");
public CliOption<bool> Exe { get; } =
new("--exe") { Description = "Don't compile tests, just execute them" };
public Option<bool> NoExe { get; } =
new(new[] { "--noexe" }, "Compilation-only mode (don't execute the built apps)");
public CliOption<bool> NoExe { get; } =
new("--noexe") { Description = "Compilation-only mode (don't execute the built apps)" };
public Option<bool> NoEtw { get; } =
new(new[] { "--noetw" }, "Don't capture jitted methods using ETW");
public CliOption<bool> NoEtw { get; } =
new("--noetw") { Description = "Don't capture jitted methods using ETW" };
public Option<bool> NoCleanup { get; } =
new(new[] { "--nocleanup" }, "Don't clean up compilation artifacts after test runs");
public CliOption<bool> NoCleanup { get; } =
new("--nocleanup") { Description = "Don't clean up compilation artifacts after test runs" };
public Option<bool> Map { get; } =
new(new[] { "--map" }, "Generate a map file (Crossgen2)");
public CliOption<bool> Map { get; } =
new("--map") { Description = "Generate a map file (Crossgen2)" };
public Option<bool> Pdb { get; } =
new(new[] { "--pdb" }, "Generate PDB symbol information (Crossgen2 / Windows only)");
public CliOption<bool> Pdb { get; } =
new("--pdb") { Description = "Generate PDB symbol information (Crossgen2 / Windows only)" };
public Option<bool> Perfmap { get; } =
new(new[] { "--perfmap" }, "Generate perfmap symbol information");
public CliOption<bool> Perfmap { get; } =
new("--perfmap") { Description = "Generate perfmap symbol information" };
public Option<int> PerfmapFormatVersion { get; } =
new(new[] { "--perfmap-format-version" }, () => 1, "Perfmap format version to generate");
public CliOption<int> PerfmapFormatVersion { get; } =
new("--perfmap-format-version") { DefaultValueFactory = _ => 1, Description = "Perfmap format version to generate" };
public Option<int> DegreeOfParallelism { get; } =
new(new[] { "--degree-of-parallelism", "-dop" }, "Override default compilation / execution DOP (default = logical processor count)");
public CliOption<int> DegreeOfParallelism { get; } =
new("--degree-of-parallelism", "-dop") { Description = "Override default compilation / execution DOP (default = logical processor count)" };
public Option<bool> Sequential { get; } =
new(new[] { "--sequential" }, "Run tests sequentially");
public CliOption<bool> Sequential { get; } =
new("--sequential") { Description = "Run tests sequentially" };
public Option<int> Iterations { get; } =
new(new[] { "--iterations" }, () => 1, "Number of iterations for each test execution");
public CliOption<int> Iterations { get; } =
new("--iterations") { DefaultValueFactory = _ => 1, Description = "Number of iterations for each test execution" };
public Option<bool> Framework { get; } =
new(new[] { "--framework" }, "Precompile and use native framework");
public CliOption<bool> Framework { get; } =
new("--framework") { Description = "Precompile and use native framework" };
public Option<bool> UseFramework { get; } =
new(new[] { "--use-framework" }, "Use native framework (don't precompile, assume previously compiled)");
public CliOption<bool> UseFramework { get; } =
new("--use-framework") { Description = "Use native framework (don't precompile, assume previously compiled)" };
public Option<bool> Release { get; } =
new(new[] { "--release" }, "Build the tests in release mode");
public CliOption<bool> Release { get; } =
new("--release") { Description = "Build the tests in release mode" };
public Option<bool> LargeBubble { get; } =
new(new[] { "--large-bubble" }, "Assume all input files as part of one version bubble");
public CliOption<bool> LargeBubble { get; } =
new("--large-bubble") { Description = "Assume all input files as part of one version bubble" };
public Option<bool> Composite { get; } =
new(new[] { "--composite" }, "Compile tests in composite R2R mode");
public CliOption<bool> Composite { get; } =
new("--composite") { Description = "Compile tests in composite R2R mode" };
public Option<int> Crossgen2Parallelism { get; } =
new(new[] { "--crossgen2-parallelism" }, "Max number of threads to use in Crossgen2 (default = logical processor count)");
public CliOption<int> Crossgen2Parallelism { get; } =
new("--crossgen2-parallelism") { Description = "Max number of threads to use in Crossgen2 (default = logical processor count)" };
public Option<FileInfo> Crossgen2JitPath { get; } =
new(new[] { "--crossgen2-jitpath" }, "Jit path to use for crossgen2");
public CliOption<FileInfo> Crossgen2JitPath { get; } =
new("--crossgen2-jitpath") { Description = "Jit path to use for crossgen2" };
public Option<FileInfo[]> IssuesPath { get; } =
new Option<FileInfo[]>(new[] { "--issues-path", "-ip" }, "Path to issues.targets")
{ Arity = ArgumentArity.ZeroOrMore };
public CliOption<FileInfo[]> IssuesPath { get; } =
new("--issues-path", "-ip") { Description = "Path to issues.targets", Arity = ArgumentArity.ZeroOrMore };
public Option<int> CompilationTimeoutMinutes { get; } =
new(new[] { "--compilation-timeout-minutes", "-ct" }, "Compilation timeout (minutes)");
public CliOption<int> CompilationTimeoutMinutes { get; } =
new("--compilation-timeout-minutes", "-ct") { Description = "Compilation timeout (minutes)" };
public Option<int> ExecutionTimeoutMinutes { get; } =
new(new[] { "--execution-timeout-minutes", "-et" }, "Execution timeout (minutes)");
public CliOption<int> ExecutionTimeoutMinutes { get; } =
new("--execution-timeout-minutes", "-et") { Description = "Execution timeout (minutes)" };
public Option<FileInfo> R2RDumpPath { get; } =
new Option<FileInfo>(new[] { "--r2r-dump-path" }, "Path to R2RDump.exe/dll").AcceptExistingOnly();
public CliOption<FileInfo> R2RDumpPath { get; } =
new CliOption<FileInfo>("--r2r-dump-path") { Description = "Path to R2RDump.exe/dll" }.AcceptExistingOnly();
public Option<bool> MeasurePerf { get; } =
new(new[] { "--measure-perf" }, "Print out compilation time");
public CliOption<bool> MeasurePerf { get; } =
new("--measure-perf") { Description = "Print out compilation time" };
public Option<string> InputFileSearchString { get; } =
new(new[] { "--input-file-search-string", "-input-file" }, "Search string for input files in the input directory");
public CliOption<string> InputFileSearchString { get; } =
new("--input-file-search-string", "-input-file") { Description = "Search string for input files in the input directory" };
public Option<string> GCStress { get; } =
new(new[] { "--gcstress" }, "Run tests with the specified GC stress level enabled (the argument value is in hex)");
public CliOption<string> GCStress { get; } =
new("--gcstress") { Description = "Run tests with the specified GC stress level enabled (the argument value is in hex)" };
public Option<string> DotNetCli { get; } =
new(new [] { "--dotnet-cli", "-cli" }, "For dev box testing, point at .NET 5 dotnet.exe or <repo>/dotnet.cmd.");
public CliOption<string> DotNetCli { get; } =
new("--dotnet-cli", "-cli") { Description = "For dev box testing, point at .NET 5 dotnet.exe or <repo>/dotnet.cmd." };
public Option<string> TargetArch { get; } =
new(new[] { "--target-arch" }, "Target architecture for crossgen2");
public CliOption<string> TargetArch { get; } =
new("--target-arch") { Description = "Target architecture for crossgen2" };
//
// compile-nuget specific options
//
public Option<FileInfo> PackageList { get; } =
new Option<FileInfo>(new[] { "--package-list", "-pl" }, "Text file containing a package name on each line").AcceptExistingOnly();
public CliOption<FileInfo> PackageList { get; } =
new CliOption<FileInfo>("--package-list", "-pl") { Description = "Text file containing a package name on each line" }.AcceptExistingOnly();
//
// compile-serp specific options
//
public Option<DirectoryInfo> AspNetPath { get; } =
new Option<DirectoryInfo>(new[] { "--asp-net-path", "-asp" }, "Path to SERP's ASP.NET Core folder").AcceptExistingOnly();
public CliOption<DirectoryInfo> AspNetPath { get; } =
new CliOption<DirectoryInfo>("--asp-net-path", "-asp") { Description = "Path to SERP's ASP.NET Core folder" }.AcceptExistingOnly();
private static int Main(string[] args) =>
new CommandLineBuilder(new R2RTestRootCommand())
.UseVersionOption("--version", "-v")
.UseHelp()
.UseParseErrorReporting()
.Build()
.Invoke(args);
new CliConfiguration(new R2RTestRootCommand().UseVersion())
{
EnableParseErrorReporting = true
}.Invoke(args);
}
public partial class BuildOptions
......
......@@ -11,17 +11,16 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Build">
<Version>16.0.461</Version>
</PackageReference>
<PackageReference Include="Microsoft.Build.Framework">
<Version>16.0.461</Version>
</PackageReference>
<PackageReference Include="Microsoft.Diagnostics.Tracing.TraceEvent">
<Version>$(TraceEventVersion)</Version>
</PackageReference>
<PackageReference Include="System.CommandLine">
<Version>$(SystemCommandLineVersion)</Version>
</PackageReference>
<Compile Include="..\Common\CommandLineHelpers.cs" Link="CommandLineHelpers.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\aot\ILCompiler.TypeSystem\ILCompiler.TypeSystem.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Build" Version="$(MicrosoftBuildVersion)" />
<PackageReference Include="Microsoft.Diagnostics.Tracing.TraceEvent" Version="$(TraceEventVersion)" />
<PackageReference Include="System.CommandLine" Version="$(SystemCommandLineVersion)" />
</ItemGroup>
</Project>
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册