Skip to content

Commit 5e0d144

Browse files
authored
Add GetConsoleLog() to BuildOutput class (#4)
1 parent 4a37ec5 commit 5e0d144

File tree

3 files changed

+129
-5
lines changed

3 files changed

+129
-5
lines changed

src/MSBuildProjectCreator.UnitTests/BuildOutputTests.cs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,33 @@ namespace Microsoft.Build.Utilities.ProjectCreation.UnitTests
1313
{
1414
public class BuildOutputTests
1515
{
16+
[Fact]
17+
public void ConsoleLog()
18+
{
19+
BuildOutput buildOutput = GetProjectLoggerWithEvents(eventSource =>
20+
{
21+
eventSource.OnErrorRaised("FDC8FB4F8E084055974580DF7CD7531E", "6496288436BE4E7CAE014F163914063C", "7B07B020E38343A89B3FA844A40895E4", 1, 2, 0, 0);
22+
eventSource.OnWarningRaised("E00BBDAEEFAB45949AFEE1BF792B1691", "56206897E63F44159603D22BB7C08145", "C455F26F4D4543E78F109BCB00F02BE2", 1, 2, 0, 0);
23+
eventSource.OnMessageRaised("55B991507D52403295E92E4FFA8704F3", MessageImportance.High);
24+
eventSource.OnMessageRaised("FA7FCCBE43B741998BAB399E74F2997D", MessageImportance.Normal);
25+
eventSource.OnMessageRaised("67C0E0E52F2A45A981F3143BAF00A4A3", MessageImportance.Low);
26+
});
27+
28+
buildOutput.GetConsoleLog()
29+
#pragma warning disable SA1116 // Split parameters must start on line after declaration
30+
.ShouldBe(@"7B07B020E38343A89B3FA844A40895E4(1,2): error 6496288436BE4E7CAE014F163914063C: FDC8FB4F8E084055974580DF7CD7531E
31+
32+
C455F26F4D4543E78F109BCB00F02BE2(1,2): warning 56206897E63F44159603D22BB7C08145: E00BBDAEEFAB45949AFEE1BF792B1691
33+
34+
55B991507D52403295E92E4FFA8704F3
35+
36+
FA7FCCBE43B741998BAB399E74F2997D
37+
38+
",
39+
#pragma warning restore SA1116 // Split parameters must start on line after declaration
40+
StringCompareShould.IgnoreLineEndings);
41+
}
42+
1643
[Theory]
1744
[InlineData("5F56E5B72FDE4405A021F166D0E4D7A8", "B586E6DA25314DA8B6700CF798A88892")]
1845
public void Errors(string expectedMessage, string expectedCode)

src/MSBuildProjectCreator.UnitTests/MockEventSource.cs

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,27 +40,37 @@ public sealed class MockEventSource : IEventSource2
4040

4141
public void OnBuildFinished(bool succeeded, string message = null, string helpKeyword = null)
4242
{
43-
BuildFinished?.Invoke(this, new BuildFinishedEventArgs(message, helpKeyword, succeeded));
43+
BuildFinishedEventArgs args = new BuildFinishedEventArgs(message, helpKeyword, succeeded);
44+
BuildFinished?.Invoke(this, args);
45+
OnAnyEventRaised(args);
4446
}
4547

4648
public void OnErrorRaised(string message, string code = null, string file = null, int lineNumber = -1, int columnNumber = -1, int endLineNumber = -1, int endColumnNumber = -1, string helpKeyword = null, string senderName = null)
4749
{
48-
ErrorRaised?.Invoke(this, new BuildErrorEventArgs(null, code, file, lineNumber, columnNumber, endLineNumber, endColumnNumber, message, helpKeyword, senderName));
50+
BuildErrorEventArgs args = new BuildErrorEventArgs(null, code, file, lineNumber, columnNumber, endLineNumber, endColumnNumber, message, helpKeyword, senderName);
51+
ErrorRaised?.Invoke(this, args);
52+
OnAnyEventRaised(args);
4953
}
5054

5155
public void OnMessageRaised(string message, MessageImportance importance = MessageImportance.Normal)
5256
{
53-
MessageRaised?.Invoke(this, new BuildMessageEventArgs(message, null, null, importance));
57+
BuildMessageEventArgs args = new BuildMessageEventArgs(message, null, null, importance);
58+
MessageRaised?.Invoke(this, args);
59+
OnAnyEventRaised(args);
5460
}
5561

5662
public void OnProjectFinished(string projectFile, bool succeeded, string message = null, string helpKeyword = null)
5763
{
58-
ProjectFinished?.Invoke(this, new ProjectFinishedEventArgs(message, helpKeyword, projectFile, succeeded));
64+
ProjectFinishedEventArgs args = new ProjectFinishedEventArgs(message, helpKeyword, projectFile, succeeded);
65+
ProjectFinished?.Invoke(this, args);
66+
OnAnyEventRaised(args);
5967
}
6068

6169
public void OnWarningRaised(string message, string code = null, string file = null, int lineNumber = -1, int columnNumber = -1, int endLineNumber = -1, int endColumnNumber = -1, string helpKeyword = null, string senderName = null)
6270
{
63-
WarningRaised?.Invoke(this, new BuildWarningEventArgs(null, code, file, lineNumber, columnNumber, endLineNumber, endColumnNumber, message, helpKeyword, senderName));
71+
BuildWarningEventArgs args = new BuildWarningEventArgs(null, code, file, lineNumber, columnNumber, endLineNumber, endColumnNumber, message, helpKeyword, senderName);
72+
WarningRaised?.Invoke(this, args);
73+
OnAnyEventRaised(args);
6474
}
6575

6676
// ReSharper disable once UnusedMember.Local

src/MSBuildProjectCreator/BuildOutput.cs

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,12 @@
33
// Licensed under the MIT license.
44

55
using Microsoft.Build.Framework;
6+
using Microsoft.Build.Logging;
67
using System;
78
using System.Collections.Concurrent;
89
using System.Collections.Generic;
910
using System.Linq;
11+
using System.Text;
1012

1113
namespace Microsoft.Build.Utilities.ProjectCreation
1214
{
@@ -35,6 +37,11 @@ public sealed class BuildOutput : ILogger, IDisposable
3537
/// </summary>
3638
private readonly List<BuildWarningEventArgs> _warnings = new List<BuildWarningEventArgs>();
3739

40+
/// <summary>
41+
/// Stores all build events.
42+
/// </summary>
43+
private ConcurrentQueue<BuildEventArgs> _allEvents = new ConcurrentQueue<BuildEventArgs>();
44+
3845
/// <summary>
3946
/// Stores the <see cref="BuildFinishedEventArgs"/> that were logged when the build finished.
4047
/// </summary>
@@ -44,6 +51,11 @@ private BuildOutput()
4451
{
4552
}
4653

54+
/// <summary>
55+
/// Gets all events that were logged.
56+
/// </summary>
57+
public IReadOnlyCollection<BuildEventArgs> AllEvents => _allEvents;
58+
4759
/// <summary>
4860
/// Gets the errors that were logged.
4961
/// </summary>
@@ -106,6 +118,75 @@ public void Dispose()
106118
_errors.Clear();
107119
_messages.Clear();
108120
_warnings.Clear();
121+
_allEvents = null;
122+
}
123+
124+
/// <summary>
125+
/// Gets the current build output in the format of a console log.
126+
/// </summary>
127+
/// <param name="verbosity">The logger verbosity to use.</param>
128+
/// <returns>The build output in the format of a console log.</returns>
129+
public string GetConsoleLog(LoggerVerbosity verbosity = LoggerVerbosity.Normal)
130+
{
131+
StringBuilder sb = new StringBuilder(_allEvents.Count * 300);
132+
133+
ConsoleLogger logger = new ConsoleLogger(verbosity, message => sb.AppendLine(message), color => { }, () => { });
134+
135+
foreach (BuildEventArgs buildEventArgs in _allEvents)
136+
{
137+
switch (buildEventArgs)
138+
{
139+
case BuildMessageEventArgs buildMessageEventArgs:
140+
logger.MessageHandler(logger, buildMessageEventArgs);
141+
break;
142+
143+
case BuildErrorEventArgs buildErrorEventArgs:
144+
logger.ErrorHandler(logger, buildErrorEventArgs);
145+
break;
146+
147+
case BuildWarningEventArgs buildWarningEventArgs:
148+
logger.WarningHandler(logger, buildWarningEventArgs);
149+
break;
150+
151+
case BuildStartedEventArgs buildStartedEventArgs:
152+
logger.BuildStartedHandler(logger, buildStartedEventArgs);
153+
break;
154+
155+
case BuildFinishedEventArgs buildFinishedEventArgs:
156+
logger.BuildFinishedHandler(logger, buildFinishedEventArgs);
157+
break;
158+
159+
case ProjectStartedEventArgs projectStartedEventArgs:
160+
logger.ProjectStartedHandler(logger, projectStartedEventArgs);
161+
break;
162+
163+
case ProjectFinishedEventArgs projectFinishedEventArgs:
164+
logger.ProjectFinishedHandler(logger, projectFinishedEventArgs);
165+
break;
166+
167+
case TargetStartedEventArgs targetStartedEventArgs:
168+
logger.TargetStartedHandler(logger, targetStartedEventArgs);
169+
break;
170+
171+
case TargetFinishedEventArgs targetFinishedEventArgs:
172+
logger.TargetFinishedHandler(logger, targetFinishedEventArgs);
173+
break;
174+
175+
case TaskStartedEventArgs taskStartedEventArgs:
176+
logger.TaskStartedHandler(logger, taskStartedEventArgs);
177+
break;
178+
179+
case TaskFinishedEventArgs taskFinishedEventArgs:
180+
logger.TaskFinishedHandler(logger, taskFinishedEventArgs);
181+
break;
182+
183+
case CustomBuildEventArgs customBuildEventArgs:
184+
logger.CustomEventHandler(logger, customBuildEventArgs);
185+
break;
186+
}
187+
}
188+
189+
return sb.ToString();
109190
}
110191

111192
/// <inheritdoc cref="ILogger.Initialize"/>
@@ -116,13 +197,19 @@ public void Initialize(IEventSource eventSource)
116197
eventSource.MessageRaised += OnMessageRaised;
117198
eventSource.ProjectFinished += OnProjectFinished;
118199
eventSource.WarningRaised += OnWarningRaised;
200+
eventSource.AnyEventRaised += OnAnyEventRaised;
119201
}
120202

121203
/// <inheritdoc cref="ILogger.Shutdown"/>
122204
public void Shutdown()
123205
{
124206
}
125207

208+
private void OnAnyEventRaised(object sender, BuildEventArgs e)
209+
{
210+
_allEvents.Enqueue(e);
211+
}
212+
126213
private void OnBuildFinished(object sender, BuildFinishedEventArgs args) => _buildFinished = args;
127214

128215
private void OnErrorRaised(object sender, BuildErrorEventArgs args) => _errors.Add(args);

0 commit comments

Comments
 (0)