Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
]9;4;3;\MSB0001 error EvaluationError: An error occurred during evaluation.
[?25l
[?25h
Build failed with 1 error(s) in 5.0s
]9;4;0;\
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
MSB0001 error EvaluationError: An error occurred during evaluation.
[?25l
[?25h
Build failed with 1 error(s) in 5.0s
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
]9;4;3;\MSB0001 error EvaluationError: An error occurred during evaluation.
[?25l
[?25h
Build failed with 1 error(s) in 5.0s
]9;4;0;\
26 changes: 23 additions & 3 deletions src/Build.UnitTests/TerminalLogger_Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
using VerifyTests;
using VerifyXunit;
using Xunit;
using Xunit.Abstractions;
using static VerifyXunit.Verifier;

namespace Microsoft.Build.UnitTests
Expand Down Expand Up @@ -49,9 +50,11 @@ public class TerminalLogger_Tests : IEventSource, IDisposable
private VerifySettings _settings = new();

private readonly CultureInfo _originalCulture = Thread.CurrentThread.CurrentCulture;
private readonly ITestOutputHelper _outputHelper;

public TerminalLogger_Tests()
public TerminalLogger_Tests(ITestOutputHelper outputHelper)
{
_outputHelper = outputHelper;
_mockTerminal = new Terminal(_outputWriter);
_terminallogger = new TerminalLogger(_mockTerminal);

Expand Down Expand Up @@ -592,6 +595,23 @@ public Task PrintBuildSummaryMinimalVerbosity_FailedWithErrors()
return Verify(_outputWriter.ToString(), _settings).UniqueForOSPlatform();
}

[Fact]
public Task LogEvaluationErrorFromEngine()
{
_terminallogger.Verbosity = LoggerVerbosity.Normal;
InvokeLoggerCallbacksForSimpleProject(succeeded: false, () =>
{
ErrorRaised?.Invoke(_eventSender, new BuildErrorEventArgs(
"MSB0001", "EvaluationError", "MSBUILD", 0, 0, 0, 0,
"An error occurred during evaluation.", null, null)
{
BuildEventContext = new BuildEventContext(1, -1, -1, -1) // context that belongs to no project
});
});

return Verify(_outputWriter.ToString(), _settings).UniqueForOSPlatform();
}

[Fact]
public Task PrintBuildSummaryNormalVerbosity_FailedWithErrors()
{
Expand Down Expand Up @@ -782,11 +802,11 @@ public void TestTerminalLoggerTogetherWithOtherLoggers()
string logFileWithoutTL = env.ExpectFile(".binlog").Path;

// Execute MSBuild with binary, file and terminal loggers
RunnerUtilities.ExecMSBuild($"{projectFile.Path} /m /bl:{logFileWithTL} -flp:logfile={Path.Combine(logFolder.Path, "logFileWithTL.log")};verbosity=diagnostic -tl:on", out bool success);
RunnerUtilities.ExecMSBuild($"{projectFile.Path} /m /bl:{logFileWithTL} -flp:logfile={Path.Combine(logFolder.Path, "logFileWithTL.log")};verbosity=diagnostic -tl:on", out bool success, outputHelper: _outputHelper);
success.ShouldBeTrue();

// Execute MSBuild with binary and file loggers
RunnerUtilities.ExecMSBuild($"{projectFile.Path} /m /bl:{logFileWithoutTL} -flp:logfile={Path.Combine(logFolder.Path, "logFileWithoutTL.log")};verbosity=diagnostic", out success);
RunnerUtilities.ExecMSBuild($"{projectFile.Path} /m /bl:{logFileWithoutTL} -flp:logfile={Path.Combine(logFolder.Path, "logFileWithoutTL.log")};verbosity=diagnostic", out success, outputHelper: _outputHelper);
success.ShouldBeTrue();

// Read the binary log and replay into mockLogger
Expand Down
2 changes: 2 additions & 0 deletions src/Build/BackEnd/Components/Logging/EventSourceSink.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using System.Diagnostics;
using Microsoft.Build.Experimental.BuildCheck;
using Microsoft.Build.Framework;
using Microsoft.Build.Framework.Telemetry;
Expand All @@ -15,6 +16,7 @@ namespace Microsoft.Build.BackEnd.Logging
/// <summary>
/// This class raises events on behalf of the build engine to all registered loggers.
/// </summary>
[DebuggerDisplay("{Name}")]
internal sealed class EventSourceSink :
#if FEATURE_APPDOMAIN
MarshalByRefObject,
Expand Down
25 changes: 14 additions & 11 deletions src/Build/BackEnd/Components/Logging/LoggingService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@
using System.Reflection;
using System.Threading;
using Microsoft.Build.BackEnd.Components.RequestBuilder;
using Microsoft.Build.Evaluation;
using Microsoft.Build.Experimental.BuildCheck;
using Microsoft.Build.Experimental.BuildCheck.Infrastructure;
using Microsoft.Build.Framework;
using Microsoft.Build.Logging;
using Microsoft.Build.Shared;
using InternalLoggerException = Microsoft.Build.Exceptions.InternalLoggerException;
using LoggerDescription = Microsoft.Build.Logging.LoggerDescription;
Expand Down Expand Up @@ -1109,7 +1109,9 @@ public bool RegisterDistributedLogger(ILogger centralLogger, LoggerDescription f
EventSourceSink eventSourceSink = new EventSourceSink();

// If the logger is already in the list it should not be registered again.
if (_loggers.Contains(centralLogger))
// Note here that we are checking for direct equivalence (fast)
// and if we're dealing with a reusable logger, we need to check its original logger (slower)
if (_loggers.Contains(centralLogger) || _loggers.Any(l => l is ReusableLogger rl && rl.OriginalLogger == centralLogger))
{
return false;
}
Expand Down Expand Up @@ -1778,7 +1780,7 @@ private void InitializeLogger(ILogger logger, IEventSource sourceForLogger)
{
ILogger UnwrapLoggerType(ILogger log)
{
while (log is ProjectCollection.ReusableLogger reusableLogger)
while (log is Microsoft.Build.Logging.ReusableLogger reusableLogger)
{
log = reusableLogger.OriginalLogger;
}
Expand Down Expand Up @@ -1824,12 +1826,12 @@ ILogger UnwrapLoggerType(ILogger log)
/// </remarks>
private void UpdateMinimumMessageImportance(ILogger logger)
{
var innerLogger = (logger is ProjectCollection.ReusableLogger reusableLogger) ? reusableLogger.OriginalLogger : logger;
var innerLogger = (logger is ReusableLogger reusableLogger) ? reusableLogger.OriginalLogger : logger;

MessageImportance? minimumImportance = innerLogger switch
{
Build.Logging.ConsoleLogger consoleLogger => consoleLogger.GetMinimumMessageImportance(),
Build.Logging.ConfigurableForwardingLogger forwardingLogger => forwardingLogger.GetMinimumMessageImportance(),
ConsoleLogger consoleLogger => consoleLogger.GetMinimumMessageImportance(),
ConfigurableForwardingLogger forwardingLogger => forwardingLogger.GetMinimumMessageImportance(),

// The BuildCheck connector logger consumes only high priority messages.
BuildCheckForwardingLogger => MessageImportance.High,
Expand All @@ -1846,11 +1848,12 @@ private void UpdateMinimumMessageImportance(ILogger logger)
// The null logger has no effect on minimum verbosity.
Execution.BuildManager.NullLogger => null,

// The terminal logger consumes only high priority messages.
_ => innerLogger.GetType().FullName == "Microsoft.Build.Logging.TerminalLogger.TerminalLogger"
? MessageImportance.High
// If the logger is not on our allow list, there are no importance guarantees. Fall back to "any importance".
: MessageImportance.Low,
TerminalLogger terminalLogger => terminalLogger.GetMinimumMessageImportance(),
_ =>
innerLogger.GetType().FullName == "Microsoft.Build.Logging.TerminalLogger"
? MessageImportance.High
// If the logger is not on our allow list, there are no importance guarantees. Fall back to "any importance".
: MessageImportance.Low,
};

if (minimumImportance != null)
Expand Down
Loading