1 /*
2  * This file is part of libmodulemd
3  * Copyright (C) 2018-2020 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 #pragma once
15 
16 #include <glib-object.h>
17 #include <glib.h>
18 #include <glib/gstdio.h>
19 
20 #include "modulemd-deprecated.h"
21 
22 G_BEGIN_DECLS
23 
24 /**
25  * SECTION: modulemd-module-stream
26  * @title: Modulemd.ModuleStream
27  * @stability: stable
28  * @short_description: A parent class for all versions of #ModulemdModuleStream
29  * objects.
30  */
31 
32 /**
33  * MMD_MAXCONTEXTLEN:
34  *
35  * The ModuleStream v3 specification defines the maximum lenth of the context
36  * field.
37  *
38  * Since: 2.10
39  */
40 #define MMD_MAXCONTEXTLEN 10
41 
42 /* Forward declarations */
43 typedef struct _ModulemdModule ModulemdModule;
44 
45 /**
46  * ModulemdModuleStreamVersionEnum:
47  * @MD_MODULESTREAM_VERSION_ERROR: Represents an error handling module stream
48  * version.
49  * @MD_MODULESTREAM_VERSION_UNSET: Represents an unset module stream version.
50  * @MD_MODULESTREAM_VERSION_ONE: Represents v1 of the #ModulemdModuleStream
51  * metadata format.
52  * @MD_MODULESTREAM_VERSION_TWO: Represents v2 of the #ModulemdModuleStream
53  * metadata format.
54  * @MD_MODULESTREAM_VERSION_LATEST: Represents the highest-supported version of
55  * the #ModulemdModuleStream metadata format.
56  *
57  * Since: 2.0
58  */
59 typedef enum
60 {
61   MD_MODULESTREAM_VERSION_ERROR = -1,
62   MD_MODULESTREAM_VERSION_UNSET = 0,
63 
64   MD_MODULESTREAM_VERSION_ONE = 1,
65   MD_MODULESTREAM_VERSION_TWO = 2,
66 
67   MD_MODULESTREAM_VERSION_LATEST = MD_MODULESTREAM_VERSION_TWO
68 } ModulemdModuleStreamVersionEnum;
69 
70 
71 #define MODULEMD_TYPE_MODULE_STREAM (modulemd_module_stream_get_type ())
72 
73 G_DECLARE_DERIVABLE_TYPE (ModulemdModuleStream,
74                           modulemd_module_stream,
75                           MODULEMD,
76                           MODULE_STREAM,
77                           GObject)
78 
79 struct _ModulemdModuleStreamClass
80 {
81   GObjectClass parent_class;
82 
83   ModulemdModuleStream *(*copy) (ModulemdModuleStream *self,
84                                  const gchar *module_name,
85                                  const gchar *module_stream);
86 
87   gboolean (*validate) (ModulemdModuleStream *self, GError **error);
88 
89   guint64 (*get_mdversion) (ModulemdModuleStream *self);
90 
91   gboolean (*depends_on_stream) (ModulemdModuleStream *self,
92                                  const gchar *module_name,
93                                  const gchar *stream_name);
94 
95   gboolean (*build_depends_on_stream) (ModulemdModuleStream *self,
96                                        const gchar *module_name,
97                                        const gchar *stream_name);
98 
99   gboolean (*equals) (ModulemdModuleStream *self_1,
100                       ModulemdModuleStream *self_2);
101 
102   /* Padding to allow adding up to 7 new virtual functions without
103    * breaking ABI. */
104   gpointer padding[7];
105 };
106 
107 
108 /**
109  * modulemd_module_stream_new:
110  * @mdversion: (in): The metadata version of #ModulemdModuleStream to create.
111  * @module_name: (in) (nullable): The name of the module.
112  * @module_stream: (in) (nullable): The name of this stream. Optional.
113  *
114  * Returns: (transfer full): A newly-allocated #ModulemdModuleStream object of
115  * the requested metadata version.
116  *
117  * Since: 2.0
118  */
119 ModulemdModuleStream *
120 modulemd_module_stream_new (guint64 mdversion,
121                             const gchar *module_name,
122                             const gchar *module_stream);
123 
124 
125 /**
126  * modulemd_module_stream_read_file:
127  * @path: (in): The path to a YAML document containing a module stream
128  * definition.
129  * @strict: (in): Whether the parser should return failure if it encounters an
130  * unknown mapping key or if it should ignore it.
131  * @module_name: (in) (nullable): An optional module name to override the
132  * document on disk. Mostly useful in cases where the name is being
133  * auto-detected from git.
134  * @module_stream: (in) (nullable): An optional module stream name to override
135  * the document on disk. Mostly useful in cases where the name is being
136  * auto-detected from git.
137  * @error: (out): A #GError that will return the reason for a failed read.
138  *
139  * Create a #ModulemdModuleStream object from a YAML file.
140  *
141  * Note: This function also reads modulemd-packager v2 and v3 documents, which
142  * are transparently returned as #ModulemdModuleStream (V2) objects. However,
143  * if a modulemd-packager v3 document (#ModulemdPackagerV3) is encountered and
144  * it uses buildopts (#ModulemdBuildopts) in one or more build configurations,
145  * only the buildopts present in the first listed configuration (if any) will be
146  * applied to the returned #ModulemdModuleStreamV2 object.
147  *
148  * Returns: (transfer full): A newly-allocated #ModulemdModuleStream object if
149  * the YAML file was valid and contained exactly one `document: modulemd`
150  * subdocument. NULL if the document fails validation or multiple documents are
151  * encountered and sets @error appropriately. See #ModulemdModuleIndex for
152  * functions to read in multiple-subdocument YAML.
153  *
154  * Since: 2.0
155  * Deprecated: 2.11: Use modulemd_read_packager_file() instead.
156  */
157 MMD_DEPRECATED_FOR (modulemd_read_packager_file)
158 ModulemdModuleStream *
159 modulemd_module_stream_read_file (const gchar *path,
160                                   gboolean strict,
161                                   const gchar *module_name,
162                                   const gchar *module_stream,
163                                   GError **error);
164 
165 
166 /**
167  * modulemd_module_stream_read_string:
168  * @yaml_string: (in): A YAML document string containing a module stream
169  * definition.
170  * @strict: (in): Whether the parser should return failure if it encounters an
171  * unknown mapping key or if it should ignore it.
172  * @module_name: (in) (nullable): An optional module name to override the
173  * document on disk. Mostly useful in cases where the name is being
174  * auto-detected from git.
175  * @module_stream: (in) (nullable): An optional module stream name to override
176  * the document on disk. Mostly useful in cases where the name is being
177  * auto-detected from git.
178  * @error: (out): A #GError that will return the reason for a failed read.
179  *
180  * Create a #ModulemdModuleStream object from a YAML string.
181  *
182  * Note: This function also reads modulemd-packager v2 and v3 documents, which
183  * are transparently returned as #ModulemdModuleStream (V2) objects. However,
184  * if a modulemd-packager v3 document (#ModulemdPackagerV3) is encountered and
185  * it uses buildopts (#ModulemdBuildopts) in one or more build configurations,
186  * only the buildopts present in the first listed configuration (if any) will be
187  * applied to the returned #ModulemdModuleStreamV2 object.
188  *
189  * Returns: (transfer full): A newly-allocated #ModulemdModuleStream object if
190  * the YAML string was valid and contained exactly one `document: modulemd`
191  * subdocument. NULL if the document fails validation or multiple documents are
192  * encountered and sets @error appropriately. See #ModulemdModuleIndex for
193  * functions to read in multiple-subdocument YAML.
194  *
195  * Since: 2.0
196  * Deprecated: 2.11: Use modulemd_read_packager_string() instead.
197  */
198 MMD_DEPRECATED_FOR (modulemd_read_packager_string)
199 ModulemdModuleStream *
200 modulemd_module_stream_read_string (const gchar *yaml_string,
201                                     gboolean strict,
202                                     const gchar *module_name,
203                                     const gchar *module_stream,
204                                     GError **error);
205 
206 
207 /**
208  * modulemd_module_stream_read_stream: (skip)
209  * @stream: (in): A YAML document as a FILE * containing a module stream
210  * definition.
211  * @strict: (in): Whether the parser should return failure if it encounters an
212  * unknown mapping key or if it should ignore it.
213  * @module_name: (in) (nullable): An optional module name to override the
214  * document on disk. Mostly useful in cases where the name is being
215  * auto-detected from git.
216  * @module_stream: (in) (nullable): An optional module stream name to override
217  * the document on disk. Mostly useful in cases where the name is being
218  * auto-detected from git.
219  * @error: (out): A #GError that will return the reason for a failed read.
220  *
221  * Create a #ModulemdModuleStream object from a YAML file.
222  *
223  * Returns: (transfer full): A newly-allocated #ModulemdModuleStream object if
224  * the YAML file was valid and contained exactly one `document: modulemd`
225  * subdocument. NULL if the document fails validation or multiple documents are
226  * encountered and sets NULL appropriately. See #ModulemdModuleIndex for
227  * functions to read in multiple-subdocument YAML.
228  *
229  * Since: 2.0
230  */
231 ModulemdModuleStream *
232 modulemd_module_stream_read_stream (FILE *stream,
233                                     gboolean strict,
234                                     const gchar *module_name,
235                                     const gchar *module_stream,
236                                     GError **error);
237 
238 
239 /**
240  * modulemd_module_stream_equals:
241  * @self_1: (in): A #ModulemdModuleStream object.
242  * @self_2: (in): A #ModulemdModuleStream object.
243  *
244  * Checks if @self_1 and @self_2 are identical objects.
245  *
246  * Returns: TRUE, If both objects are equal. FALSE, otherwise.
247  *
248  * Since: 2.3
249  */
250 gboolean
251 modulemd_module_stream_equals (ModulemdModuleStream *self_1,
252                                ModulemdModuleStream *self_2);
253 
254 
255 /**
256  * modulemd_module_stream_copy:
257  * @self: (in): This #ModulemdModuleStream object.
258  * @module_name: (in) (nullable): An optional new name for the module of the
259  * copied stream.
260  * @module_stream: (in) (nullable): An optional new name for the copied stream.
261  *
262  * Copies a #ModulemdModuleStream, optionally assigning it a new stream name in
263  * the process.
264  *
265  * Returns: (transfer full): A newly-allocated #ModulemdModuleStream object
266  * that is a complete copy of @self, optionally with a new stream name.
267  *
268  * Since: 2.0
269  */
270 ModulemdModuleStream *
271 modulemd_module_stream_copy (ModulemdModuleStream *self,
272                              const gchar *module_name,
273                              const gchar *module_stream);
274 
275 
276 /**
277  * modulemd_module_stream_upgrade:
278  * @self: (in): This #ModulemdModuleStream object.
279  * @mdversion: (in): The metadata version to upgrade to. If zero, upgrades to
280  * the highest-supported version.
281  * @error: (out): A #GError that will return the reason for an upgrade error.
282  *
283  * Return an upgraded copy of this object. Does not modify the original.
284  *
285  * Returns: (transfer full): A newly-allocated #ModulemdModuleStream copy of
286  * this object upgraded to the requested version. Returns NULL and sets @error
287  * appropriately if the upgrade could not be completed automatically.
288  *
289  * Since: 2.0
290  * Deprecated: 2.10: Use modulemd_module_stream_upgrade_ext() instead.
291  */
292 MMD_DEPRECATED_FOR (modulemd_module_stream_upgrade_ext)
293 ModulemdModuleStream *
294 modulemd_module_stream_upgrade (ModulemdModuleStream *self,
295                                 guint64 mdversion,
296                                 GError **error);
297 
298 /**
299  * modulemd_module_stream_upgrade_ext:
300  * @self: (in): This #ModulemdModuleStream object.
301  * @mdversion: (in): The metadata version to upgrade to. If zero, upgrades to
302  * the highest-supported version.
303  * @error: (out): A #GError that will return the reason for an upgrade error.
304  *
305  * Does not modify the original #ModulemdModuleStream object, @from.
306  *
307  * Returns: (transfer full): A newly-allocated #ModulemdModule containing a copy
308  * of this object upgraded to the requested version, possibly with multiple
309  * streams. Returns NULL and sets @error appropriately if the upgrade could not
310  * be completed automatically.
311  *
312  * Since: 2.10
313  */
314 ModulemdModule *
315 modulemd_module_stream_upgrade_ext (ModulemdModuleStream *self,
316                                     guint64 mdversion,
317                                     GError **error);
318 
319 /**
320  * modulemd_module_stream_validate:
321  * @self: (in): This #ModulemdModuleStream object.
322  * @error: (out): A #GError that will return the reason for a validation error.
323  *
324  * Verifies that all stored values are internally consistent and that the
325  * module is sufficiently-complete for emitting. This function is called
326  * implicitly before attempting to emit the contents.
327  *
328  * Returns: TRUE if the #ModulemdModuleStream passed validation. FALSE and sets
329  * @error appropriately if validation fails.
330  *
331  * Since: 2.0
332  */
333 gboolean
334 modulemd_module_stream_validate (ModulemdModuleStream *self, GError **error);
335 
336 
337 /**
338  * modulemd_module_stream_get_mdversion:
339  * @self: (in): This #ModulemdModuleStream object.
340  *
341  * Returns: The metadata version of this #ModulemdModuleStream.
342  *
343  * Since: 2.0
344  */
345 guint64
346 modulemd_module_stream_get_mdversion (ModulemdModuleStream *self);
347 
348 
349 /**
350  * modulemd_module_stream_get_module_name:
351  * @self: (in): This #ModulemdModuleStream object.
352  *
353  * Returns: (transfer none): The name of the module.
354  *
355  * Since: 2.0
356  */
357 const gchar *
358 modulemd_module_stream_get_module_name (ModulemdModuleStream *self);
359 
360 
361 /**
362  * modulemd_module_stream_get_stream_name:
363  * @self: (in): This #ModulemdModuleStream object.
364  *
365  * Returns: (transfer none): The name of this stream.
366  *
367  * Since: 2.0
368  */
369 const gchar *
370 modulemd_module_stream_get_stream_name (ModulemdModuleStream *self);
371 
372 
373 /**
374  * modulemd_module_stream_set_version:
375  * @self: (in): This #ModulemdModuleStream object.
376  * @version: (in): The version of this #ModulemdModuleStream.
377  *
378  * Since: 2.0
379  */
380 void
381 modulemd_module_stream_set_version (ModulemdModuleStream *self,
382                                     guint64 version);
383 
384 
385 /**
386  * modulemd_module_stream_get_version:
387  * @self: (in): This #ModulemdModuleStream object.
388  *
389  * Returns: The version of this #ModulemdModuleStream.
390  */
391 guint64
392 modulemd_module_stream_get_version (ModulemdModuleStream *self);
393 
394 /**
395  * modulemd_module_stream_set_context:
396  * @self: (in): This #ModulemdModuleStream object.
397  * @context: (in) (nullable): Module context flag.
398  * The context flag serves to distinguish module builds with the same name,
399  * stream and version and plays an important role in automatic module stream
400  * name expansion.
401  *
402  * Since: 2.0
403  */
404 void
405 modulemd_module_stream_set_context (ModulemdModuleStream *self,
406                                     const gchar *context);
407 
408 
409 /**
410  * modulemd_module_stream_get_context:
411  * @self: (in): This #ModulemdModuleStream object.
412  *
413  * Returns: (transfer none): Module context flag.
414  * The context flag serves to distinguish module builds with the same name,
415  * stream and version and plays an important role in automatic module stream
416  * name expansion.
417  *
418  * Since: 2.0
419  */
420 const gchar *
421 modulemd_module_stream_get_context (ModulemdModuleStream *self);
422 
423 
424 /**
425  * modulemd_module_stream_set_arch:
426  * @self: (in): This #ModulemdModuleStream object.
427  * @arch: (in) (nullable): Module architecture.
428  * Indicates to which processor architecture this #ModulemdModuleStream
429  * applies.
430  *
431  * Since: 2.2
432  */
433 void
434 modulemd_module_stream_set_arch (ModulemdModuleStream *self,
435                                  const gchar *arch);
436 
437 
438 /**
439  * modulemd_module_stream_get_arch:
440  * @self: (in): This #ModulemdModuleStream object.
441  *
442  * Returns: (transfer none): Module architecture object.
443  * Indicates to which processor architecture this #ModulemdModuleStream
444  * applies.
445  *
446  * Since: 2.2
447  */
448 const gchar *
449 modulemd_module_stream_get_arch (ModulemdModuleStream *self);
450 
451 
452 /**
453  * modulemd_module_stream_get_nsvc_as_string: (rename-to modulemd_module_stream_get_nsvc)
454  * @self: (in): This #ModulemdModuleStream object.
455  *
456  * Retrieves a representation of the module name, stream name, version and
457  * context of this #ModulemdModuleStream in the form
458  * `module_name:stream_name:version:context`. Note that this excludes the
459  * architecture of the module stream and as such is not guaranteed to be unique
460  * within a repository.
461  *
462  * Returns: (transfer full): The NSVC (name:stream:version[:context]) of this
463  * module stream. NULL if module name or stream stream is unknown.
464  *
465  * Since: 2.0
466  */
467 gchar *
468 modulemd_module_stream_get_nsvc_as_string (ModulemdModuleStream *self);
469 
470 
471 /**
472  * modulemd_module_stream_get_NSVCA_as_string: (rename-to modulemd_module_stream_get_NSVCA)
473  * @self: (in): This #ModulemdModuleStream object.
474  *
475  * Returns: (transfer full): The NSVCA of this module stream. The returned
476  * format is described
477  * [here](https://docs.fedoraproject.org/en-US/modularity/architecture/consuming/naming-policy/#_forms).
478  * NULL if module name or stream stream is unknown.
479  *
480  * Since: 2.2
481  */
482 gchar *
483 modulemd_module_stream_get_NSVCA_as_string (ModulemdModuleStream *self);
484 
485 
486 /**
487  * modulemd_module_stream_depends_on_stream:
488  * @self: (not nullable): This #ModulemdModuleStream object.
489  * @module_name: (not nullable): A module name.
490  * @stream_name: (not nullable): The stream of the module.
491  *
492  * Returns: TRUE if any of the #ModulemdDependencies objects associated with
493  * this module applies to the provided module name and stream in the runtime
494  * dependencies.
495  *
496  * Since: 2.1
497  *
498  * Stability: unstable
499  */
500 gboolean
501 modulemd_module_stream_depends_on_stream (ModulemdModuleStream *self,
502                                           const gchar *module_name,
503                                           const gchar *stream_name);
504 
505 
506 /**
507  * modulemd_module_stream_build_depends_on_stream:
508  * @self: (not nullable): This #ModulemdModuleStream object.
509  * @module_name: (not nullable): A module name.
510  * @stream_name: (not nullable): The stream of the module.
511  *
512  * Returns: TRUE if any of the #ModulemdDependencies objects associated with
513  * this module applies to the provided module name and stream in the build-time
514  * dependencies.
515  *
516  * Since: 2.1
517  *
518  * Stability: unstable
519  */
520 gboolean
521 modulemd_module_stream_build_depends_on_stream (ModulemdModuleStream *self,
522                                                 const gchar *module_name,
523                                                 const gchar *stream_name);
524 G_END_DECLS
525