mirror of
https://github.com/Kitware/CMake.git
synced 2026-01-11 00:11:07 -06:00
file(RENAME): Add option to capture error message on failure
This commit is contained in:
@@ -38,7 +38,7 @@ Synopsis
|
||||
|
||||
`Filesystem`_
|
||||
file({`GLOB`_ | `GLOB_RECURSE`_} <out-var> [...] [<globbing-expr>...])
|
||||
file(`RENAME`_ <oldname> <newname>)
|
||||
file(`RENAME`_ <oldname> <newname> [...])
|
||||
file({`REMOVE`_ | `REMOVE_RECURSE`_ } [<files>...])
|
||||
file(`MAKE_DIRECTORY`_ [<dir>...])
|
||||
file({`COPY`_ | `INSTALL`_} <file>... DESTINATION <dir> [...])
|
||||
@@ -665,11 +665,18 @@ Examples of recursive globbing include::
|
||||
|
||||
.. code-block:: cmake
|
||||
|
||||
file(RENAME <oldname> <newname>)
|
||||
file(RENAME <oldname> <newname>
|
||||
[RESULT <result>])
|
||||
|
||||
Move a file or directory within a filesystem from ``<oldname>`` to
|
||||
``<newname>``, replacing the destination atomically.
|
||||
|
||||
The options are:
|
||||
|
||||
``RESULT <result>``
|
||||
Set ``<result>`` variable to ``0`` on success or an error message otherwise.
|
||||
If ``RESULT`` is not specified and the operation fails, an error is emitted.
|
||||
|
||||
.. _REMOVE:
|
||||
.. _REMOVE_RECURSE:
|
||||
|
||||
|
||||
5
Help/release/dev/file-RENAME.rst
Normal file
5
Help/release/dev/file-RENAME.rst
Normal file
@@ -0,0 +1,5 @@
|
||||
file-RENAME
|
||||
-----------
|
||||
|
||||
* The :command:`file(RENAME)` command learned to optionally capture
|
||||
failure in a result variable.
|
||||
@@ -1313,8 +1313,9 @@ bool HandleRelativePathCommand(std::vector<std::string> const& args,
|
||||
bool HandleRename(std::vector<std::string> const& args,
|
||||
cmExecutionStatus& status)
|
||||
{
|
||||
if (args.size() != 3) {
|
||||
status.SetError("RENAME given incorrect number of arguments.");
|
||||
if (args.size() < 3) {
|
||||
status.SetError("RENAME must be called with at least two additional "
|
||||
"arguments");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1330,13 +1331,39 @@ bool HandleRename(std::vector<std::string> const& args,
|
||||
cmStrCat(status.GetMakefile().GetCurrentSourceDirectory(), '/', args[2]);
|
||||
}
|
||||
|
||||
if (!cmSystemTools::RenameFile(oldname, newname)) {
|
||||
std::string err = cmSystemTools::GetLastSystemError();
|
||||
status.SetError(cmStrCat("RENAME failed to rename\n ", oldname,
|
||||
"\nto\n ", newname, "\nbecause: ", err, "\n"));
|
||||
struct Arguments
|
||||
{
|
||||
std::string Result;
|
||||
};
|
||||
|
||||
static auto const parser =
|
||||
cmArgumentParser<Arguments>{}.Bind("RESULT"_s, &Arguments::Result);
|
||||
|
||||
std::vector<std::string> unconsumedArgs;
|
||||
Arguments const arguments =
|
||||
parser.Parse(cmMakeRange(args).advance(3), &unconsumedArgs);
|
||||
if (!unconsumedArgs.empty()) {
|
||||
status.SetError("RENAME unknown argument:\n " + unconsumedArgs.front());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
std::string err;
|
||||
switch (cmSystemTools::RenameFile(oldname, newname, &err)) {
|
||||
case cmSystemTools::RenameResult::Success:
|
||||
if (!arguments.Result.empty()) {
|
||||
status.GetMakefile().AddDefinition(arguments.Result, "0");
|
||||
}
|
||||
return true;
|
||||
case cmSystemTools::RenameResult::Failure:
|
||||
if (!arguments.Result.empty()) {
|
||||
status.GetMakefile().AddDefinition(arguments.Result, err);
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
status.SetError(cmStrCat("RENAME failed to rename\n ", oldname, "\nto\n ",
|
||||
newname, "\nbecause: ", err, "\n"));
|
||||
return false;
|
||||
}
|
||||
|
||||
bool HandleRemoveImpl(std::vector<std::string> const& args, bool recurse,
|
||||
|
||||
1
Tests/RunCMake/file/RENAME-arg-missing-result.txt
Normal file
1
Tests/RunCMake/file/RENAME-arg-missing-result.txt
Normal file
@@ -0,0 +1 @@
|
||||
1
|
||||
3
Tests/RunCMake/file/RENAME-arg-missing-stderr.txt
Normal file
3
Tests/RunCMake/file/RENAME-arg-missing-stderr.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
^CMake Error at [^
|
||||
]*/Tests/RunCMake/file/RENAME-arg-missing.cmake:1 \(file\):
|
||||
file RENAME must be called with at least two additional arguments$
|
||||
1
Tests/RunCMake/file/RENAME-arg-missing.cmake
Normal file
1
Tests/RunCMake/file/RENAME-arg-missing.cmake
Normal file
@@ -0,0 +1 @@
|
||||
file(RENAME "old")
|
||||
1
Tests/RunCMake/file/RENAME-arg-unknown-result.txt
Normal file
1
Tests/RunCMake/file/RENAME-arg-unknown-result.txt
Normal file
@@ -0,0 +1 @@
|
||||
1
|
||||
5
Tests/RunCMake/file/RENAME-arg-unknown-stderr.txt
Normal file
5
Tests/RunCMake/file/RENAME-arg-unknown-stderr.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
^CMake Error at [^
|
||||
]*/Tests/RunCMake/file/RENAME-arg-unknown.cmake:1 \(file\):
|
||||
file RENAME unknown argument:
|
||||
|
||||
unknown$
|
||||
1
Tests/RunCMake/file/RENAME-arg-unknown.cmake
Normal file
1
Tests/RunCMake/file/RENAME-arg-unknown.cmake
Normal file
@@ -0,0 +1 @@
|
||||
file(RENAME "old" "new" unknown)
|
||||
@@ -0,0 +1 @@
|
||||
^-- file\(RENAME\) failed with result: [A-Za-z]
|
||||
9
Tests/RunCMake/file/RENAME-file-to-dir-capture.cmake
Normal file
9
Tests/RunCMake/file/RENAME-file-to-dir-capture.cmake
Normal file
@@ -0,0 +1,9 @@
|
||||
set(oldname "${CMAKE_CURRENT_BINARY_DIR}/input")
|
||||
set(newname "${CMAKE_CURRENT_BINARY_DIR}/output")
|
||||
file(WRITE "${oldname}" "")
|
||||
file(MAKE_DIRECTORY "${newname}")
|
||||
file(RENAME "${oldname}" "${newname}" RESULT result)
|
||||
message(STATUS "file(RENAME) failed with result: ${result}")
|
||||
if(NOT EXISTS "${oldname}")
|
||||
message(FATAL_ERROR "The old name does not still exist:\n ${oldname}")
|
||||
endif()
|
||||
1
Tests/RunCMake/file/RENAME-file-to-dir-fail-result.txt
Normal file
1
Tests/RunCMake/file/RENAME-file-to-dir-fail-result.txt
Normal file
@@ -0,0 +1 @@
|
||||
1
|
||||
13
Tests/RunCMake/file/RENAME-file-to-dir-fail-stderr.txt
Normal file
13
Tests/RunCMake/file/RENAME-file-to-dir-fail-stderr.txt
Normal file
@@ -0,0 +1,13 @@
|
||||
^CMake Error at [^
|
||||
]*/Tests/RunCMake/file/RENAME-file-to-dir-fail.cmake:[0-9] \(file\):
|
||||
file RENAME failed to rename
|
||||
|
||||
[^
|
||||
]*/Tests/RunCMake/file/RENAME-file-to-dir-fail-build/input
|
||||
|
||||
to
|
||||
|
||||
[^
|
||||
]*/Tests/RunCMake/file/RENAME-file-to-dir-fail-build/output
|
||||
|
||||
because: [A-Za-z]
|
||||
5
Tests/RunCMake/file/RENAME-file-to-dir-fail.cmake
Normal file
5
Tests/RunCMake/file/RENAME-file-to-dir-fail.cmake
Normal file
@@ -0,0 +1,5 @@
|
||||
set(oldname "${CMAKE_CURRENT_BINARY_DIR}/input")
|
||||
set(newname "${CMAKE_CURRENT_BINARY_DIR}/output")
|
||||
file(WRITE "${oldname}" "")
|
||||
file(MAKE_DIRECTORY "${newname}")
|
||||
file(RENAME "${oldname}" "${newname}")
|
||||
10
Tests/RunCMake/file/RENAME-file-to-file.cmake
Normal file
10
Tests/RunCMake/file/RENAME-file-to-file.cmake
Normal file
@@ -0,0 +1,10 @@
|
||||
set(oldname "${CMAKE_CURRENT_BINARY_DIR}/input")
|
||||
set(newname "${CMAKE_CURRENT_BINARY_DIR}/output")
|
||||
file(WRITE "${oldname}" "")
|
||||
file(RENAME "${oldname}" "${newname}")
|
||||
if(EXISTS "${oldname}")
|
||||
message(FATAL_ERROR "The old name still exists:\n ${oldname}")
|
||||
endif()
|
||||
if(NOT EXISTS "${newname}")
|
||||
message(FATAL_ERROR "The new name does not exist:\n ${newname}")
|
||||
endif()
|
||||
@@ -50,6 +50,12 @@ run_cmake(SIZE-error-does-not-exist)
|
||||
|
||||
run_cmake(REMOVE-empty)
|
||||
|
||||
run_cmake_script(RENAME-file-to-file)
|
||||
run_cmake_script(RENAME-file-to-dir-capture)
|
||||
run_cmake_script(RENAME-file-to-dir-fail)
|
||||
run_cmake_script(RENAME-arg-missing)
|
||||
run_cmake_script(RENAME-arg-unknown)
|
||||
|
||||
# tests are valid both for GLOB and GLOB_RECURSE
|
||||
run_cmake(GLOB-sort-dedup)
|
||||
run_cmake(GLOB-error-LIST_DIRECTORIES-not-boolean)
|
||||
|
||||
Reference in New Issue
Block a user