Browse Source

Merge topic 'feature/message-indent'

5f6fd917a3 message(): Control indentation via CMAKE_MESSAGE_INDENT

Acked-by: Kitware Robot <[email protected]>
Merge-request: !3464
Craig Scott 6 years ago
parent
commit
f4131e4e1b

+ 5 - 0
Help/command/message.rst

@@ -60,6 +60,11 @@ messages one at a time on a status line and other messages in an
 interactive pop-up box.  The ``--loglevel`` command-line option to each of
 these tools can be used to control which messages will be shown.
 
+Messages of log levels ``NOTICE`` and below will also have each line preceded
+by the content of the :variable:`CMAKE_MESSAGE_INDENT` variable (converted to
+a single string by concatenating its list items).  For ``STATUS`` to ``TRACE``
+messages, this indenting content will be inserted after the hyphens.
+
 CMake Warning and Error message text displays using a simple markup
 language.  Non-indented text is formatted in line-wrapped paragraphs
 delimited by newlines.  Indented text is considered pre-formatted.

+ 1 - 0
Help/manual/cmake-variables.7.rst

@@ -69,6 +69,7 @@ Variables that Provide Information
    /variable/CMAKE_MAKE_PROGRAM
    /variable/CMAKE_MATCH_COUNT
    /variable/CMAKE_MATCH_n
+   /variable/CMAKE_MESSAGE_INDENT
    /variable/CMAKE_MINIMUM_REQUIRED_VERSION
    /variable/CMAKE_MINOR_VERSION
    /variable/CMAKE_NETRC

+ 5 - 0
Help/release/dev/message-indent.rst

@@ -0,0 +1,5 @@
+message-indent
+--------------
+
+* The :command:`message` command learned indentation control with the new
+  :variable:`CMAKE_MESSAGE_INDENT` variable.

+ 30 - 0
Help/variable/CMAKE_MESSAGE_INDENT.rst

@@ -0,0 +1,30 @@
+CMAKE_MESSAGE_INDENT
+--------------------
+
+The :command:`message` command joins the strings from this list and for
+log levels of ``NOTICE`` and below, it prepends the resultant string to
+each line of the message.
+
+Example:
+
+.. code-block:: cmake
+
+  list(APPEND listVar one two three)
+
+  message(VERBOSE [[Collected items in the "listVar":]])
+  list(APPEND CMAKE_MESSAGE_INDENT "  ")
+
+  foreach(item IN LISTS listVar)
+    message(VERBOSE ${item})
+  endforeach()
+
+  list(POP_BACK CMAKE_MESSAGE_INDENT)
+  message(VERBOSE "No more indent")
+
+Which results in the following output:
+
+  -- Collected items in the "listVar":
+  --   one
+  --   two
+  --   tree
+  -- No more indent

+ 38 - 14
Source/cmMessageCommand.cxx

