[gnome-software] Add all wildcard matches when resolving



commit 0cde75afaecc2879421ea0c160a390a7e733f60a
Author: Richard Hughes <richard hughsie com>
Date:   Mon Jun 27 11:30:16 2016 +0100

    Add all wildcard matches when resolving
    
    This allows us to filter them in the plugin loader rather than using a hacky
    heuristic in the appstream plugin.
    
    This allows us to respect the plugin 'priority' value, which means we can
    define preferences for search results; for instance: 'prefer apps from flatpak
    rather than those from packagekit'.

 src/gs-plugin-loader.c            |    2 +
 src/plugins/gs-plugin-appstream.c |  117 +++++++++++++++++++++++--------------
 src/plugins/gs-plugin-dummy.c     |   29 +++++++--
 3 files changed, 97 insertions(+), 51 deletions(-)
---
diff --git a/src/gs-plugin-loader.c b/src/gs-plugin-loader.c
index e233f54..54c6497 100644
--- a/src/gs-plugin-loader.c
+++ b/src/gs-plugin-loader.c
@@ -263,6 +263,8 @@ gs_plugin_loader_run_adopt (GsPluginLoader *plugin_loader, GsAppList *list)
                        GsApp *app = gs_app_list_index (list, j);
                        if (gs_app_get_management_plugin (app) != NULL)
                                continue;
+                       if (gs_app_has_quirk (app, AS_APP_QUIRK_MATCH_ANY_PREFIX))
+                               continue;
                        gs_plugin_loader_action_start (plugin_loader, plugin, FALSE);
                        adopt_app_func (plugin, app);
                        gs_plugin_loader_action_stop (plugin_loader, plugin);
