in Public/Src/Tools/Execution.Analyzer/Args.cs [60:377]
public Args(string[] args)
: base(args)
{
List<Option> analyzerOptions = new List<Option>();
string cachedGraphDirectory = null;
// TODO: Embed HashType in XLG file and update analyzer to use that instead of setting HashType globally.
ContentHashingUtilities.SetDefaultHashType();
foreach (Option opt in Options)
{
if (opt.Name.Equals("executionLog", StringComparison.OrdinalIgnoreCase) ||
opt.Name.Equals("xl", StringComparison.OrdinalIgnoreCase))
{
if (string.IsNullOrEmpty(m_analysisInput.ExecutionLogPath))
{
m_analysisInput.ExecutionLogPath = ParsePathOption(opt);
}
else
{
m_analysisInputOther.ExecutionLogPath = ParseSingletonPathOption(opt, m_analysisInputOther.ExecutionLogPath);
}
}
else if (opt.Name.Equals("graphDirectory", StringComparison.OrdinalIgnoreCase) ||
opt.Name.Equals("gd", StringComparison.OrdinalIgnoreCase))
{
cachedGraphDirectory = ParseSingletonPathOption(opt, cachedGraphDirectory);
}
else if (opt.Name.Equals("mode", StringComparison.OrdinalIgnoreCase) ||
opt.Name.Equals("m", StringComparison.OrdinalIgnoreCase))
{
m_mode = ParseEnumOption<AnalysisMode>(opt);
}
else if (opt.Name.Equals("disableTelemetry"))
{
m_telemetryDisabled = true;
}
else if (opt.Name.Equals("disableWorkerEvents", StringComparison.OrdinalIgnoreCase))
{
m_canHandleWorkerEvents = false;
}
else if (s_helpStrings.Any(s => opt.Name.Equals(s, StringComparison.OrdinalIgnoreCase)))
{
// If the analyzer was called with '/help' argument - print help and exit
Help = true;
WriteHelp();
return;
}
else
{
analyzerOptions.Add(opt);
}
}
AnalyzerOptions = analyzerOptions;
if (!m_mode.HasValue)
{
throw Error("Mode parameter is required");
}
// Add required parameter errors here
switch (m_mode.Value)
{
case AnalysisMode.ObservedAccess:
{
if (!analyzerOptions.Any(opt => opt.Name.Equals("o")))
{
throw Error("When executing `ObservedAccess` mode, an `/o:PATH_TO_OUTPUT_FILE` parameter is required to store the generated output");
}
break;
}
}
// Only send telemetry if all arguments were valid
TelemetryStartup();
switch (m_mode.Value)
{
case AnalysisMode.SpecClosure:
var analyzer = InitializeSpecClosureAnalyzer();
analyzer.Analyze();
break;
}
if (string.IsNullOrEmpty(m_analysisInput.ExecutionLogPath) && string.IsNullOrEmpty(cachedGraphDirectory))
{
// Try to find the last build log from the user if none was specied.
var invocation = new global::BuildXL.Engine.Invocations().GetLastInvocation(LoggingContext);
if (invocation == null || !Directory.Exists(invocation.Value.LogsFolder))
{
throw Error("executionLog or graphDirectory parameter is required");
}
Console.WriteLine("Using last build from: '{0}', you can use /executionLog or /graphDirectory arguments to explicitly choose a build", invocation.Value.LogsFolder);
m_analysisInput.ExecutionLogPath = invocation.Value.LogsFolder;
}
if (m_mode.Value == AnalysisMode.LogCompare && string.IsNullOrEmpty(m_analysisInput.ExecutionLogPath))
{
throw Error("Additional executionLog to compare parameter is required");
}
// The fingerprint store based cache miss analyzer
// only uses graph information from the newer build, so skip loading the graph for the earlier build
if (m_mode.Value != AnalysisMode.CacheMiss)
{
if (!m_analysisInput.LoadCacheGraph(cachedGraphDirectory))
{
throw Error($"Could not load cached graph from directory {cachedGraphDirectory}");
}
}
switch (m_mode.Value)
{
case AnalysisMode.Allowlist:
case AnalysisMode.Whitelist:
m_analyzer = InitializeAllowlistAnalyzer();
break;
case AnalysisMode.BuildStatus:
m_analyzer = InitializeBuildStatus(m_analysisInput);
break;
case AnalysisMode.CacheDump:
m_analyzer = InitializeCacheDumpAnalyzer(m_analysisInput);
break;
#if FEATURE_VSTS_ARTIFACTSERVICES
case AnalysisMode.CacheHitPredictor:
m_analyzer = InitializeCacheHitPredictor();
break;
#endif
case AnalysisMode.CacheMiss:
// This analyzer does not rely on the execution log
if (!m_analysisInputOther.LoadCacheGraph(null))
{
throw Error("Could not load second cached graph");
}
m_analyzer = InitializeFingerprintStoreAnalyzer(m_analysisInput, m_analysisInputOther);
break;
case AnalysisMode.CacheMissLegacy:
m_analyzer = InitializeCacheMissAnalyzer(m_analysisInput);
if (!m_analysisInputOther.LoadCacheGraph(null))
{
throw Error("Could not load second cached graph");
}
m_analyzerOther = ((CacheMissAnalyzer)m_analyzer).GetDiffAnalyzer(m_analysisInputOther);
break;
case AnalysisMode.Codex:
m_analyzer = InitializeCodexAnalyzer();
break;
case AnalysisMode.CopyFile:
m_analyzer = InitializeCopyFilesAnalyzer();
break;
case AnalysisMode.CosineDumpPip:
m_analyzer = InitializeCosineDumpPip();
break;
case AnalysisMode.CosineJson:
m_analyzer = InitializeCosineJsonExport();
break;
case AnalysisMode.CriticalPath:
m_analyzer = InitializeCriticalPathAnalyzer();
break;
case AnalysisMode.DebugLogs:
ConsoleListener.RegisterEventSource(ETWLogger.Log);
ConsoleListener.RegisterEventSource(FrontEnd.Script.Debugger.ETWLogger.Log);
m_analyzer = InitializeDebugLogsAnalyzer();
break;
case AnalysisMode.DependencyAnalyzer:
m_analyzer = InitializeDependencyAnalyzer();
break;
case AnalysisMode.Dev:
m_analyzer = InitializeDevAnalyzer();
break;
case AnalysisMode.DirMembership:
m_analyzer = InitializeDirMembershipAnalyzer();
break;
case AnalysisMode.DumpMounts:
m_analyzer = InitializeDumpMountsAnalyzer();
break;
case AnalysisMode.DumpPip:
m_analyzer = InitializeDumpPipAnalyzer();
break;
case AnalysisMode.DumpPipLite:
m_analyzer = InitializeDumpPipLiteAnalyzer(m_analysisInput);
break;
case AnalysisMode.DumpProcess:
m_analyzer = InitializeDumpProcessAnalyzer();
break;
case AnalysisMode.DumpStringTable:
m_analyzer = InitializeDumpStringTableAnalyzer();
break;
case AnalysisMode.EventStats:
m_analyzer = InitializeEventStatsAnalyzer();
break;
case AnalysisMode.ExportDgml:
m_analyzer = InitializeExportDgmlAnalyzer();
break;
case AnalysisMode.ExportGraph:
m_analyzer = InitializePipGraphExporter();
break;
case AnalysisMode.ExtraDependencies:
m_analyzer = InitializeExtraDependenciesAnalyzer();
break;
case AnalysisMode.FailedPipsDump:
m_analyzer = InitializeFailedPipsDumpAnalyzer();
if (!string.IsNullOrEmpty(m_analysisInputOther.ExecutionLogPath))
{
if (!m_analysisInputOther.LoadCacheGraph(null))
{
throw Error("Could not load second cached graph");
}
m_analyzerOther = ((FailedPipsDumpAnalyzer)m_analyzer).GetDiffAnalyzer(m_analysisInputOther);
}
break;
case AnalysisMode.FailedPipInput:
m_analyzer = InitializeFailedPipInputAnalyzer();
break;
case AnalysisMode.FileConsumption:
m_analyzer = InitializeFileConsumptionAnalyzer();
break;
case AnalysisMode.FileChangeTracker:
m_analyzer = InitializeFileChangeTrackerAnalyzer();
break;
case AnalysisMode.FileImpact:
m_analyzer = InitializeFileImpactAnalyzer();
break;
case AnalysisMode.FilterLog:
m_analyzer = InitializeFilterLogAnalyzer();
break;
case AnalysisMode.FingerprintText:
m_analyzer = InitializeFingerprintTextAnalyzer();
break;
case AnalysisMode.GraphDiffAnalyzer:
if (!m_analysisInputOther.LoadCacheGraph(null))
{
throw Error("Could not load second cached graph");
}
m_analyzer = InitializeGraphDiffAnalyzer();
break;
case AnalysisMode.IdeGenerator:
m_analyzer = InitializeIdeGenerator();
break;
case AnalysisMode.IncrementalSchedulingState:
m_analyzer = InitializeIncrementalSchedulingStateAnalyzer();
break;
case AnalysisMode.InputTracker:
m_analyzer = InitializeInputTrackerAnalyzer();
break;
case AnalysisMode.JavaScriptDependencyFixer:
m_analyzer = JavaScriptDependencyFixerAnalyzer();
break;
case AnalysisMode.LogCompare:
m_analyzer = InitializeSummaryAnalyzer(m_analysisInput);
if (!m_analysisInputOther.LoadCacheGraph(null))
{
throw Error("Could not load second cached graph");
}
m_analyzerOther = InitializeSummaryAnalyzer(m_analysisInputOther, true);
break;
case AnalysisMode.ObservedAccess:
m_analyzer = InitializeObservedAccessAnalyzer();
break;
case AnalysisMode.ObservedInput:
m_analyzer = InitializeObservedInputResult();
break;
case AnalysisMode.ObservedInputSummary:
m_analyzer = InitializeObservedInputSummaryResult();
break;
case AnalysisMode.PackedExecutionExporter:
m_analyzer = InitializePackedExecutionExporter();
break;
case AnalysisMode.PerfSummary:
m_analyzer = InitializePerfSummaryAnalyzer();
break;
case AnalysisMode.PipExecutionPerformance:
m_analyzer = InitializePipExecutionPerformanceAnalyzer();
break;
case AnalysisMode.PipFilter:
m_analyzer = InitializePipFilterAnalyzer();
break;
case AnalysisMode.PipFingerprint:
m_analyzer = InitializePipFingerprintAnalyzer(m_analysisInput);
break;
case AnalysisMode.ProcessDetouringStatus:
m_analyzer = InitializeProcessDetouringStatusAnalyzer();
break;
case AnalysisMode.ProcessRunScript:
m_analyzer = InitializeProcessRunScriptAnalyzer();
break;
case AnalysisMode.RequiredDependencies:
m_analyzer = InitializeRequiredDependencyAnalyzer();
break;
case AnalysisMode.ScheduledInputsOutputs:
m_analyzer = InitializeScheduledInputsOutputsAnalyzer();
break;
case AnalysisMode.Simulate:
m_analyzer = InitializeBuildSimulatorAnalyzer(m_analysisInput);
break;
case AnalysisMode.ToolEnumeration:
m_analyzer = InitializeToolEnumerationAnalyzer();
break;
case AnalysisMode.WinIdeDependency:
m_analyzer = InitializeWinIdeDependencyAnalyzer();
break;
default:
Contract.Assert(false, "Unhandled analysis mode");
break;
}
Contract.Assert(m_analyzer != null, "Analyzer must be set.");
m_analyzer.LoggingContext = LoggingContext;
m_analyzer.CanHandleWorkerEvents = m_canHandleWorkerEvents;
if (m_analyzerOther != null)
{
m_analyzerOther.CanHandleWorkerEvents = m_canHandleWorkerEvents;
}
}