@@ -25,7 +25,6 @@ bool cmMessageCommand::InitialPass(std::vector<std::string> const& args,
   auto i = args.cbegin();
 
   auto type = MessageType::MESSAGE;
-  auto status = false;
   auto fatal = false;
   auto level = cmake::LogLevel::LOG_UNDEFINED;
   if (*i == "SEND_ERROR") {
@@ -55,19 +54,15 @@ bool cmMessageCommand::InitialPass(std::vector<std::string> const& args,
     }
     ++i;
   } else if (*i == "STATUS") {
-    status = true;
     level = cmake::LogLevel::LOG_STATUS;
     ++i;
   } else if (*i == "VERBOSE") {
-    status = true;
     level = cmake::LogLevel::LOG_VERBOSE;
     ++i;
   } else if (*i == "DEBUG") {
-    status = true;
     level = cmake::LogLevel::LOG_DEBUG;
     ++i;
   } else if (*i == "TRACE") {
-    status = true;
     level = cmake::LogLevel::LOG_TRACE;
     ++i;
   } else if (*i == "DEPRECATION") {
@@ -105,17 +100,46 @@ bool cmMessageCommand::InitialPass(std::vector<std::string> const& args,
 
   auto message = cmJoin(cmMakeRange(i, args.cend()), "");
 
-  if (type != MessageType::MESSAGE) {
-    // we've overridden the message type, above, so display it directly
-    cmMessenger* m = this->Makefile->GetMessenger();
-    m->DisplayMessage(type, message, this->Makefile->GetBacktrace());
-  } else {
-    if (status) {
-      this->Makefile->DisplayStatus(message, -1);
-    } else {
+  if (cmake::LogLevel::LOG_NOTICE <= level) {
+    // Check if any indentation has requested:
+    // `CMAKE_MESSAGE_INDENT` is a list of "padding" pieces
+    // to be joined and prepended to the message lines.
+    auto indent =
+      cmJoin(cmSystemTools::ExpandedListArgument(
+               this->Makefile->GetSafeDefinition("CMAKE_MESSAGE_INDENT")),
+             "");
+    // Make every line of the `message` indented
+    // NOTE Can't reuse `cmDocumentationFormatter::PrintPreformatted`
+    // here cuz it appends `\n` to the EOM ;-(
+    cmSystemTools::ReplaceString(message, "\n", "\n" + indent);
+    message = indent + message;
+  }
+
+  switch (level) {
+    case cmake::LogLevel::LOG_ERROR:
+    case cmake::LogLevel::LOG_WARNING:
+      // we've overridden the message type, above, so display it directly
+      this->Makefile->GetMessenger()->DisplayMessage(
+        type, message, this->Makefile->GetBacktrace());
+      break;
+
+    case cmake::LogLevel::LOG_NOTICE:
       cmSystemTools::Message(message);
-    }
+      break;
+
+    case cmake::LogLevel::LOG_STATUS:
+    case cmake::LogLevel::LOG_VERBOSE:
+    case cmake::LogLevel::LOG_DEBUG:
+    case cmake::LogLevel::LOG_TRACE:
+      this->Makefile->DisplayStatus(message, -1);
+      break;
+
+    default:
+      assert("Unexpected log level! Review the `cmMessageCommand.cxx`." &&
+             false);
+      break;
   }
+
   if (fatal) {
     cmSystemTools::SetFatalErrorOccured();
   }

+ 9 - 0
Tests/RunCMake/message/RunCMakeTest.cmake

@@ -52,3 +52,12 @@ run_cmake_command(
     message-loglevel-trace
     ${CMAKE_COMMAND} --loglevel=trace -P ${RunCMake_SOURCE_DIR}/message-all-loglevels.cmake
   )
+
+run_cmake_command(
+    message-indent
+    ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/message-indent.cmake
+  )
+run_cmake_command(
+    message-indent-multiline
+    ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/message-indent-multiline.cmake
+  )

+ 3 - 0
Tests/RunCMake/message/message-indent-multiline-stderr.txt

@@ -0,0 +1,3 @@
+ >This is
+ >the multiline
+ >message

+ 8 - 0
Tests/RunCMake/message/message-indent-multiline-stdout.txt

@@ -0,0 +1,8 @@
+--  >This is
+ >the multiline
+ >message
+ >
+ >
+--  >This is
+ >the multiline
+ >message

+ 13 - 0
Tests/RunCMake/message/message-indent-multiline.cmake

@@ -0,0 +1,13 @@
+# NOTE Use non-space indent string, to check indentation
+# of line endings and "empty" lines.
+# ALERT Do not put any space characters after the non-space!
+list(APPEND CMAKE_MESSAGE_INDENT " >")
+set(msg [[This is
+the multiline
+message]]) # No `\n` at the end!
+# NOTE Two empty lines after the text
+message(STATUS "${msg}\n\n")
+message(STATUS "${msg}")
+# This is just to make sure NOTICE messages are also get indented:
+# https://gitlab.kitware.com/cmake/cmake/issues/19418#note_588011
+message(NOTICE "${msg}")

+ 13 - 0
Tests/RunCMake/message/message-indent-stdout.txt

@@ -0,0 +1,13 @@
+-- COUNTING:
+--    COUNTING_ENGLISH:
+--       one
+--       two
+--       three
+--       four
+--       five
+--    COUNTING_BAHASA:
+--       satu
+--       dua
+--       tiga
+--       empat
+--       lima

+ 19 - 0
Tests/RunCMake/message/message-indent.cmake

@@ -0,0 +1,19 @@
+function(debug_list LIST_VAR)
+  message(STATUS "${LIST_VAR}:")
+  list(APPEND CMAKE_MESSAGE_INDENT "   ")
+  foreach(_item IN LISTS ${LIST_VAR})
+    list(LENGTH ${_item} _item_len)
+    if(_item_len GREATER 1)
+      debug_list(${_item})
+    else()
+      message(STATUS "${_item}")
+    endif()
+  endforeach()
+endfunction()
+
+list(APPEND COUNTING_ENGLISH one two three four five)
+list(APPEND COUNTING_BAHASA satu dua tiga empat lima)
+
+list(APPEND COUNTING COUNTING_ENGLISH COUNTING_BAHASA)
+
+debug_list(COUNTING)