diff --git a/src/plugins/gs-plugin-appstream.c b/src/plugins/gs-plugin-appstream.c
index 4cec0e3..daaa9fc 100644
--- a/src/plugins/gs-plugin-appstream.c
+++ b/src/plugins/gs-plugin-appstream.c
@@ -306,8 +306,7 @@ gs_plugin_refine_from_id (GsPlugin *plugin,
 {
        GsPluginData *priv = gs_plugin_get_data (plugin);
        const gchar *id;
-       guint i;
-       AsApp *item = NULL;
+       AsApp *item;
 
        /* unfound */
        *found = FALSE;
@@ -317,49 +316,8 @@ gs_plugin_refine_from_id (GsPlugin *plugin,
        if (id == NULL)
                return TRUE;
 
-       /* find the best app when matching any prefixes */
-       if (gs_app_has_quirk (app, AS_APP_QUIRK_MATCH_ANY_PREFIX)) {
-               g_autoptr(GPtrArray) items = NULL;
-               g_autofree gchar *id_wildcard = g_strdup (id);
-
-               items = as_store_get_apps_by_id (priv->store, id);
-               for (i = 0; i < items->len; i++) {
-                       AsApp *item_tmp = NULL;
-
-                       /* does the app have an installation method */
-                       item_tmp = g_ptr_array_index (items, i);
-                       if (as_app_get_pkgname_default (item_tmp) == NULL &&
-                           as_app_get_bundle_default (item_tmp) == NULL) {
-                               g_debug ("not using %s for wildcard as "
-                                        "no bundle or pkgname",
-                                        as_app_get_id (item_tmp));
-                               continue;
-                       }
-
-
-                       /* already set! */
-                       if (item != NULL) {
-                               g_warning ("found duplicate %s for wildcard %s",
-                                          as_app_get_id (item_tmp),
-                                          id_wildcard);
-                               continue;
-                       }
-
-                       /* only match the first entry */
-                       g_debug ("found %s for wildcard %s",
-                                as_app_get_id (item_tmp), id_wildcard);
-
-                       /* adopt the new prefix */
-                       gs_app_set_id (app, as_app_get_id (item_tmp));
-
-                       /* refine using this */
-                       item = item_tmp;
-               }
-       } else {
-               item = as_store_get_app_by_id (priv->store, id);
-       }
-
        /* nothing found */
+       item = as_store_get_app_by_id (priv->store, id);
        if (item == NULL)
                return TRUE;
 
@@ -452,6 +410,10 @@ gs_plugin_refine_app (GsPlugin *plugin,
 {
        gboolean found = FALSE;
 
+       /* handled already */
+       if (gs_app_has_quirk (app, AS_APP_QUIRK_MATCH_ANY_PREFIX))
+               return TRUE;
+
        /* find by ID then package name */
        if (!gs_plugin_refine_from_id (plugin, app, &found, error))
                return FALSE;
@@ -465,6 +427,73 @@ gs_plugin_refine_app (GsPlugin *plugin,
 }
 
 static gboolean
+gs_plugin_appstream_add_wildcards (GsPlugin *plugin,
+                                  GsAppList *list,
+                                  GsApp *app,
+                                  GError **error)
+{
+       GsPluginData *priv = gs_plugin_get_data (plugin);
+       const gchar *id;
+       guint i;
+       g_autoptr(GPtrArray) items = NULL;
+
+       id = gs_app_get_id (app);
+       if (id == NULL)
+               return TRUE;
+
+       /* find all apps when matching any prefixes */
+       items = as_store_get_apps_by_id (priv->store, id);
+       for (i = 0; i < items->len; i++) {
+               AsApp *item = NULL;
+               g_autoptr(GsApp) new = NULL;
+
+               /* does the app have an installation method */
+               item = g_ptr_array_index (items, i);
+               if (as_app_get_pkgname_default (item) == NULL &&
+                   as_app_get_bundle_default (item) == NULL) {
+                       g_debug ("not using %s for wildcard as "
+                                "no bundle or pkgname",
+                                as_app_get_id (item));
+                       continue;
+               }
+
+               /* new app */
+               g_debug ("found %s for wildcard %s",
+                        as_app_get_id (item), id);
+               new = gs_plugin_appstream_create_app (plugin,
+                                                     as_app_get_id (item));
+               if (!gs_appstream_refine_app (plugin, new, item, error))
+                       return FALSE;
+               gs_app_list_add (list, new);
+       }
+       return TRUE;
+}
+
+/* wildcard results get added to the list, not replaced */
+gboolean
+gs_plugin_refine (GsPlugin *plugin,
+                 GsAppList *list,
+                 GsPluginRefineFlags flags,
+                 GCancellable *cancellable,
+                 GError **error)
+{
+       guint i;
+
+       for (i = 0; i < gs_app_list_length (list); i++) {
+               GsApp *app = gs_app_list_index (list, i);
+               if (!gs_app_has_quirk (app, AS_APP_QUIRK_MATCH_ANY_PREFIX))
+                       continue;
+               if (!gs_plugin_appstream_add_wildcards (plugin,
+                                                       list,
+                                                       app,
+                                                       error))
+                       return FALSE;
+       }
+
+       return TRUE;
+}
+
+static gboolean
 _as_app_matches_desktop_group_set (AsApp *app, gchar **desktop_groups)
 {
        guint i;
diff --git a/src/plugins/gs-plugin-dummy.c b/src/plugins/gs-plugin-dummy.c
index f870b04..67df02b 100644
--- a/src/plugins/gs-plugin-dummy.c
+++ b/src/plugins/gs-plugin-dummy.c
@@ -71,6 +71,11 @@ gs_plugin_destroy (GsPlugin *plugin)
 void
 gs_plugin_adopt_app (GsPlugin *plugin, GsApp *app)
 {
+       if (gs_app_get_id (app) != NULL &&
+           g_str_has_prefix (gs_app_get_id (app), "dummy:")) {
+               gs_app_set_management_plugin (app, gs_plugin_get_name (plugin));
+               return;
+       }
        if (g_strcmp0 (gs_app_get_id (app), "mate-spell.desktop") == 0 ||
            g_strcmp0 (gs_app_get_id (app), "chiron.desktop") == 0 ||
            g_strcmp0 (gs_app_get_id (app), "zeus.desktop") == 0 ||
@@ -288,11 +293,21 @@ gs_plugin_add_popular (GsPlugin *plugin,
                       GCancellable *cancellable,
                       GError **error)
 {
-       g_autoptr(GsApp) app = gs_app_new ("chiron.desktop");
-       gs_app_add_quirk (app, AS_APP_QUIRK_MATCH_ANY_PREFIX);
-       gs_app_set_metadata (app, "GnomeSoftware::Creator",
+       g_autoptr(GsApp) app1 = NULL;
+       g_autoptr(GsApp) app2 = NULL;
+
+       /* add wildcard */
+       app1 = gs_app_new ("zeus.desktop");
+       gs_app_add_quirk (app1, AS_APP_QUIRK_MATCH_ANY_PREFIX);
+       gs_app_set_metadata (app1, "GnomeSoftware::Creator",
                             gs_plugin_get_name (plugin));
-       gs_app_list_add (list, app);
+       gs_app_list_add (list, app1);
+
+       /* add again, this time with a prefix so it gets deduplicated */
+       app2 = gs_app_new ("dummy:zeus.desktop");
+       gs_app_set_metadata (app2, "GnomeSoftware::Creator",
+                            gs_plugin_get_name (plugin));
+       gs_app_list_add (list, app2);
        return TRUE;
 }
 
@@ -369,9 +384,9 @@ gs_plugin_refine_app (GsPlugin *plugin,
                      GError **error)
 {
        /* default */
-       if (g_strcmp0 (gs_app_get_id (app), "chiron.desktop") == 0 ||
-           g_strcmp0 (gs_app_get_id (app), "mate-spell.desktop") == 0 ||
-           g_strcmp0 (gs_app_get_id (app), "zeus.desktop") == 0) {
+       if (g_strcmp0 (gs_app_get_id_no_prefix (app), "chiron.desktop") == 0 ||
+           g_strcmp0 (gs_app_get_id_no_prefix (app), "mate-spell.desktop") == 0 ||
+           g_strcmp0 (gs_app_get_id_no_prefix (app), "zeus.desktop") == 0) {
                if (gs_app_get_state (app) == AS_APP_STATE_UNKNOWN)
                        gs_app_set_state (app, AS_APP_STATE_INSTALLED);
                if (gs_app_get_kind (app) == AS_APP_KIND_UNKNOWN)


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]