LCOV - code coverage report
Current view: top level - src/esys/repo/manifest - xmlfileimpl_manifest.cpp (source / functions) Hit Total Coverage
Test: esysrepo_coverage.info Lines: 322 359 89.7 %
Date: 2026-09-26 15:38:18 Functions: 27 28 96.4 %

          Line data    Source code
       1             : /*!
       2             :  * \file esys/repo/manifest/xmlfileimpl_manifest.cpp
       3             :  * \brief
       4             :  *
       5             :  * \cond
       6             :  * __legal_b__
       7             :  *
       8             :  * Copyright (c) 2020 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/manifest/xmlfileimpl.h"
      20             : #include "esys/repo/manifest/xmlfile.h"
      21             : #include "esys/repo/manifest/depends.h"
      22             : #include "esys/repo/manifest/syncs.h"
      23             : 
      24             : #include <esysfile/xml/writer.h>
      25             : #include <esysfile/xml/file.h>
      26             : #include <esysfile/xml/attr.h>
      27             : 
      28             : #include <string>
      29             : 
      30             : namespace esys::repo::manifest
      31             : {
      32             : 
      33          42 : XMLFileImpl::XMLFileImpl(XMLFile *self)
      34          42 :     : m_self(self)
      35             : {
      36          42 : }
      37             : 
      38          84 : XMLFileImpl::~XMLFileImpl() = default;
      39             : 
      40          38 : Result XMLFileImpl::read(const std::string &path)
      41             : {
      42          38 :     esysfile::xml::File xml_file;
      43             : 
      44          38 :     xml_file.set_root_node_name("esysrepo_manifest");
      45          38 :     int result = xml_file.read(path);
      46          38 :     if (result < 0)
      47             :     {
      48           0 :         self()->add_error(result, "XML parsing failed.");
      49           0 :         return ESYSREPO_RESULT(ResultCode::MANIFEST_ERROR_PARSING_FILE, path);
      50             :     }
      51             : 
      52          76 :     if (self()->get_data() == nullptr) self()->set_data(std::make_shared<Manifest>());
      53             : 
      54          38 :     self()->get_data()->set_type(Type::ESYSREPO_MANIFEST);
      55             : 
      56          76 :     return read(xml_file.get_data());
      57          38 : }
      58             : 
      59          38 : Result XMLFileImpl::read(std::shared_ptr<esysfile::xml::Data> data)
      60             : {
      61          38 :     if (data->get_attrs().size() != 0)
      62             :     {
      63          28 :         Result result = read_root_attributes(data);
      64          14 :         if (result.error())
      65             :         {
      66           1 :             self()->add_error(result.get_result_code_int(), "read_root_attributes failed.");
      67           2 :             return ESYSREPO_RESULT(result);
      68             :         }
      69          14 :     }
      70             :     else
      71          48 :         self()->get_data()->set_kind(manifest::Kind::ISOLATED);
      72             : 
      73          37 :     Result result;
      74             : 
      75         143 :     for (auto el : data->get_elements())
      76             :     {
      77         106 :         if (el->get_name() == "location")
      78         186 :             result = read_location(el);
      79          44 :         else if ((el->get_name() == "default"))
      80         111 :             result = read_default(el);
      81           7 :         else if ((el->get_name() == "group"))
      82           6 :             result = read_group(el);
      83           5 :         else if (el->get_name() == "revision-set")
      84          12 :             result = read_revision_set(el);
      85             :         else
      86           1 :             result = unknown_element(el->get_name());
      87         106 :         if (result.error())
      88             :         {
      89           0 :             self()->add_error(result.get_result_code_int(), "Reading XML element failed : " + el->get_name());
      90           0 :             return result;
      91             :         }
      92         106 :     }
      93             : 
      94          37 :     Result depends_result = self()->get_data()->validate_depends();
      95          37 :     if (depends_result.error())
      96             :     {
      97           2 :         self()->add_error(depends_result.get_result_code_int(), "validate_depends failed.");
      98           2 :         return depends_result;
      99             :     }
     100          35 :     return ESYSREPO_RESULT(ResultCode::OK);
     101          37 : }
     102             : 
     103           2 : Result XMLFileImpl::unknown_element(const std::string &name)
     104             : {
     105           2 :     if (self()->get_parse_mode() == ParseMode::Tolerant) return ESYSREPO_RESULT(ResultCode::OK);
     106           0 :     return ESYSREPO_RESULT(ResultCode::MANIFEST_ELEMENT_UNKNOWN, name);
     107             : }
     108             : 
     109           3 : Result XMLFileImpl::unknown_attribute(const std::string &context, const std::string &attr_name)
     110             : {
     111           3 :     if (self()->get_parse_mode() == ParseMode::Tolerant) return ESYSREPO_RESULT(ResultCode::OK);
     112           1 :     return ESYSREPO_RESULT(ResultCode::MANIFEST_ATTRIBUTE_UNKNOWN, context + ": " + attr_name);
     113             : }
     114             : 
     115          14 : Result XMLFileImpl::read_root_attributes(std::shared_ptr<esysfile::xml::Element> root_el)
     116             : {
     117          33 :     for (auto attr : root_el->get_attrs())
     118             :     {
     119          40 :         Result result = read_root_attribute(attr);
     120          21 :         if (result.error()) return ESYSREPO_RESULT(result);
     121          40 :     }
     122          13 :     return ESYSREPO_RESULT(ResultCode::OK);
     123             : }
     124             : 
     125          20 : Result XMLFileImpl::read_root_attribute(std::shared_ptr<esysfile::xml::Attr> attr)
     126             : {
     127          20 :     if (attr->get_name() == "kind")
     128             :     {
     129          14 :         manifest::Kind kind;
     130          14 :         Result result = convert(attr->get_value(), kind);
     131          14 :         if (result.error()) return ESYSREPO_RESULT(result, ResultCode::MANIFEST_KIND_UNKNOWN, attr->get_value());
     132             : 
     133          14 :         self()->get_data()->set_kind(kind);
     134          14 :         return ESYSREPO_RESULT(ResultCode::OK);
     135          14 :     }
     136           6 :     if (attr->get_name() == "schema-version")
     137             :     {
     138           4 :         const std::string &ver = attr->get_value();
     139           8 :         if (ver != "1.0" && ver != "1.1")
     140           0 :             return ESYSREPO_RESULT(ResultCode::MANIFEST_INCORRECT_ATTRIBUTE_VALUE, ver);
     141           4 :         return ESYSREPO_RESULT(ResultCode::OK);
     142             :     }
     143           4 :     return unknown_attribute("esysrepo_manifest", attr->get_name());
     144             : }
     145             : 
     146          62 : Result XMLFileImpl::read_location(std::shared_ptr<esysfile::xml::Element> el)
     147             : {
     148          62 :     if (el->get_name() != "location") return ESYSREPO_RESULT(ResultCode::INTERNAL_ERROR);
     149             : 
     150          62 :     std::shared_ptr<Location> location = std::make_shared<Location>();
     151             : 
     152          62 :     auto attr = el->get_attr("name");
     153          62 :     if (attr != nullptr)
     154          62 :         location->set_name(attr->get_value());
     155             :     else
     156           0 :         return ESYSREPO_RESULT(ResultCode::MANIFEST_LOCATION_WITHOUT_NAME);
     157             : 
     158         124 :     attr = el->get_attr("addr");
     159          62 :     if (attr != nullptr)
     160          62 :         location->set_address(attr->get_value());
     161             :     else
     162           0 :         return ESYSREPO_RESULT(ResultCode::MANIFEST_LOCATION_WITHOUT_ADDRESS);
     163             : 
     164         124 :     attr = el->get_attr("alt_addr");
     165          62 :     if (attr != nullptr) location->set_alt_address(attr->get_value());
     166             : 
     167          62 :     Result result;
     168             : 
     169         364 :     for (auto child_el : el->get_elements())
     170             :     {
     171         302 :         if (child_el->get_name() == "repository")
     172        1505 :             result = read_repository(child_el, location);
     173             :         else
     174           1 :             result = unknown_element(child_el->get_name());
     175         302 :         if (result.error()) return result;
     176         302 :     }
     177             : 
     178         186 :     self()->get_data()->add_location(location);
     179          62 :     return ESYSREPO_RESULT(ResultCode::OK);
     180         186 : }
     181             : 
     182         301 : Result XMLFileImpl::read_repository(std::shared_ptr<esysfile::xml::Element> el, std::shared_ptr<Location> location)
     183             : {
     184         301 :     if (el->get_name() != "repository") return ESYSREPO_RESULT(ResultCode::INTERNAL_ERROR);
     185             : 
     186         301 :     auto repository = std::make_shared<Repository>();
     187         301 :     repository->set_location(location.get());
     188             : 
     189         301 :     auto attr = el->get_attr("name");
     190         301 :     if (attr == nullptr) return ESYSREPO_RESULT(ResultCode::MANIFEST_REPOSITORY_WITHOUT_NAME);
     191         301 :     repository->set_name(attr->get_value());
     192             : 
     193         602 :     attr = el->get_attr("path");
     194         301 :     if (attr == nullptr) return ESYSREPO_RESULT(ResultCode::MANIFEST_REPOSITORY_WITHOUT_PATH);
     195         301 :     repository->set_path(attr->get_value());
     196             : 
     197         602 :     attr = el->get_attr("revision");
     198         301 :     if (attr != nullptr) repository->set_revision(attr->get_value());
     199             : 
     200         602 :     attr = el->get_attr("sync-s");
     201         301 :     if (attr != nullptr)
     202             :     {
     203           1 :         bool sync_s = false;
     204           1 :         if (!parse_sync_s_value(attr->get_value(), sync_s))
     205           0 :             return ESYSREPO_RESULT(ResultCode::MANIFEST_INCORRECT_ATTRIBUTE_VALUE, "repository.sync-s");
     206           1 :         repository->set_sync_s(sync_s);
     207             :     }
     208             : 
     209         308 :     for (auto child_el : el->get_elements())
     210             :     {
     211           7 :         if (child_el->get_name() == "depends")
     212             :         {
     213          28 :             Result result = read_depends(child_el, repository);
     214           7 :             if (result.error()) return result;
     215           7 :         }
     216             :         else
     217             :         {
     218           0 :             Result result = unknown_element(child_el->get_name());
     219           0 :             if (result.error()) return result;
     220           0 :         }
     221           7 :     }
     222             : 
     223         602 :     location->add_repo(repository);
     224             : 
     225         301 :     return ESYSREPO_RESULT(ResultCode::OK);
     226         602 : }
     227             : 
     228           7 : Result XMLFileImpl::read_depends(std::shared_ptr<esysfile::xml::Element> el, std::shared_ptr<Repository> repository)
     229             : {
     230           7 :     if (el->get_name() != "depends") return ESYSREPO_RESULT(ResultCode::INTERNAL_ERROR);
     231             : 
     232           7 :     auto depends = std::make_shared<Depends>();
     233           7 :     int identity_count = 0;
     234             : 
     235           7 :     auto attr = el->get_attr("path");
     236           7 :     if (attr != nullptr)
     237             :     {
     238           7 :         depends->set_selector(DependsSelector::PATH);
     239           7 :         depends->set_value(attr->get_value());
     240             :         ++identity_count;
     241             :     }
     242          14 :     attr = el->get_attr("name");
     243           7 :     if (attr != nullptr)
     244             :     {
     245           0 :         if (identity_count > 0)
     246           0 :             return ESYSREPO_RESULT(ResultCode::MANIFEST_INCORRECT_ATTRIBUTE_VALUE, "depends: multiple identities");
     247           0 :         depends->set_selector(DependsSelector::NAME);
     248           0 :         depends->set_value(attr->get_value());
     249             :         ++identity_count;
     250             :     }
     251          14 :     attr = el->get_attr("project");
     252           7 :     if (attr != nullptr)
     253             :     {
     254           0 :         if (identity_count > 0)
     255           0 :             return ESYSREPO_RESULT(ResultCode::MANIFEST_INCORRECT_ATTRIBUTE_VALUE, "depends: multiple identities");
     256           0 :         depends->set_selector(DependsSelector::PROJECT);
     257           0 :         depends->set_value(attr->get_value());
     258             :         ++identity_count;
     259             :     }
     260          14 :     attr = el->get_attr("url");
     261           7 :     if (attr != nullptr)
     262             :     {
     263           0 :         if (identity_count > 0)
     264           0 :             return ESYSREPO_RESULT(ResultCode::MANIFEST_INCORRECT_ATTRIBUTE_VALUE, "depends: multiple identities");
     265           0 :         depends->set_selector(DependsSelector::URL);
     266           0 :         depends->set_value(attr->get_value());
     267             :         ++identity_count;
     268             :     }
     269             : 
     270           7 :     if (identity_count != 1)
     271           0 :         return ESYSREPO_RESULT(ResultCode::MANIFEST_DEPENDS_WITHOUT_IDENTITY, "repository=" + repository->get_path());
     272             : 
     273          14 :     for (auto child_attr : el->get_attrs())
     274             :     {
     275           7 :         const auto &n = child_attr->get_name();
     276           7 :         if (n != "path" && n != "name" && n != "project" && n != "url")
     277             :         {
     278           0 :             Result result = unknown_attribute("depends", n);
     279           0 :             if (result.error()) return result;
     280           0 :         }
     281           7 :     }
     282             : 
     283          14 :     repository->add_depends(depends);
     284           7 :     return ESYSREPO_RESULT(ResultCode::OK);
     285          14 : }
     286             : 
     287          37 : Result XMLFileImpl::read_default(std::shared_ptr<esysfile::xml::Element> el)
     288             : {
     289          37 :     if (el->get_name() != "default") return ESYSREPO_RESULT(ResultCode::INTERNAL_ERROR);
     290             : 
     291         112 :     for (auto attr : el->get_attrs())
     292             :     {
     293         150 :         Result result = read_default_attr(attr);
     294          75 :         if (result.error()) return result;
     295         150 :     }
     296          37 :     return ESYSREPO_RESULT(ResultCode::OK);
     297             : }
     298             : 
     299          75 : Result XMLFileImpl::read_default_attr(std::shared_ptr<esysfile::xml::Attr> attr)
     300             : {
     301          75 :     if (attr->get_name() == "revision")
     302          74 :         self()->get_data()->set_default_revision(attr->get_value());
     303          38 :     else if (attr->get_name() == "sync-j")
     304          68 :         self()->get_data()->set_default_job_count(atoi(attr->get_value().c_str()));
     305           4 :     else if (attr->get_name() == "revision-set")
     306           4 :         self()->get_data()->set_default_revision_set(attr->get_value());
     307           2 :     else if (attr->get_name() == "sync-s")
     308             :     {
     309           1 :         bool sync_s = false;
     310           1 :         if (!parse_sync_s_value(attr->get_value(), sync_s))
     311           0 :             return ESYSREPO_RESULT(ResultCode::MANIFEST_INCORRECT_ATTRIBUTE_VALUE, "default.sync-s");
     312           2 :         self()->get_data()->set_default_sync_s(sync_s);
     313             :     }
     314             :     else
     315           2 :         return unknown_attribute("default", attr->get_name());
     316          74 :     return ESYSREPO_RESULT(ResultCode::OK);
     317             : }
     318             : 
     319           2 : Result XMLFileImpl::read_group(std::shared_ptr<esysfile::xml::Element> el)
     320             : {
     321           2 :     auto attr = el->get_attr("name");
     322           2 :     if (attr == nullptr) return ESYSREPO_RESULT(ResultCode::MANIFEST_GROUP_WITHOUT_NAME);
     323             : 
     324           2 :     std::shared_ptr<Group> group = std::make_shared<Group>();
     325           2 :     group->set_name(attr->get_value());
     326             : 
     327           6 :     for (auto child : el->get_elements())
     328             :     {
     329          16 :         Result result = read_group_repo(child, group);
     330           4 :         if (result.error()) return ESYSREPO_RESULT(result);
     331           8 :     }
     332             : 
     333           6 :     self()->get_data()->get_groups().add_group(group);
     334             : 
     335           2 :     return ESYSREPO_RESULT(ResultCode::OK);
     336           4 : }
     337             : 
     338           4 : Result XMLFileImpl::read_group_repo(std::shared_ptr<esysfile::xml::Element> el, std::shared_ptr<Group> group)
     339             : {
     340           4 :     if (el->get_name() != "repo") return unknown_element(el->get_name());
     341             : 
     342           4 :     auto attr = el->get_attr("path");
     343           4 :     if (attr == nullptr) return ESYSREPO_RESULT(ResultCode::MANIFEST_GROUP_REPO_WITHOUT_PATH);
     344             : 
     345           4 :     auto repo = self()->get_data()->find_repo_by_path(attr->get_value());
     346           4 :     if (repo == nullptr) return ESYSREPO_RESULT(ResultCode::MANIFEST_REPO_UNKNOWN, "path = " + attr->get_value());
     347             : 
     348           8 :     group->add_repo(repo);
     349           4 :     return ESYSREPO_RESULT(ResultCode::OK);
     350           8 : }
     351             : 
     352           4 : Result XMLFileImpl::read_revision_set(std::shared_ptr<esysfile::xml::Element> el)
     353             : {
     354           4 :     if (el->get_name() != "revision-set") return ESYSREPO_RESULT(ResultCode::INTERNAL_ERROR);
     355             : 
     356           4 :     auto attr = el->get_attr("name");
     357           4 :     if (attr == nullptr) return ESYSREPO_RESULT(ResultCode::MANIFEST_ATTRIBUTE_UNKNOWN, "revision-set missing name");
     358             : 
     359           4 :     auto revision_set = std::make_shared<RevisionSet>(attr->get_value());
     360          10 :     for (auto child : el->get_elements())
     361             :     {
     362          24 :         Result result = read_revision_set_child(child, revision_set);
     363           6 :         if (result.error()) return ESYSREPO_RESULT(result);
     364          12 :     }
     365             : 
     366          12 :     self()->get_data()->get_revision_sets().add_revision_set(revision_set);
     367           4 :     return ESYSREPO_RESULT(ResultCode::OK);
     368           8 : }
     369             : 
     370           6 : Result XMLFileImpl::read_revision_set_child(std::shared_ptr<esysfile::xml::Element> el,
     371             :                                            std::shared_ptr<RevisionSet> revision_set)
     372             : {
     373           6 :     if (el->get_name() == "default")
     374             :     {
     375           4 :         auto attr = el->get_attr("revision");
     376           4 :         if (attr == nullptr) return ESYSREPO_RESULT(ResultCode::MANIFEST_ATTRIBUTE_UNKNOWN, "default missing revision");
     377           4 :         revision_set->set_default_revision(attr->get_value());
     378           4 :         return ESYSREPO_RESULT(ResultCode::OK);
     379           4 :     }
     380           2 :     if (el->get_name() == "repository")
     381             :     {
     382           2 :         auto path_attr = el->get_attr("path");
     383           2 :         auto rev_attr = el->get_attr("revision");
     384           2 :         if (path_attr == nullptr) return ESYSREPO_RESULT(ResultCode::MANIFEST_REPOSITORY_WITHOUT_PATH);
     385           2 :         if (rev_attr == nullptr) return ESYSREPO_RESULT(ResultCode::MANIFEST_ATTRIBUTE_UNKNOWN, "repository missing revision");
     386           2 :         revision_set->set_repo_revision(path_attr->get_value(), rev_attr->get_value());
     387           2 :         return ESYSREPO_RESULT(ResultCode::OK);
     388           4 :     }
     389           0 :     return unknown_element(el->get_name());
     390             : }
     391             : 
     392           6 : Result XMLFileImpl::write_xml()
     393             : {
     394          12 :     if (self()->get_data() == nullptr) return ESYSREPO_RESULT(ResultCode::MANIFEST_XML_DATA_NULLPTR);
     395             : 
     396           6 :     m_xml_data = std::make_shared<esysfile::xml::Data>();
     397           6 :     m_xml_data->set_root_node_name("esysrepo_manifest");
     398             : 
     399          12 :     if (self()->get_data()->get_kind() != manifest::Kind::ISOLATED)
     400             :     {
     401           0 :         std::string kind;
     402           0 :         Result result = convert(self()->get_data()->get_kind(), kind);
     403           0 :         if (result.error()) return ESYSREPO_RESULT(result);
     404           0 :         m_xml_data->add_attr("kind", kind);
     405           0 :     }
     406             : 
     407           6 :     {
     408          12 :         Result result = write_default(m_xml_data);
     409           6 :         if (result.error()) return ESYSREPO_RESULT(result);
     410           6 :     }
     411             : 
     412          22 :     for (auto location : self()->get_data()->get_locations())
     413             :     {
     414          40 :         Result result = write(m_xml_data, location);
     415          10 :         if (result.error()) return ESYSREPO_RESULT(result);
     416          20 :     }
     417             : 
     418          14 :     for (auto group : self()->get_data()->get_groups().get_groups())
     419             :     {
     420           8 :         Result result = write(m_xml_data, group);
     421           2 :         if (result.error()) return ESYSREPO_RESULT(result);
     422           4 :     }
     423             : 
     424          14 :     for (auto revision_set : self()->get_data()->get_revision_sets().get_revision_sets())
     425             :     {
     426           8 :         Result result = write(m_xml_data, revision_set);
     427           2 :         if (result.error()) return ESYSREPO_RESULT(result);
     428           4 :     }
     429           6 :     return ESYSREPO_RESULT(ResultCode::OK);
     430             : }
     431             : 
     432           6 : Result XMLFileImpl::write_default(std::shared_ptr<esysfile::xml::Element> parent_el)
     433             : {
     434           6 :     auto data = self()->get_data();
     435             :     // Constructor default revision is "master"; omit <default> unless something is non-default
     436             :     // so existing 1.0 write round-trips stay unchanged.
     437           6 :     const bool has_jobs = data->get_default_job_count() != 1;
     438           6 :     const bool has_rev_set = !data->get_default_revision_set().empty();
     439           6 :     const bool has_nondefault_rev = !data->get_default_revision().empty() && data->get_default_revision() != "master";
     440           6 :     const bool has_sync_s = data->get_default_sync_s().has_value();
     441           6 :     if (!has_jobs && !has_rev_set && !has_nondefault_rev && !has_sync_s) return ESYSREPO_RESULT(ResultCode::OK);
     442             : 
     443           5 :     auto default_el = std::make_shared<esysfile::xml::Element>();
     444           5 :     default_el->set_name("default");
     445          10 :     if (!data->get_default_revision().empty()) default_el->add_attr("revision", data->get_default_revision());
     446           9 :     if (has_jobs) default_el->add_attr("sync-j", std::to_string(data->get_default_job_count()));
     447           6 :     if (has_rev_set) default_el->add_attr("revision-set", data->get_default_revision_set());
     448           6 :     if (has_sync_s) default_el->add_attr("sync-s", *data->get_default_sync_s() ? "true" : "false");
     449          10 :     parent_el->add_element(default_el);
     450           5 :     return ESYSREPO_RESULT(ResultCode::OK);
     451          12 : }
     452             : 
     453           4 : Result XMLFileImpl::write(const std::string &path)
     454             : {
     455           4 :     Result result = write_xml();
     456           4 :     if (result.error()) return ESYSREPO_RESULT(result);
     457             : 
     458           4 :     esysfile::xml::Writer writer;
     459             : 
     460           4 :     writer.set_indent(4);
     461           8 :     int result_int = writer.write(path, m_xml_data);
     462           4 :     if (result_int < 0) return ESYSREPO_RESULT(ResultCode::RAW_INT_ERROR, result_int);
     463           4 :     return ESYSREPO_RESULT(ResultCode::OK);
     464           4 : }
     465             : 
     466           2 : Result XMLFileImpl::write(std::ostream &os)
     467             : {
     468           2 :     Result result = write_xml();
     469           2 :     if (result.error()) return ESYSREPO_RESULT(result);
     470             : 
     471           2 :     esysfile::xml::Writer writer;
     472             : 
     473           2 :     writer.set_indent(4);
     474           4 :     int result_int = writer.write(os, m_xml_data);
     475           2 :     if (result_int < 0) return ESYSREPO_RESULT(ResultCode::RAW_INT_ERROR, result_int);
     476           2 :     return ESYSREPO_RESULT(ResultCode::OK);
     477           2 : }
     478             : 
     479          10 : Result XMLFileImpl::write(std::shared_ptr<esysfile::xml::Element> parent_el, std::shared_ptr<Location> location)
     480             : {
     481          10 :     std::shared_ptr<esysfile::xml::Element> location_el = std::make_shared<esysfile::xml::Element>();
     482             : 
     483          10 :     location_el->set_name("location");
     484          10 :     location_el->add_attr("name", location->get_name());
     485          10 :     location_el->add_attr("addr", location->get_address());
     486             : 
     487          87 :     for (auto repo : location->get_repos())
     488             :     {
     489         308 :         Result result = write(location_el, repo);
     490          77 :         if (result.error()) return ESYSREPO_RESULT(result);
     491         154 :     }
     492             : 
     493          20 :     parent_el->add_element(location_el);
     494          10 :     return ESYSREPO_RESULT(ResultCode::OK);
     495          10 : }
     496             : 
     497          77 : Result XMLFileImpl::write(std::shared_ptr<esysfile::xml::Element> parent_el, std::shared_ptr<Repository> repository)
     498             : {
     499          77 :     std::shared_ptr<esysfile::xml::Element> repo_el = std::make_shared<esysfile::xml::Element>();
     500             : 
     501          77 :     repo_el->set_name("repository");
     502          77 :     repo_el->add_attr("path", repository->get_path());
     503          77 :     repo_el->add_attr("name", repository->get_name());
     504          97 :     if (!repository->get_revision().empty()) repo_el->add_attr("revision", repository->get_revision());
     505          77 :     if (repository->get_sync_s().has_value())
     506           3 :         repo_el->add_attr("sync-s", *repository->get_sync_s() ? "true" : "false");
     507             : 
     508          79 :     for (const auto &depends : repository->get_depends())
     509             :     {
     510           2 :         if (depends == nullptr) continue;
     511           2 :         auto dep_el = std::make_shared<esysfile::xml::Element>();
     512           2 :         dep_el->set_name("depends");
     513           2 :         dep_el->add_attr(to_string(depends->get_selector()), depends->get_value());
     514           6 :         repo_el->add_element(dep_el);
     515           2 :     }
     516             : 
     517         154 :     parent_el->add_element(repo_el);
     518          77 :     return ESYSREPO_RESULT(ResultCode::OK);
     519          77 : }
     520             : 
     521           2 : Result XMLFileImpl::write(std::shared_ptr<esysfile::xml::Element> parent_el, std::shared_ptr<Group> group)
     522             : {
     523           2 :     std::shared_ptr<esysfile::xml::Element> grp_el = std::make_shared<esysfile::xml::Element>();
     524             : 
     525           2 :     grp_el->set_name("group");
     526           2 :     grp_el->add_attr("name", group->get_name());
     527             : 
     528           8 :     for (auto repo : group->get_repos())
     529             :     {
     530           6 :         std::shared_ptr<esysfile::xml::Element> repo_el = std::make_shared<esysfile::xml::Element>();
     531             : 
     532           6 :         repo_el->set_name("repo");
     533           6 :         repo_el->add_attr("path", repo->get_path());
     534          18 :         grp_el->add_element(repo_el);
     535          12 :     }
     536             : 
     537           4 :     parent_el->add_element(grp_el);
     538           2 :     return ESYSREPO_RESULT(ResultCode::OK);
     539           2 : }
     540             : 
     541           2 : Result XMLFileImpl::write(std::shared_ptr<esysfile::xml::Element> parent_el, std::shared_ptr<RevisionSet> revision_set)
     542             : {
     543           2 :     auto set_el = std::make_shared<esysfile::xml::Element>();
     544           2 :     set_el->set_name("revision-set");
     545           2 :     set_el->add_attr("name", revision_set->get_name());
     546             : 
     547           2 :     if (!revision_set->get_default_revision().empty())
     548             :     {
     549           2 :         auto default_el = std::make_shared<esysfile::xml::Element>();
     550           2 :         default_el->set_name("default");
     551           2 :         default_el->add_attr("revision", revision_set->get_default_revision());
     552           6 :         set_el->add_element(default_el);
     553           2 :     }
     554             : 
     555           3 :     for (const auto &kv : revision_set->get_repo_revisions())
     556             :     {
     557           1 :         auto repo_el = std::make_shared<esysfile::xml::Element>();
     558           1 :         repo_el->set_name("repository");
     559           1 :         repo_el->add_attr("path", kv.first);
     560           1 :         repo_el->add_attr("revision", kv.second);
     561           3 :         set_el->add_element(repo_el);
     562           1 :     }
     563             : 
     564           4 :     parent_el->add_element(set_el);
     565           2 :     return ESYSREPO_RESULT(ResultCode::OK);
     566           2 : }
     567             : 
     568         351 : XMLFile *XMLFileImpl::self()
     569             : {
     570         351 :     return m_self;
     571             : }
     572             : 
     573           0 : const XMLFile *XMLFileImpl::self() const
     574             : {
     575           0 :     return m_self;
     576             : }
     577             : 
     578             : } // namespace esys::repo::manifest

Generated by: LCOV version 1.14