utils: expand AbsolutePathBase to provide some filesystem related methods via Boost

Summary:
These methods will be used in my later Windows fsck diff as it will need to scan disk state to find changes.

It is a bit unfortunate that we'll need to stick with boost for now. However this should be a fairly easy migration to `std::filesystem` once that is available.

Reviewed By: kmancini

Differential Revision: D27872828

fbshipit-source-id: f6b27a171026aeaaea3db9f17b8f43cfa25004e4
This commit is contained in:
Zeyi (Rice) Fan 2021-04-23 15:21:01 -07:00 committed by Facebook GitHub Bot
parent 8e1a30a2a9
commit a87cfb9aa3
3 changed files with 72 additions and 12 deletions

View File

@ -8,7 +8,6 @@
#include "eden/fs/utils/PathFuncs.h"
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/path.hpp>
#include <folly/Exception.h>
#include <folly/logging/xlog.h>
@ -273,29 +272,22 @@ void validatePathComponentLength(PathComponentPiece name) {
}
}
namespace {
boost::filesystem::path toBoostPath(AbsolutePathPiece path) {
auto piece = path.stringPiece();
return boost::filesystem::path(piece.begin(), piece.end());
}
} // namespace
bool ensureDirectoryExists(AbsolutePathPiece path) {
return boost::filesystem::create_directories(toBoostPath(path));
return boost::filesystem::create_directories(path.as_boost());
}
bool removeRecursively(AbsolutePathPiece path) {
return boost::filesystem::remove_all(toBoostPath(path));
return boost::filesystem::remove_all(path.as_boost());
}
bool removeFileWithAbsolutePath(AbsolutePathPiece path) {
return boost::filesystem::remove(toBoostPath(path));
return boost::filesystem::remove(path.as_boost());
}
void renameWithAbsolutePath(
AbsolutePathPiece srcPath,
AbsolutePathPiece destPath) {
boost::filesystem::rename(toBoostPath(srcPath), toBoostPath(destPath));
boost::filesystem::rename(srcPath.as_boost(), destPath.as_boost());
}
AbsolutePath expandUser(

View File

@ -9,6 +9,8 @@
#include "eden/fs/utils/Memory.h"
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/path.hpp>
#include <boost/operators.hpp>
#include <fmt/format.h>
@ -1420,6 +1422,24 @@ class AbsolutePathBase : public ComposedPathBase<
const char* c_str() const {
return this->path_.c_str();
}
// TODO: switch to `std::filesystem` once it is ready
boost::filesystem::path as_boost() const {
auto piece = this->stringPiece();
return boost::filesystem::path(piece.begin(), piece.end());
}
bool is_regular_file() const {
return boost::filesystem::is_regular_file(as_boost());
}
bool is_directory() const {
return boost::filesystem::is_directory(as_boost());
}
bool exists() const {
return boost::filesystem::exists(as_boost());
}
};
/**

View File

@ -1015,6 +1015,54 @@ TEST(PathFuncs, localDirCreateRemove) {
ASSERT_FALSE(removeRecursively(topDir));
}
TEST(PathFuncs, exists) {
folly::test::TemporaryDirectory dir = makeTempDir();
string pathStr{dir.path().string()};
AbsolutePathPiece tmpDir{pathStr};
auto filePath = tmpDir + "test.txt"_relpath;
EXPECT_FALSE(filePath.exists());
writeFile(filePath, StringPiece("hello\nworld")).throwUnlessValue();
EXPECT_TRUE(filePath.exists());
auto directoryPath = tmpDir + "dir"_relpath;
EXPECT_FALSE(directoryPath.exists());
ensureDirectoryExists(directoryPath);
EXPECT_TRUE(directoryPath.exists());
}
TEST(PathFuns, isRegularFile) {
folly::test::TemporaryDirectory dir = makeTempDir();
string pathStr{dir.path().string()};
AbsolutePathPiece tmpDir{pathStr};
auto filePath = tmpDir + "test.txt"_relpath;
EXPECT_FALSE(filePath.is_regular_file());
writeFile(filePath, StringPiece("hello\nworld")).throwUnlessValue();
EXPECT_TRUE(filePath.is_regular_file());
auto directoryPath = tmpDir + "dir"_relpath;
EXPECT_FALSE(directoryPath.is_regular_file());
ensureDirectoryExists(directoryPath);
EXPECT_FALSE(directoryPath.is_regular_file());
}
TEST(PathFuncs, isDirectory) {
folly::test::TemporaryDirectory dir = makeTempDir();
string pathStr{dir.path().string()};
AbsolutePathPiece tmpDir{pathStr};
auto filePath = tmpDir + "test.txt"_relpath;
EXPECT_FALSE(filePath.is_directory());
writeFile(filePath, StringPiece("hello\nworld")).throwUnlessValue();
EXPECT_FALSE(filePath.is_directory());
auto directoryPath = tmpDir + "dir"_relpath;
EXPECT_FALSE(directoryPath.is_directory());
ensureDirectoryExists(directoryPath);
EXPECT_TRUE(directoryPath.is_directory());
}
TEST(PathFuncs, noThrow) {
// if std::string is nothrow move constructible and assignable, the
// path types should be as well.