From 3ece058d9751878cb7c7111f0cd729f938342d6a Mon Sep 17 00:00:00 2001 From: Martin Duffy Date: Mon, 13 Jan 2025 08:16:21 -0500 Subject: execute_process: Allow setting default COMMAND_ERROR_IS_FATAL value Issue: #26576 --- Help/command/execute_process.rst | 19 ++++++++++++++-- Help/manual/cmake-variables.7.rst | 1 + Help/release/dev/execute-process-error.rst | 6 ++++++ ...MAKE_EXECUTE_PROCESS_COMMAND_ERROR_IS_FATAL.rst | 9 ++++++++ Source/cmExecuteProcessCommand.cxx | 25 ++++++++++++++++------ .../execute_process/AnyCommandErrorVar-result.txt | 1 + .../execute_process/AnyCommandErrorVar-stderr.txt | 5 +++++ .../execute_process/AnyCommandErrorVar.cmake | 6 ++++++ .../AnyCommandErrorVarIgnore-result.txt | 1 + .../execute_process/AnyCommandErrorVarIgnore.cmake | 7 ++++++ .../execute_process/CommandError-stderr.txt | 2 +- .../execute_process/CommandErrorVar-result.txt | 1 + .../execute_process/CommandErrorVar-stderr.txt | 4 ++++ .../RunCMake/execute_process/CommandErrorVar.cmake | 23 ++++++++++++++++++++ .../execute_process/LastCommandGoodVar.cmake | 15 +++++++++++++ .../execute_process/NoneCommandError.cmake | 5 +++++ Tests/RunCMake/execute_process/RunCMakeTest.cmake | 5 +++++ 17 files changed, 126 insertions(+), 9 deletions(-) create mode 100644 Help/release/dev/execute-process-error.rst create mode 100644 Help/variable/CMAKE_EXECUTE_PROCESS_COMMAND_ERROR_IS_FATAL.rst create mode 100644 Tests/RunCMake/execute_process/AnyCommandErrorVar-result.txt create mode 100644 Tests/RunCMake/execute_process/AnyCommandErrorVar-stderr.txt create mode 100644 Tests/RunCMake/execute_process/AnyCommandErrorVar.cmake create mode 100644 Tests/RunCMake/execute_process/AnyCommandErrorVarIgnore-result.txt create mode 100644 Tests/RunCMake/execute_process/AnyCommandErrorVarIgnore.cmake create mode 100644 Tests/RunCMake/execute_process/CommandErrorVar-result.txt create mode 100644 Tests/RunCMake/execute_process/CommandErrorVar-stderr.txt create mode 100644 Tests/RunCMake/execute_process/CommandErrorVar.cmake create mode 100644 Tests/RunCMake/execute_process/LastCommandGoodVar.cmake create mode 100644 Tests/RunCMake/execute_process/NoneCommandError.cmake diff --git a/Help/command/execute_process.rst b/Help/command/execute_process.rst index 4d5e380..a554aa1 100644 --- a/Help/command/execute_process.rst +++ b/Help/command/execute_process.rst @@ -24,7 +24,7 @@ Execute one or more child processes. [ENCODING ] [ECHO_OUTPUT_VARIABLE] [ECHO_ERROR_VARIABLE] - [COMMAND_ERROR_IS_FATAL ]) + [COMMAND_ERROR_IS_FATAL ]) Runs the given sequence of one or more commands. @@ -168,7 +168,7 @@ Options: `UTF-8 RFC `_ naming convention. -``COMMAND_ERROR_IS_FATAL `` +``COMMAND_ERROR_IS_FATAL `` .. versionadded:: 3.19 The option following ``COMMAND_ERROR_IS_FATAL`` determines the behavior when @@ -182,3 +182,18 @@ Options: If the last command in the list of commands fails, the ``execute_process()`` command halts with an error. Commands earlier in the list will not cause a fatal error. + + + ``NONE`` + .. versionadded:: 3.32 + + Regardless of any of the commands failing, the ``execute_process()`` + command will not halt with an error. + + .. versionadded:: 3.32 + + If not provided, the + :variable:`CMAKE_EXECUTE_PROCESS_COMMAND_ERROR_IS_FATAL` variable + is checked. If the variable is not set, the default is ``NONE``. + If ``RESULT_VARIABLE`` or ``RESULTS_VARIABLE`` is supplied, + :variable:`CMAKE_EXECUTE_PROCESS_COMMAND_ERROR_IS_FATAL` is ignored. diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst index 5e20196..310af93 100644 --- a/Help/manual/cmake-variables.7.rst +++ b/Help/manual/cmake-variables.7.rst @@ -198,6 +198,7 @@ Variables that Change Behavior /variable/CMAKE_ERROR_DEPRECATED /variable/CMAKE_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION /variable/CMAKE_EXECUTE_PROCESS_COMMAND_ECHO + /variable/CMAKE_EXECUTE_PROCESS_COMMAND_ERROR_IS_FATAL /variable/CMAKE_EXPORT_BUILD_DATABASE /variable/CMAKE_EXPORT_COMPILE_COMMANDS /variable/CMAKE_EXPORT_PACKAGE_REGISTRY diff --git a/Help/release/dev/execute-process-error.rst b/Help/release/dev/execute-process-error.rst new file mode 100644 index 0000000..73136b2 --- /dev/null +++ b/Help/release/dev/execute-process-error.rst @@ -0,0 +1,6 @@ +execute-process-error +--------------------- + +* The :variable:`CMAKE_EXECUTE_PROCESS_COMMAND_ERROR_IS_FATAL` variable + was added to specify the :command:`execute_process` command's + default ``COMMAND_ERROR_IS_FATAL`` behavior. diff --git a/Help/variable/CMAKE_EXECUTE_PROCESS_COMMAND_ERROR_IS_FATAL.rst b/Help/variable/CMAKE_EXECUTE_PROCESS_COMMAND_ERROR_IS_FATAL.rst new file mode 100644 index 0000000..0be51a9 --- /dev/null +++ b/Help/variable/CMAKE_EXECUTE_PROCESS_COMMAND_ERROR_IS_FATAL.rst @@ -0,0 +1,9 @@ +CMAKE_EXECUTE_PROCESS_COMMAND_ERROR_IS_FATAL +-------------------------------------------- + +.. versionadded:: 3.32 + +Specify a default for the :command:`execute_process` command's +``COMMAND_ERROR_IS_FATAL`` option. This variable is ignored when a +``RESULTS_VARIABLE`` or ``RESULT_VARIABLE`` keyword is supplied to +the command. diff --git a/Source/cmExecuteProcessCommand.cxx b/Source/cmExecuteProcessCommand.cxx index e186a08..97ee05c 100644 --- a/Source/cmExecuteProcessCommand.cxx +++ b/Source/cmExecuteProcessCommand.cxx @@ -177,12 +177,25 @@ bool cmExecuteProcessCommand(std::vector const& args, } } - if (!arguments.CommandErrorIsFatal.empty()) { - if (arguments.CommandErrorIsFatal != "ANY"_s && - arguments.CommandErrorIsFatal != "LAST"_s) { - status.SetError("COMMAND_ERROR_IS_FATAL option can be ANY or LAST"); + std::string commandErrorIsFatal = arguments.CommandErrorIsFatal; + if (commandErrorIsFatal.empty() && arguments.ResultVariable.empty() && + arguments.ResultsVariable.empty()) { + commandErrorIsFatal = status.GetMakefile().GetSafeDefinition( + "CMAKE_EXECUTE_PROCESS_COMMAND_ERROR_IS_FATAL"); + } + + if (!commandErrorIsFatal.empty() && commandErrorIsFatal != "ANY"_s && + commandErrorIsFatal != "LAST"_s && commandErrorIsFatal != "NONE"_s) { + if (!arguments.CommandErrorIsFatal.empty()) { + status.SetError( + "COMMAND_ERROR_IS_FATAL option can be ANY, LAST or NONE"); return false; } + status.SetError(cmStrCat( + "Using CMAKE_EXECUTE_PROCESS_COMMAND_ERROR_IS_FATAL with invalid value " + "\"", + commandErrorIsFatal, "\". This variable can be ANY, LAST or NONE")); + return false; } // Create a process instance. cmUVProcessChainBuilder builder; @@ -479,7 +492,7 @@ bool cmExecuteProcessCommand(std::vector const& args, exception.second); }; - if (arguments.CommandErrorIsFatal == "ANY"_s) { + if (commandErrorIsFatal == "ANY"_s) { bool ret = true; if (timedOut) { status.SetError("Process terminated due to timeout"); @@ -510,7 +523,7 @@ bool cmExecuteProcessCommand(std::vector const& args, } } - if (arguments.CommandErrorIsFatal == "LAST"_s) { + if (commandErrorIsFatal == "LAST"_s) { bool ret = true; if (timedOut) { status.SetError("Process terminated due to timeout"); diff --git a/Tests/RunCMake/execute_process/AnyCommandErrorVar-result.txt b/Tests/RunCMake/execute_process/AnyCommandErrorVar-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/execute_process/AnyCommandErrorVar-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/execute_process/AnyCommandErrorVar-stderr.txt b/Tests/RunCMake/execute_process/AnyCommandErrorVar-stderr.txt new file mode 100644 index 0000000..cc7aa12 --- /dev/null +++ b/Tests/RunCMake/execute_process/AnyCommandErrorVar-stderr.txt @@ -0,0 +1,5 @@ +CMake Error at .*AnyCommandErrorVar.cmake:2 \(execute_process\): + execute_process failed command indexes: + + 2: "Child return code: 1" + 3: "Child return code: 1" diff --git a/Tests/RunCMake/execute_process/AnyCommandErrorVar.cmake b/Tests/RunCMake/execute_process/AnyCommandErrorVar.cmake new file mode 100644 index 0000000..e3cb1ae --- /dev/null +++ b/Tests/RunCMake/execute_process/AnyCommandErrorVar.cmake @@ -0,0 +1,6 @@ +set(CMAKE_EXECUTE_PROCESS_COMMAND_ERROR_IS_FATAL ANY) +execute_process(COMMAND ${CMAKE_COMMAND} -E true + COMMAND ${CMAKE_COMMAND} -E false + COMMAND ${CMAKE_COMMAND} -E false + COMMAND ${CMAKE_COMMAND} -E true +) diff --git a/Tests/RunCMake/execute_process/AnyCommandErrorVarIgnore-result.txt b/Tests/RunCMake/execute_process/AnyCommandErrorVarIgnore-result.txt new file mode 100644 index 0000000..573541a --- /dev/null +++ b/Tests/RunCMake/execute_process/AnyCommandErrorVarIgnore-result.txt @@ -0,0 +1 @@ +0 diff --git a/Tests/RunCMake/execute_process/AnyCommandErrorVarIgnore.cmake b/Tests/RunCMake/execute_process/AnyCommandErrorVarIgnore.cmake new file mode 100644 index 0000000..b1c1b2f --- /dev/null +++ b/Tests/RunCMake/execute_process/AnyCommandErrorVarIgnore.cmake @@ -0,0 +1,7 @@ +set(CMAKE_EXECUTE_PROCESS_COMMAND_ERROR_IS_FATAL ANY) +execute_process(COMMAND ${CMAKE_COMMAND} -E true + COMMAND ${CMAKE_COMMAND} -E false + COMMAND ${CMAKE_COMMAND} -E false + COMMAND ${CMAKE_COMMAND} -E true + RESULTS_VARIABLE result +) diff --git a/Tests/RunCMake/execute_process/CommandError-stderr.txt b/Tests/RunCMake/execute_process/CommandError-stderr.txt index c28f3a3..a5188e7 100644 --- a/Tests/RunCMake/execute_process/CommandError-stderr.txt +++ b/Tests/RunCMake/execute_process/CommandError-stderr.txt @@ -1,2 +1,2 @@ CMake Error at .*CommandError.cmake:1 \(execute_process\): - execute_process COMMAND_ERROR_IS_FATAL option can be ANY or LAST + execute_process COMMAND_ERROR_IS_FATAL option can be ANY, LAST or NONE diff --git a/Tests/RunCMake/execute_process/CommandErrorVar-result.txt b/Tests/RunCMake/execute_process/CommandErrorVar-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/execute_process/CommandErrorVar-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/execute_process/CommandErrorVar-stderr.txt b/Tests/RunCMake/execute_process/CommandErrorVar-stderr.txt new file mode 100644 index 0000000..557b93e --- /dev/null +++ b/Tests/RunCMake/execute_process/CommandErrorVar-stderr.txt @@ -0,0 +1,4 @@ +CMake Error at [^ +]*CommandErrorVar.cmake:23 \(execute_process\): + execute_process Using CMAKE_EXECUTE_PROCESS_COMMAND_ERROR_IS_FATAL with + invalid value \"BAD_VALUE\". This variable can be ANY, LAST or NONE diff --git a/Tests/RunCMake/execute_process/CommandErrorVar.cmake b/Tests/RunCMake/execute_process/CommandErrorVar.cmake new file mode 100644 index 0000000..4569c8a --- /dev/null +++ b/Tests/RunCMake/execute_process/CommandErrorVar.cmake @@ -0,0 +1,23 @@ +# Ignores var when RESULT_VARIABLE is used +set(CMAKE_EXECUTE_PROCESS_COMMAND_ERROR_IS_FATAL ANY) +execute_process(COMMAND ${CMAKE_COMMAND} -E false + RESULT_VARIABLE result +) + +# Ignores var when RESULTS_VARIABLE is used +execute_process(COMMAND ${CMAKE_COMMAND} -E false + RESULTS_VARIABLE results +) + +# Ignores var when argument supplied +execute_process(COMMAND ${CMAKE_COMMAND} -E false + COMMAND_ERROR_IS_FATAL NONE +) + +# Value of NONE has no effect +set(CMAKE_EXECUTE_PROCESS_COMMAND_ERROR_IS_FATAL NONE) +execute_process(COMMAND ${CMAKE_COMMAND} -E false) + +# Error on invalid value +set(CMAKE_EXECUTE_PROCESS_COMMAND_ERROR_IS_FATAL BAD_VALUE) +execute_process(COMMAND ${CMAKE_COMMAND} -E false) diff --git a/Tests/RunCMake/execute_process/LastCommandGoodVar.cmake b/Tests/RunCMake/execute_process/LastCommandGoodVar.cmake new file mode 100644 index 0000000..ced2e17 --- /dev/null +++ b/Tests/RunCMake/execute_process/LastCommandGoodVar.cmake @@ -0,0 +1,15 @@ +execute_process(COMMAND ${CMAKE_COMMAND} -E true + COMMAND ${CMAKE_COMMAND} -E false + COMMAND ${CMAKE_COMMAND} -E false + COMMAND ${CMAKE_COMMAND} -E true + RESULT_VARIABLE result + ) + +set(CMAKE_EXECUTE_PROCESS_COMMAND_ERROR_IS_FATAL LAST) +if(result EQUAL "0") + execute_process(COMMAND ${CMAKE_COMMAND} -E true + COMMAND ${CMAKE_COMMAND} -E false + COMMAND ${CMAKE_COMMAND} -E false + COMMAND ${CMAKE_COMMAND} -E true + ) +endif() diff --git a/Tests/RunCMake/execute_process/NoneCommandError.cmake b/Tests/RunCMake/execute_process/NoneCommandError.cmake new file mode 100644 index 0000000..254732a --- /dev/null +++ b/Tests/RunCMake/execute_process/NoneCommandError.cmake @@ -0,0 +1,5 @@ +set(CMAKE_EXECUTE_PROCESS_COMMAND_ERROR_IS_FATAL ANY) +execute_process(COMMAND ${CMAKE_COMMAND} -E true + COMMAND ${CMAKE_COMMAND} -E false + COMMAND_ERROR_IS_FATAL NONE +) diff --git a/Tests/RunCMake/execute_process/RunCMakeTest.cmake b/Tests/RunCMake/execute_process/RunCMakeTest.cmake index dad6322..e9b18a5 100644 --- a/Tests/RunCMake/execute_process/RunCMakeTest.cmake +++ b/Tests/RunCMake/execute_process/RunCMakeTest.cmake @@ -32,12 +32,17 @@ run_cmake_command(EchoCommand3 ${CMAKE_COMMAND} run_cmake_command(EchoVariable ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/EchoVariable.cmake) run_cmake_command(CommandError ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/CommandError.cmake) +run_cmake_command(CommandErrorVar ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/CommandErrorVar.cmake) run_cmake_command(AnyCommandError ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/AnyCommandError.cmake) run_cmake_command(AnyCommandTimeout ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/AnyCommandTimeout.cmake) run_cmake_command(AnyCommandGood ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/AnyCommandGood.cmake) +run_cmake_command(AnyCommandErrorVar ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/AnyCommandErrorVar.cmake) +run_cmake_command(AnyCommandErrorVarIgnore ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/AnyCommandErrorVarIgnore.cmake) run_cmake_command(LastCommandError ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/LastCommandError.cmake) run_cmake_command(LastCommandTimeout ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/LastCommandTimeout.cmake) run_cmake_command(LastCommandGood ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/LastCommandGood.cmake) +run_cmake_command(LastCommandGoodVar ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/LastCommandGoodVar.cmake) +run_cmake_command(NoneCommandError ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/NoneCommandError.cmake) run_cmake_command(Stdin ${CMAKE_COMMAND} -DPRINT_STDIN_EXE=${PRINT_STDIN_EXE} -P ${RunCMake_SOURCE_DIR}/Stdin.cmake) run_cmake_command(StdinNoexist ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/StdinNoexist.cmake) run_cmake_command(StdoutNoexist ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/StdoutNoexist.cmake) -- cgit v0.12