mirror of
https://github.com/Kitware/CMake.git
synced 2026-01-07 06:09:52 -06:00
file(RENAME): Add option to not replace existing path
Add a `NO_REPLACE` option that prevents overwriting `<newname>` if it exists.
This commit is contained in:
@@ -666,7 +666,8 @@ Examples of recursive globbing include::
|
||||
.. code-block:: cmake
|
||||
|
||||
file(RENAME <oldname> <newname>
|
||||
[RESULT <result>])
|
||||
[RESULT <result>]
|
||||
[NO_REPLACE])
|
||||
|
||||
Move a file or directory within a filesystem from ``<oldname>`` to
|
||||
``<newname>``, replacing the destination atomically.
|
||||
@@ -677,6 +678,11 @@ The options are:
|
||||
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.
|
||||
|
||||
``NO_REPLACE``
|
||||
If the ``<newname>`` path already exists, do not replace it.
|
||||
If ``RESULT <result>`` is used, the result variable will be
|
||||
set to ``NO_REPLACE``. Otherwise, an error is emitted.
|
||||
|
||||
.. _REMOVE:
|
||||
.. _REMOVE_RECURSE:
|
||||
|
||||
|
||||
@@ -2,4 +2,5 @@ file-RENAME
|
||||
-----------
|
||||
|
||||
* The :command:`file(RENAME)` command learned to optionally capture
|
||||
failure in a result variable.
|
||||
failure in a result variable. It also gained a ``NO_REPLACE``
|
||||
option to fail if the destination exists.
|
||||
|
||||
@@ -1333,11 +1333,13 @@ bool HandleRename(std::vector<std::string> const& args,
|
||||
|
||||
struct Arguments
|
||||
{
|
||||
bool NoReplace = false;
|
||||
std::string Result;
|
||||
};
|
||||
|
||||
static auto const parser =
|
||||
cmArgumentParser<Arguments>{}.Bind("RESULT"_s, &Arguments::Result);
|
||||
static auto const parser = cmArgumentParser<Arguments>{}
|
||||
.Bind("NO_REPLACE"_s, &Arguments::NoReplace)
|
||||
.Bind("RESULT"_s, &Arguments::Result);
|
||||
|
||||
std::vector<std::string> unconsumedArgs;
|
||||
Arguments const arguments =
|
||||
@@ -1349,13 +1351,22 @@ bool HandleRename(std::vector<std::string> const& args,
|
||||
|
||||
std::string err;
|
||||
switch (cmSystemTools::RenameFile(oldname, newname,
|
||||
cmSystemTools::Replace::Yes, &err)) {
|
||||
arguments.NoReplace
|
||||
? cmSystemTools::Replace::No
|
||||
: cmSystemTools::Replace::Yes,
|
||||
&err)) {
|
||||
case cmSystemTools::RenameResult::Success:
|
||||
if (!arguments.Result.empty()) {
|
||||
status.GetMakefile().AddDefinition(arguments.Result, "0");
|
||||
}
|
||||
return true;
|
||||
case cmSystemTools::RenameResult::NoReplace:
|
||||
if (!arguments.Result.empty()) {
|
||||
err = "NO_REPLACE";
|
||||
} else {
|
||||
err = "path not replaced";
|
||||
}
|
||||
CM_FALLTHROUGH;
|
||||
case cmSystemTools::RenameResult::Failure:
|
||||
if (!arguments.Result.empty()) {
|
||||
status.GetMakefile().AddDefinition(arguments.Result, err);
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
^-- file\(RENAME\) failed with result: NO_REPLACE$
|
||||
9
Tests/RunCMake/file/RENAME-file-NO_REPLACE-capture.cmake
Normal file
9
Tests/RunCMake/file/RENAME-file-NO_REPLACE-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}" "a")
|
||||
file(WRITE "${newname}" "b")
|
||||
file(RENAME "${oldname}" "${newname}" NO_REPLACE 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()
|
||||
@@ -0,0 +1 @@
|
||||
1
|
||||
13
Tests/RunCMake/file/RENAME-file-NO_REPLACE-fail-stderr.txt
Normal file
13
Tests/RunCMake/file/RENAME-file-NO_REPLACE-fail-stderr.txt
Normal file
@@ -0,0 +1,13 @@
|
||||
^CMake Error at [^
|
||||
]*/Tests/RunCMake/file/RENAME-file-NO_REPLACE-fail.cmake:[0-9] \(file\):
|
||||
file RENAME failed to rename
|
||||
|
||||
[^
|
||||
]*/Tests/RunCMake/file/RENAME-file-NO_REPLACE-fail-build/input
|
||||
|
||||
to
|
||||
|
||||
[^
|
||||
]*/Tests/RunCMake/file/RENAME-file-NO_REPLACE-fail-build/output
|
||||
|
||||
because: path not replaced$
|
||||
5
Tests/RunCMake/file/RENAME-file-NO_REPLACE-fail.cmake
Normal file
5
Tests/RunCMake/file/RENAME-file-NO_REPLACE-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}" "a")
|
||||
file(WRITE "${newname}" "b")
|
||||
file(RENAME "${oldname}" "${newname}" NO_REPLACE)
|
||||
9
Tests/RunCMake/file/RENAME-file-replace.cmake
Normal file
9
Tests/RunCMake/file/RENAME-file-replace.cmake
Normal file
@@ -0,0 +1,9 @@
|
||||
set(oldname "${CMAKE_CURRENT_BINARY_DIR}/input")
|
||||
set(newname "${CMAKE_CURRENT_BINARY_DIR}/output")
|
||||
file(WRITE "${oldname}" "a")
|
||||
file(WRITE "${newname}" "b")
|
||||
file(RENAME "${oldname}" "${newname}")
|
||||
file(READ "${newname}" new)
|
||||
if(NOT "${new}" STREQUAL "a")
|
||||
message(FATAL_ERROR "New name:\n ${newname}\ndoes not contain expected content 'a'.")
|
||||
endif()
|
||||
@@ -50,9 +50,12 @@ run_cmake(SIZE-error-does-not-exist)
|
||||
|
||||
run_cmake(REMOVE-empty)
|
||||
|
||||
run_cmake_script(RENAME-file-replace)
|
||||
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-file-NO_REPLACE-capture)
|
||||
run_cmake_script(RENAME-file-NO_REPLACE-fail)
|
||||
run_cmake_script(RENAME-arg-missing)
|
||||
run_cmake_script(RENAME-arg-unknown)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user