diff options
author | Paul Cristian Sarbu <paul.cristian.sarbu@huawei.com> | 2023-07-03 14:37:22 +0200 |
---|---|---|
committer | Klaus Aehlig <klaus.aehlig@huawei.com> | 2023-07-13 17:21:10 +0200 |
commit | 9a7d5ddd3e151dd06ef8c590c9ec09490a016345 (patch) | |
tree | f9e9515d4157d616b24e4e93c7e413528cef2bc3 /src | |
parent | ce5c7d7fd12570868bcdd1145e7184daf31ac147 (diff) | |
download | justbuild-9a7d5ddd3e151dd06ef8c590c9ec09490a016345.tar.gz |
FileSystemManager: Add recursive directory entries reader...
...allowing the skipping of certain subtrees if needed. This is
useful, e.g., in simulating what a 'git add' call would do,
which ignores all '.git' subdirectories.
(cherry picked from 14715e3da452dd73363bc86f92cd9e5b9fdb3a7b)
Diffstat (limited to 'src')
-rw-r--r-- | src/buildtool/file_system/file_system_manager.hpp | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/src/buildtool/file_system/file_system_manager.hpp b/src/buildtool/file_system/file_system_manager.hpp index 22e91da8..c226725a 100644 --- a/src/buildtool/file_system/file_system_manager.hpp +++ b/src/buildtool/file_system/file_system_manager.hpp @@ -23,6 +23,7 @@ #include <filesystem> #include <fstream> #include <optional> +#include <unordered_set> #include <fcntl.h> @@ -53,6 +54,9 @@ class FileSystemManager { using ReadDirEntryFunc = std::function<bool(std::filesystem::path const&, ObjectType type)>; + using UseDirEntryFunc = + std::function<bool(std::filesystem::path const&, bool /*is_tree*/)>; + class DirectoryAnchor { friend class FileSystemManager; @@ -577,6 +581,43 @@ class FileSystemManager { return true; } + /// \brief Read all entries recursively in a filesystem directory tree. + /// \param dir root directory to traverse + /// \param use_entry callback to call with found valid entries + /// \param ignored_subdirs directory names to be ignored wherever found in + /// the directory tree of dir. + [[nodiscard]] static auto ReadDirectoryEntriesRecursive( + std::filesystem::path const& dir, + UseDirEntryFunc const& use_entry, + std::unordered_set<std::string> const& ignored_subdirs = {}) noexcept + -> bool { + try { + // constructor of this iterator points to end by default; + for (auto it = std::filesystem::recursive_directory_iterator(dir); + it != std::filesystem::recursive_directory_iterator(); + ++it) { + // check for ignored subdirs + if (std::filesystem::is_directory(it->symlink_status()) and + ignored_subdirs.contains(*--it->path().end())) { + it.disable_recursion_pending(); + continue; + } + // use the entry + if (not use_entry( + it->path().lexically_relative(dir), + std::filesystem::is_directory(it->symlink_status()))) { + return false; + } + } + } catch (std::exception const& ex) { + Logger::Log(LogLevel::Error, + "reading directory {} recursively failed", + dir.string()); + return false; + } + return true; + } + /// \brief Write file /// If argument fd_less is given, the write will be performed in a child /// process to prevent polluting the parent with open writable file |