]> git.ipfire.org Git - thirdparty/ccache.git/commitdiff
Implement Util::wipe_path
authorJoel Rosdahl <joel@rosdahl.net>
Sun, 10 May 2020 07:13:31 +0000 (09:13 +0200)
committerJoel Rosdahl <joel@rosdahl.net>
Wed, 13 May 2020 19:24:20 +0000 (21:24 +0200)
src/Util.cpp
src/Util.hpp
unittest/test_Util.cpp

index be057e86d431c3d2a2322cf2ce353db0c62b87c8..10f1aca96b3c014b9f8cac553543bf169034faed 100644 (file)
@@ -692,6 +692,23 @@ traverse(const std::string& path, const TraverseVisitor& visitor)
   }
 }
 
+void
+wipe_path(const std::string& path)
+{
+  if (!Stat::lstat(path)) {
+    return;
+  }
+  traverse(path, [](const std::string& p, bool is_dir) {
+    if (is_dir) {
+      if (rmdir(p.c_str()) != 0 && errno != ENOENT && errno != ESTALE) {
+        throw Error(fmt::format("failed to rmdir {}: {}", p, strerror(errno)));
+      }
+    } else if (unlink(p.c_str()) != 0 && errno != ENOENT && errno != ESTALE) {
+      throw Error(fmt::format("failed to unlink {}: {}", p, strerror(errno)));
+    }
+  });
+}
+
 void
 write_file(const std::string& path, const std::string& data, bool binary)
 {
index c6069d51dbcfe54cf96f90aeaacdda3232dd51e6..4902dcd86b2b76fa9f4eba991ca3c26de0109634 100644 (file)
@@ -288,6 +288,12 @@ strip_whitespace(const std::string& string);
 // Throws Error on error.
 void traverse(const std::string& path, const TraverseVisitor& visitor);
 
+// Remove `path` (and its contents if it's a directory). A non-existing path is
+// not considered an error.
+//
+// Throws Error on error.
+void wipe_path(const std::string& path);
+
 // Write file data from a string.
 //
 // Throws `Error` on error. The description contains the error message without
index f508cf54d26465f1235a182731f296b214a41fef..28fed2133cf4250c333b864da0d9159402c130ef 100644 (file)
@@ -671,3 +671,37 @@ TEST_CASE("Util::traverse")
     CHECK(visited[2] == "[d] traverse/dir-with-subdir-and-file");
   }
 }
+
+TEST_CASE("Util::wipe_path")
+{
+  SECTION("Wipe non-existing path")
+  {
+    CHECK_NOTHROW(Util::wipe_path("a"));
+  }
+
+  SECTION("Wipe file")
+  {
+    Util::write_file("a", "");
+    CHECK_NOTHROW(Util::wipe_path("a"));
+    CHECK(!Stat::stat("a"));
+  }
+
+  SECTION("Wipe directory")
+  {
+    REQUIRE(Util::create_dir("a/b"));
+    Util::write_file("a/1", "");
+    Util::write_file("a/b/1", "");
+    CHECK_NOTHROW(Util::wipe_path("a"));
+    CHECK(!Stat::stat("a"));
+  }
+
+  SECTION("Wipe bad path")
+  {
+#ifdef _WIN32
+    const char error[] = "failed to rmdir .: Permission denied";
+#else
+    const char error[] = "failed to rmdir .: Invalid argument";
+#endif
+    CHECK_THROWS_WITH(Util::wipe_path("."), error);
+  }
+}