1 /*
2 * This file is part of libmodulemd
3 * Copyright (C) 2018 Red Hat, Inc.
4 *
5 * Fedora-License-Identifier: MIT
6 * SPDX-2.0-License-Identifier: MIT
7 * SPDX-3.0-License-Identifier: MIT
8 *
9 * This program is free software.
10 * For more information on the license, see COPYING.
11 * For more information on free software, see <https://www.gnu.org/philosophy/free-sw.en.html>.
12 */
13
14 #include "modulemd-buildopts.h"
15 #include "modulemd-component-module.h"
16 #include "modulemd-component-rpm.h"
17 #include "modulemd-component.h"
18 #include "modulemd-errors.h"
19 #include "modulemd-module-stream-v1.h"
20 #include "modulemd-module-stream.h"
21 #include "modulemd-profile.h"
22 #include "modulemd-service-level.h"
23 #include "modulemd-translation-entry.h"
24 #include "private/glib-extensions.h"
25 #include "private/modulemd-buildopts-private.h"
26 #include "private/modulemd-component-module-private.h"
27 #include "private/modulemd-component-private.h"
28 #include "private/modulemd-component-rpm-private.h"
29 #include "private/modulemd-module-stream-private.h"
30 #include "private/modulemd-module-stream-v1-private.h"
31 #include "private/modulemd-profile-private.h"
32 #include "private/modulemd-service-level-private.h"
33 #include "private/modulemd-subdocument-info-private.h"
34 #include "private/modulemd-util.h"
35 #include "private/modulemd-yaml.h"
36
37
38 G_DEFINE_TYPE (ModulemdModuleStreamV1,
39 modulemd_module_stream_v1,
40 MODULEMD_TYPE_MODULE_STREAM)
41
42 enum
43 {
44 PROP_0,
45 PROP_ARCH,
46 PROP_BUILDOPTS,
47 PROP_COMMUNITY,
48 PROP_DOCUMENTATION,
49 PROP_TRACKER,
50 N_PROPS
51 };
52
53 static GParamSpec *properties[N_PROPS];
54
55 ModulemdModuleStreamV1 *
modulemd_module_stream_v1_new(const gchar * module_name,const gchar * module_stream)56 modulemd_module_stream_v1_new (const gchar *module_name,
57 const gchar *module_stream)
58 {
59 // clang-format off
60 return g_object_new (MODULEMD_TYPE_MODULE_STREAM_V1,
61 "module-name", module_name,
62 "stream-name", module_stream,
63 NULL);
64 // clang-format on
65 }
66
67
68 static void
modulemd_module_stream_v1_finalize(GObject * object)69 modulemd_module_stream_v1_finalize (GObject *object)
70 {
71 ModulemdModuleStreamV1 *self = MODULEMD_MODULE_STREAM_V1 (object);
72
73 /* Properties */
74 g_clear_object (&self->buildopts);
75 g_clear_pointer (&self->community, g_free);
76 g_clear_pointer (&self->description, g_free);
77 g_clear_pointer (&self->documentation, g_free);
78 g_clear_pointer (&self->summary, g_free);
79 g_clear_pointer (&self->tracker, g_free);
80
81 /* Internal Data Structures */
82 g_clear_pointer (&self->module_components, g_hash_table_unref);
83 g_clear_pointer (&self->rpm_components, g_hash_table_unref);
84
85 g_clear_pointer (&self->content_licenses, g_hash_table_unref);
86 g_clear_pointer (&self->module_licenses, g_hash_table_unref);
87
88 g_clear_pointer (&self->profiles, g_hash_table_unref);
89
90 g_clear_pointer (&self->rpm_api, g_hash_table_unref);
91
92 g_clear_pointer (&self->rpm_artifacts, g_hash_table_unref);
93
94 g_clear_pointer (&self->rpm_filters, g_hash_table_unref);
95
96 g_clear_pointer (&self->servicelevels, g_hash_table_unref);
97
98 g_clear_pointer (&self->buildtime_deps, g_hash_table_unref);
99 g_clear_pointer (&self->runtime_deps, g_hash_table_unref);
100
101 g_clear_pointer (&self->xmd, g_variant_unref);
102
103 G_OBJECT_CLASS (modulemd_module_stream_v1_parent_class)->finalize (object);
104 }
105
106
107 /* ===== Properties ====== */
108
109
110 static guint64
modulemd_module_stream_v1_get_mdversion(ModulemdModuleStream * self)111 modulemd_module_stream_v1_get_mdversion (ModulemdModuleStream *self)
112 {
113 return MD_MODULESTREAM_VERSION_ONE;
114 }
115
116 void
modulemd_module_stream_v1_set_arch(ModulemdModuleStreamV1 * self,const gchar * arch)117 modulemd_module_stream_v1_set_arch (ModulemdModuleStreamV1 *self,
118 const gchar *arch)
119 {
120 g_return_if_fail (MODULEMD_IS_MODULE_STREAM_V1 (self));
121
122 modulemd_module_stream_set_arch (MODULEMD_MODULE_STREAM (self), arch);
123
124 g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_ARCH]);
125 }
126
127
128 const gchar *
modulemd_module_stream_v1_get_arch(ModulemdModuleStreamV1 * self)129 modulemd_module_stream_v1_get_arch (ModulemdModuleStreamV1 *self)
130 {
131 g_return_val_if_fail (MODULEMD_IS_MODULE_STREAM_V1 (self), NULL);
132
133 return modulemd_module_stream_get_arch (MODULEMD_MODULE_STREAM (self));
134 }
135
136
137 void
modulemd_module_stream_v1_set_buildopts(ModulemdModuleStreamV1 * self,ModulemdBuildopts * buildopts)138 modulemd_module_stream_v1_set_buildopts (ModulemdModuleStreamV1 *self,
139 ModulemdBuildopts *buildopts)
140 {
141 g_return_if_fail (MODULEMD_IS_MODULE_STREAM_V1 (self));
142
143 g_clear_object (&self->buildopts);
144 self->buildopts = modulemd_buildopts_copy (buildopts);
145
146 g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_BUILDOPTS]);
147 }
148
149
150 ModulemdBuildopts *
modulemd_module_stream_v1_get_buildopts(ModulemdModuleStreamV1 * self)151 modulemd_module_stream_v1_get_buildopts (ModulemdModuleStreamV1 *self)
152 {
153 g_return_val_if_fail (MODULEMD_IS_MODULE_STREAM_V1 (self), NULL);
154
155 return self->buildopts;
156 }
157
158
159 void
modulemd_module_stream_v1_set_community(ModulemdModuleStreamV1 * self,const gchar * community)160 modulemd_module_stream_v1_set_community (ModulemdModuleStreamV1 *self,
161 const gchar *community)
162 {
163 g_return_if_fail (MODULEMD_IS_MODULE_STREAM_V1 (self));
164
165 g_clear_pointer (&self->community, g_free);
166 self->community = g_strdup (community);
167
168 g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_COMMUNITY]);
169 }
170
171
172 const gchar *
modulemd_module_stream_v1_get_community(ModulemdModuleStreamV1 * self)173 modulemd_module_stream_v1_get_community (ModulemdModuleStreamV1 *self)
174 {
175 g_return_val_if_fail (MODULEMD_IS_MODULE_STREAM_V1 (self), NULL);
176
177 return self->community;
178 }
179
180
181 void
modulemd_module_stream_v1_set_description(ModulemdModuleStreamV1 * self,const gchar * description)182 modulemd_module_stream_v1_set_description (ModulemdModuleStreamV1 *self,
183 const gchar *description)
184 {
185 g_return_if_fail (MODULEMD_IS_MODULE_STREAM_V1 (self));
186
187 g_clear_pointer (&self->description, g_free);
188 self->description = g_strdup (description);
189 }
190
191
192 const gchar *
modulemd_module_stream_v1_get_description(ModulemdModuleStreamV1 * self,const gchar * locale)193 modulemd_module_stream_v1_get_description (ModulemdModuleStreamV1 *self,
194 const gchar *locale)
195 {
196 g_return_val_if_fail (MODULEMD_IS_MODULE_STREAM_V1 (self), NULL);
197
198 ModulemdTranslationEntry *entry =
199 modulemd_module_stream_get_translation_entry (
200 MODULEMD_MODULE_STREAM (self), locale);
201 if (entry != NULL &&
202 modulemd_translation_entry_get_description (entry) != NULL)
203 {
204 return modulemd_translation_entry_get_description (entry);
205 }
206
207 return self->description;
208 }
209
210
211 void
modulemd_module_stream_v1_set_documentation(ModulemdModuleStreamV1 * self,const gchar * documentation)212 modulemd_module_stream_v1_set_documentation (ModulemdModuleStreamV1 *self,
213 const gchar *documentation)
214 {
215 g_return_if_fail (MODULEMD_IS_MODULE_STREAM_V1 (self));
216
217 g_clear_pointer (&self->documentation, g_free);
218 self->documentation = g_strdup (documentation);
219
220 g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_COMMUNITY]);
221 }
222
223
224 const gchar *
modulemd_module_stream_v1_get_documentation(ModulemdModuleStreamV1 * self)225 modulemd_module_stream_v1_get_documentation (ModulemdModuleStreamV1 *self)
226 {
227 g_return_val_if_fail (MODULEMD_IS_MODULE_STREAM_V1 (self), NULL);
228
229 return self->documentation;
230 }
231
232
233 void
modulemd_module_stream_v1_set_summary(ModulemdModuleStreamV1 * self,const gchar * summary)234 modulemd_module_stream_v1_set_summary (ModulemdModuleStreamV1 *self,
235 const gchar *summary)
236 {
237 g_return_if_fail (MODULEMD_IS_MODULE_STREAM_V1 (self));
238
239 g_clear_pointer (&self->summary, g_free);
240 self->summary = g_strdup (summary);
241 }
242
243
244 const gchar *
modulemd_module_stream_v1_get_summary(ModulemdModuleStreamV1 * self,const gchar * locale)245 modulemd_module_stream_v1_get_summary (ModulemdModuleStreamV1 *self,
246 const gchar *locale)
247 {
248 g_return_val_if_fail (MODULEMD_IS_MODULE_STREAM_V1 (self), NULL);
249
250 ModulemdTranslationEntry *entry =
251 modulemd_module_stream_get_translation_entry (
252 MODULEMD_MODULE_STREAM (self), locale);
253 if (entry != NULL && modulemd_translation_entry_get_summary (entry) != NULL)
254 {
255 return modulemd_translation_entry_get_summary (entry);
256 }
257
258 return self->summary;
259 }
260
261
262 void
modulemd_module_stream_v1_set_tracker(ModulemdModuleStreamV1 * self,const gchar * tracker)263 modulemd_module_stream_v1_set_tracker (ModulemdModuleStreamV1 *self,
264 const gchar *tracker)
265 {
266 g_return_if_fail (MODULEMD_IS_MODULE_STREAM_V1 (self));
267
268 g_clear_pointer (&self->tracker, g_free);
269 self->tracker = g_strdup (tracker);
270
271 g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_TRACKER]);
272 }
273
274
275 const gchar *
modulemd_module_stream_v1_get_tracker(ModulemdModuleStreamV1 * self)276 modulemd_module_stream_v1_get_tracker (ModulemdModuleStreamV1 *self)
277 {
278 g_return_val_if_fail (MODULEMD_IS_MODULE_STREAM_V1 (self), NULL);
279
280 return self->tracker;
281 }
282
283
284 /* ===== Non-property Methods ===== */
285
286
287 void
modulemd_module_stream_v1_add_component(ModulemdModuleStreamV1 * self,ModulemdComponent * component)288 modulemd_module_stream_v1_add_component (ModulemdModuleStreamV1 *self,
289 ModulemdComponent *component)
290 {
291 GHashTable *table = NULL;
292
293 /* Do nothing if we were passed a NULL component */
294 if (!component)
295 {
296 return;
297 }
298
299 g_return_if_fail (MODULEMD_IS_MODULE_STREAM_V1 (self));
300 g_return_if_fail (MODULEMD_IS_COMPONENT (component));
301
302 if (MODULEMD_IS_COMPONENT_RPM (component))
303 {
304 table = self->rpm_components;
305 }
306 else if (MODULEMD_IS_COMPONENT_MODULE (component))
307 {
308 table = self->module_components;
309 }
310 else
311 {
312 /* Unknown component. Raise a warning and return */
313 g_return_if_reached ();
314 }
315
316 /* Add the component to the table. This will replace an existing component
317 * with the same name
318 */
319 g_hash_table_replace (table,
320 g_strdup (modulemd_component_get_key (component)),
321 modulemd_component_copy (component, NULL));
322 }
323
324
325 void
modulemd_module_stream_v1_remove_module_component(ModulemdModuleStreamV1 * self,const gchar * component_name)326 modulemd_module_stream_v1_remove_module_component (
327 ModulemdModuleStreamV1 *self, const gchar *component_name)
328 {
329 /* Do nothing if we were passed a NULL component_name */
330 if (!component_name)
331 {
332 return;
333 }
334
335 g_return_if_fail (MODULEMD_IS_MODULE_STREAM_V1 (self));
336
337 g_hash_table_remove (self->module_components, component_name);
338 }
339
340
341 void
modulemd_module_stream_v1_clear_module_components(ModulemdModuleStreamV1 * self)342 modulemd_module_stream_v1_clear_module_components (
343 ModulemdModuleStreamV1 *self)
344 {
345 g_return_if_fail (MODULEMD_IS_MODULE_STREAM_V1 (self));
346
347 g_hash_table_remove_all (self->module_components);
348 }
349
350
351 void
modulemd_module_stream_v1_remove_rpm_component(ModulemdModuleStreamV1 * self,const gchar * component_name)352 modulemd_module_stream_v1_remove_rpm_component (ModulemdModuleStreamV1 *self,
353 const gchar *component_name)
354 {
355 /* Do nothing if we were passed a NULL component_name */
356 if (!component_name)
357 {
358 return;
359 }
360
361 g_return_if_fail (MODULEMD_IS_MODULE_STREAM_V1 (self));
362
363 g_hash_table_remove (self->rpm_components, component_name);
364 }
365
366
367 void
modulemd_module_stream_v1_clear_rpm_components(ModulemdModuleStreamV1 * self)368 modulemd_module_stream_v1_clear_rpm_components (ModulemdModuleStreamV1 *self)
369 {
370 g_return_if_fail (MODULEMD_IS_MODULE_STREAM_V1 (self));
371
372 g_hash_table_remove_all (self->rpm_components);
373 }
374
375
376 GStrv
modulemd_module_stream_v1_get_module_component_names_as_strv(ModulemdModuleStreamV1 * self)377 modulemd_module_stream_v1_get_module_component_names_as_strv (
378 ModulemdModuleStreamV1 *self)
379 {
380 g_return_val_if_fail (MODULEMD_IS_MODULE_STREAM_V1 (self), NULL);
381
382 return modulemd_ordered_str_keys_as_strv (self->module_components);
383 }
384
385
386 GStrv
modulemd_module_stream_v1_get_rpm_component_names_as_strv(ModulemdModuleStreamV1 * self)387 modulemd_module_stream_v1_get_rpm_component_names_as_strv (
388 ModulemdModuleStreamV1 *self)
389 {
390 g_return_val_if_fail (MODULEMD_IS_MODULE_STREAM_V1 (self), NULL);
391
392 return modulemd_ordered_str_keys_as_strv (self->rpm_components);
393 }
394
395
396 ModulemdComponentModule *
modulemd_module_stream_v1_get_module_component(ModulemdModuleStreamV1 * self,const gchar * component_name)397 modulemd_module_stream_v1_get_module_component (ModulemdModuleStreamV1 *self,
398 const gchar *component_name)
399 {
400 g_return_val_if_fail (MODULEMD_IS_MODULE_STREAM_V1 (self), NULL);
401
402 return g_hash_table_lookup (self->module_components, component_name);
403 }
404
405
406 ModulemdComponentRpm *
modulemd_module_stream_v1_get_rpm_component(ModulemdModuleStreamV1 * self,const gchar * component_name)407 modulemd_module_stream_v1_get_rpm_component (ModulemdModuleStreamV1 *self,
408 const gchar *component_name)
409 {
410 g_return_val_if_fail (MODULEMD_IS_MODULE_STREAM_V1 (self), NULL);
411
412 return g_hash_table_lookup (self->rpm_components, component_name);
413 }
414
415
416 void
modulemd_module_stream_v1_add_content_license(ModulemdModuleStreamV1 * self,const gchar * license)417 modulemd_module_stream_v1_add_content_license (ModulemdModuleStreamV1 *self,
418 const gchar *license)
419 {
420 if (!license)
421 {
422 return;
423 }
424
425 g_return_if_fail (MODULEMD_IS_MODULE_STREAM_V1 (self));
426
427 g_hash_table_add (self->content_licenses, g_strdup (license));
428 }
429
430
431 static void
modulemd_module_stream_v1_replace_content_licenses(ModulemdModuleStreamV1 * self,GHashTable * set)432 modulemd_module_stream_v1_replace_content_licenses (
433 ModulemdModuleStreamV1 *self, GHashTable *set)
434 {
435 g_return_if_fail (MODULEMD_IS_MODULE_STREAM_V1 (self));
436
437 MODULEMD_REPLACE_SET (self->content_licenses, set);
438 }
439
440
441 void
modulemd_module_stream_v1_clear_content_licenses(ModulemdModuleStreamV1 * self)442 modulemd_module_stream_v1_clear_content_licenses (ModulemdModuleStreamV1 *self)
443 {
444 g_return_if_fail (MODULEMD_IS_MODULE_STREAM_V1 (self));
445
446 g_hash_table_remove_all (self->content_licenses);
447 }
448
449
450 void
modulemd_module_stream_v1_add_module_license(ModulemdModuleStreamV1 * self,const gchar * license)451 modulemd_module_stream_v1_add_module_license (ModulemdModuleStreamV1 *self,
452 const gchar *license)
453 {
454 if (!license)
455 {
456 return;
457 }
458
459 g_return_if_fail (MODULEMD_IS_MODULE_STREAM_V1 (self));
460
461 g_hash_table_add (self->module_licenses, g_strdup (license));
462 }
463
464
465 static void
modulemd_module_stream_v1_replace_module_licenses(ModulemdModuleStreamV1 * self,GHashTable * set)466 modulemd_module_stream_v1_replace_module_licenses (
467 ModulemdModuleStreamV1 *self, GHashTable *set)
468 {
469 g_return_if_fail (MODULEMD_IS_MODULE_STREAM_V1 (self));
470
471 MODULEMD_REPLACE_SET (self->module_licenses, set);
472 }
473
474
475 void
modulemd_module_stream_v1_clear_module_licenses(ModulemdModuleStreamV1 * self)476 modulemd_module_stream_v1_clear_module_licenses (ModulemdModuleStreamV1 *self)
477 {
478 g_return_if_fail (MODULEMD_IS_MODULE_STREAM_V1 (self));
479
480 g_hash_table_remove_all (self->module_licenses);
481 }
482
483
484 void
modulemd_module_stream_v1_remove_content_license(ModulemdModuleStreamV1 * self,const gchar * license)485 modulemd_module_stream_v1_remove_content_license (ModulemdModuleStreamV1 *self,
486 const gchar *license)
487 {
488 if (!license)
489 {
490 return;
491 }
492
493 g_return_if_fail (MODULEMD_IS_MODULE_STREAM_V1 (self));
494
495 g_hash_table_remove (self->content_licenses, license);
496 }
497
498
499 void
modulemd_module_stream_v1_remove_module_license(ModulemdModuleStreamV1 * self,const gchar * license)500 modulemd_module_stream_v1_remove_module_license (ModulemdModuleStreamV1 *self,
501 const gchar *license)
502 {
503 if (!license)
504 {
505 return;
506 }
507
508 g_return_if_fail (MODULEMD_IS_MODULE_STREAM_V1 (self));
509
510 g_hash_table_remove (self->module_licenses, license);
511 }
512
513
514 GStrv
modulemd_module_stream_v1_get_content_licenses_as_strv(ModulemdModuleStreamV1 * self)515 modulemd_module_stream_v1_get_content_licenses_as_strv (
516 ModulemdModuleStreamV1 *self)
517 {
518 g_return_val_if_fail (MODULEMD_IS_MODULE_STREAM_V1 (self), NULL);
519
520 return modulemd_ordered_str_keys_as_strv (self->content_licenses);
521 }
522
523
524 GStrv
modulemd_module_stream_v1_get_module_licenses_as_strv(ModulemdModuleStreamV1 * self)525 modulemd_module_stream_v1_get_module_licenses_as_strv (
526 ModulemdModuleStreamV1 *self)
527 {
528 g_return_val_if_fail (MODULEMD_IS_MODULE_STREAM_V1 (self), NULL);
529
530 return modulemd_ordered_str_keys_as_strv (self->module_licenses);
531 }
532
533
534 void
modulemd_module_stream_v1_add_profile(ModulemdModuleStreamV1 * self,ModulemdProfile * profile)535 modulemd_module_stream_v1_add_profile (ModulemdModuleStreamV1 *self,
536 ModulemdProfile *profile)
537 {
538 if (!profile)
539 {
540 return;
541 }
542 g_return_if_fail (MODULEMD_IS_MODULE_STREAM_V1 (self));
543 g_return_if_fail (MODULEMD_IS_PROFILE (profile));
544
545 ModulemdProfile *copied_profile = modulemd_profile_copy (profile);
546 modulemd_profile_set_owner (copied_profile, MODULEMD_MODULE_STREAM (self));
547
548 g_hash_table_replace (self->profiles,
549 g_strdup (modulemd_profile_get_name (profile)),
550 copied_profile);
551 }
552
553
554 void
modulemd_module_stream_v1_clear_profiles(ModulemdModuleStreamV1 * self)555 modulemd_module_stream_v1_clear_profiles (ModulemdModuleStreamV1 *self)
556 {
557 g_return_if_fail (MODULEMD_IS_MODULE_STREAM_V1 (self));
558
559 g_hash_table_remove_all (self->profiles);
560 }
561
562
563 GStrv
modulemd_module_stream_v1_get_profile_names_as_strv(ModulemdModuleStreamV1 * self)564 modulemd_module_stream_v1_get_profile_names_as_strv (
565 ModulemdModuleStreamV1 *self)
566 {
567 g_return_val_if_fail (MODULEMD_IS_MODULE_STREAM_V1 (self), NULL);
568
569 return modulemd_ordered_str_keys_as_strv (self->profiles);
570 }
571
572
573 ModulemdProfile *
modulemd_module_stream_v1_get_profile(ModulemdModuleStreamV1 * self,const gchar * profile_name)574 modulemd_module_stream_v1_get_profile (ModulemdModuleStreamV1 *self,
575 const gchar *profile_name)
576 {
577 g_return_val_if_fail (MODULEMD_IS_MODULE_STREAM_V1 (self), NULL);
578
579 return g_hash_table_lookup (self->profiles, profile_name);
580 }
581
582
583 void
modulemd_module_stream_v1_add_rpm_api(ModulemdModuleStreamV1 * self,const gchar * rpm)584 modulemd_module_stream_v1_add_rpm_api (ModulemdModuleStreamV1 *self,
585 const gchar *rpm)
586 {
587 if (!rpm)
588 {
589 return;
590 }
591
592 g_return_if_fail (MODULEMD_IS_MODULE_STREAM_V1 (self));
593
594 g_hash_table_add (self->rpm_api, g_strdup (rpm));
595 }
596
597
598 static void
modulemd_module_stream_v1_replace_rpm_api(ModulemdModuleStreamV1 * self,GHashTable * set)599 modulemd_module_stream_v1_replace_rpm_api (ModulemdModuleStreamV1 *self,
600 GHashTable *set)
601 {
602 g_return_if_fail (MODULEMD_IS_MODULE_STREAM_V1 (self));
603
604 MODULEMD_REPLACE_SET (self->rpm_api, set);
605 }
606
607
608 void
modulemd_module_stream_v1_remove_rpm_api(ModulemdModuleStreamV1 * self,const gchar * rpm)609 modulemd_module_stream_v1_remove_rpm_api (ModulemdModuleStreamV1 *self,
610 const gchar *rpm)
611 {
612 if (!rpm)
613 {
614 return;
615 }
616
617 g_return_if_fail (MODULEMD_IS_MODULE_STREAM_V1 (self));
618
619 g_hash_table_remove (self->rpm_api, rpm);
620 }
621
622
623 void
modulemd_module_stream_v1_clear_rpm_api(ModulemdModuleStreamV1 * self)624 modulemd_module_stream_v1_clear_rpm_api (ModulemdModuleStreamV1 *self)
625 {
626 g_return_if_fail (MODULEMD_IS_MODULE_STREAM_V1 (self));
627
628 g_hash_table_remove_all (self->rpm_api);
629 }
630
631
632 GStrv
modulemd_module_stream_v1_get_rpm_api_as_strv(ModulemdModuleStreamV1 * self)633 modulemd_module_stream_v1_get_rpm_api_as_strv (ModulemdModuleStreamV1 *self)
634 {
635 g_return_val_if_fail (MODULEMD_IS_MODULE_STREAM_V1 (self), NULL);
636
637 return modulemd_ordered_str_keys_as_strv (self->rpm_api);
638 }
639
640
641 void
modulemd_module_stream_v1_add_rpm_artifact(ModulemdModuleStreamV1 * self,const gchar * nevr)642 modulemd_module_stream_v1_add_rpm_artifact (ModulemdModuleStreamV1 *self,
643 const gchar *nevr)
644 {
645 if (!nevr)
646 {
647 return;
648 }
649
650 g_return_if_fail (MODULEMD_IS_MODULE_STREAM_V1 (self));
651
652 g_hash_table_add (self->rpm_artifacts, g_strdup (nevr));
653 }
654
655
656 static void
modulemd_module_stream_v1_replace_rpm_artifacts(ModulemdModuleStreamV1 * self,GHashTable * set)657 modulemd_module_stream_v1_replace_rpm_artifacts (ModulemdModuleStreamV1 *self,
658 GHashTable *set)
659 {
660 g_return_if_fail (MODULEMD_IS_MODULE_STREAM_V1 (self));
661
662 MODULEMD_REPLACE_SET (self->rpm_artifacts, set);
663 }
664
665
666 void
modulemd_module_stream_v1_remove_rpm_artifact(ModulemdModuleStreamV1 * self,const gchar * nevr)667 modulemd_module_stream_v1_remove_rpm_artifact (ModulemdModuleStreamV1 *self,
668 const gchar *nevr)
669 {
670 if (!nevr)
671 {
672 return;
673 }
674
675 g_return_if_fail (MODULEMD_IS_MODULE_STREAM_V1 (self));
676
677 g_hash_table_remove (self->rpm_artifacts, nevr);
678 }
679
680
681 void
modulemd_module_stream_v1_clear_rpm_artifacts(ModulemdModuleStreamV1 * self)682 modulemd_module_stream_v1_clear_rpm_artifacts (ModulemdModuleStreamV1 *self)
683 {
684 g_return_if_fail (MODULEMD_IS_MODULE_STREAM_V1 (self));
685
686 g_hash_table_remove_all (self->rpm_artifacts);
687 }
688
689
690 GStrv
modulemd_module_stream_v1_get_rpm_artifacts_as_strv(ModulemdModuleStreamV1 * self)691 modulemd_module_stream_v1_get_rpm_artifacts_as_strv (
692 ModulemdModuleStreamV1 *self)
693 {
694 g_return_val_if_fail (MODULEMD_IS_MODULE_STREAM_V1 (self), NULL);
695
696 return modulemd_ordered_str_keys_as_strv (self->rpm_artifacts);
697 }
698
699
700 void
modulemd_module_stream_v1_add_rpm_filter(ModulemdModuleStreamV1 * self,const gchar * rpm)701 modulemd_module_stream_v1_add_rpm_filter (ModulemdModuleStreamV1 *self,
702 const gchar *rpm)
703 {
704 if (!rpm)
705 {
706 return;
707 }
708
709 g_return_if_fail (MODULEMD_IS_MODULE_STREAM_V1 (self));
710
711 g_hash_table_add (self->rpm_filters, g_strdup (rpm));
712 }
713
714
715 static void
modulemd_module_stream_v1_replace_rpm_filters(ModulemdModuleStreamV1 * self,GHashTable * set)716 modulemd_module_stream_v1_replace_rpm_filters (ModulemdModuleStreamV1 *self,
717 GHashTable *set)
718 {
719 g_return_if_fail (MODULEMD_IS_MODULE_STREAM_V1 (self));
720
721 MODULEMD_REPLACE_SET (self->rpm_filters, set);
722 }
723
724
725 void
modulemd_module_stream_v1_remove_rpm_filter(ModulemdModuleStreamV1 * self,const gchar * rpm)726 modulemd_module_stream_v1_remove_rpm_filter (ModulemdModuleStreamV1 *self,
727 const gchar *rpm)
728 {
729 if (!rpm)
730 {
731 return;
732 }
733
734 g_return_if_fail (MODULEMD_IS_MODULE_STREAM_V1 (self));
735
736 g_hash_table_remove (self->rpm_filters, rpm);
737 }
738
739
740 void
modulemd_module_stream_v1_clear_rpm_filters(ModulemdModuleStreamV1 * self)741 modulemd_module_stream_v1_clear_rpm_filters (ModulemdModuleStreamV1 *self)
742 {
743 g_return_if_fail (MODULEMD_IS_MODULE_STREAM_V1 (self));
744
745 g_hash_table_remove_all (self->rpm_filters);
746 }
747
748
749 GStrv
modulemd_module_stream_v1_get_rpm_filters_as_strv(ModulemdModuleStreamV1 * self)750 modulemd_module_stream_v1_get_rpm_filters_as_strv (
751 ModulemdModuleStreamV1 *self)
752 {
753 g_return_val_if_fail (MODULEMD_IS_MODULE_STREAM_V1 (self), NULL);
754
755 return modulemd_ordered_str_keys_as_strv (self->rpm_filters);
756 }
757
758
759 void
modulemd_module_stream_v1_add_servicelevel(ModulemdModuleStreamV1 * self,ModulemdServiceLevel * servicelevel)760 modulemd_module_stream_v1_add_servicelevel (ModulemdModuleStreamV1 *self,
761 ModulemdServiceLevel *servicelevel)
762 {
763 if (!servicelevel)
764 {
765 return;
766 }
767 g_return_if_fail (MODULEMD_IS_MODULE_STREAM_V1 (self));
768 g_return_if_fail (MODULEMD_IS_SERVICE_LEVEL (servicelevel));
769
770 g_hash_table_replace (
771 self->servicelevels,
772 g_strdup (modulemd_service_level_get_name (servicelevel)),
773 modulemd_service_level_copy (servicelevel));
774 }
775
776
777 void
modulemd_module_stream_v1_clear_servicelevels(ModulemdModuleStreamV1 * self)778 modulemd_module_stream_v1_clear_servicelevels (ModulemdModuleStreamV1 *self)
779 {
780 g_return_if_fail (MODULEMD_IS_MODULE_STREAM_V1 (self));
781
782 g_hash_table_remove_all (self->servicelevels);
783 }
784
785
786 GStrv
modulemd_module_stream_v1_get_servicelevel_names_as_strv(ModulemdModuleStreamV1 * self)787 modulemd_module_stream_v1_get_servicelevel_names_as_strv (
788 ModulemdModuleStreamV1 *self)
789 {
790 g_return_val_if_fail (MODULEMD_IS_MODULE_STREAM_V1 (self), NULL);
791
792 return modulemd_ordered_str_keys_as_strv (self->servicelevels);
793 }
794
795
796 ModulemdServiceLevel *
modulemd_module_stream_v1_get_servicelevel(ModulemdModuleStreamV1 * self,const gchar * servicelevel_name)797 modulemd_module_stream_v1_get_servicelevel (ModulemdModuleStreamV1 *self,
798 const gchar *servicelevel_name)
799 {
800 g_return_val_if_fail (MODULEMD_IS_MODULE_STREAM_V1 (self), NULL);
801
802 return g_hash_table_lookup (self->servicelevels, servicelevel_name);
803 }
804
805
806 void
modulemd_module_stream_v1_set_eol(ModulemdModuleStreamV1 * self,GDate * eol)807 modulemd_module_stream_v1_set_eol (ModulemdModuleStreamV1 *self, GDate *eol)
808 {
809 g_return_if_fail (MODULEMD_IS_MODULE_STREAM_V1 (self));
810
811 /* The "eol" field in the YAML is a relic of an early iteration and has been
812 * entirely replaced by the ServiceLevel concept. If we encounter it, we just
813 * treat it as if it was the EOL value for a service level named "rawhide".
814 */
815 g_autoptr (ModulemdServiceLevel) sl = modulemd_service_level_new ("rawhide");
816 modulemd_service_level_set_eol (sl, eol);
817
818 return modulemd_module_stream_v1_add_servicelevel (self, sl);
819 }
820
821
822 GDate *
modulemd_module_stream_v1_get_eol(ModulemdModuleStreamV1 * self)823 modulemd_module_stream_v1_get_eol (ModulemdModuleStreamV1 *self)
824 {
825 g_return_val_if_fail (MODULEMD_IS_MODULE_STREAM_V1 (self), NULL);
826
827 ModulemdServiceLevel *sl =
828 modulemd_module_stream_v1_get_servicelevel (self, "rawhide");
829
830 return modulemd_service_level_get_eol (sl);
831 }
832
833
834 void
modulemd_module_stream_v1_add_buildtime_requirement(ModulemdModuleStreamV1 * self,const gchar * module_name,const gchar * module_stream)835 modulemd_module_stream_v1_add_buildtime_requirement (
836 ModulemdModuleStreamV1 *self,
837 const gchar *module_name,
838 const gchar *module_stream)
839 {
840 g_return_if_fail (MODULEMD_IS_MODULE_STREAM_V1 (self));
841 g_return_if_fail (module_name && module_stream);
842
843 g_hash_table_replace (
844 self->buildtime_deps, g_strdup (module_name), g_strdup (module_stream));
845 }
846
847
848 static void
modulemd_module_stream_v1_replace_buildtime_deps(ModulemdModuleStreamV1 * self,GHashTable * deps)849 modulemd_module_stream_v1_replace_buildtime_deps (ModulemdModuleStreamV1 *self,
850 GHashTable *deps)
851 {
852 g_return_if_fail (MODULEMD_IS_MODULE_STREAM_V1 (self));
853
854 if (deps)
855 {
856 g_hash_table_unref (self->buildtime_deps);
857 self->buildtime_deps = modulemd_hash_table_deep_str_copy (deps);
858 }
859 else
860 {
861 g_hash_table_remove_all (self->buildtime_deps);
862 }
863 }
864
865
866 void
modulemd_module_stream_v1_add_runtime_requirement(ModulemdModuleStreamV1 * self,const gchar * module_name,const gchar * module_stream)867 modulemd_module_stream_v1_add_runtime_requirement (
868 ModulemdModuleStreamV1 *self,
869 const gchar *module_name,
870 const gchar *module_stream)
871 {
872 g_return_if_fail (MODULEMD_IS_MODULE_STREAM_V1 (self));
873 g_return_if_fail (module_name && module_stream);
874
875 g_hash_table_replace (
876 self->runtime_deps, g_strdup (module_name), g_strdup (module_stream));
877 }
878
879
880 static void
modulemd_module_stream_v1_replace_runtime_deps(ModulemdModuleStreamV1 * self,GHashTable * deps)881 modulemd_module_stream_v1_replace_runtime_deps (ModulemdModuleStreamV1 *self,
882 GHashTable *deps)
883 {
884 g_return_if_fail (MODULEMD_IS_MODULE_STREAM_V1 (self));
885
886 if (deps)
887 {
888 g_hash_table_unref (self->runtime_deps);
889 self->runtime_deps = modulemd_hash_table_deep_str_copy (deps);
890 }
891 else
892 {
893 g_hash_table_remove_all (self->runtime_deps);
894 }
895 }
896
897
898 void
modulemd_module_stream_v1_remove_buildtime_requirement(ModulemdModuleStreamV1 * self,const gchar * module_name)899 modulemd_module_stream_v1_remove_buildtime_requirement (
900 ModulemdModuleStreamV1 *self, const gchar *module_name)
901 {
902 g_return_if_fail (MODULEMD_IS_MODULE_STREAM_V1 (self));
903 g_return_if_fail (module_name);
904
905 g_hash_table_remove (self->buildtime_deps, module_name);
906 }
907
908
909 void
modulemd_module_stream_v1_remove_runtime_requirement(ModulemdModuleStreamV1 * self,const gchar * module_name)910 modulemd_module_stream_v1_remove_runtime_requirement (
911 ModulemdModuleStreamV1 *self, const gchar *module_name)
912 {
913 g_return_if_fail (MODULEMD_IS_MODULE_STREAM_V1 (self));
914 g_return_if_fail (module_name);
915
916 g_hash_table_remove (self->runtime_deps, module_name);
917 }
918
919
920 void
modulemd_module_stream_v1_clear_buildtime_requirements(ModulemdModuleStreamV1 * self)921 modulemd_module_stream_v1_clear_buildtime_requirements (
922 ModulemdModuleStreamV1 *self)
923 {
924 g_return_if_fail (MODULEMD_IS_MODULE_STREAM_V1 (self));
925
926 g_hash_table_remove_all (self->buildtime_deps);
927 }
928
929
930 void
modulemd_module_stream_v1_clear_runtime_requirements(ModulemdModuleStreamV1 * self)931 modulemd_module_stream_v1_clear_runtime_requirements (
932 ModulemdModuleStreamV1 *self)
933 {
934 g_return_if_fail (MODULEMD_IS_MODULE_STREAM_V1 (self));
935
936 g_hash_table_remove_all (self->runtime_deps);
937 }
938
939
940 GStrv
modulemd_module_stream_v1_get_buildtime_modules_as_strv(ModulemdModuleStreamV1 * self)941 modulemd_module_stream_v1_get_buildtime_modules_as_strv (
942 ModulemdModuleStreamV1 *self)
943 {
944 g_return_val_if_fail (MODULEMD_IS_MODULE_STREAM_V1 (self), NULL);
945
946 return modulemd_ordered_str_keys_as_strv (self->buildtime_deps);
947 }
948
949
950 GStrv
modulemd_module_stream_v1_get_runtime_modules_as_strv(ModulemdModuleStreamV1 * self)951 modulemd_module_stream_v1_get_runtime_modules_as_strv (
952 ModulemdModuleStreamV1 *self)
953 {
954 g_return_val_if_fail (MODULEMD_IS_MODULE_STREAM_V1 (self), NULL);
955
956 return modulemd_ordered_str_keys_as_strv (self->runtime_deps);
957 }
958
959
960 const gchar *
modulemd_module_stream_v1_get_buildtime_requirement_stream(ModulemdModuleStreamV1 * self,const gchar * module_name)961 modulemd_module_stream_v1_get_buildtime_requirement_stream (
962 ModulemdModuleStreamV1 *self, const gchar *module_name)
963 {
964 g_return_val_if_fail (MODULEMD_IS_MODULE_STREAM_V1 (self), NULL);
965
966 return g_hash_table_lookup (self->buildtime_deps, module_name);
967 }
968
969
970 const gchar *
modulemd_module_stream_v1_get_runtime_requirement_stream(ModulemdModuleStreamV1 * self,const gchar * module_name)971 modulemd_module_stream_v1_get_runtime_requirement_stream (
972 ModulemdModuleStreamV1 *self, const gchar *module_name)
973 {
974 g_return_val_if_fail (MODULEMD_IS_MODULE_STREAM_V1 (self), NULL);
975
976 return g_hash_table_lookup (self->runtime_deps, module_name);
977 }
978
979
980 void
modulemd_module_stream_v1_set_xmd(ModulemdModuleStreamV1 * self,GVariant * xmd)981 modulemd_module_stream_v1_set_xmd (ModulemdModuleStreamV1 *self, GVariant *xmd)
982 {
983 g_return_if_fail (MODULEMD_IS_MODULE_STREAM_V1 (self));
984
985 /* Do nothing if we were passed the same pointer */
986 if (self->xmd == xmd)
987 {
988 return;
989 }
990
991 g_clear_pointer (&self->xmd, g_variant_unref);
992 self->xmd = modulemd_variant_deep_copy (xmd);
993 }
994
995 GVariant *
modulemd_module_stream_v1_get_xmd(ModulemdModuleStreamV1 * self)996 modulemd_module_stream_v1_get_xmd (ModulemdModuleStreamV1 *self)
997 {
998 g_return_val_if_fail (MODULEMD_IS_MODULE_STREAM_V1 (self), NULL);
999
1000 return self->xmd;
1001 }
1002
1003
1004 gboolean
modulemd_module_stream_v1_includes_nevra(ModulemdModuleStreamV1 * self,const gchar * nevra_pattern)1005 modulemd_module_stream_v1_includes_nevra (ModulemdModuleStreamV1 *self,
1006 const gchar *nevra_pattern)
1007 {
1008 /* If g_hash_table_find() returns non-NULL, the nevra was found in this
1009 * module stream, so return TRUE
1010 */
1011 return !!g_hash_table_find (
1012 self->rpm_artifacts, modulemd_rpm_match, (void *)nevra_pattern);
1013 }
1014
1015 static gboolean
modulemd_module_stream_v1_equals(ModulemdModuleStream * self_1,ModulemdModuleStream * self_2)1016 modulemd_module_stream_v1_equals (ModulemdModuleStream *self_1,
1017 ModulemdModuleStream *self_2)
1018 {
1019 ModulemdModuleStreamV1 *v1_self_1 = NULL;
1020 ModulemdModuleStreamV1 *v1_self_2 = NULL;
1021
1022 g_return_val_if_fail (MODULEMD_IS_MODULE_STREAM_V1 (self_1), FALSE);
1023 v1_self_1 = MODULEMD_MODULE_STREAM_V1 (self_1);
1024 g_return_val_if_fail (MODULEMD_IS_MODULE_STREAM_V1 (self_2), FALSE);
1025 v1_self_2 = MODULEMD_MODULE_STREAM_V1 (self_2);
1026
1027 if (!MODULEMD_MODULE_STREAM_CLASS (modulemd_module_stream_v1_parent_class)
1028 ->equals (self_1, self_2))
1029 {
1030 return FALSE;
1031 }
1032
1033 /*Check property equality*/
1034 if (g_strcmp0 (v1_self_1->community, v1_self_2->community) != 0)
1035 {
1036 return FALSE;
1037 }
1038
1039 if (g_strcmp0 (v1_self_1->description, v1_self_2->description) != 0)
1040 {
1041 return FALSE;
1042 }
1043
1044 if (g_strcmp0 (v1_self_1->documentation, v1_self_2->documentation) != 0)
1045 {
1046 return FALSE;
1047 }
1048
1049 if (g_strcmp0 (v1_self_1->summary, v1_self_2->summary) != 0)
1050 {
1051 return FALSE;
1052 }
1053
1054 if (g_strcmp0 (v1_self_1->tracker, v1_self_2->tracker) != 0)
1055 {
1056 return FALSE;
1057 }
1058
1059 if (!modulemd_buildopts_equals (v1_self_1->buildopts, v1_self_2->buildopts))
1060 {
1061 return FALSE;
1062 }
1063
1064 if (!modulemd_hash_table_equals (v1_self_1->rpm_components,
1065 v1_self_2->rpm_components,
1066 modulemd_component_equals_wrapper))
1067 {
1068 return FALSE;
1069 }
1070
1071 if (!modulemd_hash_table_equals (v1_self_1->module_components,
1072 v1_self_2->module_components,
1073 modulemd_component_equals_wrapper))
1074 {
1075 return FALSE;
1076 }
1077
1078 if (!modulemd_hash_table_sets_are_equal (v1_self_1->module_licenses,
1079 v1_self_2->module_licenses))
1080 {
1081 return FALSE;
1082 }
1083
1084 if (!modulemd_hash_table_sets_are_equal (v1_self_1->content_licenses,
1085 v1_self_2->content_licenses))
1086 {
1087 return FALSE;
1088 }
1089
1090 if (!modulemd_hash_table_equals (v1_self_1->profiles,
1091 v1_self_2->profiles,
1092 modulemd_profile_equals_wrapper))
1093 {
1094 return FALSE;
1095 }
1096
1097 if (!modulemd_hash_table_sets_are_equal (v1_self_1->rpm_api,
1098 v1_self_2->rpm_api))
1099 {
1100 return FALSE;
1101 }
1102
1103 if (!modulemd_hash_table_sets_are_equal (v1_self_1->rpm_artifacts,
1104 v1_self_2->rpm_artifacts))
1105 {
1106 return FALSE;
1107 }
1108
1109 if (!modulemd_hash_table_sets_are_equal (v1_self_1->rpm_filters,
1110 v1_self_2->rpm_filters))
1111 {
1112 return FALSE;
1113 }
1114
1115 if (!modulemd_hash_table_equals (v1_self_1->servicelevels,
1116 v1_self_2->servicelevels,
1117 modulemd_service_level_equals_wrapper))
1118 {
1119 return FALSE;
1120 }
1121
1122 if (!modulemd_hash_table_equals (
1123 v1_self_1->buildtime_deps, v1_self_2->buildtime_deps, g_str_equal))
1124 {
1125 return FALSE;
1126 }
1127
1128 if (!modulemd_hash_table_equals (
1129 v1_self_1->runtime_deps, v1_self_2->runtime_deps, g_str_equal))
1130 {
1131 return FALSE;
1132 }
1133
1134 if (v1_self_1->xmd == NULL && v1_self_2->xmd == NULL)
1135 {
1136 return TRUE;
1137 }
1138
1139 if (v1_self_1->xmd == NULL || v1_self_2->xmd == NULL)
1140 {
1141 return FALSE;
1142 }
1143
1144 if (!g_variant_equal (v1_self_1->xmd, v1_self_2->xmd))
1145 {
1146 return FALSE;
1147 }
1148
1149 return TRUE;
1150 }
1151
1152
1153 static gboolean
modulemd_module_stream_v1_validate(ModulemdModuleStream * self,GError ** error)1154 modulemd_module_stream_v1_validate (ModulemdModuleStream *self, GError **error)
1155 {
1156 GHashTableIter iter;
1157 gpointer key;
1158 gpointer value;
1159 gchar *nevra = NULL;
1160 ModulemdModuleStreamV1 *v1_self = NULL;
1161 g_autoptr (GError) nested_error = NULL;
1162
1163 g_return_val_if_fail (MODULEMD_IS_MODULE_STREAM_V1 (self), FALSE);
1164 v1_self = MODULEMD_MODULE_STREAM_V1 (self);
1165
1166 if (!MODULEMD_MODULE_STREAM_CLASS (modulemd_module_stream_v1_parent_class)
1167 ->validate (self, error))
1168 {
1169 return FALSE;
1170 }
1171
1172 /* Make sure that mandatory fields are present */
1173 if (!modulemd_module_stream_v1_get_summary (v1_self, "C"))
1174 {
1175 g_set_error (error,
1176 MODULEMD_YAML_ERROR,
1177 MMD_YAML_ERROR_MISSING_REQUIRED,
1178 "Summary is missing");
1179 return FALSE;
1180 }
1181
1182 if (!modulemd_module_stream_v1_get_description (v1_self, "C"))
1183 {
1184 g_set_error (error,
1185 MODULEMD_YAML_ERROR,
1186 MMD_YAML_ERROR_MISSING_REQUIRED,
1187 "Description is missing");
1188 return FALSE;
1189 }
1190
1191 if (!g_hash_table_size (v1_self->module_licenses))
1192 {
1193 g_set_error (error,
1194 MODULEMD_YAML_ERROR,
1195 MMD_YAML_ERROR_MISSING_REQUIRED,
1196 "Module license is missing");
1197 return FALSE;
1198 }
1199
1200 /* Verify that the components are consistent with regards to buildorder and
1201 * buildafter values.
1202 */
1203 if (!modulemd_module_stream_validate_components (v1_self->rpm_components,
1204 &nested_error))
1205 {
1206 g_propagate_error (error, g_steal_pointer (&nested_error));
1207 return FALSE;
1208 }
1209
1210 /* Iterate through the artifacts and validate that they are in the proper
1211 * NEVRA format
1212 */
1213 g_hash_table_iter_init (&iter, v1_self->rpm_artifacts);
1214 while (g_hash_table_iter_next (&iter, &key, &value))
1215 {
1216 nevra = (gchar *)key;
1217 if (!modulemd_validate_nevra (nevra))
1218 {
1219 g_set_error (error,
1220 MODULEMD_ERROR,
1221 MMD_ERROR_VALIDATE,
1222 "Artifact '%s' was not in valid N-E:V-R.A format.",
1223 nevra);
1224 return FALSE;
1225 }
1226 }
1227
1228 return TRUE;
1229 }
1230
1231
1232 static void
modulemd_module_stream_v1_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)1233 modulemd_module_stream_v1_get_property (GObject *object,
1234 guint prop_id,
1235 GValue *value,
1236 GParamSpec *pspec)
1237 {
1238 ModulemdModuleStreamV1 *self = MODULEMD_MODULE_STREAM_V1 (object);
1239
1240 switch (prop_id)
1241 {
1242 case PROP_ARCH:
1243 g_value_set_string (value, modulemd_module_stream_v1_get_arch (self));
1244 break;
1245
1246 case PROP_BUILDOPTS:
1247 g_value_set_object (value,
1248 modulemd_module_stream_v1_get_buildopts (self));
1249 break;
1250
1251 case PROP_COMMUNITY:
1252 g_value_set_string (value,
1253 modulemd_module_stream_v1_get_community (self));
1254 break;
1255
1256 case PROP_DOCUMENTATION:
1257 g_value_set_string (value,
1258 modulemd_module_stream_v1_get_documentation (self));
1259 break;
1260
1261 case PROP_TRACKER:
1262 g_value_set_string (value, modulemd_module_stream_v1_get_tracker (self));
1263 break;
1264
1265 default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1266 }
1267 }
1268
1269 static void
modulemd_module_stream_v1_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)1270 modulemd_module_stream_v1_set_property (GObject *object,
1271 guint prop_id,
1272 const GValue *value,
1273 GParamSpec *pspec)
1274 {
1275 ModulemdModuleStreamV1 *self = MODULEMD_MODULE_STREAM_V1 (object);
1276
1277 switch (prop_id)
1278 {
1279 case PROP_ARCH:
1280 modulemd_module_stream_v1_set_arch (self, g_value_get_string (value));
1281 break;
1282
1283 case PROP_BUILDOPTS:
1284 modulemd_module_stream_v1_set_buildopts (self,
1285 g_value_get_object (value));
1286 break;
1287
1288 case PROP_COMMUNITY:
1289 modulemd_module_stream_v1_set_community (self,
1290 g_value_get_string (value));
1291 break;
1292
1293 case PROP_DOCUMENTATION:
1294 modulemd_module_stream_v1_set_documentation (self,
1295 g_value_get_string (value));
1296 break;
1297
1298 case PROP_TRACKER:
1299 modulemd_module_stream_v1_set_tracker (self, g_value_get_string (value));
1300 break;
1301
1302 default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1303 }
1304 }
1305
1306
1307 static ModulemdModuleStream *
modulemd_module_stream_v1_copy(ModulemdModuleStream * self,const gchar * module_name,const gchar * module_stream)1308 modulemd_module_stream_v1_copy (ModulemdModuleStream *self,
1309 const gchar *module_name,
1310 const gchar *module_stream)
1311 {
1312 ModulemdModuleStreamV1 *v1_self = NULL;
1313 g_autoptr (ModulemdModuleStreamV1) copy = NULL;
1314 g_return_val_if_fail (MODULEMD_IS_MODULE_STREAM_V1 (self), NULL);
1315 v1_self = MODULEMD_MODULE_STREAM_V1 (self);
1316
1317 copy = MODULEMD_MODULE_STREAM_V1 (
1318 MODULEMD_MODULE_STREAM_CLASS (modulemd_module_stream_v1_parent_class)
1319 ->copy (self, module_name, module_stream));
1320
1321 /* Properties */
1322 STREAM_COPY_IF_SET (v1, copy, v1_self, arch);
1323 STREAM_COPY_IF_SET (v1, copy, v1_self, buildopts);
1324 STREAM_COPY_IF_SET (v1, copy, v1_self, community);
1325 STREAM_COPY_IF_SET_WITH_LOCALE (v1, copy, v1_self, description);
1326 STREAM_COPY_IF_SET (v1, copy, v1_self, documentation);
1327 STREAM_COPY_IF_SET_WITH_LOCALE (v1, copy, v1_self, summary);
1328 STREAM_COPY_IF_SET (v1, copy, v1_self, tracker);
1329
1330 /* Internal Data Structures: With replace function */
1331 STREAM_REPLACE_HASHTABLE (v1, copy, v1_self, content_licenses);
1332 STREAM_REPLACE_HASHTABLE (v1, copy, v1_self, module_licenses);
1333 STREAM_REPLACE_HASHTABLE (v1, copy, v1_self, rpm_api);
1334 STREAM_REPLACE_HASHTABLE (v1, copy, v1_self, rpm_artifacts);
1335 STREAM_REPLACE_HASHTABLE (v1, copy, v1_self, rpm_filters);
1336 STREAM_REPLACE_HASHTABLE (v1, copy, v1_self, buildtime_deps);
1337 STREAM_REPLACE_HASHTABLE (v1, copy, v1_self, runtime_deps);
1338
1339 /* Internal Data Structures: With add on value */
1340 COPY_HASHTABLE_BY_VALUE_ADDER (
1341 copy, v1_self, rpm_components, modulemd_module_stream_v1_add_component);
1342 COPY_HASHTABLE_BY_VALUE_ADDER (
1343 copy, v1_self, module_components, modulemd_module_stream_v1_add_component);
1344 COPY_HASHTABLE_BY_VALUE_ADDER (
1345 copy, v1_self, profiles, modulemd_module_stream_v1_add_profile);
1346 COPY_HASHTABLE_BY_VALUE_ADDER (
1347 copy, v1_self, servicelevels, modulemd_module_stream_v1_add_servicelevel);
1348
1349 STREAM_COPY_IF_SET (v1, copy, v1_self, xmd);
1350
1351 return MODULEMD_MODULE_STREAM (g_steal_pointer (©));
1352 }
1353
1354
1355 static gboolean
modulemd_module_stream_v1_depends_on_stream(ModulemdModuleStream * self,const gchar * module_name,const gchar * stream_name)1356 modulemd_module_stream_v1_depends_on_stream (ModulemdModuleStream *self,
1357 const gchar *module_name,
1358 const gchar *stream_name)
1359 {
1360 const gchar *stream = NULL;
1361 ModulemdModuleStreamV1 *v1_self = NULL;
1362
1363 g_return_val_if_fail (MODULEMD_IS_MODULE_STREAM_V1 (self), FALSE);
1364 g_return_val_if_fail (module_name && stream_name, FALSE);
1365
1366 v1_self = MODULEMD_MODULE_STREAM_V1 (self);
1367
1368 stream = g_hash_table_lookup (v1_self->runtime_deps, module_name);
1369 if (!stream)
1370 {
1371 return FALSE;
1372 }
1373
1374 return g_str_equal (stream, stream_name);
1375 }
1376
1377
1378 static gboolean
modulemd_module_stream_v1_build_depends_on_stream(ModulemdModuleStream * self,const gchar * module_name,const gchar * stream_name)1379 modulemd_module_stream_v1_build_depends_on_stream (ModulemdModuleStream *self,
1380 const gchar *module_name,
1381 const gchar *stream_name)
1382 {
1383 const gchar *stream = NULL;
1384 ModulemdModuleStreamV1 *v1_self = NULL;
1385
1386 g_return_val_if_fail (MODULEMD_IS_MODULE_STREAM_V1 (self), FALSE);
1387 g_return_val_if_fail (module_name && stream_name, FALSE);
1388
1389 v1_self = MODULEMD_MODULE_STREAM_V1 (self);
1390
1391 stream = g_hash_table_lookup (v1_self->buildtime_deps, module_name);
1392 if (!stream)
1393 {
1394 return FALSE;
1395 }
1396
1397 return g_str_equal (stream, stream_name);
1398 }
1399
1400
1401 static void
modulemd_module_stream_v1_class_init(ModulemdModuleStreamV1Class * klass)1402 modulemd_module_stream_v1_class_init (ModulemdModuleStreamV1Class *klass)
1403 {
1404 GObjectClass *object_class = G_OBJECT_CLASS (klass);
1405 ModulemdModuleStreamClass *stream_class =
1406 MODULEMD_MODULE_STREAM_CLASS (object_class);
1407
1408 object_class->finalize = modulemd_module_stream_v1_finalize;
1409 object_class->get_property = modulemd_module_stream_v1_get_property;
1410 object_class->set_property = modulemd_module_stream_v1_set_property;
1411
1412 stream_class->get_mdversion = modulemd_module_stream_v1_get_mdversion;
1413 stream_class->copy = modulemd_module_stream_v1_copy;
1414 stream_class->equals = modulemd_module_stream_v1_equals;
1415 stream_class->validate = modulemd_module_stream_v1_validate;
1416 stream_class->depends_on_stream =
1417 modulemd_module_stream_v1_depends_on_stream;
1418 stream_class->build_depends_on_stream =
1419 modulemd_module_stream_v1_build_depends_on_stream;
1420
1421 properties[PROP_ARCH] = g_param_spec_string (
1422 "arch",
1423 "Module Artifact Architecture",
1424 "The architecture of the produced artifacts",
1425 NULL,
1426 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT);
1427
1428 properties[PROP_BUILDOPTS] =
1429 g_param_spec_object ("buildopts",
1430 "Module Build Options",
1431 "Build options for module components",
1432 MODULEMD_TYPE_BUILDOPTS,
1433 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
1434
1435 properties[PROP_COMMUNITY] = g_param_spec_string (
1436 "community",
1437 "Module Community Website",
1438 "The website address of the upstream community for this module",
1439 NULL,
1440 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT);
1441
1442 properties[PROP_DOCUMENTATION] = g_param_spec_string (
1443 "documentation",
1444 "Module Documentation Website",
1445 "The website address of the upstream documentation for this module",
1446 NULL,
1447 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT);
1448
1449 properties[PROP_TRACKER] = g_param_spec_string (
1450 "tracker",
1451 "Module Bug Tracker Website",
1452 "The website address of the upstream bug tracker for this module",
1453 NULL,
1454 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT);
1455
1456 g_object_class_install_properties (object_class, N_PROPS, properties);
1457 }
1458
1459 static void
modulemd_module_stream_v1_init(ModulemdModuleStreamV1 * self)1460 modulemd_module_stream_v1_init (ModulemdModuleStreamV1 *self)
1461 {
1462 /* Properties */
1463
1464 /* Internal Data Structures */
1465 self->module_components =
1466 g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
1467 self->rpm_components =
1468 g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
1469
1470 self->content_licenses =
1471 g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
1472 self->module_licenses =
1473 g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
1474
1475 self->profiles =
1476 g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
1477
1478 self->rpm_api =
1479 g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
1480
1481 self->rpm_artifacts =
1482 g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
1483
1484 self->rpm_filters =
1485 g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
1486
1487 self->servicelevels =
1488 g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
1489
1490 self->buildtime_deps =
1491 g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
1492 self->runtime_deps =
1493 g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
1494 }
1495
1496
1497 static gboolean
1498 modulemd_module_stream_v1_parse_licenses (yaml_parser_t *parser,
1499 ModulemdModuleStreamV1 *modulestream,
1500 gboolean strict,
1501 GError **error);
1502
1503 static gboolean
1504 modulemd_module_stream_v1_parse_servicelevels (
1505 yaml_parser_t *parser,
1506 ModulemdModuleStreamV1 *modulestream,
1507 gboolean strict,
1508 GError **error);
1509
1510 static gboolean
1511 modulemd_module_stream_v1_parse_deps (yaml_parser_t *parser,
1512 ModulemdModuleStreamV1 *modulestream,
1513 gboolean strict,
1514 GError **error);
1515
1516 static gboolean
1517 modulemd_module_stream_v1_parse_refs (yaml_parser_t *parser,
1518 ModulemdModuleStreamV1 *modulestream,
1519 gboolean strict,
1520 GError **error);
1521
1522 static gboolean
1523 modulemd_module_stream_v1_parse_profiles (yaml_parser_t *parser,
1524 ModulemdModuleStreamV1 *modulestream,
1525 gboolean strict,
1526 GError **error);
1527
1528 static gboolean
1529 modulemd_module_stream_v1_parse_components (
1530 yaml_parser_t *parser,
1531 ModulemdModuleStreamV1 *modulestream,
1532 gboolean strict,
1533 GError **error);
1534
1535
1536 ModulemdModuleStreamV1 *
modulemd_module_stream_v1_parse_yaml(ModulemdSubdocumentInfo * subdoc,gboolean strict,GError ** error)1537 modulemd_module_stream_v1_parse_yaml (ModulemdSubdocumentInfo *subdoc,
1538 gboolean strict,
1539 GError **error)
1540 {
1541 MODULEMD_INIT_TRACE ();
1542 MMD_INIT_YAML_PARSER (parser);
1543 MMD_INIT_YAML_EVENT (event);
1544 gboolean done = FALSE;
1545 g_autoptr (GError) nested_error = NULL;
1546 g_autoptr (ModulemdModuleStreamV1) modulestream = NULL;
1547 g_autoptr (GHashTable) set = NULL;
1548 g_autoptr (ModulemdBuildopts) buildopts = NULL;
1549 g_autoptr (GVariant) xmd = NULL;
1550 g_autoptr (GDate) eol = NULL;
1551 g_autoptr (ModulemdServiceLevel) sl = NULL;
1552
1553 if (!modulemd_subdocument_info_get_data_parser (
1554 subdoc, &parser, strict, error))
1555 {
1556 return NULL;
1557 }
1558
1559 guint64 version;
1560
1561 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
1562
1563 modulestream = modulemd_module_stream_v1_new (NULL, NULL);
1564
1565 /* Read the MAPPING_START */
1566 YAML_PARSER_PARSE_WITH_EXIT (&parser, &event, error);
1567 if (event.type != YAML_MAPPING_START_EVENT)
1568 {
1569 MMD_YAML_ERROR_EVENT_EXIT (
1570 error, event, "Data section did not begin with a map.");
1571 }
1572
1573 /* Process through the mapping */
1574 while (!done)
1575 {
1576 YAML_PARSER_PARSE_WITH_EXIT (&parser, &event, error);
1577
1578 switch (event.type)
1579 {
1580 case YAML_MAPPING_END_EVENT: done = TRUE; break;
1581
1582 case YAML_SCALAR_EVENT:
1583 /* Mapping Keys */
1584
1585 /* Module Name */
1586 if (g_str_equal ((const gchar *)event.data.scalar.value, "name"))
1587 {
1588 MMD_SET_PARSED_YAML_STRING (
1589 &parser,
1590 error,
1591 modulemd_module_stream_set_module_name,
1592 MODULEMD_MODULE_STREAM (modulestream));
1593 }
1594
1595 /* Module Stream Name */
1596 else if (g_str_equal ((const gchar *)event.data.scalar.value,
1597 "stream"))
1598 {
1599 MMD_SET_PARSED_YAML_STRING (
1600 &parser,
1601 error,
1602 modulemd_module_stream_set_stream_name,
1603 MODULEMD_MODULE_STREAM (modulestream));
1604 }
1605
1606 /* Module Version */
1607 else if (g_str_equal ((const gchar *)event.data.scalar.value,
1608 "version"))
1609 {
1610 version = modulemd_yaml_parse_uint64 (&parser, &nested_error);
1611 if (nested_error)
1612 {
1613 g_propagate_error (error, g_steal_pointer (&nested_error));
1614 return NULL;
1615 }
1616
1617 modulemd_module_stream_set_version (
1618 MODULEMD_MODULE_STREAM (modulestream), version);
1619 }
1620
1621 /* Module Context */
1622 else if (g_str_equal ((const gchar *)event.data.scalar.value,
1623 "context"))
1624 {
1625 MMD_SET_PARSED_YAML_STRING (
1626 &parser,
1627 error,
1628 modulemd_module_stream_set_context,
1629 MODULEMD_MODULE_STREAM (modulestream));
1630 }
1631
1632 /* Module Artifact Architecture */
1633 else if (g_str_equal ((const gchar *)event.data.scalar.value,
1634 "arch"))
1635 {
1636 MMD_SET_PARSED_YAML_STRING (&parser,
1637 error,
1638 modulemd_module_stream_v1_set_arch,
1639 modulestream);
1640 }
1641
1642 /* Module Summary */
1643 else if (g_str_equal ((const gchar *)event.data.scalar.value,
1644 "summary"))
1645 {
1646 MMD_SET_PARSED_YAML_STRING (
1647 &parser,
1648 error,
1649 modulemd_module_stream_v1_set_summary,
1650 modulestream);
1651 }
1652
1653 /* Module Description */
1654 else if (g_str_equal ((const gchar *)event.data.scalar.value,
1655 "description"))
1656 {
1657 MMD_SET_PARSED_YAML_STRING (
1658 &parser,
1659 error,
1660 modulemd_module_stream_v1_set_description,
1661 modulestream);
1662 }
1663
1664 /* Service Levels */
1665 else if (g_str_equal ((const gchar *)event.data.scalar.value,
1666 "servicelevels"))
1667 {
1668 if (!modulemd_module_stream_v1_parse_servicelevels (
1669 &parser, modulestream, strict, &nested_error))
1670 {
1671 g_propagate_error (error, g_steal_pointer (&nested_error));
1672 return NULL;
1673 }
1674 }
1675
1676 /* Licences */
1677 else if (g_str_equal ((const gchar *)event.data.scalar.value,
1678 "license"))
1679 {
1680 if (!modulemd_module_stream_v1_parse_licenses (
1681 &parser, modulestream, strict, &nested_error))
1682 {
1683 g_propagate_error (error, g_steal_pointer (&nested_error));
1684 return NULL;
1685 }
1686 }
1687
1688 /* Extensible Metadata */
1689 else if (g_str_equal ((const gchar *)event.data.scalar.value, "xmd"))
1690 {
1691 xmd = mmd_parse_xmd (&parser, &nested_error);
1692 if (!xmd)
1693 {
1694 g_propagate_error (error, g_steal_pointer (&nested_error));
1695 return NULL;
1696 }
1697 modulemd_module_stream_v1_set_xmd (modulestream, xmd);
1698 g_clear_pointer (&xmd, g_variant_unref);
1699 }
1700
1701 /* Dependencies */
1702 else if (g_str_equal ((const gchar *)event.data.scalar.value,
1703 "dependencies"))
1704 {
1705 if (!modulemd_module_stream_v1_parse_deps (
1706 &parser, modulestream, strict, &nested_error))
1707 {
1708 g_propagate_error (error, g_steal_pointer (&nested_error));
1709 return NULL;
1710 }
1711 }
1712
1713 /* References */
1714 else if (g_str_equal ((const gchar *)event.data.scalar.value,
1715 "references"))
1716 {
1717 if (!modulemd_module_stream_v1_parse_refs (
1718 &parser, modulestream, strict, &nested_error))
1719 {
1720 g_propagate_error (error, g_steal_pointer (&nested_error));
1721 return NULL;
1722 }
1723 }
1724
1725 /* Profiles */
1726 else if (g_str_equal ((const gchar *)event.data.scalar.value,
1727 "profiles"))
1728 {
1729 if (!modulemd_module_stream_v1_parse_profiles (
1730 &parser, modulestream, strict, &nested_error))
1731 {
1732 g_propagate_error (error, g_steal_pointer (&nested_error));
1733 return NULL;
1734 }
1735 }
1736
1737 /* API */
1738 else if (g_str_equal ((const gchar *)event.data.scalar.value, "api"))
1739 {
1740 set = modulemd_yaml_parse_string_set_from_map (
1741 &parser, "rpms", strict, &nested_error);
1742 modulemd_module_stream_v1_replace_rpm_api (modulestream, set);
1743 g_clear_pointer (&set, g_hash_table_unref);
1744 }
1745
1746 /* Filter */
1747 else if (g_str_equal ((const gchar *)event.data.scalar.value,
1748 "filter"))
1749 {
1750 set = modulemd_yaml_parse_string_set_from_map (
1751 &parser, "rpms", strict, &nested_error);
1752 modulemd_module_stream_v1_replace_rpm_filters (modulestream,
1753 set);
1754 g_clear_pointer (&set, g_hash_table_unref);
1755 }
1756
1757 /* Build Options */
1758 else if (g_str_equal ((const gchar *)event.data.scalar.value,
1759 "buildopts"))
1760 {
1761 buildopts =
1762 modulemd_buildopts_parse_yaml (&parser, strict, &nested_error);
1763 if (!buildopts)
1764 {
1765 g_propagate_error (error, g_steal_pointer (&nested_error));
1766 return NULL;
1767 }
1768
1769 modulemd_module_stream_v1_set_buildopts (modulestream,
1770 buildopts);
1771 g_clear_object (&buildopts);
1772 }
1773
1774 /* Components */
1775 else if (g_str_equal ((const gchar *)event.data.scalar.value,
1776 "components"))
1777 {
1778 if (!modulemd_module_stream_v1_parse_components (
1779 &parser, modulestream, strict, &nested_error))
1780 {
1781 g_propagate_error (error, g_steal_pointer (&nested_error));
1782 return NULL;
1783 }
1784 }
1785
1786 /* Artifacts */
1787 else if (g_str_equal ((const gchar *)event.data.scalar.value,
1788 "artifacts"))
1789 {
1790 set = modulemd_yaml_parse_string_set_from_map (
1791 &parser, "rpms", strict, &nested_error);
1792 if (!set)
1793 {
1794 g_propagate_error (error, g_steal_pointer (&nested_error));
1795 return NULL;
1796 }
1797 modulemd_module_stream_v1_replace_rpm_artifacts (modulestream,
1798 set);
1799 g_clear_pointer (&set, g_hash_table_unref);
1800 }
1801
1802 /* EOL (Deprecated) */
1803 else if (g_str_equal ((const gchar *)event.data.scalar.value, "eol"))
1804 {
1805 eol = modulemd_yaml_parse_date (&parser, &nested_error);
1806 if (!eol)
1807 {
1808 MMD_YAML_ERROR_EVENT_EXIT (
1809 error,
1810 event,
1811 "Failed to parse EOL date in data: %s",
1812 nested_error->message);
1813 }
1814
1815 /* We store EOL as the "rawhide" service level, according to the
1816 * spec.
1817 */
1818 sl = modulemd_service_level_new ("rawhide");
1819 modulemd_service_level_set_eol (sl, eol);
1820 modulemd_module_stream_v1_add_servicelevel (modulestream, sl);
1821
1822 g_clear_object (&sl);
1823 g_clear_pointer (&eol, g_date_free);
1824 }
1825
1826
1827 /* Unknown key */
1828 else
1829 {
1830 SKIP_UNKNOWN (&parser,
1831 NULL,
1832 "Unexpected key in data: %s",
1833 (const gchar *)event.data.scalar.value);
1834 break;
1835 }
1836 break;
1837
1838
1839 default:
1840 MMD_YAML_ERROR_EVENT_EXIT (
1841 error,
1842 event,
1843 "Unexpected YAML event in ModuleStreamV1: %s",
1844 mmd_yaml_get_event_name (event.type));
1845 break;
1846 }
1847 yaml_event_delete (&event);
1848 }
1849
1850 return g_steal_pointer (&modulestream);
1851 }
1852
1853
1854 static gboolean
modulemd_module_stream_v1_parse_licenses(yaml_parser_t * parser,ModulemdModuleStreamV1 * modulestream,gboolean strict,GError ** error)1855 modulemd_module_stream_v1_parse_licenses (yaml_parser_t *parser,
1856 ModulemdModuleStreamV1 *modulestream,
1857 gboolean strict,
1858 GError **error)
1859 {
1860 MODULEMD_INIT_TRACE ();
1861 MMD_INIT_YAML_EVENT (event);
1862 gboolean done = FALSE;
1863 gboolean in_map = FALSE;
1864 g_autoptr (GError) nested_error = NULL;
1865 g_autoptr (GHashTable) set = NULL;
1866
1867 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
1868
1869 /* Process through the mapping */
1870 while (!done)
1871 {
1872 YAML_PARSER_PARSE_WITH_EXIT_BOOL (parser, &event, error);
1873
1874 switch (event.type)
1875 {
1876 case YAML_MAPPING_START_EVENT:
1877 if (in_map)
1878 {
1879 MMD_YAML_ERROR_EVENT_EXIT_BOOL (
1880 error,
1881 event,
1882 "Unexpected extra MAPPING_START event in licenses");
1883 }
1884 in_map = TRUE;
1885 break;
1886
1887 case YAML_MAPPING_END_EVENT:
1888 if (!in_map)
1889 {
1890 MMD_YAML_ERROR_EVENT_EXIT_BOOL (
1891 error, event, "Unexpected MAPPING_END event in licenses");
1892 }
1893 done = TRUE;
1894 break;
1895
1896 case YAML_SCALAR_EVENT:
1897 if (!in_map)
1898 {
1899 MMD_YAML_ERROR_EVENT_EXIT_BOOL (
1900 error, event, "Received scalar outside of mapping");
1901 }
1902
1903 if (g_str_equal ((const gchar *)event.data.scalar.value, "module"))
1904 {
1905 set = modulemd_yaml_parse_string_set (parser, &nested_error);
1906 if (!set)
1907 {
1908 g_propagate_error (error, g_steal_pointer (&nested_error));
1909 return FALSE;
1910 }
1911 modulemd_module_stream_v1_replace_module_licenses (modulestream,
1912 set);
1913 g_clear_pointer (&set, g_hash_table_unref);
1914 }
1915 else if (g_str_equal ((const gchar *)event.data.scalar.value,
1916 "content"))
1917 {
1918 set = modulemd_yaml_parse_string_set (parser, &nested_error);
1919 modulemd_module_stream_v1_replace_content_licenses (modulestream,
1920 set);
1921 g_clear_pointer (&set, g_hash_table_unref);
1922 }
1923 else
1924 {
1925 SKIP_UNKNOWN (parser,
1926 FALSE,
1927 "Unexpected key in licenses: %s",
1928 (const gchar *)event.data.scalar.value);
1929 break;
1930 }
1931
1932 break;
1933
1934 default:
1935 MMD_YAML_ERROR_EVENT_EXIT_BOOL (
1936 error,
1937 event,
1938 "Unexpected YAML event in licenses: %s",
1939 mmd_yaml_get_event_name (event.type));
1940 break;
1941 }
1942 yaml_event_delete (&event);
1943 }
1944
1945 return TRUE;
1946 }
1947
1948
1949 static gboolean
modulemd_module_stream_v1_parse_servicelevels(yaml_parser_t * parser,ModulemdModuleStreamV1 * modulestream,gboolean strict,GError ** error)1950 modulemd_module_stream_v1_parse_servicelevels (
1951 yaml_parser_t *parser,
1952 ModulemdModuleStreamV1 *modulestream,
1953 gboolean strict,
1954 GError **error)
1955 {
1956 MODULEMD_INIT_TRACE ();
1957 MMD_INIT_YAML_EVENT (event);
1958 gboolean done = FALSE;
1959 gboolean in_map = FALSE;
1960 const gchar *name = NULL;
1961 g_autoptr (ModulemdServiceLevel) sl = NULL;
1962 g_autoptr (GError) nested_error = NULL;
1963
1964 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
1965
1966 /* Process through the mapping */
1967 while (!done)
1968 {
1969 YAML_PARSER_PARSE_WITH_EXIT_BOOL (parser, &event, error);
1970
1971 switch (event.type)
1972 {
1973 case YAML_MAPPING_START_EVENT:
1974 if (in_map)
1975 {
1976 MMD_YAML_ERROR_EVENT_EXIT_BOOL (
1977 error,
1978 event,
1979 "Unexpected extra MAPPING_START event in servicelevels");
1980 }
1981 in_map = TRUE;
1982 break;
1983
1984 case YAML_MAPPING_END_EVENT:
1985 if (!in_map)
1986 {
1987 MMD_YAML_ERROR_EVENT_EXIT_BOOL (
1988 error, event, "Unexpected MAPPING_END event in servicelevels");
1989 }
1990 done = TRUE;
1991 break;
1992
1993 case YAML_SCALAR_EVENT:
1994 if (!in_map)
1995 {
1996 MMD_YAML_ERROR_EVENT_EXIT_BOOL (
1997 error, event, "Received scalar outside of mapping");
1998 }
1999
2000 name = (const gchar *)event.data.scalar.value;
2001
2002 sl = modulemd_service_level_parse_yaml (
2003 parser, name, strict, &nested_error);
2004 if (!sl)
2005 {
2006 g_propagate_error (error, g_steal_pointer (&nested_error));
2007 return FALSE;
2008 }
2009
2010 modulemd_module_stream_v1_add_servicelevel (modulestream, sl);
2011 g_clear_object (&sl);
2012
2013 break;
2014
2015 default:
2016 MMD_YAML_ERROR_EVENT_EXIT_BOOL (
2017 error,
2018 event,
2019 "Unexpected YAML event in servicelevels: %s",
2020 mmd_yaml_get_event_name (event.type));
2021 break;
2022 }
2023 yaml_event_delete (&event);
2024 }
2025
2026 return TRUE;
2027 }
2028
2029 static gboolean
modulemd_module_stream_v1_parse_deps(yaml_parser_t * parser,ModulemdModuleStreamV1 * modulestream,gboolean strict,GError ** error)2030 modulemd_module_stream_v1_parse_deps (yaml_parser_t *parser,
2031 ModulemdModuleStreamV1 *modulestream,
2032 gboolean strict,
2033 GError **error)
2034 {
2035 MODULEMD_INIT_TRACE ();
2036 MMD_INIT_YAML_EVENT (event);
2037 gboolean done = FALSE;
2038 g_autoptr (GError) nested_error = NULL;
2039 g_autoptr (GHashTable) deptable = NULL;
2040
2041 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
2042
2043 /* Process through the sequence */
2044 /* We *must* get a MAPPING_START here */
2045 YAML_PARSER_PARSE_WITH_EXIT_BOOL (parser, &event, error);
2046 if (event.type != YAML_MAPPING_START_EVENT)
2047 {
2048 MMD_YAML_ERROR_EVENT_EXIT_BOOL (
2049 error,
2050 event,
2051 "Got %s instead of SEQUENCE_START in dependencies.",
2052 mmd_yaml_get_event_name (event.type));
2053 }
2054
2055 while (!done)
2056 {
2057 YAML_PARSER_PARSE_WITH_EXIT_BOOL (parser, &event, error);
2058
2059 switch (event.type)
2060 {
2061 case YAML_MAPPING_END_EVENT: done = TRUE; break;
2062
2063 case YAML_SCALAR_EVENT:
2064 if (g_str_equal ((const gchar *)event.data.scalar.value,
2065 "buildrequires"))
2066 {
2067 deptable =
2068 modulemd_yaml_parse_string_string_map (parser, &nested_error);
2069 if (!deptable)
2070 {
2071 g_propagate_error (error, g_steal_pointer (&nested_error));
2072 return FALSE;
2073 }
2074 modulemd_module_stream_v1_replace_buildtime_deps (modulestream,
2075 deptable);
2076 g_clear_pointer (&deptable, g_hash_table_unref);
2077 }
2078
2079 else if (g_str_equal ((const gchar *)event.data.scalar.value,
2080 "requires"))
2081 {
2082 deptable =
2083 modulemd_yaml_parse_string_string_map (parser, &nested_error);
2084 if (!deptable)
2085 {
2086 g_propagate_error (error, g_steal_pointer (&nested_error));
2087 return FALSE;
2088 }
2089 modulemd_module_stream_v1_replace_runtime_deps (modulestream,
2090 deptable);
2091 g_clear_pointer (&deptable, g_hash_table_unref);
2092 }
2093
2094 else
2095 {
2096 SKIP_UNKNOWN (parser,
2097 FALSE,
2098 "Unexpected key in dependencies: %s",
2099 (const gchar *)event.data.scalar.value);
2100 break;
2101 }
2102
2103 break;
2104
2105 default:
2106 MMD_YAML_ERROR_EVENT_EXIT_BOOL (
2107 error,
2108 event,
2109 "Unexpected YAML event in dependencies: %s",
2110 mmd_yaml_get_event_name (event.type));
2111 break;
2112 }
2113 yaml_event_delete (&event);
2114 }
2115
2116 return TRUE;
2117 }
2118
2119
2120 static gboolean
modulemd_module_stream_v1_parse_refs(yaml_parser_t * parser,ModulemdModuleStreamV1 * modulestream,gboolean strict,GError ** error)2121 modulemd_module_stream_v1_parse_refs (yaml_parser_t *parser,
2122 ModulemdModuleStreamV1 *modulestream,
2123 gboolean strict,
2124 GError **error)
2125 {
2126 MODULEMD_INIT_TRACE ();
2127 MMD_INIT_YAML_EVENT (event);
2128 gboolean done = FALSE;
2129 g_autofree gchar *scalar = NULL;
2130 g_autoptr (GError) nested_error = NULL;
2131
2132 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
2133
2134 /* Process through the map */
2135 /* We *must* get a MAPPING_START here */
2136 YAML_PARSER_PARSE_WITH_EXIT_BOOL (parser, &event, error);
2137 if (event.type != YAML_MAPPING_START_EVENT)
2138 {
2139 MMD_YAML_ERROR_EVENT_EXIT_BOOL (
2140 error,
2141 event,
2142 "Got %s instead of MAPPING_START in dependencies.",
2143 mmd_yaml_get_event_name (event.type));
2144 }
2145
2146 while (!done)
2147 {
2148 YAML_PARSER_PARSE_WITH_EXIT_BOOL (parser, &event, error);
2149
2150 switch (event.type)
2151 {
2152 case YAML_MAPPING_END_EVENT: done = TRUE; break;
2153
2154 case YAML_SCALAR_EVENT:
2155 if (g_str_equal ((const gchar *)event.data.scalar.value,
2156 "community"))
2157 {
2158 scalar = modulemd_yaml_parse_string (parser, &nested_error);
2159 if (!scalar)
2160 {
2161 g_propagate_error (error, g_steal_pointer (&nested_error));
2162 return FALSE;
2163 }
2164
2165 modulemd_module_stream_v1_set_community (modulestream, scalar);
2166 g_clear_pointer (&scalar, g_free);
2167 }
2168
2169 else if (g_str_equal ((const gchar *)event.data.scalar.value,
2170 "documentation"))
2171 {
2172 scalar = modulemd_yaml_parse_string (parser, &nested_error);
2173 if (!scalar)
2174 {
2175 g_propagate_error (error, g_steal_pointer (&nested_error));
2176 return FALSE;
2177 }
2178
2179 modulemd_module_stream_v1_set_documentation (modulestream,
2180 scalar);
2181 g_clear_pointer (&scalar, g_free);
2182 }
2183
2184 else if (g_str_equal ((const gchar *)event.data.scalar.value,
2185 "tracker"))
2186 {
2187 scalar = modulemd_yaml_parse_string (parser, &nested_error);
2188 if (!scalar)
2189 {
2190 g_propagate_error (error, g_steal_pointer (&nested_error));
2191 return FALSE;
2192 }
2193
2194 modulemd_module_stream_v1_set_tracker (modulestream, scalar);
2195 g_clear_pointer (&scalar, g_free);
2196 }
2197
2198 else
2199 {
2200 SKIP_UNKNOWN (parser,
2201 FALSE,
2202 "Unexpected key in references: %s",
2203 (const gchar *)event.data.scalar.value);
2204 break;
2205 }
2206 break;
2207
2208 default:
2209 MMD_YAML_ERROR_EVENT_EXIT_BOOL (
2210 error,
2211 event,
2212 "Unexpected YAML event in dependencies: %s",
2213 mmd_yaml_get_event_name (event.type));
2214 break;
2215 }
2216 yaml_event_delete (&event);
2217 }
2218
2219 return TRUE;
2220 }
2221
2222
2223 static gboolean
modulemd_module_stream_v1_parse_profiles(yaml_parser_t * parser,ModulemdModuleStreamV1 * modulestream,gboolean strict,GError ** error)2224 modulemd_module_stream_v1_parse_profiles (yaml_parser_t *parser,
2225 ModulemdModuleStreamV1 *modulestream,
2226 gboolean strict,
2227 GError **error)
2228 {
2229 MODULEMD_INIT_TRACE ();
2230 MMD_INIT_YAML_EVENT (event);
2231 gboolean done = FALSE;
2232 g_autoptr (GError) nested_error = NULL;
2233 g_autoptr (ModulemdProfile) profile = NULL;
2234
2235 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
2236
2237 /* Process through the map */
2238 /* We *must* get a MAPPING_START here */
2239 YAML_PARSER_PARSE_WITH_EXIT_BOOL (parser, &event, error);
2240 if (event.type != YAML_MAPPING_START_EVENT)
2241 {
2242 MMD_YAML_ERROR_EVENT_EXIT_BOOL (
2243 error,
2244 event,
2245 "Got %s instead of MAPPING_START in profiles.",
2246 mmd_yaml_get_event_name (event.type));
2247 }
2248
2249 while (!done)
2250 {
2251 YAML_PARSER_PARSE_WITH_EXIT_BOOL (parser, &event, error);
2252
2253 switch (event.type)
2254 {
2255 case YAML_MAPPING_END_EVENT: done = TRUE; break;
2256
2257 case YAML_SCALAR_EVENT:
2258 profile = modulemd_profile_parse_yaml (
2259 parser,
2260 (const gchar *)event.data.scalar.value,
2261 strict,
2262 &nested_error);
2263 if (!profile)
2264 {
2265 g_propagate_error (error, g_steal_pointer (&nested_error));
2266 return FALSE;
2267 }
2268
2269 modulemd_module_stream_v1_add_profile (modulestream, profile);
2270 g_clear_pointer (&profile, g_object_unref);
2271 break;
2272
2273 default:
2274 MMD_YAML_ERROR_EVENT_EXIT_BOOL (
2275 error,
2276 event,
2277 "Unexpected YAML event in dependencies: %s",
2278 mmd_yaml_get_event_name (event.type));
2279 break;
2280 }
2281 yaml_event_delete (&event);
2282 }
2283
2284 return TRUE;
2285 }
2286
2287
2288 static gboolean
2289 modulemd_module_stream_v1_parse_rpm_components (
2290 yaml_parser_t *parser,
2291 ModulemdModuleStreamV1 *modulestream,
2292 gboolean strict,
2293 GError **error);
2294 static gboolean
2295 modulemd_module_stream_v1_parse_module_components (
2296 yaml_parser_t *parser,
2297 ModulemdModuleStreamV1 *modulestream,
2298 gboolean strict,
2299 GError **error);
2300
2301
2302 static gboolean
modulemd_module_stream_v1_parse_components(yaml_parser_t * parser,ModulemdModuleStreamV1 * modulestream,gboolean strict,GError ** error)2303 modulemd_module_stream_v1_parse_components (
2304 yaml_parser_t *parser,
2305 ModulemdModuleStreamV1 *modulestream,
2306 gboolean strict,
2307 GError **error)
2308 {
2309 MODULEMD_INIT_TRACE ();
2310 MMD_INIT_YAML_EVENT (event);
2311 gboolean done = FALSE;
2312 g_autoptr (GError) nested_error = NULL;
2313
2314 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
2315
2316 /* Process through the sequence */
2317 /* We *must* get a MAPPING_START here */
2318 YAML_PARSER_PARSE_WITH_EXIT_BOOL (parser, &event, error);
2319 if (event.type != YAML_MAPPING_START_EVENT)
2320 {
2321 MMD_YAML_ERROR_EVENT_EXIT_BOOL (
2322 error,
2323 event,
2324 "Got %s instead of MAPPING_START in components.",
2325 mmd_yaml_get_event_name (event.type));
2326 }
2327
2328 while (!done)
2329 {
2330 YAML_PARSER_PARSE_WITH_EXIT_BOOL (parser, &event, error);
2331
2332 switch (event.type)
2333 {
2334 case YAML_MAPPING_END_EVENT: done = TRUE; break;
2335
2336 case YAML_SCALAR_EVENT:
2337 if (g_str_equal ((const gchar *)event.data.scalar.value, "rpms"))
2338 {
2339 if (!modulemd_module_stream_v1_parse_rpm_components (
2340 parser, modulestream, strict, &nested_error))
2341 {
2342 g_propagate_error (error, g_steal_pointer (&nested_error));
2343 return FALSE;
2344 }
2345 }
2346 else if (g_str_equal ((const gchar *)event.data.scalar.value,
2347 "modules"))
2348 {
2349 if (!modulemd_module_stream_v1_parse_module_components (
2350 parser, modulestream, strict, &nested_error))
2351 {
2352 g_propagate_error (error, g_steal_pointer (&nested_error));
2353 return FALSE;
2354 }
2355 }
2356
2357 else
2358 {
2359 SKIP_UNKNOWN (parser,
2360 FALSE,
2361 "Unexpected key in components: %s",
2362 (const gchar *)event.data.scalar.value);
2363 break;
2364 }
2365
2366 break;
2367
2368
2369 default:
2370 MMD_YAML_ERROR_EVENT_EXIT_BOOL (
2371 error,
2372 event,
2373 "Unexpected YAML event in components: %s",
2374 mmd_yaml_get_event_name (event.type));
2375 break;
2376 }
2377 yaml_event_delete (&event);
2378 }
2379
2380 return TRUE;
2381 }
2382
2383
2384 static gboolean
modulemd_module_stream_v1_parse_rpm_components(yaml_parser_t * parser,ModulemdModuleStreamV1 * modulestream,gboolean strict,GError ** error)2385 modulemd_module_stream_v1_parse_rpm_components (
2386 yaml_parser_t *parser,
2387 ModulemdModuleStreamV1 *modulestream,
2388 gboolean strict,
2389 GError **error)
2390 {
2391 MODULEMD_INIT_TRACE ();
2392 MMD_INIT_YAML_EVENT (event);
2393 gboolean done = FALSE;
2394 g_autoptr (GError) nested_error = NULL;
2395 g_autoptr (ModulemdComponentRpm) component = NULL;
2396
2397 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
2398
2399 /* We *must* get a MAPPING_START here */
2400 YAML_PARSER_PARSE_WITH_EXIT_BOOL (parser, &event, error);
2401 if (event.type != YAML_MAPPING_START_EVENT)
2402 {
2403 MMD_YAML_ERROR_EVENT_EXIT_BOOL (
2404 error,
2405 event,
2406 "Got %s instead of MAPPING_START in rpm components.",
2407 mmd_yaml_get_event_name (event.type));
2408 }
2409
2410 while (!done)
2411 {
2412 YAML_PARSER_PARSE_WITH_EXIT_BOOL (parser, &event, error);
2413
2414 switch (event.type)
2415 {
2416 case YAML_MAPPING_END_EVENT: done = TRUE; break;
2417
2418 case YAML_SCALAR_EVENT:
2419 component = modulemd_component_rpm_parse_yaml (
2420 parser,
2421 (const gchar *)event.data.scalar.value,
2422 strict,
2423 &nested_error);
2424 if (!component)
2425 {
2426 g_propagate_error (error, g_steal_pointer (&nested_error));
2427 return FALSE;
2428 }
2429 modulemd_module_stream_v1_add_component (
2430 modulestream, (ModulemdComponent *)component);
2431 g_clear_pointer (&component, g_object_unref);
2432 break;
2433
2434 default:
2435 MMD_YAML_ERROR_EVENT_EXIT_BOOL (
2436 error,
2437 event,
2438 "Unexpected YAML event in RPM component: %s",
2439 mmd_yaml_get_event_name (event.type));
2440 break;
2441 }
2442 yaml_event_delete (&event);
2443 }
2444
2445 return TRUE;
2446 }
2447
2448
2449 static gboolean
modulemd_module_stream_v1_parse_module_components(yaml_parser_t * parser,ModulemdModuleStreamV1 * modulestream,gboolean strict,GError ** error)2450 modulemd_module_stream_v1_parse_module_components (
2451 yaml_parser_t *parser,
2452 ModulemdModuleStreamV1 *modulestream,
2453 gboolean strict,
2454 GError **error)
2455 {
2456 MODULEMD_INIT_TRACE ();
2457 MMD_INIT_YAML_EVENT (event);
2458 gboolean done = FALSE;
2459 g_autoptr (GError) nested_error = NULL;
2460 g_autoptr (ModulemdComponentModule) component = NULL;
2461
2462 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
2463
2464 /* We *must* get a MAPPING_START here */
2465 YAML_PARSER_PARSE_WITH_EXIT_BOOL (parser, &event, error);
2466 if (event.type != YAML_MAPPING_START_EVENT)
2467 {
2468 MMD_YAML_ERROR_EVENT_EXIT_BOOL (
2469 error,
2470 event,
2471 "Got %s instead of MAPPING_START in module components.",
2472 mmd_yaml_get_event_name (event.type));
2473 }
2474
2475 while (!done)
2476 {
2477 YAML_PARSER_PARSE_WITH_EXIT_BOOL (parser, &event, error);
2478
2479 switch (event.type)
2480 {
2481 case YAML_MAPPING_END_EVENT: done = TRUE; break;
2482
2483 case YAML_SCALAR_EVENT:
2484 component = modulemd_component_module_parse_yaml (
2485 parser,
2486 (const gchar *)event.data.scalar.value,
2487 strict,
2488 &nested_error);
2489 if (!component)
2490 {
2491 g_propagate_error (error, g_steal_pointer (&nested_error));
2492 return FALSE;
2493 }
2494 modulemd_module_stream_v1_add_component (
2495 modulestream, (ModulemdComponent *)component);
2496 g_clear_pointer (&component, g_object_unref);
2497 break;
2498
2499 default:
2500 MMD_YAML_ERROR_EVENT_EXIT_BOOL (
2501 error,
2502 event,
2503 "Unexpected YAML event in module component: %s",
2504 mmd_yaml_get_event_name (event.type));
2505 break;
2506 }
2507 yaml_event_delete (&event);
2508 }
2509
2510 return TRUE;
2511 }
2512
2513
2514 gboolean
modulemd_module_stream_v1_emit_yaml(ModulemdModuleStreamV1 * self,yaml_emitter_t * emitter,GError ** error)2515 modulemd_module_stream_v1_emit_yaml (ModulemdModuleStreamV1 *self,
2516 yaml_emitter_t *emitter,
2517 GError **error)
2518 {
2519 MODULEMD_INIT_TRACE ();
2520 if (!modulemd_module_stream_emit_yaml_base (
2521 MODULEMD_MODULE_STREAM (self), emitter, error))
2522 {
2523 return FALSE;
2524 }
2525
2526 EMIT_KEY_VALUE_IF_SET (
2527 emitter, error, "arch", modulemd_module_stream_v1_get_arch (self));
2528 EMIT_KEY_VALUE (emitter, error, "summary", self->summary);
2529 EMIT_KEY_VALUE_FULL (emitter,
2530 error,
2531 "description",
2532 self->description,
2533 YAML_FOLDED_SCALAR_STYLE);
2534
2535 EMIT_HASHTABLE_VALUES_IF_NON_EMPTY (emitter,
2536 error,
2537 "servicelevels",
2538 self->servicelevels,
2539 modulemd_service_level_emit_yaml);
2540
2541 if (!NON_EMPTY_TABLE (self->module_licenses))
2542 {
2543 g_set_error (error,
2544 MODULEMD_YAML_ERROR,
2545 MMD_YAML_ERROR_EMIT,
2546 "Module licenses is not allowed to be empty");
2547 return FALSE;
2548 }
2549
2550 EMIT_SCALAR (emitter, error, "license");
2551 EMIT_MAPPING_START (emitter, error);
2552 EMIT_STRING_SET (emitter, error, "module", self->module_licenses);
2553 EMIT_STRING_SET_IF_NON_EMPTY (
2554 emitter, error, "content", self->content_licenses);
2555 EMIT_MAPPING_END (emitter, error);
2556
2557 if (self->xmd != NULL)
2558 {
2559 EMIT_SCALAR (emitter, error, "xmd");
2560 if (!modulemd_yaml_emit_variant (emitter, self->xmd, error))
2561 {
2562 return FALSE;
2563 }
2564 }
2565
2566 if (NON_EMPTY_TABLE (self->buildtime_deps) ||
2567 NON_EMPTY_TABLE (self->runtime_deps))
2568 {
2569 EMIT_SCALAR (emitter, error, "dependencies");
2570 EMIT_MAPPING_START (emitter, error);
2571 EMIT_HASHTABLE_KEY_VALUES_IF_NON_EMPTY (
2572 emitter, error, "buildrequires", self->buildtime_deps);
2573 EMIT_HASHTABLE_KEY_VALUES_IF_NON_EMPTY (
2574 emitter, error, "requires", self->runtime_deps);
2575 EMIT_MAPPING_END (emitter, error);
2576 }
2577
2578 if (self->community || self->documentation || self->tracker)
2579 {
2580 EMIT_SCALAR (emitter, error, "references");
2581 EMIT_MAPPING_START (emitter, error);
2582 EMIT_KEY_VALUE_IF_SET (emitter, error, "community", self->community);
2583 EMIT_KEY_VALUE_IF_SET (
2584 emitter, error, "documentation", self->documentation);
2585 EMIT_KEY_VALUE_IF_SET (emitter, error, "tracker", self->tracker);
2586 EMIT_MAPPING_END (emitter, error);
2587 }
2588
2589 EMIT_HASHTABLE_VALUES_IF_NON_EMPTY (
2590 emitter, error, "profiles", self->profiles, modulemd_profile_emit_yaml);
2591
2592 if (NON_EMPTY_TABLE (self->rpm_api))
2593 {
2594 EMIT_SCALAR (emitter, error, "api");
2595 EMIT_MAPPING_START (emitter, error);
2596 EMIT_STRING_SET (emitter, error, "rpms", self->rpm_api);
2597 EMIT_MAPPING_END (emitter, error);
2598 }
2599
2600 if (NON_EMPTY_TABLE (self->rpm_filters))
2601 {
2602 EMIT_SCALAR (emitter, error, "filter");
2603 EMIT_MAPPING_START (emitter, error);
2604 EMIT_STRING_SET (emitter, error, "rpms", self->rpm_filters);
2605 EMIT_MAPPING_END (emitter, error);
2606 }
2607
2608 if (self->buildopts != NULL)
2609 {
2610 EMIT_SCALAR (emitter, error, "buildopts");
2611 EMIT_MAPPING_START (emitter, error);
2612 if (!modulemd_buildopts_emit_yaml (self->buildopts, emitter, error))
2613 {
2614 return FALSE;
2615 }
2616 EMIT_MAPPING_END (emitter, error);
2617 }
2618
2619 if (NON_EMPTY_TABLE (self->rpm_components) ||
2620 NON_EMPTY_TABLE (self->module_components))
2621 {
2622 EMIT_SCALAR (emitter, error, "components");
2623 EMIT_MAPPING_START (emitter, error);
2624 EMIT_HASHTABLE_VALUES_IF_NON_EMPTY (emitter,
2625 error,
2626 "rpms",
2627 self->rpm_components,
2628 modulemd_component_rpm_emit_yaml);
2629 EMIT_HASHTABLE_VALUES_IF_NON_EMPTY (emitter,
2630 error,
2631 "modules",
2632 self->module_components,
2633 modulemd_component_module_emit_yaml);
2634 EMIT_MAPPING_END (emitter, error);
2635 }
2636
2637 if (NON_EMPTY_TABLE (self->rpm_artifacts))
2638 {
2639 EMIT_SCALAR (emitter, error, "artifacts");
2640 EMIT_MAPPING_START (emitter, error);
2641 EMIT_STRING_SET (emitter, error, "rpms", self->rpm_artifacts);
2642 EMIT_MAPPING_END (emitter, error);
2643 }
2644
2645 /* The "data" mapping */
2646 EMIT_MAPPING_END (emitter, error);
2647 /* The overall document mapping */
2648 EMIT_MAPPING_END (emitter, error);
2649 if (!mmd_emitter_end_document (emitter, error))
2650 {
2651 return FALSE;
2652 }
2653
2654 return TRUE;
2655 }
2656