diff options
Diffstat (limited to 'src/buildtool/file_system/file_root.hpp')
-rw-r--r-- | src/buildtool/file_system/file_root.hpp | 63 |
1 files changed, 52 insertions, 11 deletions
diff --git a/src/buildtool/file_system/file_root.hpp b/src/buildtool/file_system/file_root.hpp index 1d4b6f1c..b2768471 100644 --- a/src/buildtool/file_system/file_root.hpp +++ b/src/buildtool/file_system/file_root.hpp @@ -175,21 +175,21 @@ class FileRoot { explicit DirectoryEntries(tree_t const& git_tree) noexcept : data_{git_tree} {} - [[nodiscard]] auto ContainsFile(std::string const& name) const noexcept + [[nodiscard]] auto ContainsBlob(std::string const& name) const noexcept -> bool { try { if (std::holds_alternative<tree_t>(data_)) { auto const& data = std::get<tree_t>(data_); auto ptr = data->LookupEntryByName(name); if (static_cast<bool>(ptr)) { - return IsFileObject(ptr->Type()); + return IsBlobObject(ptr->Type()); } return false; } if (std::holds_alternative<pairs_t>(data_)) { auto const& data = std::get<pairs_t>(data_); auto it = data.find(name); - return (it != data.end() and IsFileObject(it->second)); + return (it != data.end() and IsBlobObject(it->second)); } } catch (...) { } @@ -254,6 +254,22 @@ class FileRoot { }}}; } + [[nodiscard]] auto SymlinksIterator() const -> Iterator { + if (std::holds_alternative<pairs_t>(data_)) { + auto const& data = std::get<pairs_t>(data_); + return Iterator{FilteredIterator{ + data.begin(), data.end(), [](auto const& x) { + return IsSymlinkObject(x.second); + }}}; + } + // std::holds_alternative<tree_t>(data_) == true + auto const& data = std::get<tree_t>(data_); + return Iterator{FilteredIterator{ + data->begin(), data->end(), [](auto const& x) noexcept -> bool { + return IsSymlinkObject(x.second->Type()); + }}}; + } + [[nodiscard]] auto DirectoriesIterator() const -> Iterator { if (std::holds_alternative<pairs_t>(data_)) { auto const& data = std::get<pairs_t>(data_); @@ -325,7 +341,7 @@ class FileRoot { } // Indicates that subsequent calls to `Exists()`, `IsFile()`, - // `IsDirectory()`, and `FileType()` on contents of the same directory will + // `IsDirectory()`, and `BlobType()` on contents of the same directory will // be served without any additional file system lookups. [[nodiscard]] auto HasFastDirectoryLookup() const noexcept -> bool { return std::holds_alternative<git_root_t>(root_); @@ -362,6 +378,25 @@ class FileRoot { file_path); } + [[nodiscard]] auto IsSymlink( + std::filesystem::path const& file_path) const noexcept -> bool { + if (std::holds_alternative<git_root_t>(root_)) { + if (auto entry = + std::get<git_root_t>(root_).tree->LookupEntryByPath( + file_path)) { + return IsSymlinkObject(entry->Type()); + } + return false; + } + return FileSystemManager::IsNonUpwardsSymlink( + std::get<fs_root_t>(root_) / file_path); + } + + [[nodiscard]] auto IsBlob( + std::filesystem::path const& file_path) const noexcept -> bool { + return IsFile(file_path) or IsSymlink(file_path); + } + [[nodiscard]] auto IsDirectory( std::filesystem::path const& dir_path) const noexcept -> bool { if (std::holds_alternative<git_root_t>(root_)) { @@ -379,20 +414,26 @@ class FileRoot { dir_path); } - [[nodiscard]] auto ReadFile(std::filesystem::path const& file_path) + /// \brief Read content of file or symlink. + [[nodiscard]] auto ReadContent(std::filesystem::path const& file_path) const noexcept -> std::optional<std::string> { if (std::holds_alternative<git_root_t>(root_)) { if (auto entry = std::get<git_root_t>(root_).tree->LookupEntryByPath( file_path)) { - if (IsFileObject(entry->Type())) { + if (IsBlobObject(entry->Type())) { return entry->Blob(); } } return std::nullopt; } - return FileSystemManager::ReadFile(std::get<fs_root_t>(root_) / - file_path); + auto full_path = std::get<fs_root_t>(root_) / file_path; + if (auto type = FileSystemManager::Type(full_path)) { + return IsSymlinkObject(*type) + ? FileSystemManager::ReadSymlink(full_path) + : FileSystemManager::ReadFile(full_path); + } + return std::nullopt; } [[nodiscard]] auto ReadDirectory(std::filesystem::path const& dir_path) @@ -430,13 +471,13 @@ class FileRoot { return DirectoryEntries{DirectoryEntries::pairs_t{}}; } - [[nodiscard]] auto FileType(std::filesystem::path const& file_path) + [[nodiscard]] auto BlobType(std::filesystem::path const& file_path) const noexcept -> std::optional<ObjectType> { if (std::holds_alternative<git_root_t>(root_)) { if (auto entry = std::get<git_root_t>(root_).tree->LookupEntryByPath( file_path)) { - if (IsFileObject(entry->Type())) { + if (IsBlobObject(entry->Type())) { return entry->Type(); } } @@ -444,7 +485,7 @@ class FileRoot { } auto type = FileSystemManager::Type(std::get<fs_root_t>(root_) / file_path); - if (type and IsFileObject(*type)) { + if (type and IsBlobObject(*type)) { return type; } return std::nullopt; |