[gnome-software] trivial: Allow deduplicating using the provides ID as additional keys
- From: Richard Hughes <rhughes src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-software] trivial: Allow deduplicating using the provides ID as additional keys
- Date: Fri, 28 Sep 2018 11:36:19 +0000 (UTC)
commit 3c6509b5254c9572681ae53e34b82183be4067ce
Author: Richard Hughes <richard hughsie com>
Date: Fri Sep 28 11:30:32 2018 +0100
trivial: Allow deduplicating using the provides ID as additional keys
This allows us to deduplicate firefox.desktop and org.mozilla.Firefox
lib/gs-app-list-private.h | 2 +
lib/gs-app-list.c | 115 +++++++++++++++++++++++++++++-----------------
lib/gs-self-test.c | 24 +++++++++-
3 files changed, 97 insertions(+), 44 deletions(-)
---
diff --git a/lib/gs-app-list-private.h b/lib/gs-app-list-private.h
index 30223f97..0ae8405f 100644
--- a/lib/gs-app-list-private.h
+++ b/lib/gs-app-list-private.h
@@ -55,6 +55,7 @@ typedef enum {
* @GS_APP_LIST_FILTER_FLAG_KEY_SOURCE: Filter by default source
* @GS_APP_LIST_FILTER_FLAG_KEY_VERSION: Filter by version
* @GS_APP_LIST_FILTER_FLAG_PREFER_INSTALLED: Prefer installed applications
+ * @GS_APP_LIST_FILTER_FLAG_KEY_ID_PROVIDES: Filter using the provides ID
*
* Flags to use when filtering. The priority of eash #GsApp is used to choose
* which application object to keep.
@@ -65,6 +66,7 @@ typedef enum {
GS_APP_LIST_FILTER_FLAG_KEY_SOURCE = 1 << 1,
GS_APP_LIST_FILTER_FLAG_KEY_VERSION = 1 << 2,
GS_APP_LIST_FILTER_FLAG_PREFER_INSTALLED= 1 << 3,
+ GS_APP_LIST_FILTER_FLAG_KEY_ID_PROVIDES = 1 << 4,
/*< private >*/
GS_APP_LIST_FILTER_FLAG_LAST
} GsAppListFilterFlags;
diff --git a/lib/gs-app-list.c b/lib/gs-app-list.c
index 640e1301..eab044d9 100644
--- a/lib/gs-app-list.c
+++ b/lib/gs-app-list.c
@@ -742,6 +742,55 @@ gs_app_list_filter_app_is_better (GsApp *app, GsApp *found, GsAppListFilterFlags
return FALSE;
}
+static GPtrArray *
+gs_app_list_filter_app_get_keys (GsApp *app, GsAppListFilterFlags flags)
+{
+ GPtrArray *keys = g_ptr_array_new_with_free_func (g_free);
+ g_autoptr(GString) key = NULL;
+
+ /* just use the unique ID */
+ if (flags == GS_APP_LIST_FILTER_FLAG_NONE) {
+ if (gs_app_get_unique_id (app) != NULL)
+ g_ptr_array_add (keys, g_strdup (gs_app_get_unique_id (app)));
+ return keys;
+ }
+
+ /* use the ID and any provides */
+ if (flags & GS_APP_LIST_FILTER_FLAG_KEY_ID_PROVIDES) {
+ GPtrArray *provides = gs_app_get_provides (app);
+ g_ptr_array_add (keys, g_strdup (gs_app_get_id (app)));
+ for (guint i = 0; i < provides->len; i++) {
+ AsProvide *prov = g_ptr_array_index (provides, i);
+ if (as_provide_get_kind (prov) != AS_PROVIDE_KIND_ID)
+ continue;
+ g_ptr_array_add (keys, g_strdup (as_provide_get_value (prov)));
+ }
+ return keys;
+ }
+
+ /* specific compound type */
+ key = g_string_new (NULL);
+ if (flags & GS_APP_LIST_FILTER_FLAG_KEY_ID) {
+ const gchar *tmp = gs_app_get_id (app);
+ if (tmp != NULL)
+ g_string_append (key, gs_app_get_id (app));
+ }
+ if (flags & GS_APP_LIST_FILTER_FLAG_KEY_SOURCE) {
+ const gchar *tmp = gs_app_get_source_default (app);
+ if (tmp != NULL)
+ g_string_append_printf (key, ":%s", tmp);
+ }
+ if (flags & GS_APP_LIST_FILTER_FLAG_KEY_VERSION) {
+ const gchar *tmp = gs_app_get_version (app);
+ if (tmp != NULL)
+ g_string_append_printf (key, ":%s", tmp);
+ }
+ if (key->len == 0)
+ return keys;
+ g_ptr_array_add (keys, g_string_free (g_steal_pointer (&key), FALSE));
+ return keys;
+}
+
/**
* gs_app_list_filter_duplicates:
* @list: A #GsAppList
@@ -769,43 +818,25 @@ gs_app_list_filter_duplicates (GsAppList *list, GsAppListFilterFlags flags)
kept_apps = g_hash_table_new (g_direct_hash, g_direct_equal);
for (guint i = 0; i < list->array->len; i++) {
- GsApp *app;
- GsApp *found;
- g_autoptr(GString) key = NULL;
-
- app = gs_app_list_index (list, i);
- if (flags == GS_APP_LIST_FILTER_FLAG_NONE) {
- key = g_string_new (gs_app_get_unique_id (app));
- } else {
- key = g_string_new (NULL);
- if (flags & GS_APP_LIST_FILTER_FLAG_KEY_ID) {
- const gchar *tmp = gs_app_get_id (app);
- if (tmp != NULL)
- g_string_append (key, gs_app_get_id (app));
- }
- if (flags & GS_APP_LIST_FILTER_FLAG_KEY_SOURCE) {
- const gchar *tmp = gs_app_get_source_default (app);
- if (tmp != NULL)
- g_string_append_printf (key, ":%s", tmp);
- }
- if (flags & GS_APP_LIST_FILTER_FLAG_KEY_VERSION) {
- const gchar *tmp = gs_app_get_version (app);
- if (tmp != NULL)
- g_string_append_printf (key, ":%s", tmp);
- }
- }
- if (key->len == 0) {
- g_autofree gchar *str = gs_app_to_string (app);
- g_debug ("adding without deduplication as no app key: %s", str);
- g_hash_table_add (kept_apps, app);
- continue;
+ GsApp *app = gs_app_list_index (list, i);
+ GsApp *found = NULL;
+ g_autoptr(GPtrArray) keys = NULL;
+
+ /* get all the keys used to identify this app */
+ keys = gs_app_list_filter_app_get_keys (app, flags);
+ for (guint j = 0; j < keys->len; j++) {
+ const gchar *key = g_ptr_array_index (keys, j);
+ found = g_hash_table_lookup (hash, key);
+ if (found != NULL)
+ break;
}
- found = g_hash_table_lookup (hash, key->str);
+
+ /* new app */
if (found == NULL) {
- g_debug ("found new %s", key->str);
- g_hash_table_insert (hash,
- g_strdup (key->str),
- app);
+ for (guint j = 0; j < keys->len; j++) {
+ const gchar *key = g_ptr_array_index (keys, j);
+ g_hash_table_insert (hash, g_strdup (key), app);
+ }
g_hash_table_add (kept_apps, app);
continue;
}
@@ -813,24 +844,22 @@ gs_app_list_filter_duplicates (GsAppList *list, GsAppListFilterFlags flags)
/* better? */
if (flags != GS_APP_LIST_FILTER_FLAG_NONE) {
if (gs_app_list_filter_app_is_better (app, found, flags)) {
- g_debug ("using better %s (priority %u > %u)",
- key->str,
+ g_debug ("using better (priority %u > %u)",
gs_app_get_priority (app),
gs_app_get_priority (found));
- g_hash_table_insert (hash,
- g_strdup (key->str),
- app);
+ for (guint j = 0; j < keys->len; j++) {
+ const gchar *key = g_ptr_array_index (keys, j);
+ g_hash_table_insert (hash, g_strdup (key), app);
+ }
g_hash_table_remove (kept_apps, found);
g_hash_table_add (kept_apps, app);
continue;
}
- g_debug ("ignoring worse duplicate %s (priority %u > %u)",
- key->str,
+ g_debug ("ignoring worse duplicate (priority %u > %u)",
gs_app_get_priority (app),
gs_app_get_priority (found));
continue;
}
- g_debug ("ignoring duplicate %s", key->str);
continue;
}
diff --git a/lib/gs-self-test.c b/lib/gs-self-test.c
index fb44124a..b60e0491 100644
--- a/lib/gs-self-test.c
+++ b/lib/gs-self-test.c
@@ -271,6 +271,7 @@ gs_plugin_func (void)
GsAppList *list_dup;
GsAppList *list_remove;
GsApp *app;
+ g_autoptr(AsProvide) prov = as_provide_new ();
/* check enums converted */
for (guint i = 0; i < GS_PLUGIN_ACTION_LAST; i++) {
@@ -436,12 +437,33 @@ gs_plugin_func (void)
gs_app_list_add (list, app);
g_object_unref (app);
gs_app_list_filter_duplicates (list,
- GS_APP_LIST_FILTER_FLAG_KEY_ID|
+ GS_APP_LIST_FILTER_FLAG_KEY_ID |
GS_APP_LIST_FILTER_FLAG_PREFER_INSTALLED);
g_assert_cmpint (gs_app_list_length (list), ==, 1);
g_assert_cmpstr (gs_app_get_unique_id (gs_app_list_index (list, 0)), ==, "user/foo/*/*/e/*");
g_object_unref (list);
+ /* use the provides ID to dedupe */
+ list = gs_app_list_new ();
+ app = gs_app_new ("gimp.desktop");
+ gs_app_set_unique_id (app, "user/fedora/*/*/gimp.desktop/*");
+ gs_app_set_priority (app, 0);
+ gs_app_list_add (list, app);
+ g_object_unref (app);
+ app = gs_app_new ("org.gimp.GIMP");
+ as_provide_set_kind (prov, AS_PROVIDE_KIND_ID);
+ as_provide_set_value (prov, "gimp.desktop");
+ gs_app_add_provide (app, prov);
+ gs_app_set_unique_id (app, "user/flathub/*/*/org.gimp.GIMP/*");
+ gs_app_set_priority (app, 100);
+ gs_app_list_add (list, app);
+ g_object_unref (app);
+ gs_app_list_filter_duplicates (list, GS_APP_LIST_FILTER_FLAG_KEY_ID_PROVIDES);
+ g_assert_cmpint (gs_app_list_length (list), ==, 1);
+ g_assert_cmpstr (gs_app_get_unique_id (gs_app_list_index (list, 0)), ==,
+ "user/flathub/*/*/org.gimp.GIMP/*");
+ g_object_unref (list);
+
/* use globs when adding */
list = gs_app_list_new ();
app = gs_app_new ("b");
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]