/
githubmirror
/
libmodulemd
Обзор
Документация
Войти
/
githubmirror
/
libmodulemd
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
modulemd/modulemd-buildopts.c
627 строк
17 KB
Petr Písař
Replace "whitelist" with allowed_build_names
09 май 2023, 13:35
09 май 2023, 13:35
5341acf
Код
Авторство
О чём код?
/* * This file is part of libmodulemd * Copyright (C) 2018 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>. */ #include <glib.h> #include <yaml.h> #include "modulemd-buildopts.h" #include "private/glib-extensions.h" #include "private/modulemd-buildopts-private.h" #include "private/modulemd-util.h" #include "private/modulemd-yaml.h" #define B_DEFAULT_STRING "__BUILDOPTS_RPM_MACROS_UNSET__" struct _ModulemdBuildopts { GObject parent_instance; gchar *rpm_macros; GHashTable *allowed_build_names; GHashTable *arches; }; G_DEFINE_TYPE (ModulemdBuildopts, modulemd_buildopts, G_TYPE_OBJECT) enum { PROP_0, PROP_RPM_MACROS, N_PROPS }; static GParamSpec *properties[N_PROPS]; gboolean modulemd_buildopts_equals (ModulemdBuildopts *self_1, ModulemdBuildopts *self_2) { if (!self_1 && !self_2) { return TRUE; } if (!self_1 || !self_2) { return FALSE; } g_return_val_if_fail (MODULEMD_IS_BUILDOPTS (self_1), FALSE); g_return_val_if_fail (MODULEMD_IS_BUILDOPTS (self_2), FALSE); if (g_strcmp0 (self_1->rpm_macros, self_2->rpm_macros) != 0) { return FALSE; } if (!modulemd_hash_table_sets_are_equal (self_1->allowed_build_names, self_2->allowed_build_names)) { return FALSE; } if (!modulemd_hash_table_sets_are_equal (self_1->arches, self_2->arches)) { return FALSE; } return TRUE; } gint modulemd_buildopts_compare (ModulemdBuildopts *self_1, ModulemdBuildopts *self_2) { gint cmp; if (!self_1 && !self_2) { return 0; } if (!self_1) { return -1; } if (!self_2) { return 1; } g_return_val_if_fail (MODULEMD_IS_BUILDOPTS (self_1), 1); g_return_val_if_fail (MODULEMD_IS_BUILDOPTS (self_2), -1); cmp = g_strcmp0 (self_1->rpm_macros, self_2->rpm_macros); if (cmp != 0) { return cmp; } cmp = modulemd_hash_table_compare ( self_1->allowed_build_names, self_2->allowed_build_names, NULL); if (cmp != 0) { return cmp; } cmp = modulemd_hash_table_compare (self_1->arches, self_2->arches, NULL); if (cmp != 0) { return cmp; } return 0; } ModulemdBuildopts * modulemd_buildopts_new (void) { return g_object_new (MODULEMD_TYPE_BUILDOPTS, NULL); } ModulemdBuildopts * modulemd_buildopts_copy (ModulemdBuildopts *self) { g_autoptr (ModulemdBuildopts) copy = NULL; g_return_val_if_fail (MODULEMD_IS_BUILDOPTS (self), NULL); copy = modulemd_buildopts_new (); modulemd_buildopts_set_rpm_macros (copy, modulemd_buildopts_get_rpm_macros (self)); MODULEMD_REPLACE_SET (copy->allowed_build_names, self->allowed_build_names); MODULEMD_REPLACE_SET (copy->arches, self->arches); return g_steal_pointer (©); } static void modulemd_buildopts_finalize (GObject *object) { ModulemdBuildopts *self = (ModulemdBuildopts *)object; g_clear_pointer (&self->rpm_macros, g_free); g_clear_pointer (&self->allowed_build_names, g_hash_table_unref); g_clear_pointer (&self->arches, g_hash_table_unref); G_OBJECT_CLASS (modulemd_buildopts_parent_class)->finalize (object); } void modulemd_buildopts_set_rpm_macros (ModulemdBuildopts *self, const gchar *rpm_macros) { g_return_if_fail (MODULEMD_IS_BUILDOPTS (self)); g_clear_pointer (&self->rpm_macros, g_free); self->rpm_macros = g_strdup (rpm_macros); g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_RPM_MACROS]); } const gchar * modulemd_buildopts_get_rpm_macros (ModulemdBuildopts *self) { g_return_val_if_fail (MODULEMD_IS_BUILDOPTS (self), NULL); return self->rpm_macros; } void modulemd_buildopts_add_rpm_to_whitelist (ModulemdBuildopts *self, const gchar *rpm) { g_return_if_fail (MODULEMD_IS_BUILDOPTS (self)); g_hash_table_add (self->allowed_build_names, g_strdup (rpm)); } void modulemd_buildopts_remove_rpm_from_whitelist (ModulemdBuildopts *self, const gchar *rpm) { g_return_if_fail (MODULEMD_IS_BUILDOPTS (self)); g_hash_table_remove (self->allowed_build_names, rpm); } void modulemd_buildopts_clear_rpm_whitelist (ModulemdBuildopts *self) { g_return_if_fail (MODULEMD_IS_BUILDOPTS (self)); g_hash_table_remove_all (self->allowed_build_names); } GStrv modulemd_buildopts_get_rpm_whitelist_as_strv (ModulemdBuildopts *self) { g_return_val_if_fail (MODULEMD_IS_BUILDOPTS (self), NULL); return modulemd_ordered_str_keys_as_strv (self->allowed_build_names); } void modulemd_buildopts_add_arch (ModulemdBuildopts *self, const gchar *arch) { g_return_if_fail (MODULEMD_IS_BUILDOPTS (self)); g_hash_table_add (self->arches, g_strdup (arch)); } void modulemd_buildopts_remove_arch (ModulemdBuildopts *self, const gchar *arch) { g_return_if_fail (MODULEMD_IS_BUILDOPTS (self)); g_hash_table_remove (self->arches, arch); } void modulemd_buildopts_clear_arches (ModulemdBuildopts *self) { g_return_if_fail (MODULEMD_IS_BUILDOPTS (self)); g_hash_table_remove_all (self->arches); } GStrv modulemd_buildopts_get_arches_as_strv (ModulemdBuildopts *self) { g_return_val_if_fail (MODULEMD_IS_BUILDOPTS (self), NULL); return modulemd_ordered_str_keys_as_strv (self->arches); } static void modulemd_buildopts_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { ModulemdBuildopts *self = MODULEMD_BUILDOPTS (object); switch (prop_id) { case PROP_RPM_MACROS: g_value_set_string (value, modulemd_buildopts_get_rpm_macros (self)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); } } static void modulemd_buildopts_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { ModulemdBuildopts *self = MODULEMD_BUILDOPTS (object); switch (prop_id) { case PROP_RPM_MACROS: modulemd_buildopts_set_rpm_macros (self, g_value_get_string (value)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); } } static void modulemd_buildopts_class_init (ModulemdBuildoptsClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->finalize = modulemd_buildopts_finalize; object_class->get_property = modulemd_buildopts_get_property; object_class->set_property = modulemd_buildopts_set_property; properties[PROP_RPM_MACROS] = g_param_spec_string ( "rpm-macros", "Rpm Macros", "A string containing RPM build macros in the form that they would appear " "in an RPM macros file on-disk.", B_DEFAULT_STRING, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); g_object_class_install_properties (object_class, N_PROPS, properties); } static void modulemd_buildopts_init (ModulemdBuildopts *self) { self->allowed_build_names = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); self->arches = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); } /* === YAML Functions === */ static gboolean modulemd_buildopts_parse_rpm_buildopts (yaml_parser_t *parser, ModulemdBuildopts *buildopts, gboolean strict, GError **error); ModulemdBuildopts * modulemd_buildopts_parse_yaml (yaml_parser_t *parser, gboolean strict, GError **error) { MODULEMD_INIT_TRACE (); MMD_INIT_YAML_EVENT (event); gboolean done = FALSE; gboolean in_map = FALSE; g_autoptr (ModulemdBuildopts) buildopts = NULL; g_autoptr (GError) nested_error = NULL; g_return_val_if_fail (error == NULL || *error == NULL, FALSE); buildopts = modulemd_buildopts_new (); while (!done) { YAML_PARSER_PARSE_WITH_EXIT (parser, &event, error); switch (event.type) { case YAML_MAPPING_START_EVENT: in_map = TRUE; break; case YAML_MAPPING_END_EVENT: in_map = FALSE; done = TRUE; break; case YAML_SCALAR_EVENT: if (!in_map) { MMD_YAML_ERROR_EVENT_EXIT_BOOL ( error, event, "Missing mapping in buildopts"); } if (g_str_equal ((const gchar *)event.data.scalar.value, "rpms")) { if (!modulemd_buildopts_parse_rpm_buildopts ( parser, buildopts, strict, &nested_error)) { g_propagate_error (error, nested_error); return NULL; } } else if (g_str_equal ((const gchar *)event.data.scalar.value, "arches")) { g_hash_table_unref (buildopts->arches); buildopts->arches = modulemd_yaml_parse_string_set (parser, &nested_error); if (buildopts->arches == NULL) { MMD_YAML_ERROR_EVENT_EXIT_BOOL ( error, event, "Failed to parse arches list in buildopts: %s", nested_error->message); } } else { SKIP_UNKNOWN (parser, NULL, "Unexpected key in buildopts: %s", (const gchar *)event.data.scalar.value); break; } break; default: MMD_YAML_ERROR_EVENT_EXIT (error, event, "Unexpected YAML event in buildopts: %s", mmd_yaml_get_event_name (event.type)); break; } yaml_event_delete (&event); } return g_steal_pointer (&buildopts); } static gboolean modulemd_buildopts_parse_rpm_buildopts (yaml_parser_t *parser, ModulemdBuildopts *buildopts, gboolean strict, GError **error) { MODULEMD_INIT_TRACE (); MMD_INIT_YAML_EVENT (event); gboolean done = FALSE; gboolean in_map = FALSE; g_autofree gchar *value = NULL; g_autoptr (GError) nested_error = NULL; /* Read in RPM attributes */ while (!done) { YAML_PARSER_PARSE_WITH_EXIT_BOOL (parser, &event, error); switch (event.type) { case YAML_MAPPING_START_EVENT: in_map = TRUE; break; case YAML_MAPPING_END_EVENT: in_map = FALSE; done = TRUE; break; case YAML_SCALAR_EVENT: if (!in_map) { MMD_YAML_ERROR_EVENT_EXIT_BOOL ( error, event, "Missing mapping in buildopts rpms entry"); } if (g_str_equal ((const gchar *)event.data.scalar.value, "whitelist")) { g_hash_table_unref (buildopts->allowed_build_names); buildopts->allowed_build_names = modulemd_yaml_parse_string_set (parser, &nested_error); if (buildopts->allowed_build_names == NULL) { MMD_YAML_ERROR_EVENT_EXIT_BOOL ( error, event, "Failed to parse whitelist list in buildopts rpms: %s", nested_error->message); } } else if (g_str_equal ((const gchar *)event.data.scalar.value, "macros")) { value = modulemd_yaml_parse_string (parser, &nested_error); if (!value) { MMD_YAML_ERROR_EVENT_EXIT_BOOL ( error, event, "Failed to parse rpm_macros in buildopts: %s", nested_error->message); } modulemd_buildopts_set_rpm_macros (buildopts, value); g_clear_pointer (&value, g_free); } else { SKIP_UNKNOWN (parser, FALSE, "Unexpected key in buildopts body: %s", (const gchar *)event.data.scalar.value); } break; default: MMD_YAML_ERROR_EVENT_EXIT_BOOL ( error, event, "Unexpected YAML event in rpm buildopts: %s", mmd_yaml_get_event_name (event.type)); break; } yaml_event_delete (&event); } return TRUE; } gboolean modulemd_buildopts_emit_yaml (ModulemdBuildopts *self, yaml_emitter_t *emitter, GError **error) { MODULEMD_INIT_TRACE (); int ret; g_auto (GStrv) list = NULL; g_autoptr (GError) nested_error = NULL; MMD_INIT_YAML_EVENT (event); ret = mmd_emitter_scalar ( emitter, "rpms", YAML_PLAIN_SCALAR_STYLE, &nested_error); if (!ret) { g_propagate_prefixed_error ( error, g_steal_pointer (&nested_error), "Failed to emit buildopts 'rpms' constant: "); return FALSE; } ret = mmd_emitter_start_mapping ( emitter, YAML_BLOCK_MAPPING_STYLE, &nested_error); if (!ret) { g_propagate_prefixed_error (error, g_steal_pointer (&nested_error), "Failed to start buildopts mapping: "); return FALSE; } if (modulemd_buildopts_get_rpm_macros (self) != NULL) { ret = mmd_emitter_scalar ( emitter, "macros", YAML_PLAIN_SCALAR_STYLE, &nested_error); if (!ret) { g_propagate_prefixed_error (error, g_steal_pointer (&nested_error), "Failed to emit buildopts macros key: "); return FALSE; } ret = mmd_emitter_scalar (emitter, modulemd_buildopts_get_rpm_macros (self), YAML_FOLDED_SCALAR_STYLE, &nested_error); if (!ret) { g_propagate_prefixed_error ( error, g_steal_pointer (&nested_error), "Failed to emit buildopts macros value: "); return FALSE; } } if (g_hash_table_size (self->allowed_build_names) != 0) { ret = mmd_emitter_scalar ( emitter, "whitelist", YAML_PLAIN_SCALAR_STYLE, &nested_error); if (!ret) { g_propagate_prefixed_error ( error, g_steal_pointer (&nested_error), "Failed to emit buildopts whitelist key: "); return FALSE; } list = modulemd_buildopts_get_rpm_whitelist_as_strv (self); ret = mmd_emitter_strv ( emitter, YAML_BLOCK_SEQUENCE_STYLE, list, &nested_error); if (!ret) { g_propagate_prefixed_error (error, g_steal_pointer (&nested_error), "Failed to emit buildopts whitelist: "); return FALSE; } g_clear_pointer (&list, g_strfreev); } ret = mmd_emitter_end_mapping (emitter, &nested_error); if (!ret) { g_propagate_prefixed_error (error, g_steal_pointer (&nested_error), "Failed to end buildopts mapping"); return FALSE; } if (g_hash_table_size (self->arches) != 0) { ret = mmd_emitter_scalar ( emitter, "arches", YAML_PLAIN_SCALAR_STYLE, &nested_error); if (!ret) { g_propagate_prefixed_error (error, g_steal_pointer (&nested_error), "Failed to emit buildopts arches key: "); return FALSE; } list = modulemd_buildopts_get_arches_as_strv (self); ret = mmd_emitter_strv ( emitter, YAML_FLOW_SEQUENCE_STYLE, list, &nested_error); if (!ret) { g_propagate_prefixed_error (error, g_steal_pointer (&nested_error), "Failed to emit buildopts arches: "); return FALSE; } g_clear_pointer (&list, g_strfreev); } return TRUE; }