/
githubmirror
/
libmodulemd
Обзор
Документация
Войти
/
githubmirror
/
libmodulemd
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
modulemd/include/modulemd-2.0/modulemd.h
444 строки
17 KB
Stephen Gallagher
DOC: Fix DNF example
22 сен 2021, 10:17
22 сен 2021, 10:17
f2d7501
Код
Авторство
О чём код?
/* * This file is part of libmodulemd * Copyright (C) 2018-2020 Red Hat, Inc. * * Fedora-License-Identifier: MIT * SPDX-2.0-License-Identifier: MIT * SPDX-3.0-License-Identifier: MIT * * This program is free software. * For more information on the license, see COPYING. * For more information on free software, see <https://www.gnu.org/philosophy/free-sw.en.html>. */ #pragma once #include "modulemd-build-config.h" #include "modulemd-buildopts.h" #include "modulemd-component-module.h" #include "modulemd-component-rpm.h" #include "modulemd-component.h" #include "modulemd-compression.h" #include "modulemd-defaults-v1.h" #include "modulemd-defaults.h" #include "modulemd-dependencies.h" #include "modulemd-deprecated.h" #include "modulemd-errors.h" #include "modulemd-module-index-merger.h" #include "modulemd-module-index.h" #include "modulemd-module-stream-v1.h" #include "modulemd-module-stream-v2.h" #include "modulemd-module-stream.h" #include "modulemd-module.h" #include "modulemd-packager-v3.h" #include "modulemd-profile.h" #include "modulemd-rpm-map-entry.h" #include "modulemd-service-level.h" #include "modulemd-subdocument-info.h" #include "modulemd-translation-entry.h" #include "modulemd-translation.h" G_BEGIN_DECLS /** * SECTION: modulemd * @title: Modulemd * @stability: stable * @short_description: User's Guide for libmodulemd * * # Working with repodata (DNF use-case) * The libmodulemd API provides a number of convenience tools for interacting * with repodata (that is, streams of YAML that contains information on multiple * streams, default data and translations). The documentation will use two * repositories, called "fedora" and "updates" for demonstrative purposes. It * will assume that the content of the YAML module metadata from those two * repositories have been loaded into string variables `fedora_yaml` and * `updates_yaml`, respectively. * * Tools such as DNF that are consuming data from a repository should always * set `strict=False`, so that it can safely handle minor, * backwards-compatible changes to the modulemd format. * * First step is to load the metadata from these two repositories into * #ModulemdModuleIndex objects. This is done as follows: * * In C: * |[<!-- language="C" --> * ModulemdModuleIndex *fedora_index = modulemd_module_index_new (); * gboolean ret = modulemd_module_index_update_from_string ( * fedora_index, fedora_yaml, FALSE, &failures, &error); * * ModulemdModuleIndex *updates_index = modulemd_module_index_new (); * gboolean ret2 = modulemd_module_index_update_from_string ( * updates_index, updates_yaml, FALSE, &failures, &error); * ]| * * In Python: * |[<!-- language="Python" --> * fedora_index = Modulemd.ModuleIndex.new() * ret, failures = fedora_index.update_from_string(fedora_yaml, False) * * updates_index = Modulemd.ModuleIndex.new() * ret, failures = updates_index.update_from_string(updates_yaml, False) * ]| * * The @failures are a list of subdocuments in the YAML that failed parsing, * along with the reason they failed. Hence, by checking the return value of * @failures we will know if the YAML parsing was successful or not. * * Since it doesn't really make sense to view the contents from separate * repositories in isolation (in most cases), the next step is to merge the two * indexes into a combined one: * * In C: * |[<!-- language="C" --> * ModulemdModuleIndexMerger *merger = modulemd_module_index_merger_new (); * * modulemd_module_index_merger_associate_index (merger, fedora_index, 0); * modulemd_module_index_merger_associate_index (merger, updates_index, 0); * * ModulemdModuleIndex *merged_index = * modulemd_module_index_merger_resolve (merger, &error); * ]| * * In Python: * |[<!-- language="Python" --> * merger = Modulemd.ModuleIndexMerger.new() * * merger.associate_index(fedora_index, 0) * merger.associate_index(updates_index, 0) * * merged_index = merger.resolve() * ]| * * At this point, you now have either a complete view of the merged repodata, * or else have received an error describing why the merge was unable to * complete successfully. Additionally, it should be noted that the combined * metadata in any #ModulemdModuleIndex will have all of its component parts * upgraded to match the highest version of those objects seen. So for example * if the repodata has a mix of v1 and v2 #ModulemdModuleStream objects, the * index will contain only v2 objects (with the v1 objects automatically * upgraded internally). * * Now, we can start operating on the retrieved data. This guide will * give only a brief overview of the most common operations. See the API * specification for a full list of information that can be retrieved. * * ## Discover the default stream for a particular module. * * In C: * |[<!-- language="C" --> * ModulemdModule *module = * modulemd_module_index_get_module (merged_index, "modulename"); * ModulemdDefaults *defaults = modulemd_module_get_defaults (module); * if (defaults) * { * printf ("Default stream for modulename is %s\n", * modulemd_defaults_v1_get_default_stream ( * MODULEMD_DEFAULTS_V1 (defaults), NULL)); * } * ]| * * In Python: * |[<!-- language="Python" --> * module = merged_index.get_module("modulename") * defaults = module.get_defaults() * print("Default stream for modulename is %s" % defaults.get_default_stream()) * ]| * * ## Get the list of RPMs defining the public API for a particular module NSVCA * First, query the #ModulemdModuleIndex for the module with a given name. * * In C: * |[<!-- language="C" --> * ModulemdModule *module = * modulemd_module_index_get_module (merged_index, "modulename"); * ]| * * In Python: * |[<!-- language="Python" --> * module = merged_index.get_module("modulename") * ]| * * Then, query the #ModulemdModule for the #ModulemdModuleStream associated with the * provided NSVCA (name-stream-version-context-architecture identifier). * * In C: * |[<!-- language="C" --> * ModulemdModuleStream *stream = modulemd_module_get_stream_by_NSVCA ( * module, "modulestream", 0, "deadbeef", "coolarch", &error); * ]| * * In Python: * |[<!-- language="Python" --> * stream = module.get_stream_by_NSVCA("modulestream", 0, "deadbeef", "coolarch") * ]| * * Lastly, read the RPM API from the #ModulemdModuleStream. Here, `api_list` is * a list of strings containing package names. * * In C: * |[<!-- language="C" --> * GStrv api_list = modulemd_module_stream_v2_get_rpm_api_as_strv ( * MODULEMD_MODULE_STREAM_V2 (stream)); * ]| * * In Python: * |[<!-- language="Python" --> * api_list = stream.get_rpm_api() * ]| * * Also note that in addition to accessor API methods, many objects also have * properties that can be accessed directly. * * In C: * |[<!-- language="C" --> * printf ("Documentation for module stream is at %s\n", * modulemd_module_stream_v2_get_documentation ( * MODULEMD_MODULE_STREAM_V2 (stream))); * g_autofree gchar *doc; * g_object_get (MODULEMD_MODULE_STREAM_V2 (stream), "documentation", &doc, NULL); * printf ("Documentation for module stream is at %s\n", doc); * ]| * * In Python: * |[<!-- language="Python" --> * print("Documentation for module stream is at %s" % stream.get_documentation()) * print("Documentation for module stream is at %s" % stream.props.documentation) * ]| * * ## Retrieve the modular runtime dependencies for a particular module NSVCA * * In C: * |[<!-- language="C" --> * ModulemdModule *module = * modulemd_module_index_get_module (merged_index, "modulename"); * ModulemdModuleStream *stream = modulemd_module_get_stream_by_NSVCA ( * module, "modulestream", 0, "deadbeef", "coolarch", &error); * GPtrArray *deps_list = modulemd_module_stream_v2_get_dependencies ( * MODULEMD_MODULE_STREAM_V2 (stream)); * * for (gint i = 0; i < deps_list->len; i++) * { * GStrv depmodules_list = * modulemd_dependencies_get_runtime_modules_as_strv ( * g_ptr_array_index (deps_list, i)); * * for (gint j = 0; j < g_strv_length (depmodules_list); j++) * { * GStrv depstreams_list = * modulemd_dependencies_get_runtime_streams_as_strv ( * g_ptr_array_index (deps_list, i), depmodules_list[j]); * * for (gint k = 0; k < g_strv_length (depstreams_list); k++) * { * // do stuff with depmodules_list[j], depstreams_list[k] * } * } * } * ]| * * In Python: * |[<!-- language="Python" --> * module = merged_index.get_module("modulename") * stream = module.get_stream_by_NSVCA("modulestream", 0, "deadbeef", "coolarch") * deps_list = stream.get_dependencies() * for dep in deps_list: * depmodules_list = dep.get_runtime_modules() * for depmod in depmodules_list: * depstream_list = dep.get_runtime_streams(depmod) * for depstream in depstream_list: * # do stuff with depmod, depstream * ]| * * # Working with a single module stream (Packager/MBS use-case) * One limitation of the #ModulemdModuleIndex format is that it requires that * all module streams loaded into it have both a name and a stream name. * This however is not possible when dealing with streams such as a packager * would be using (since the build-system auto-generates the module name and * stream name from the git repository information. In this case, we need to * work with a single module stream document at a time. For this, we will * use the #ModulemdModuleStream interface. * * This example will assume that the module name and stream name have * already been determined from the repodata and that they are stored in * string variables named `module_name` and `stream_name`, respectively. * * In Python: * |[<!-- language="Python" --> * stream = Modulemd.ModuleStream.read_file( * "/path/to/module_name.yaml", True, module_name, stream_name * ) * v2_stream = stream.upgrade(Modulemd.ModuleStreamVersionEnum.TWO) * v2_stream.validate() * ]| * In the example above, we upgraded the stream to v2, in case we were reading * from v1 metadata. This will allow us to avoid having to manage multiple * code-paths and support only the latest we understand. After that, it calls * validate() to ensure that the content that was read in was valid both * syntactically and referentially. * * Also available is `Modulemd.ModuleStreamVersionEnum.LATEST` which will * always represent the highest-supported version of the * #ModulemdModuleStream metadata format. This may change at any time. */ /** * modulemd_get_version: * * Returns: (transfer none): A string describing the version of libmodulemd. * * Since: 2.0 */ const gchar * modulemd_get_version (void); /** * modulemd_load_file: * @yaml_file: (in): A YAML file containing the module metadata and other * related information such as default streams. * @error: (out): A #GError containing additional information if this function * fails in a way that prevents program continuation. * * This is a convenience function that is a wrapper around * modulemd_module_index_new() and modulemd_module_index_update_from_file() * with `strict=False`. * * It will return the imported module metadata if all subdocuments are * parseable and valid. If any part of the document is unreadable or fails * validation, it will return NULL and set @error appropriately. If you need * more detail about which parts of the document failed, use the lower-level * functions. * * Returns: (transfer full): A newly-allocated #ModulemdModuleIndex object * initialized with the content from @yaml_file. Returns NULL and sets @error * if the file is not completely valid. * * Since: 2.10 */ ModulemdModuleIndex * modulemd_load_file (const gchar *yaml_file, GError **error); /** * modulemd_load_string: * @yaml_string: (in): A YAML string containing the module metadata and other * related information such as default streams. * @error: (out): A #GError containing additional information if this function * fails in a way that prevents program continuation. * * This is a convenience function that is a wrapper around * modulemd_module_index_new() and modulemd_module_index_update_from_string() * with `strict=False`. * * It will return the imported module metadata if all subdocuments are * parseable and valid. If any part of the document is unreadable or fails * validation, it will return NULL and set @error appropriately. If you need * more detail about which parts of the document failed, use the lower-level * functions. * * Returns: (transfer full): A newly-allocated #ModulemdModuleIndex object * initialized with the content from @yaml_string. Returns NULL and sets @error * if the metadata is not completely valid. * * Since: 2.10 */ ModulemdModuleIndex * modulemd_load_string (const gchar *yaml_string, GError **error); /** * modulemd_read_packager_file: (skip) * @yaml_path: (in): A path to a YAML file containing a packager document. * @object: (out): (transfer full): A newly allocated #ModulemdModuleStreamV2 or * #ModulemdPackagerV3 object initialized with the content from @yaml_path. * @error: (out): A #GError containing additional information if this function * fails in a way that prevents program continuation. * * Returns: @MODULEMD_TYPE_MODULE_STREAM_V2, @MODULEMD_TYPE_PACKAGER_V3, or * @G_TYPE_INVALID. Returns the matching GObject through the @object parameter. * If the return value is @G_TYPE_INVALID, returns the reason as @error. * * Since: 2.11 */ GType modulemd_read_packager_file (const gchar *yaml_path, GObject **object, GError **error); /** * modulemd_read_packager_file_ext: (rename-to modulemd_read_packager_file) * @yaml_path: (in): A path to a YAML file containing a packager document. * @object: (out): (transfer full): A newly allocated #ModulemdModuleStreamV2 or * #ModulemdPackagerV3 object initialized with the content from @yaml_path. * @module_name: (in) (nullable): An optional module name to override the * document on disk. Mostly useful in cases where the name is being * auto-detected from git. * @module_stream: (in) (nullable): An optional module stream name to override * the document on disk. Mostly useful in cases where the name is being * auto-detected from git. * @error: (out): A #GError containing additional information if this function * fails in a way that prevents program continuation. * * Returns: @MODULEMD_TYPE_MODULE_STREAM_V2, @MODULEMD_TYPE_PACKAGER_V3, or * @G_TYPE_INVALID. Returns the matching GObject through the @object parameter. * If the return value is @G_TYPE_INVALID, returns the reason as @error. * * Since: 2.11 */ GType modulemd_read_packager_file_ext (const gchar *yaml_path, GObject **object, const gchar *module_name, const gchar *module_stream, GError **error); /** * modulemd_read_packager_string: (skip) * @yaml_string: (in): A YAML string containing a packager document. * @object: (out): (transfer full): A newly allocated #ModulemdModuleStreamV2 or * #ModulemdPackagerV3 object initialized with the content from @yaml_string. * @error: (out): A #GError containing additional information if this function * fails in a way that prevents program continuation. * * Returns: @MODULEMD_TYPE_MODULE_STREAM_V2, @MODULEMD_TYPE_PACKAGER_V3, or * @G_TYPE_INVALID. Returns the matching GObject through the @object parameter. * If the return value is @G_TYPE_INVALID, returns the reason as @error. * * Since: 2.11 */ GType modulemd_read_packager_string (const gchar *yaml_string, GObject **object, GError **error); /** * modulemd_read_packager_string_ext: (rename-to modulemd_read_packager_string) * @yaml_string: (in): A YAML string containing a packager document. * @object: (out): (transfer full): A newly allocated #ModulemdModuleStreamV2 or * #ModulemdPackagerV3 object initialized with the content from @yaml_string. * @module_name: (in) (nullable): An optional module name to override the * document on disk. Mostly useful in cases where the name is being * auto-detected from git. * @module_stream: (in) (nullable): An optional module stream name to override * the document on disk. Mostly useful in cases where the name is being * auto-detected from git. * @error: (out): A #GError containing additional information if this function * fails in a way that prevents program continuation. * * Returns: @MODULEMD_TYPE_MODULE_STREAM_V2, @MODULEMD_TYPE_PACKAGER_V3, or * @G_TYPE_INVALID. Returns the matching GObject through the @object parameter. * If the return value is @G_TYPE_INVALID, returns the reason as @error. * * Since: 2.11 */ GType modulemd_read_packager_string_ext (const gchar *yaml_string, GObject **object, const gchar *module_name, const gchar *module_stream, GError **error); G_END_DECLS