From 6956a72b8fc4f13ec6f10539a3c0047568854c22 Mon Sep 17 00:00:00 2001 From: Richard Hughes Date: Thu, 11 Aug 2016 09:55:24 +0100 Subject: Support AppStream merge components These are components that should be merged into matching entries. --- libappstream-glib/as-app.c | 89 ++++++++++++++++++++++++++++++++++++++++ libappstream-glib/as-app.h | 23 +++++++++++ libappstream-glib/as-self-test.c | 2 +- libappstream-glib/as-store.c | 7 +++- 4 files changed, 119 insertions(+), 2 deletions(-) diff --git a/libappstream-glib/as-app.c b/libappstream-glib/as-app.c index 40418e8..d8d1668 100644 --- a/libappstream-glib/as-app.c +++ b/libappstream-glib/as-app.c @@ -87,6 +87,7 @@ typedef struct GPtrArray *vetos; /* of string */ AsAppSourceKind source_kind; AsAppScope scope; + AsAppMergeKind merge_kind; AsAppState state; AsAppTrustFlags trust_flags; AsAppQuirk quirk; @@ -353,6 +354,50 @@ as_app_scope_to_string (AsAppScope scope) return NULL; } +/** + * as_app_merge_kind_from_string: + * @merge_kind: a source kind string + * + * Converts the text representation to an enumerated value. + * + * Return value: A #AsAppMergeKind, e.g. %AS_APP_MERGE_KIND_REPLACE. + * + * Since: 0.6.1 + **/ +AsAppMergeKind +as_app_merge_kind_from_string (const gchar *merge_kind) +{ + if (g_strcmp0 (merge_kind, "none") == 0) + return AS_APP_MERGE_KIND_NONE; + if (g_strcmp0 (merge_kind, "replace") == 0) + return AS_APP_MERGE_KIND_REPLACE; + if (g_strcmp0 (merge_kind, "append") == 0) + return AS_APP_MERGE_KIND_APPEND; + return AS_APP_MERGE_KIND_NONE; +} + +/** + * as_app_merge_kind_to_string: + * @merge_kind: the #AsAppMergeKind, e.g. %AS_APP_MERGE_KIND_REPLACE + * + * Converts the enumerated value to an text representation. + * + * Returns: string version of @merge_kind, or %NULL for unknown + * + * Since: 0.6.1 + **/ +const gchar * +as_app_merge_kind_to_string (AsAppMergeKind merge_kind) +{ + if (merge_kind == AS_APP_MERGE_KIND_NONE) + return "none"; + if (merge_kind == AS_APP_MERGE_KIND_REPLACE) + return "replace"; + if (merge_kind == AS_APP_MERGE_KIND_APPEND) + return "append"; + return NULL; +} + /** * as_app_guess_source_kind: * @filename: a file name @@ -1418,6 +1463,23 @@ as_app_get_scope (AsApp *app) return priv->scope; } +/** + * as_app_get_merge_kind: + * @app: a #AsApp instance. + * + * Gets the merge_kind of the application. + * + * Returns: enumerated value + * + * Since: 0.6.1 + **/ +AsAppMergeKind +as_app_get_merge_kind (AsApp *app) +{ + AsAppPrivate *priv = GET_PRIVATE (app); + return priv->merge_kind; +} + /** * as_app_get_state: * @app: a #AsApp instance. @@ -1927,6 +1989,22 @@ as_app_set_scope (AsApp *app, AsAppScope scope) priv->scope = scope; } +/** + * as_app_set_merge_kind: + * @app: a #AsApp instance. + * @merge_kind: the #AsAppMergeKind. + * + * Sets the merge kind of the application. + * + * Since: 0.6.1 + **/ +void +as_app_set_merge_kind (AsApp *app, AsAppMergeKind merge_kind) +{ + AsAppPrivate *priv = GET_PRIVATE (app); + priv->merge_kind = merge_kind; +} + /** * as_app_set_state: * @app: a #AsApp instance. @@ -3747,6 +3825,14 @@ as_app_node_insert (AsApp *app, GNode *parent, AsNodeContext *ctx) as_app_kind_to_string (priv->kind)); } + /* merge type */ + if (priv->merge_kind != AS_APP_MERGE_KIND_UNKNOWN && + priv->merge_kind != AS_APP_MERGE_KIND_NONE) { + as_node_add_attribute (node_app, + "merge", + as_app_merge_kind_to_string (priv->merge_kind)); + } + /* */ as_node_insert (node_app, "id", priv->id, 0, NULL); @@ -4473,6 +4559,9 @@ as_app_node_parse_full (AsApp *app, GNode *node, AsAppParseFlags flags, as_app_set_kind (app, AS_APP_KIND_GENERIC); else as_app_set_kind (app, as_app_kind_from_string (tmp)); + tmp = as_node_get_attribute (node, "merge"); + if (tmp != NULL) + as_app_set_merge_kind (app, as_app_merge_kind_from_string (tmp)); prio = as_node_get_attribute_as_int (node, "priority"); if (prio != G_MAXINT && prio != 0) as_app_set_priority (app, prio); diff --git a/libappstream-glib/as-app.h b/libappstream-glib/as-app.h index a83e6c3..ddc75fd 100644 --- a/libappstream-glib/as-app.h +++ b/libappstream-glib/as-app.h @@ -391,6 +391,24 @@ typedef enum { AS_APP_SCOPE_LAST } AsAppScope; +/** + * AsAppMergeKind: + * @AS_APP_MERGE_KIND_UNKNOWN: Unknown merge type + * @AS_APP_MERGE_KIND_NONE: No merge to be done + * @AS_APP_MERGE_KIND_REPLACE: Merge components, replacing + * @AS_APP_MERGE_KIND_APPEND: Merge components, appending + * + * The component merge kind. + **/ +typedef enum { + AS_APP_MERGE_KIND_UNKNOWN, /* Since: 0.6.1 */ + AS_APP_MERGE_KIND_NONE, /* Since: 0.6.1 */ + AS_APP_MERGE_KIND_REPLACE, /* Since: 0.6.1 */ + AS_APP_MERGE_KIND_APPEND, /* Since: 0.6.1 */ + /*< private >*/ + AS_APP_MERGE_KIND_LAST +} AsAppMergeKind; + #define AS_APP_ERROR as_app_error_quark () AsApp *as_app_new (void); @@ -403,11 +421,14 @@ const gchar *as_app_kind_to_string (AsAppKind kind); AsAppKind as_app_kind_from_string (const gchar *kind); AsAppScope as_app_scope_from_string (const gchar *scope); const gchar *as_app_scope_to_string (AsAppScope scope); +AsAppMergeKind as_app_merge_kind_from_string (const gchar *merge_kind); +const gchar *as_app_merge_kind_to_string (AsAppMergeKind merge_kind); /* getters */ AsAppKind as_app_get_kind (AsApp *app); AsAppSourceKind as_app_get_source_kind (AsApp *app); AsAppScope as_app_get_scope (AsApp *app); +AsAppMergeKind as_app_get_merge_kind (AsApp *app); AsAppState as_app_get_state (AsApp *app); AsAppTrustFlags as_app_get_trust_flags (AsApp *app); GList *as_app_get_languages (AsApp *app); @@ -488,6 +509,8 @@ void as_app_set_source_kind (AsApp *app, AsAppSourceKind source_kind); void as_app_set_scope (AsApp *app, AsAppScope scope); +void as_app_set_merge_kind (AsApp *app, + AsAppMergeKind merge_kind); void as_app_set_state (AsApp *app, AsAppState state); void as_app_set_trust_flags (AsApp *app, diff --git a/libappstream-glib/as-self-test.c b/libappstream-glib/as-self-test.c index 2c7497d..6ec5abd 100644 --- a/libappstream-glib/as-self-test.c +++ b/libappstream-glib/as-self-test.c @@ -1446,7 +1446,7 @@ as_test_app_func (void) GString *xml; gboolean ret; const gchar *src = - "\n" + "\n" "org.gnome.Software.desktop\n" "gnome-software\n" "gnome-software-src\n" diff --git a/libappstream-glib/as-store.c b/libappstream-glib/as-store.c index c8ef6c2..f681aae 100644 --- a/libappstream-glib/as-store.c +++ b/libappstream-glib/as-store.c @@ -925,9 +925,14 @@ as_store_add_app (AsStore *store, AsApp *app) /* use some hacky logic to support older files */ if ((priv->add_flags & AS_STORE_ADD_FLAG_USE_MERGE_HEURISTIC) > 0 && _as_app_is_perhaps_merge_component (app)) { - as_app_add_quirk (app, AS_APP_QUIRK_MATCH_ANY_PREFIX); + as_app_set_merge_kind (app, AS_APP_MERGE_KIND_APPEND); } + /* FIXME: deal with the differences between append and replace */ + if (as_app_get_merge_kind (app) == AS_APP_MERGE_KIND_APPEND || + as_app_get_merge_kind (app) == AS_APP_MERGE_KIND_REPLACE) + as_app_add_quirk (app, AS_APP_QUIRK_MATCH_ANY_PREFIX); + /* this is a special merge component */ if (as_app_has_quirk (app, AS_APP_QUIRK_MATCH_ANY_PREFIX)) { apps = g_hash_table_lookup (priv->hash_merge_id, id); -- cgit v1.2.1