diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/buildtool/build_engine/base_maps/json_file_map.hpp | 2 | ||||
-rw-r--r-- | src/buildtool/build_engine/base_maps/source_map.cpp | 4 | ||||
-rw-r--r-- | src/buildtool/execution_engine/executor/executor.hpp | 4 | ||||
-rw-r--r-- | src/buildtool/file_system/file_root.hpp | 63 | ||||
-rw-r--r-- | src/buildtool/file_system/object_type.hpp | 6 | ||||
-rw-r--r-- | src/buildtool/main/main.cpp | 6 |
6 files changed, 68 insertions, 17 deletions
diff --git a/src/buildtool/build_engine/base_maps/json_file_map.hpp b/src/buildtool/build_engine/base_maps/json_file_map.hpp index 2fdd3f98..f5fb190e 100644 --- a/src/buildtool/build_engine/base_maps/json_file_map.hpp +++ b/src/buildtool/build_engine/base_maps/json_file_map.hpp @@ -77,7 +77,7 @@ auto CreateJsonFileMap(std::size_t jobs) -> JsonFileMap { return; } - auto const file_content = root->ReadFile(json_file_path); + auto const file_content = root->ReadContent(json_file_path); if (not file_content) { (*logger)(fmt::format("cannot read JSON file {}.", json_file_path.string()), diff --git a/src/buildtool/build_engine/base_maps/source_map.cpp b/src/buildtool/build_engine/base_maps/source_map.cpp index b2fa238b..1b39ec3e 100644 --- a/src/buildtool/build_engine/base_maps/source_map.cpp +++ b/src/buildtool/build_engine/base_maps/source_map.cpp @@ -89,14 +89,14 @@ auto CreateSourceTargetMap(const gsl::not_null<DirectoryEntriesMap*>& dirs, if (ws_root != nullptr and ws_root->HasFastDirectoryLookup()) { // by-pass directory map and directly attempt to read from ws_root - src_file_reader(ws_root->IsFile(path(target.module) / name)); + src_file_reader(ws_root->IsBlob(path(target.module) / name)); return; } dirs->ConsumeAfterKeysReady( ts, {ModuleName{target.repository, dir.string()}}, [key, src_file_reader](auto values) { - src_file_reader(values[0]->ContainsFile( + src_file_reader(values[0]->ContainsBlob( path(key.GetNamedTarget().name).filename().string())); }, [logger, dir](auto msg, auto fatal) { diff --git a/src/buildtool/execution_engine/executor/executor.hpp b/src/buildtool/execution_engine/executor/executor.hpp index d262eac5..32a8cc2c 100644 --- a/src/buildtool/execution_engine/executor/executor.hpp +++ b/src/buildtool/execution_engine/executor/executor.hpp @@ -394,11 +394,11 @@ class ExecutorImpl { if (ws_root == nullptr) { return std::nullopt; } - auto const object_type = ws_root->FileType(file_path); + auto const object_type = ws_root->BlobType(file_path); if (not object_type) { return std::nullopt; } - auto content = ws_root->ReadFile(file_path); + auto content = ws_root->ReadContent(file_path); if (not content.has_value()) { return std::nullopt; } 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; diff --git a/src/buildtool/file_system/object_type.hpp b/src/buildtool/file_system/object_type.hpp index 28e34236..04457582 100644 --- a/src/buildtool/file_system/object_type.hpp +++ b/src/buildtool/file_system/object_type.hpp @@ -70,6 +70,12 @@ enum class ObjectType : std::int8_t { return type == ObjectType::Symlink; } +/// \brief Valid blob sources can be files, executables, or symlinks. +[[nodiscard]] constexpr auto IsBlobObject(ObjectType type) -> bool { + return type == ObjectType::Executable or type == ObjectType::File or + type == ObjectType::Symlink; +} + /// \brief Only regular files, executables, and trees are non-special entries. [[nodiscard]] constexpr auto IsNonSpecialObject(ObjectType type) -> bool { return type == ObjectType::File or type == ObjectType::Executable or diff --git a/src/buildtool/main/main.cpp b/src/buildtool/main/main.cpp index 3dee0096..288101f5 100644 --- a/src/buildtool/main/main.cpp +++ b/src/buildtool/main/main.cpp @@ -581,7 +581,11 @@ void SetupHashFunction() { } auto const target_file = (std::filesystem::path{current_module} / target_file_name).string(); - auto file_content = target_root->ReadFile(target_file); + if (not target_root->IsFile(target_file)) { + Logger::Log(LogLevel::Error, "Expected file at {}.", target_file); + std::exit(kExitFailure); + } + auto file_content = target_root->ReadContent(target_file); if (not file_content) { Logger::Log(LogLevel::Error, "Cannot read file {}.", target_file); std::exit(kExitFailure); |