diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/buildtool/file_system/TARGETS | 10 | ||||
-rw-r--r-- | src/buildtool/file_system/git_cas.cpp | 46 | ||||
-rw-r--r-- | src/buildtool/file_system/git_cas.hpp | 8 | ||||
-rw-r--r-- | src/buildtool/file_system/git_context.cpp | 37 | ||||
-rw-r--r-- | src/buildtool/file_system/git_context.hpp | 36 |
5 files changed, 104 insertions, 33 deletions
diff --git a/src/buildtool/file_system/TARGETS b/src/buildtool/file_system/TARGETS index 20a1aab9..3bc4471e 100644 --- a/src/buildtool/file_system/TARGETS +++ b/src/buildtool/file_system/TARGETS @@ -29,7 +29,7 @@ , "name": ["git_cas"] , "hdrs": ["git_cas.hpp"] , "srcs": ["git_cas.cpp"] - , "deps": ["object_type", ["@", "gsl-lite", "", "gsl-lite"]] + , "deps": ["object_type", "git_context", ["@", "gsl-lite", "", "gsl-lite"]] , "stage": ["src", "buildtool", "file_system"] , "private-deps": [ "file_system_manager" @@ -57,6 +57,14 @@ , ["src/buildtool/logging", "logging"] ] } +, "git_context": + { "type": ["@", "rules", "CC", "library"] + , "name": ["git_context"] + , "hdrs": ["git_context.hpp"] + , "srcs": ["git_context.cpp"] + , "stage": ["src", "buildtool", "file_system"] + , "private-deps": [["src/buildtool/logging", "logging"], ["", "libgit2"]] + } , "file_root": { "type": ["@", "rules", "CC", "library"] , "name": ["file_root"] diff --git a/src/buildtool/file_system/git_cas.cpp b/src/buildtool/file_system/git_cas.cpp index 799068f2..d1ea0870 100644 --- a/src/buildtool/file_system/git_cas.cpp +++ b/src/buildtool/file_system/git_cas.cpp @@ -317,22 +317,12 @@ auto GitCAS::Open(std::filesystem::path const& repo_path) noexcept return nullptr; } -GitCAS::GitCAS() noexcept { -#ifndef BOOTSTRAP_BUILD_TOOL - if (not(initialized_ = (git_libgit2_init() >= 0))) { - Logger::Log(LogLevel::Error, "initializing libgit2 failed"); - } -#endif -} GitCAS::~GitCAS() noexcept { #ifndef BOOTSTRAP_BUILD_TOOL if (odb_ != nullptr) { git_odb_free(odb_); odb_ = nullptr; } - if (initialized_) { - git_libgit2_shutdown(); - } #endif } @@ -341,7 +331,7 @@ auto GitCAS::ReadObject(std::string const& id, bool is_hex_id) const noexcept #ifdef BOOTSTRAP_BUILD_TOOL return std::nullopt; #else - if (not initialized_) { + if (odb_ == nullptr) { return std::nullopt; } @@ -419,7 +409,7 @@ auto GitCAS::ReadTree(std::string const& id, bool is_hex_id) const noexcept auto GitCAS::ReadHeader(std::string const& id, bool is_hex_id) const noexcept -> std::optional<std::pair<std::size_t, ObjectType>> { #ifndef BOOTSTRAP_BUILD_TOOL - if (not initialized_) { + if (odb_ == nullptr) { return std::nullopt; } @@ -507,29 +497,27 @@ auto GitCAS::OpenODB(std::filesystem::path const& repo_path) noexcept -> bool { #ifdef BOOTSTRAP_BUILD_TOOL return false; #else - if (initialized_) { - { // lock as git_repository API has no thread-safety guarantees - std::unique_lock lock{repo_mutex}; - git_repository* repo = nullptr; - if (git_repository_open(&repo, repo_path.c_str()) != 0) { - Logger::Log(LogLevel::Error, - "opening git repository {} failed with:\n{}", - repo_path.string(), - GitLastError()); - return false; - } - git_repository_odb(&odb_, repo); - git_repository_free(repo); - } - if (odb_ == nullptr) { + { // lock as git_repository API has no thread-safety guarantees + std::unique_lock lock{repo_mutex}; + git_repository* repo = nullptr; + if (git_repository_open(&repo, repo_path.c_str()) != 0) { Logger::Log(LogLevel::Error, - "obtaining git object database {} failed with:\n{}", + "opening git repository {} failed with:\n{}", repo_path.string(), GitLastError()); return false; } + git_repository_odb(&odb_, repo); + git_repository_free(repo); + } + if (odb_ == nullptr) { + Logger::Log(LogLevel::Error, + "obtaining git object database {} failed with:\n{}", + repo_path.string(), + GitLastError()); + return false; } - return initialized_; + return true; #endif } diff --git a/src/buildtool/file_system/git_cas.hpp b/src/buildtool/file_system/git_cas.hpp index 26acc52f..3670d188 100644 --- a/src/buildtool/file_system/git_cas.hpp +++ b/src/buildtool/file_system/git_cas.hpp @@ -21,6 +21,7 @@ #include <unordered_map> #include <vector> +#include "src/buildtool/file_system/git_context.hpp" #include "src/buildtool/file_system/object_type.hpp" extern "C" { @@ -30,7 +31,7 @@ using git_odb = struct git_odb; class GitCAS; using GitCASPtr = std::shared_ptr<GitCAS const>; -/// \brief Git CAS that maintains its own libgit2 global state. +/// \brief Git CAS that maintains its Git context. class GitCAS { public: // Stores the data for defining a single Git tree entry, which consists of @@ -55,7 +56,7 @@ class GitCAS { static auto Open(std::filesystem::path const& repo_path) noexcept -> GitCASPtr; - GitCAS() noexcept; + GitCAS() noexcept = default; ~GitCAS() noexcept; // prohibit moves and copies @@ -123,8 +124,9 @@ class GitCAS { -> std::optional<std::pair<std::string, std::string>>; private: + // IMPORTANT: the GitContext needs to be initialized before any git object! + GitContext git_context_{}; // maintains a Git context while CAS is alive git_odb* odb_{nullptr}; - bool initialized_{false}; [[nodiscard]] auto OpenODB(std::filesystem::path const& repo_path) noexcept -> bool; diff --git a/src/buildtool/file_system/git_context.cpp b/src/buildtool/file_system/git_context.cpp new file mode 100644 index 00000000..04d4498d --- /dev/null +++ b/src/buildtool/file_system/git_context.cpp @@ -0,0 +1,37 @@ +// Copyright 2022 Huawei Cloud Computing Technology Co., Ltd. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "src/buildtool/file_system/git_context.hpp" + +#include "src/buildtool/logging/logger.hpp" + +extern "C" { +#include <git2.h> +} + +GitContext::GitContext() noexcept { +#ifndef BOOTSTRAP_BUILD_TOOL + if (not(initialized_ = (git_libgit2_init() >= 0))) { + Logger::Log(LogLevel::Error, "initializing libgit2 failed"); + } +#endif +} + +GitContext::~GitContext() noexcept { +#ifndef BOOTSTRAP_BUILD_TOOL + if (initialized_) { + git_libgit2_shutdown(); + } +#endif +}
\ No newline at end of file diff --git a/src/buildtool/file_system/git_context.hpp b/src/buildtool/file_system/git_context.hpp new file mode 100644 index 00000000..d6aaeab6 --- /dev/null +++ b/src/buildtool/file_system/git_context.hpp @@ -0,0 +1,36 @@ +// Copyright 2022 Huawei Cloud Computing Technology Co., Ltd. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef INCLUDED_SRC_BUILDTOOL_FILE_SYSTEM_GIT_CONTEXT_HPP +#define INCLUDED_SRC_BUILDTOOL_FILE_SYSTEM_GIT_CONTEXT_HPP + +/// \brief Maintainer of a libgit2 state. +/// Classes, static methods, and global functions dealing with Git operations +/// should create a GitContext before using Git operations. +class GitContext { + public: + // prohibit moves and copies + GitContext(GitContext const&) = delete; + GitContext(GitContext&& other) = delete; + auto operator=(GitContext const&) = delete; + auto operator=(GitContext&& other) = delete; + + GitContext() noexcept; + ~GitContext() noexcept; + + private: + bool initialized_{false}; +}; + +#endif // INCLUDED_SRC_BUILDTOOL_FILE_SYSTEM_GIT_CONTEXT_HPP
\ No newline at end of file |