Browse Source

ctest_build: ignore ANSI color

Ignore ANSI color when scraping logs for errors and warnings
Zack Galbreath 6 years ago
parent
commit
2079267959

+ 18 - 9
Source/CTest/cmCTestBuildHandler.cxx

@@ -10,6 +10,7 @@
 #include "cmMakefile.h"
 #include "cmProcessOutput.h"
 #include "cmStringAlgorithms.h"
+#include "cmStringReplaceHelper.h"
 #include "cmSystemTools.h"
 #include "cmXMLWriter.h"
 
@@ -408,6 +409,9 @@ int cmCTestBuildHandler::ProcessHandler()
   // Remember start build time
   this->StartBuild = this->CTest->CurrentTime();
   this->StartBuildTime = std::chrono::system_clock::now();
+
+  cmStringReplaceHelper colorRemover("\x1b\\[[0-9;]*m", "", nullptr);
+  this->ColorRemover = &colorRemover;
   int retVal = 0;
   int res = cmsysProcess_State_Exited;
   if (!this->CTest->GetShowOnly()) {
@@ -1077,7 +1081,12 @@ int cmCTestBuildHandler::ProcessSingleLine(const char* data)
     return b_REGULAR_LINE;
   }
 
-  cmCTestOptionalLog(this->CTest, DEBUG, "Line: [" << data << "]" << std::endl,
+  // Ignore ANSI color codes when checking for errors and warnings.
+  std::string input(data);
+  std::string line;
+  this->ColorRemover->Replace(input, line);
+
+  cmCTestOptionalLog(this->CTest, DEBUG, "Line: [" << line << "]" << std::endl,
                      this->Quiet);
 
   int warningLine = 0;
@@ -1089,10 +1098,10 @@ int cmCTestBuildHandler::ProcessSingleLine(const char* data)
     // Errors
     int wrxCnt = 0;
     for (cmsys::RegularExpression& rx : this->ErrorMatchRegex) {
-      if (rx.find(data)) {
+      if (rx.find(line.c_str())) {
         errorLine = 1;
         cmCTestOptionalLog(this->CTest, DEBUG,
-                           "  Error Line: " << data << " (matches: "
+                           "  Error Line: " << line << " (matches: "
                                             << this->CustomErrorMatches[wrxCnt]
                                             << ")" << std::endl,
                            this->Quiet);
@@ -1103,11 +1112,11 @@ int cmCTestBuildHandler::ProcessSingleLine(const char* data)
     // Error exceptions
     wrxCnt = 0;
     for (cmsys::RegularExpression& rx : this->ErrorExceptionRegex) {
-      if (rx.find(data)) {
+      if (rx.find(line.c_str())) {
         errorLine = 0;
         cmCTestOptionalLog(this->CTest, DEBUG,
                            "  Not an error Line: "
-                             << data << " (matches: "
+                             << line << " (matches: "
                              << this->CustomErrorExceptions[wrxCnt] << ")"
                              << std::endl,
                            this->Quiet);
@@ -1120,11 +1129,11 @@ int cmCTestBuildHandler::ProcessSingleLine(const char* data)
     // Warnings
     int wrxCnt = 0;
     for (cmsys::RegularExpression& rx : this->WarningMatchRegex) {
-      if (rx.find(data)) {
+      if (rx.find(line.c_str())) {
         warningLine = 1;
         cmCTestOptionalLog(this->CTest, DEBUG,
                            "  Warning Line: "
-                             << data << " (matches: "
+                             << line << " (matches: "
                              << this->CustomWarningMatches[wrxCnt] << ")"
                              << std::endl,
                            this->Quiet);
@@ -1136,11 +1145,11 @@ int cmCTestBuildHandler::ProcessSingleLine(const char* data)
     wrxCnt = 0;
     // Warning exceptions
     for (cmsys::RegularExpression& rx : this->WarningExceptionRegex) {
-      if (rx.find(data)) {
+      if (rx.find(line.c_str())) {
         warningLine = 0;
         cmCTestOptionalLog(this->CTest, DEBUG,
                            "  Not a warning Line: "
-                             << data << " (matches: "
+                             << line << " (matches: "
                              << this->CustomWarningExceptions[wrxCnt] << ")"
                              << std::endl,
                            this->Quiet);

+ 4 - 0
Source/CTest/cmCTestBuildHandler.h

@@ -18,6 +18,7 @@
 #include <vector>
 
 class cmMakefile;
+class cmStringReplaceHelper;
 class cmXMLWriter;
 
 /** \class cmCTestBuildHandler
@@ -143,6 +144,9 @@ private:
   int MaxErrors;
   int MaxWarnings;
 
+  // Used to remove ANSI color codes before checking for errors and warnings.
+  cmStringReplaceHelper* ColorRemover;
+
   bool UseCTestLaunch;
   std::string CTestLaunchDir;
   class LaunchHelper;

+ 2 - 1
Tests/RunCMake/CMakeLists.txt

@@ -248,7 +248,8 @@ add_RunCMake_test(export)
 add_RunCMake_test(cmake_minimum_required)
 add_RunCMake_test(cmake_parse_arguments)
 add_RunCMake_test(continue)
-add_RunCMake_test(ctest_build)
+add_executable(color_warning color_warning.c)
+add_RunCMake_test(ctest_build -DCOLOR_WARNING=$<TARGET_FILE:color_warning>)
 add_RunCMake_test(ctest_cmake_error)
 add_RunCMake_test(ctest_configure)
 if(COVERAGE_COMMAND)

+ 7 - 0
Tests/RunCMake/color_warning.c

@@ -0,0 +1,7 @@
+#include <stdio.h>
+int main(void)
+{
+  printf(
+    "/tmp/hello.c:3:2: \033[35mwarning:\033[0m Hello, World! [-W#warnings]\n");
+  return 0;
+}

+ 2 - 0
Tests/RunCMake/ctest_build/IgnoreColor-stdout.txt

@@ -0,0 +1,2 @@
+   0 Compiler errors
+   1 Compiler warnings

+ 8 - 0
Tests/RunCMake/ctest_build/RunCMakeTest.cmake

@@ -1,6 +1,8 @@
 include(RunCTest)
 
 set(CASE_CTEST_BUILD_ARGS "")
+set(RunCMake_USE_LAUNCHERS TRUE)
+set(RunCMake_USE_CUSTOM_BUILD_COMMAND FALSE)
 
 function(run_ctest_build CASE_NAME)
   set(CASE_CTEST_BUILD_ARGS "${ARGN}")
@@ -45,3 +47,9 @@ function(run_BuildChangeId)
   run_ctest(BuildChangeId)
 endfunction()
 run_BuildChangeId()
+
+set(RunCMake_USE_LAUNCHERS FALSE)
+set(RunCMake_USE_CUSTOM_BUILD_COMMAND TRUE)
+set(RunCMake_BUILD_COMMAND "${COLOR_WARNING}")
+run_ctest(IgnoreColor)
+unset(RunCMake_BUILD_COMMAND)

+ 4 - 1
Tests/RunCMake/ctest_build/test.cmake.in

@@ -9,7 +9,10 @@ set(CTEST_CMAKE_GENERATOR               "@RunCMake_GENERATOR@")
 set(CTEST_CMAKE_GENERATOR_PLATFORM      "@RunCMake_GENERATOR_PLATFORM@")
 set(CTEST_CMAKE_GENERATOR_TOOLSET       "@RunCMake_GENERATOR_TOOLSET@")
 set(CTEST_BUILD_CONFIGURATION           "$ENV{CMAKE_CONFIG_TYPE}")
-set(CTEST_USE_LAUNCHERS                 TRUE)
+set(CTEST_USE_LAUNCHERS                 "@RunCMake_USE_LAUNCHERS@")
+if (@RunCMake_USE_CUSTOM_BUILD_COMMAND@)
+  set(CTEST_BUILD_COMMAND               "\"@RunCMake_BUILD_COMMAND@\"")
+endif()
 
 set(ctest_build_args "@CASE_CTEST_BUILD_ARGS@")
 ctest_start(Experimental)