Browse Source

cmake: Teach -E remove_directory to remove multiple directories

The `make_directory` command can make multiple directories in a single
invocation.  Make `remove_directory` mirror that behavior.
John Freeman 6 years ago
parent
commit
07a80c7002

+ 2 - 2
Help/manual/cmake.1.rst

@@ -514,8 +514,8 @@ Available commands are:
   ``remove`` does not follow symlinks. That means it remove only symlinks
   and not files it point to.
 
-``remove_directory <dir>``
-  Remove a directory and its contents.  If a directory does
+``remove_directory <dir>...``
+  Remove ``<dir>`` directories and their contents.  If a directory does
   not exist it will be silently ignored.
 
 ``rename <oldname> <newname>``

+ 5 - 0
Help/release/dev/remove_directories.rst

@@ -0,0 +1,5 @@
+remove_directories
+------------------
+
+* The :manual:`cmake(1)` ``-E remove_directory`` command learned to support
+  removing multiple directories.

+ 12 - 8
Source/cmcmd.cxx

@@ -103,7 +103,7 @@ void CMakeCommandUsage(const char* program)
     << "  sha512sum <file>...       - create SHA512 checksum of files\n"
     << "  remove [-f] <file>...     - remove the file(s), use -f to force "
        "it\n"
-    << "  remove_directory dir      - remove a directory and its contents\n"
+    << "  remove_directory <dir>... - remove directories and their contents\n"
     << "  rename oldname newname    - rename a file or directory "
        "(on one volume)\n"
     << "  server                    - start cmake in server mode\n"
@@ -661,7 +661,7 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args)
 #endif
 
     if (args[1] == "make_directory" && args.size() > 2) {
-      // If error occurs we want to continue copying next files.
+      // If an error occurs, we want to continue making directories.
       bool return_value = false;
       for (auto const& arg : cmMakeRange(args).advance(2)) {
         if (!cmSystemTools::MakeDirectory(arg)) {
@@ -672,13 +672,17 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args)
       return return_value;
     }
 
-    if (args[1] == "remove_directory" && args.size() == 3) {
-      if (cmSystemTools::FileIsDirectory(args[2]) &&
-          !cmSystemTools::RemoveADirectory(args[2])) {
-        std::cerr << "Error removing directory \"" << args[2] << "\".\n";
-        return 1;
+    if (args[1] == "remove_directory" && args.size() > 2) {
+      // If an error occurs, we want to continue removing directories.
+      bool return_value = false;
+      for (auto const& arg : cmMakeRange(args).advance(2)) {
+        if (cmSystemTools::FileIsDirectory(arg) &&
+            !cmSystemTools::RemoveADirectory(arg)) {
+          std::cerr << "Error removing directory \"" << arg << "\".\n";
+          return_value = true;
+        }
       }
-      return 0;
+      return return_value;
     }
 
     // Remove file

+ 3 - 0
Tests/RunCMake/CommandLine/E_remove_directory-directory-with-parent-check.cmake

@@ -0,0 +1,3 @@
+if(IS_DIRECTORY ${out}/parent/child)
+  set(RunCMake_TEST_FAILED "child directory was not removed")
+endif()

+ 0 - 0
Tests/RunCMake/CommandLine/E_remove_directory-directory-with-parent-stderr.txt


+ 6 - 0
Tests/RunCMake/CommandLine/E_remove_directory-three-directories-check.cmake

@@ -0,0 +1,6 @@
+if(IS_DIRECTORY ${out}/d1)
+  set(RunCMake_TEST_FAILED "directory d1 was not removed")
+endif()
+if(IS_DIRECTORY ${out}/d2)
+  set(RunCMake_TEST_FAILED "directory d2 was not removed")
+endif()

+ 0 - 0
Tests/RunCMake/CommandLine/E_remove_directory-three-directories-stderr.txt


+ 3 - 0
Tests/RunCMake/CommandLine/E_remove_directory-two-directories-and-file-check.cmake

@@ -0,0 +1,3 @@
+if(NOT EXISTS ${outfile})
+  set(RunCMake_TEST_FAILED "removed non-directory ${outfile}")
+endif()

+ 0 - 0
Tests/RunCMake/CommandLine/E_remove_directory-two-directories-and-file-stderr.txt


+ 6 - 0
Tests/RunCMake/CommandLine/RunCMakeTest.cmake

@@ -332,10 +332,16 @@ file(MAKE_DIRECTORY ${out})
 file(WRITE ${outfile} "")
 run_cmake_command(E_make_directory-three-directories
   ${CMAKE_COMMAND} -E make_directory ${out}/d1 ${out}/d2 ${out}/d2)
+run_cmake_command(E_remove_directory-three-directories
+  ${CMAKE_COMMAND} -E remove_directory ${out}/d1 ${out}/d2 ${out}/d2)
 run_cmake_command(E_make_directory-directory-with-parent
   ${CMAKE_COMMAND} -E make_directory ${out}/parent/child)
+run_cmake_command(E_remove_directory-directory-with-parent
+  ${CMAKE_COMMAND} -E remove_directory ${out}/parent)
 run_cmake_command(E_make_directory-two-directories-and-file
   ${CMAKE_COMMAND} -E make_directory ${out}/d1 ${out}/d2 ${outfile})
+run_cmake_command(E_remove_directory-two-directories-and-file
+  ${CMAKE_COMMAND} -E remove_directory ${out}/d1 ${out}/d2 ${outfile})
 unset(out)
 unset(outfile)
 

+ 6 - 5
Tests/StagingPrefix/CMakeLists.txt

@@ -5,11 +5,12 @@ project(StagingPrefix)
 # Wipe out the install tree
 add_custom_command(
   OUTPUT ${CMAKE_BINARY_DIR}/CleanupProject
-  COMMAND ${CMAKE_COMMAND} -E remove_directory ${CMAKE_BINARY_DIR}/ConsumerBuild
-  COMMAND ${CMAKE_COMMAND} -E remove_directory ${CMAKE_BINARY_DIR}/ProducerBuild
-  COMMAND ${CMAKE_COMMAND} -E remove_directory ${CMAKE_BINARY_DIR}/stage
-  COMMAND ${CMAKE_COMMAND} -E remove_directory ${CMAKE_BINARY_DIR}/prefix
-  COMMAND ${CMAKE_COMMAND} -E remove_directory ${CMAKE_BINARY_DIR}/ignored
+  COMMAND ${CMAKE_COMMAND} -E remove_directory
+    ${CMAKE_BINARY_DIR}/ConsumerBuild
+    ${CMAKE_BINARY_DIR}/ProducerBuild
+    ${CMAKE_BINARY_DIR}/stage
+    ${CMAKE_BINARY_DIR}/prefix
+    ${CMAKE_BINARY_DIR}/ignored
   )
 add_custom_target(CleanupTarget ALL DEPENDS ${CMAKE_BINARY_DIR}/CleanupProject)
 set_property(