summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Hughes <richard@hughsie.com>2016-08-11 09:55:24 +0100
committerRichard Hughes <richard@hughsie.com>2016-08-11 09:55:24 +0100
commit6956a72b8fc4f13ec6f10539a3c0047568854c22 (patch)
tree9c3cd2eef9300b524c5312e66cb1273c068dd303
parent3473823d2d023ee4b3dd28b44e0a7c1d97bd85c4 (diff)
downloadappstream-glib-6956a72b8fc4f13ec6f10539a3c0047568854c22.tar.gz
Support AppStream merge components
These are components that should be merged into matching entries.
-rw-r--r--libappstream-glib/as-app.c89
-rw-r--r--libappstream-glib/as-app.h23
-rw-r--r--libappstream-glib/as-self-test.c2
-rw-r--r--libappstream-glib/as-store.c7
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;
@@ -354,6 +355,50 @@ as_app_scope_to_string (AsAppScope scope)
}
/**
+ * 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
*
@@ -1419,6 +1464,23 @@ as_app_get_scope (AsApp *app)
}
/**
+ * 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.
*
@@ -1928,6 +1990,22 @@ as_app_set_scope (AsApp *app, AsAppScope 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.
* @state: the #AsAppState.
@@ -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));
+ }
+
/* <id> */
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 =
- "<component type=\"desktop\" priority=\"-4\">\n"
+ "<component type=\"desktop\" merge=\"replace\" priority=\"-4\">\n"
"<id>org.gnome.Software.desktop</id>\n"
"<pkgname>gnome-software</pkgname>\n"
"<source_pkgname>gnome-software-src</source_pkgname>\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);