From 7cb67f17063b0ee9e3ec1e9191d4ab5efcf43aae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Jare=C5=A1?= Date: Mon, 17 Jun 2024 11:29:11 +0200 Subject: [PATCH] Handle ansi escape in terminal logger reporter (#5084) --- .../Tasks/VSTestTask2.cs | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/Microsoft.TestPlatform.Build/Tasks/VSTestTask2.cs b/src/Microsoft.TestPlatform.Build/Tasks/VSTestTask2.cs index 27d6f57cf3..44eab60c86 100644 --- a/src/Microsoft.TestPlatform.Build/Tasks/VSTestTask2.cs +++ b/src/Microsoft.TestPlatform.Build/Tasks/VSTestTask2.cs @@ -49,8 +49,10 @@ public class VSTestTask2 : ToolTask, ITestTask private readonly string _messageSplitter = "||||"; private readonly string[] _messageSplitterArray = new[] { "||||" }; + private readonly string _ansiReset = "\x1b[39;49m"; private readonly bool _disableUtf8ConsoleEncoding; + private readonly bool _canBePrependedWithAnsi; protected override string? ToolName => RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "dotnet.exe" : "dotnet"; @@ -58,6 +60,9 @@ public VSTestTask2() { // Unless user opted out, use UTF encoding, which we force in vstest.console. _disableUtf8ConsoleEncoding = Environment.GetEnvironmentVariable("VSTEST_DISABLE_UTF8_CONSOLE_ENCODING") == "1"; + var isPrependedWithAnsi = Environment.GetEnvironmentVariable("DOTNET_SYSTEM_CONSOLE_ALLOW_ANSI_COLOR_REDIRECTION"); + // On macOS and Linux the messages are prepended with ANSI reset sequence. + _canBePrependedWithAnsi = isPrependedWithAnsi?.ToLowerInvariant() == "true" || isPrependedWithAnsi == "1"; LogStandardErrorAsError = false; StandardOutputImportance = "High"; } @@ -66,6 +71,17 @@ protected override void LogEventsFromTextOutput(string singleLine, MessageImport { var useTerminalLogger = true; Debug.WriteLine($"VSTESTTASK2: Received output {singleLine}, importance {messageImportance}"); + bool wasPrependedWithAnsi = false; + + if (_canBePrependedWithAnsi) + { + while (singleLine.StartsWith(_ansiReset)) + { + wasPrependedWithAnsi = true; + singleLine = singleLine.Substring(_ansiReset.Length); + } + } + if (TryGetMessage(singleLine, out string name, out string?[] data)) { // See MSBuildLogger.cs for the messages produced. @@ -75,7 +91,9 @@ protected override void LogEventsFromTextOutput(string singleLine, MessageImport case "output-info": if (data[0] != null) { - LogMSBuildOutputMessage(data[0]!); + // This is console output was prepended with ANSI reset, add it back. + string info = wasPrependedWithAnsi ? _ansiReset + data[0]! : data[0]!; + LogMSBuildOutputMessage(info); } break; case "output-warning":