From: Thomas Jarosch Date: Tue, 15 Dec 2015 10:06:24 +0000 (+0100) Subject: Add new option to recursive_delete: keep_parent_dir X-Git-Tag: v2.8~22 X-Git-Url: http://developer.intra2net.com/git/?a=commitdiff_plain;h=997987a6d59f3b65dabf7a012d0d932c1b262265;p=libi2ncommon Add new option to recursive_delete: keep_parent_dir Also added unit tests for the new feature. --- diff --git a/src/filefunc.cpp b/src/filefunc.cpp index c061e08..4316048 100644 --- a/src/filefunc.cpp +++ b/src/filefunc.cpp @@ -731,10 +731,13 @@ bool chown(const std::string& path, const I2n::User& user, const I2n::Group& gro /** * Recursive delete of files and directories * @param path File or directory to delete + * @param keep_parent_dir Keep parent directory (=empty out directory) [optional] * @param error Will contain the error if the return value is false [optional] * @return true on success, false otherwise */ -bool recursive_delete(const std::string &path, std::string *error) +bool recursive_delete(const std::string &path, + bool keep_parent_dir, + std::string *error) { bool rtn = true; @@ -759,14 +762,14 @@ bool recursive_delete(const std::string &path, std::string *error) } // Delete subdir or file. - rtn = recursive_delete(path + "/" + filename, error); + rtn = recursive_delete(path + "/" + filename, false, error); if (rtn == false) { break; } } closedir(dir); - if (!rmdir(path)) { + if (keep_parent_dir == false && !rmdir(path)) { throw runtime_error("can't remove directory " + path); } } else { diff --git a/src/filefunc.hxx b/src/filefunc.hxx index acfd637..a2f4bc0 100644 --- a/src/filefunc.hxx +++ b/src/filefunc.hxx @@ -177,7 +177,9 @@ bool dirsync(const std::string& path); bool chmod(const std::string& path, int mode); bool chown(const std::string& path, const I2n::User& user, const I2n::Group& group= I2n::Group()); -bool recursive_delete(const std::string &path, std::string *error=NULL); +bool recursive_delete(const std::string &path, + bool keep_parent_dir=false, + std::string *error=NULL); std::string mkdtemp(const std::string &path_template, std::string *error=NULL); bool mkdir(const std::string &path, const mode_t &mode=0700, std::string *error=NULL); @@ -192,8 +194,9 @@ mode_t umask(mode_t mask); /* ** more specialized tool function(s) */ -bool remove_unlisted_files(const std::string &directory, const std::set &keep_files, - const std::string &prefix=""); +bool remove_unlisted_files(const std::string &directory, + const std::set &keep_files, + const std::string &prefix=""); } diff --git a/test/test_filefunc.cpp b/test/test_filefunc.cpp index 6dbf24b..88515d1 100644 --- a/test/test_filefunc.cpp +++ b/test/test_filefunc.cpp @@ -360,7 +360,56 @@ BOOST_AUTO_TEST_CASE(TestMkdtemp) BOOST_CHECK_EQUAL(true, Stat(unique_dir).is_directory()); // Unlink it + BOOST_CHECK_EQUAL(true, rmdir(unique_dir)); +} + +BOOST_AUTO_TEST_CASE(TestRecursiveDelete) +{ + // Create unique directory + string unique_dir = I2n::mkdtemp("foobar.XXXXXX"); + BOOST_REQUIRE(unique_dir.size() > 0); + + // Test if it's really a directory + BOOST_CHECK_EQUAL(true, Stat(unique_dir).is_directory()); + + // Create dirs and files below it + const std::string sub_dir = unique_dir + "/" + "some_subdir"; + const std::string some_file = sub_dir + "/" + "some_file"; + BOOST_CHECK_EQUAL(true, I2n::mkdir(sub_dir)); + BOOST_CHECK_EQUAL(true, write_file(some_file, "foobar")); + + // Unlink it BOOST_CHECK_EQUAL(true, I2n::recursive_delete(unique_dir)); + BOOST_CHECK_EQUAL(false, Stat(unique_dir).is_directory()); +} + +BOOST_AUTO_TEST_CASE(TestRecursiveDeleteKeepParentDir) +{ + // Create unique directory + string unique_dir = I2n::mkdtemp("foobar.XXXXXX"); + BOOST_REQUIRE(unique_dir.size() > 0); + + // Test if it's really a directory + BOOST_CHECK_EQUAL(true, Stat(unique_dir).is_directory()); + + // Create dirs and files below it + const std::string sub_dir = unique_dir + "/" + "some_subdir"; + const std::string some_file = sub_dir + "/" + "some_file"; + const std::string other_file = unique_dir + "/" + "other_file"; + + BOOST_CHECK_EQUAL(true, I2n::mkdir(sub_dir)); + BOOST_CHECK_EQUAL(true, write_file(some_file, "foobar")); + BOOST_CHECK_EQUAL(true, write_file(other_file, "foobar")); + + // Unlink it + BOOST_CHECK_EQUAL(true, I2n::recursive_delete(unique_dir, true)); + + // check result + BOOST_CHECK_EQUAL(true, Stat(unique_dir).is_directory()); + BOOST_CHECK_EQUAL(false, Stat(sub_dir).is_directory()); + BOOST_CHECK_EQUAL(false, Stat(other_file).is_regular_file()); + + BOOST_CHECK_EQUAL(true, I2n::rmdir(unique_dir)); } BOOST_AUTO_TEST_CASE(TestMkdtempBrokenTemplate)