-
-
Notifications
You must be signed in to change notification settings - Fork 200
/
Copy pathBinaryLog.cs
146 lines (120 loc) · 5.11 KB
/
BinaryLog.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
namespace Microsoft.Build.Logging.StructuredLogger
{
public class BinaryLog
{
public static IEnumerable<Record> ReadRecords(string binLogFilePath)
{
var reader = new BinLogReader();
return reader.ReadRecords(binLogFilePath);
}
public static IEnumerable<Record> ReadRecords(Stream binlogStream)
{
var reader = new BinLogReader();
return reader.ReadRecords(binlogStream);
}
public static IEnumerable<Record> ReadRecords(byte[] binlogBytes)
{
var reader = new BinLogReader();
return reader.ReadRecords(binlogBytes);
}
public static Build ReadBuild(string filePath) => ReadBuild(filePath, progress: null);
public static Build ReadBuild(string filePath, Progress progress)
{
using (var stream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read))
{
var projectImportsZipFile = Path.ChangeExtension(filePath, ".ProjectImports.zip");
byte[] projectImportsArchive = null;
if (File.Exists(projectImportsZipFile))
{
projectImportsArchive = File.ReadAllBytes(projectImportsZipFile);
}
var build = ReadBuild(stream, progress, projectImportsArchive);
build.LogFilePath = filePath;
return build;
}
}
public static Build ReadBuild(Stream stream, byte[] projectImportsArchive = null)
=> ReadBuild(stream, progress: null, projectImportsArchive: projectImportsArchive);
internal const bool ReuseBinlogStrings = false;
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;
}
}
}