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
|