public IEnumerable <CompilerInvocation> Read(string binLogFilePath) { binLogFilePath = Path.GetFullPath(binLogFilePath); if (!File.Exists(binLogFilePath)) { throw new FileNotFoundException(binLogFilePath); } if (binLogFilePath.EndsWith(".buildlog", StringComparison.OrdinalIgnoreCase)) { return(ReadBuildLogFormat(binLogFilePath)); } var invocations = new List <CompilerInvocation>(); var reader = new BinLogReader(); var taskIdToInvocationMap = new Dictionary <(int, int), CompilerInvocation>(); void TryGetInvocationFromEvent(object sender, BuildEventArgs args) { var invocation = TryGetInvocationFromRecord(args, taskIdToInvocationMap); if (invocation != null) { invocations.Add(invocation); } } reader.TargetStarted += TryGetInvocationFromEvent; reader.MessageRaised += TryGetInvocationFromEvent; reader.Replay(binLogFilePath); return(invocations); }
public static IEnumerable <CompilerInvocation> ExtractInvocations(string binLogFilePath) { // Normalize the path binLogFilePath = Path.GetFullPath(binLogFilePath); if (!File.Exists(binLogFilePath)) { throw new FileNotFoundException(binLogFilePath); } var lazyResult = m_binlogInvocationMap.GetOrAdd(binLogFilePath, new Lazy <List <CompilerInvocation> >(() => { if (binLogFilePath.EndsWith(".buildlog", StringComparison.OrdinalIgnoreCase)) { return(ExtractInvocationsFromBuild(binLogFilePath)); } var invocations = new List <CompilerInvocation>(); var reader = new Microsoft.Build.Logging.StructuredLogger.BinLogReader(); var taskIdToInvocationMap = new Dictionary <(int, int), CompilerInvocation>(); void TryGetInvocationFromEvent(object sender, BuildEventArgs args) { var invocation = TryGetInvocationFromRecord(args, taskIdToInvocationMap); if (invocation != null) { invocations.Add(invocation); } } reader.TargetStarted += TryGetInvocationFromEvent; reader.MessageRaised += TryGetInvocationFromEvent; reader.Replay(binLogFilePath); return(invocations); })); var result = lazyResult.Value; // Remove the lazy now that the operation has completed m_binlogInvocationMap.TryRemove(binLogFilePath, out var ignored); return(result); }
private static (StLogger.Build, IEnumerable <StLogger.Error>) ProcessBuildLog(string tempPath) { var reader = new StLogger.BinLogReader(); var stlogger = new StLogger.StructuredLogger(); // prevent output temporary file StLogger.StructuredLogger.SaveLogToDisk = false; // never output, but if not set, throw exception when initializing stlogger.Parameters = "tmp.buildlog"; stlogger.Initialize(reader); reader.Replay(Path.Combine(tempPath, "build.binlog")); stlogger.Shutdown(); StLogger.Build buildlog = stlogger.Construction.Build; if (buildlog.Succeeded) { return(buildlog, null); } else { IEnumerable <StLogger.Error> errors = FindAllErrors(buildlog); return(null, errors); } }
public static Build ReadBuild(Stream stream, Progress progress, byte[] projectImportsArchive = null) { var eventSource = new BinLogReader(); Build build = null; IEnumerable <string> strings = null; eventSource.OnBlobRead += (kind, bytes) => { if (kind == BinaryLogRecordKind.ProjectImportArchive) { projectImportsArchive = bytes; } }; eventSource.OnException += ex => { if (build != null) { build.AddChild(new Error() { Text = "Error when reading the file: " + ex.ToString() }); } }; eventSource.OnStringDictionaryComplete += s => { strings = s; }; StructuredLogger.SaveLogToDisk = false; StructuredLogger.CurrentBuild = null; var structuredLogger = new StructuredLogger(); structuredLogger.Parameters = "build.buildlog"; structuredLogger.Initialize(eventSource); build = structuredLogger.Construction.Build; eventSource.OnFileFormatVersionRead += fileFormatVersion => { build.FileFormatVersion = fileFormatVersion; // strings are deduplicated starting with version 10 if (fileFormatVersion >= 10) { build.StringTable.NormalizeLineEndings = false; build.StringTable.HasDeduplicatedStrings = true; if (ReuseBinlogStrings) { build.StringTable.DisableDeduplication = true; } } }; var sw = Stopwatch.StartNew(); eventSource.Replay(stream, progress); var elapsed = sw.Elapsed; if (strings != null) { if (ReuseBinlogStrings) { // since strings are already deduplicated in the file, no need to do it again build.StringTable.SetStrings(strings); } else { // intern all strings in one fell swoop here instead of interning multiple times // one by one when processing task parameters build.StringTable.Intern(strings); } } structuredLogger.Shutdown(); build = StructuredLogger.CurrentBuild; StructuredLogger.CurrentBuild = null; if (build == null) { build = new Build() { Succeeded = false }; build.AddChild(new Error() { Text = "Error when opening the log file." }); } if (build.SourceFilesArchive == null && projectImportsArchive != null) { build.SourceFilesArchive = projectImportsArchive; } // strings = build.StringTable.Instances.OrderBy(s => s).ToArray(); // Serialization.WriteStringsToFile(@"C:\temp\1.txt", strings.ToArray()); return(build); }
public static Build ReadBuild(Stream stream, byte[] projectImportsArchive = null) { var eventSource = new BinLogReader(); Build build = null; eventSource.OnBlobRead += (kind, bytes) => { if (kind == BinaryLogRecordKind.ProjectImportArchive) { projectImportsArchive = bytes; } }; eventSource.OnException += ex => { if (build != null) { build.AddChild(new Error() { Text = "Error when reading the file: " + ex.ToString() }); } }; StructuredLogger.SaveLogToDisk = false; StructuredLogger.CurrentBuild = null; var structuredLogger = new StructuredLogger(); structuredLogger.Parameters = "build.buildlog"; structuredLogger.Initialize(eventSource); build = structuredLogger.Construction.Build; var sw = Stopwatch.StartNew(); eventSource.Replay(stream); var elapsed = sw.Elapsed; structuredLogger.Shutdown(); build = StructuredLogger.CurrentBuild; StructuredLogger.CurrentBuild = null; if (build == null) { build = new Build() { Succeeded = false }; build.AddChild(new Error() { Text = "Error when opening the log file." }); } if (build.SourceFilesArchive == null && projectImportsArchive != null) { build.SourceFilesArchive = projectImportsArchive; } // build.AddChildAtBeginning(new Message { Text = "Elapsed: " + elapsed.ToString() }); return(build); }
public static Build ReadBuild(Stream stream, byte[] projectImportsArchive = null) { var eventSource = new BinLogReader(); Build build = null; eventSource.OnBlobRead += (kind, bytes) => { if (kind == BinaryLogRecordKind.ProjectImportArchive) { projectImportsArchive = bytes; } }; eventSource.OnException += ex => { if (build != null) { build.AddChild(new Error() { Text = "Error when reading the file: " + ex.ToString() }); } }; StructuredLogger.SaveLogToDisk = false; StructuredLogger.CurrentBuild = null; var structuredLogger = new StructuredLogger(); structuredLogger.Parameters = "build.buildlog"; structuredLogger.Initialize(eventSource); eventSource.OnFileFormatVersionRead += fileFormatVersion => { if (fileFormatVersion >= 10) { // since strings are already deduplicated in the file, no need to do it again // TODO: but search will not work if the string table is empty // structuredLogger.Construction.StringTable.DisableDeduplication = true; } }; build = structuredLogger.Construction.Build; var sw = Stopwatch.StartNew(); eventSource.Replay(stream); var elapsed = sw.Elapsed; structuredLogger.Shutdown(); build = StructuredLogger.CurrentBuild; StructuredLogger.CurrentBuild = null; if (build == null) { build = new Build() { Succeeded = false }; build.AddChild(new Error() { Text = "Error when opening the log file." }); } if (build.SourceFilesArchive == null && projectImportsArchive != null) { build.SourceFilesArchive = projectImportsArchive; } // build.AddChildAtBeginning(new Message { Text = "Elapsed: " + elapsed.ToString() }); return(build); }