LCOV - code coverage report
Current view: top level - src/esys/repo/libgit2 - notes_libgit2.cpp (source / functions) Hit Total Coverage
Test: esysrepo_coverage.info Lines: 103 107 96.3 %
Date: 2026-08-01 10:43:40 Functions: 13 14 92.9 %

          Line data    Source code
       1             : /*!
       2             :  * \file esys/repo/libgit2/notes_libgit2.cpp.
       3             :  * \brief
       4             :  *
       5             :  * \cond
       6             :  * __legal_b__
       7             :  *
       8             :  * Copyright (c) 2023 Michel Gillet
       9             :  * Distributed under the MIT License.
      10             :  * (See accompanying file LICENSE.txt or
      11             :  * copy at https://opensource.org/licenses/MIT)
      12             :  *
      13             :  * __legal_e__
      14             :  * \endcond
      15             :  *
      16             :  */
      17             : 
      18             : #include "esys/repo/esysrepo_prec.h"
      19             : #include "esys/repo/libgit2/notes.h"
      20             : #include "esys/repo/libgit2/gitimpl.h"
      21             : #include "esys/repo/libgit2/git.h"
      22             : 
      23             : namespace esys::repo::libgit2
      24             : {
      25             : 
      26         203 : Notes::Notes(Git *git)
      27         203 :     : m_git(git)
      28             : {
      29         203 : }
      30             : 
      31           6 : Git *Notes::get_git()
      32             : {
      33           6 :     return m_git;
      34             : }
      35             : 
      36          22 : GitImpl *Notes::get_git_impl()
      37             : {
      38          22 :     return m_git->get_impl();
      39             : }
      40             : 
      41           6 : Result Notes::load_all()
      42             : {
      43           6 :     if (is_loaded()) return ESYSREPO_RESULT(ResultCode::OK);
      44             : 
      45           6 :     Result result;
      46             : 
      47          13 :     for (auto const &ref : get_git()->get_notes_references())
      48             :     {
      49           7 :         result = load(ref);
      50           7 :         if (result.error()) return ESYSREPO_RESULT(result);
      51             :     }
      52             : 
      53           6 :     set_loaded(true);
      54             : 
      55           6 :     return ESYSREPO_RESULT(ResultCode::OK);
      56           6 : }
      57             : 
      58           7 : Result Notes::load(const std::string &ref)
      59             : {
      60           7 :     Guard<git_iterator> it;
      61           7 :     std::string the_ref = GitImpl::normalize_notes_ref(ref);
      62             : 
      63           7 :     auto result_int = git_note_iterator_new(it.get_p(), get_git_impl()->get_repo(), the_ref.c_str());
      64           7 :     if (result_int != 0)
      65             :     {
      66             :         // It would seem that this error means there are no notes to iterate over
      67           1 :         if (result_int == GIT_ENOTFOUND) return ESYSREPO_RESULT(ResultCode::OK);
      68           0 :         return ESYSREPO_RESULT(ResultCode::GIT_RAW_INT_ERROR, result_int);
      69             :     }
      70             : 
      71           6 :     git_oid note_id;
      72           6 :     git_oid annotated_id;
      73           6 :     auto ref_map_notes_it = m_ref_map_notes.find(ref);
      74             : 
      75           6 :     if (ref_map_notes_it != m_ref_map_notes.end()) return ESYSREPO_RESULT(ResultCode::GENERIC_ERROR);
      76             : 
      77           6 :     auto ref_map_notes = std::make_shared<RefMapNotesItem>();
      78           6 :     ref_map_notes->m_ref = ref;
      79             : 
      80           6 :     m_ref_map_notes[ref] = ref_map_notes;
      81             : 
      82          11 :     do
      83             :     {
      84          11 :         result_int = git_note_next(&note_id, &annotated_id, it.get());
      85          21 :         if (result_int == 0) add_note(ref_map_notes, note_id, annotated_id);
      86          11 :     } while (result_int == 0);
      87             : 
      88           6 :     if (result_int == GIT_ITEROVER) return ESYSREPO_RESULT(ResultCode::OK);
      89           0 :     return ESYSREPO_RESULT(ResultCode::GIT_RAW_INT_ERROR, result_int);
      90           7 : }
      91             : 
      92           0 : Notes::OIDCommitMapNoteItem::OIDCommitMapNoteItem() = default;
      93             : 
      94           5 : Notes::OIDCommitMapNoteItem::OIDCommitMapNoteItem(Notes *notes, const git_oid &note_oid, const git_oid &comment_oid,
      95           5 :                                                   RefMapNotesItem *ref_map)
      96           5 :     : m_notes(notes)
      97           5 :     , m_note_oid(note_oid)
      98           5 :     , m_comment_oid(comment_oid)
      99           5 :     , m_ref_map(ref_map)
     100             : {
     101           5 : }
     102             : 
     103           5 : std::shared_ptr<git::Note> Notes::OIDCommitMapNoteItem::get_note()
     104             : {
     105           5 :     if (m_note != nullptr) return m_note;
     106             : 
     107           5 :     Guard<git_note> note_obj;
     108             : 
     109           5 :     if (m_ref.empty()) m_ref = GitImpl::normalize_notes_ref(m_ref_map->m_ref);
     110             : 
     111           5 :     auto result_int =
     112           5 :         git_note_read(note_obj.get_p(), m_notes->get_git_impl()->get_repo(), m_ref.c_str(), &m_comment_oid);
     113          10 :     if (result_int != 0) return nullptr;
     114             : 
     115           5 :     m_note = std::make_shared<git::Note>();
     116           5 :     auto message = git_note_message(note_obj.get());
     117          10 :     if (message != nullptr) m_note->set_message(message);
     118             : 
     119           5 :     m_note->set_reference(m_ref_map->m_ref);
     120             : 
     121           5 :     auto author = git_note_author(note_obj.get());
     122           5 :     Result result = m_notes->get_git_impl()->get_signature(author, m_note->get_author());
     123           5 :     if (result.error()) return nullptr;
     124             : 
     125           5 :     auto committer = git_note_committer(note_obj.get());
     126           5 :     result = m_notes->get_git_impl()->get_signature(author, m_note->get_committer());
     127           5 :     if (result.error()) return nullptr;
     128             : 
     129           5 :     return m_note;
     130          10 : }
     131             : 
     132          10 : bool Comparegit_oid::operator()(const git_oid &lhs, const git_oid &rhs) const
     133             : {
     134         210 :     for (int idx = 0; idx < GIT_OID_RAWSZ; ++idx)
     135             :     {
     136         200 :         if (lhs.id[idx] < rhs.id[idx]) return true;
     137             :     }
     138             :     return false;
     139             : }
     140             : 
     141           5 : void Notes::add_note(std::shared_ptr<RefMapNotesItem> map, const git_oid &note_oid, const git_oid &commit_oid)
     142             : {
     143           5 :     OIDCommitMapNoteItem item(this, note_oid, commit_oid, map.get());
     144             : 
     145           5 :     std::shared_ptr<OIDCommitMapNoteVec> oid_map_notes_vec;
     146             : 
     147           5 :     auto oid_map_notes_it = m_oid_map_notes.find(commit_oid);
     148           5 :     if (oid_map_notes_it == m_oid_map_notes.end())
     149             :     {
     150           8 :         oid_map_notes_vec = std::make_shared<OIDCommitMapNoteVec>();
     151           4 :         m_oid_map_notes[commit_oid] = oid_map_notes_vec;
     152             :     }
     153             :     else
     154           1 :         oid_map_notes_vec = oid_map_notes_it->second;
     155           5 :     oid_map_notes_vec->push_back(item);
     156             : 
     157           5 :     std::shared_ptr<OIDCommitMapNoteVec> iod_commit_map_note_vec;
     158           5 :     auto iod_commit_map_note_it = map->m_iod_commit_map_note.find(commit_oid);
     159           5 :     if (iod_commit_map_note_it == map->m_iod_commit_map_note.end())
     160             :     {
     161          10 :         iod_commit_map_note_vec = std::make_shared<OIDCommitMapNoteVec>();
     162           5 :         map->m_iod_commit_map_note[commit_oid] = iod_commit_map_note_vec;
     163             :     }
     164             :     else
     165           0 :         iod_commit_map_note_vec = iod_commit_map_note_it->second;
     166             : 
     167           5 :     iod_commit_map_note_vec->push_back(item);
     168          10 : }
     169             : 
     170           6 : Result Notes::get_note(const git_oid &note_oid, std::vector<std::shared_ptr<git::Note>> &notes) const
     171             : {
     172           6 :     notes.clear();
     173             : 
     174           6 :     auto it = m_oid_map_notes.find(note_oid);
     175           6 :     if (it == m_oid_map_notes.end()) return ESYSREPO_RESULT(ResultCode::OK);
     176             : 
     177           4 :     auto vec = it->second;
     178             : 
     179           4 :     if (vec == nullptr) return ESYSREPO_RESULT(ResultCode::OK);
     180             : 
     181           9 :     for (auto &item : *vec.get())
     182             :     {
     183           5 :         auto note = item.get_note();
     184           5 :         if (note == nullptr) return ESYSREPO_RESULT(ResultCode::INTERNAL_ERROR);
     185           5 :         notes.push_back(note);
     186           5 :     }
     187             : 
     188           4 :     return ESYSREPO_RESULT(ResultCode::OK);
     189           6 : }
     190             : 
     191           6 : bool Notes::is_loaded() const
     192             : {
     193           6 :     return m_loaded;
     194             : }
     195             : 
     196          14 : void Notes::set_loaded(bool loaded)
     197             : {
     198          14 :     m_loaded = loaded;
     199          14 : }
     200             : 
     201           8 : void Notes::clear()
     202             : {
     203           8 :     m_ref_map_notes.clear();
     204           8 :     m_oid_map_notes.clear();
     205           8 :     set_loaded(false);
     206           8 : }
     207             : 
     208             : } // namespace esys::repo::libgit2

Generated by: LCOV version 1.14