[gnome-software/wip/hughsie/xdg-app] f



commit 55eb7266d6d1df2e7b171ee44703bc4326ac8c6e
Author: Richard Hughes <richard hughsie com>
Date:   Fri Dec 18 13:55:45 2015 +0000

    f

 src/plugins/gs-plugin-xdg-app.c |  294 +++++++++++++++++++++++++++------------
 1 files changed, 208 insertions(+), 86 deletions(-)
---
diff --git a/src/plugins/gs-plugin-xdg-app.c b/src/plugins/gs-plugin-xdg-app.c
index 01203cb..a2c137d 100644
--- a/src/plugins/gs-plugin-xdg-app.c
+++ b/src/plugins/gs-plugin-xdg-app.c
@@ -27,13 +27,8 @@
  *
  * Some outstanding notes:
  *
- * - Why xdg_app_installation_list_installed_refs() not return a GPtrArray?
  * - How can I get the AppStream metadata using libxdgapp?
  * - Where is the privaledge elevation helper?
- * - Is there a faster way to get the installed apps and frameworks at the same time?
- * - How do I get the list of updates using libxdg-app, e.g. like "xdg-app --user --updates repo-contents 
test-repo" used to work
- * - How do I do download-not-apply when on network?
- * - How do I do I know when an update needs network access?
  */
 
 #include <config.h>
@@ -63,10 +58,6 @@ gs_plugin_initialize (GsPlugin *plugin)
 {
        /* create private area */
        plugin->priv = GS_PLUGIN_GET_PRIVATE (GsPluginPrivate);
-
-       /* FIXME: this should default to system-wide, but we need a permissions
-        * helper to elevate privs */
-       plugin->priv->installation = xdg_app_installation_new_user ();
 }
 
 /**
@@ -79,6 +70,23 @@ gs_plugin_destroy (GsPlugin *plugin)
 }
 
 /**
+ * gs_plugin_ensure_installation:
+ */
+static gboolean
+gs_plugin_ensure_installation (GsPlugin *plugin,
+                              GCancellable *cancellable,
+                              GError **error)
+{
+       if (plugin->priv->installation != NULL)
+               return TRUE;
+
+       /* FIXME: this should default to system-wide, but we need a permissions
+        * helper to elevate privs */
+       plugin->priv->installation = xdg_app_installation_new_user (cancellable, error);
+       return plugin->priv->installation != NULL;
+}
+
+/**
  * gs_plugin_add_search:
  */
 gboolean
@@ -109,7 +117,7 @@ gs_plugin_xdg_app_create_installed (XdgAppInstalledRef *app_ref)
         *  1) the default to launch unless you specify a version
         *  2) The one that gets its exported files exported
         */
-       if (!xdg_app_installed_ref_get_current (app_ref))
+       if (!xdg_app_installed_ref_get_is_current (app_ref))
                return NULL;
 
        /* create new object */
@@ -118,7 +126,8 @@ gs_plugin_xdg_app_create_installed (XdgAppInstalledRef *app_ref)
        gs_app_set_state (app, AS_APP_STATE_INSTALLED);
        gs_app_set_kind (app, GS_APP_KIND_NORMAL);
        gs_app_set_id_kind (app, AS_ID_KIND_DESKTOP);
-       gs_app_set_version (app, xdg_app_ref_get_version (XDG_APP_REF(app_ref)));
+       gs_app_set_metadata (app, "XgdApp::branch",
+                            xdg_app_ref_get_branch (XDG_APP_REF(app_ref)));
        gs_app_set_origin (app, xdg_app_installed_ref_get_origin (app_ref));
 
        switch (xdg_app_ref_get_kind (XDG_APP_REF(app_ref))) {
@@ -135,9 +144,6 @@ gs_plugin_xdg_app_create_installed (XdgAppInstalledRef *app_ref)
        /* we need this for uninstalling */
        gs_app_set_metadata (app, "XgdApp::arch", xdg_app_ref_get_arch (XDG_APP_REF(app_ref)));
 
-       // read AppData from here: xdg_app_installed_ref_get_deploy_dir (app_ref)
-       // xdg_app_ref_get_commit (XDG_APP_REF(app_ref)),
-
        //FIXME need to refine using AppData/AppStream
        gs_app_set_name (app, GS_APP_QUALITY_NORMAL, "GNOME Builder");
        gs_app_set_summary (app, GS_APP_QUALITY_NORMAL, "GNOME BUILDER");
@@ -146,6 +152,26 @@ gs_plugin_xdg_app_create_installed (XdgAppInstalledRef *app_ref)
        return g_object_ref (app);
 }
 
+typedef struct {
+       GsApp           *app;
+       GsPlugin        *plugin;
+} GsPluginHelper;
+
+/**
+ * gs_plugin_xdg_app_progress_cb:
+ */
+static void
+gs_plugin_xdg_app_progress_cb (const gchar *status,
+                              guint progress,
+                              gboolean estimating,
+                              gpointer user_data)
+{
+       GsPluginHelper *helper = (GsPluginHelper *) user_data;
+       if (helper->app == NULL)
+               return;
+       gs_plugin_progress_update (helper->plugin, helper->app, progress);
+}
+
 /**
  * gs_plugin_add_installed:
  */
@@ -155,33 +181,22 @@ gs_plugin_add_installed (GsPlugin *plugin,
                         GCancellable *cancellable,
                         GError **error)
 {
-       XdgAppInstalledRef **apps;
-       XdgAppInstalledRef **runtimes;
+       g_autoptr(GPtrArray) xrefs = NULL;
        guint i;
 
-       /* get apps */
-       apps = xdg_app_installation_list_installed_refs (plugin->priv->installation,
-                                                        XDG_APP_REF_KIND_APP,
-                                                        cancellable, error);
-       if (apps == NULL)
+       /* ensure we can set up the repo */
+       if (!gs_plugin_ensure_installation (plugin, cancellable, error))
                return FALSE;
-       for (i = 0; apps[i] != NULL; i++) {
-               g_autoptr(GsApp) app = NULL;
-               app = gs_plugin_xdg_app_create_installed (apps[i]);
-               if (app == NULL)
-                       continue;
-               gs_plugin_add_app (list, app);
-       }
 
-       /* get runtimes */
-       runtimes = xdg_app_installation_list_installed_refs (plugin->priv->installation,
-                                                            XDG_APP_REF_KIND_RUNTIME,
-                                                            cancellable, error);
-       if (runtimes == NULL)
+       /* get apps and runtimes */
+       xrefs = xdg_app_installation_list_installed_refs (plugin->priv->installation,
+                                                        cancellable, error);
+       if (xrefs == NULL)
                return FALSE;
-       for (i = 0; runtimes[i] != NULL; i++) {
+       for (i = 0; i < xrefs->len; i++) {
+               XdgAppInstalledRef *xref = g_ptr_array_index (xrefs, i);
                g_autoptr(GsApp) app = NULL;
-               app = gs_plugin_xdg_app_create_installed (runtimes[i]);
+               app = gs_plugin_xdg_app_create_installed (xref);
                if (app == NULL)
                        continue;
                gs_plugin_add_app (list, app);
@@ -199,29 +214,34 @@ gs_plugin_add_sources (GsPlugin *plugin,
                       GCancellable *cancellable,
                       GError **error)
 {
-       XdgAppRemote **remotes;
+       g_autoptr(GPtrArray) xremotes = NULL;
        guint i;
 
-       remotes = xdg_app_installation_list_remotes (plugin->priv->installation,
-                                                    cancellable,
-                                                    error);
-       if (remotes == NULL)
+       /* ensure we can set up the repo */
+       if (!gs_plugin_ensure_installation (plugin, cancellable, error))
                return FALSE;
-       for (i = 0; remotes[i] != NULL; i++) {
+
+       xremotes = xdg_app_installation_list_remotes (plugin->priv->installation,
+                                                     cancellable,
+                                                     error);
+       if (xremotes == NULL)
+               return FALSE;
+       for (i = 0; i < xremotes->len; i++) {
+               XdgAppRemote *xremote = g_ptr_array_index (xremotes, i);
                g_autoptr(GsApp) app = NULL;
-               app = gs_app_new (xdg_app_remote_get_name (remotes[i]));
+               app = gs_app_new (xdg_app_remote_get_name (xremote));
                gs_app_set_management_plugin (app, "XgdApp");
                gs_app_set_kind (app, GS_APP_KIND_SOURCE);
                gs_app_set_state (app, AS_APP_STATE_INSTALLED);
                gs_app_set_name (app,
                                 GS_APP_QUALITY_LOWEST,
-                                xdg_app_remote_get_name (remotes[i]));
+                                xdg_app_remote_get_name (xremote));
                gs_app_set_summary (app,
                                    GS_APP_QUALITY_LOWEST,
-                                   xdg_app_remote_get_title (remotes[i]));
+                                   xdg_app_remote_get_title (xremote));
                gs_app_set_url (app,
                                AS_URL_KIND_HOMEPAGE,
-                               xdg_app_remote_get_url (remotes[i]));
+                               xdg_app_remote_get_url (xremote));
                gs_plugin_add_app (list, app);
        }
        return TRUE;
@@ -236,6 +256,113 @@ gs_plugin_add_updates (GsPlugin *plugin,
                       GCancellable *cancellable,
                       GError **error)
 {
+       guint i;
+       g_autoptr(GPtrArray) xrefs = NULL;
+
+       /* ensure we can set up the repo */
+       if (!gs_plugin_ensure_installation (plugin, cancellable, error))
+               return FALSE;
+
+       /* get all the installed apps (no network I/O) */
+       xrefs = xdg_app_installation_list_installed_refs (plugin->priv->installation,
+                                                         cancellable,
+                                                         error);
+       if (xrefs == NULL)
+               return FALSE;
+       for (i = 0; i < xrefs->len; i++) {
+               XdgAppInstalledRef *xref = g_ptr_array_index (xrefs, i);
+               const gchar *commit;
+               const gchar *latest_commit;
+               g_autoptr(GsApp) app = NULL;
+
+               /* check the application has already been downloaded */
+               commit = xdg_app_ref_get_commit (XDG_APP_REF (xref));
+               latest_commit = xdg_app_installed_ref_get_latest_commit (xref);
+               if (g_strcmp0 (commit, latest_commit) == 0) {
+                       g_debug ("no downloaded update for %s",
+                                xdg_app_ref_get_name (XDG_APP_REF (xref)));
+                       continue;
+               }
+
+               /* we have an update to show */
+               g_debug ("%s has a downloaded update %s->%s",
+                        xdg_app_ref_get_name (XDG_APP_REF (xref)),
+                        commit, latest_commit);
+               app = gs_plugin_xdg_app_create_installed (xref);
+               if (app == NULL)
+                       continue;
+               gs_plugin_add_app (list, app);
+       }
+
+       return TRUE;
+}
+
+/**
+ * gs_plugin_refresh:
+ */
+gboolean
+gs_plugin_refresh (GsPlugin *plugin,
+                  guint cache_age,
+                  GsPluginRefreshFlags flags,
+                  GCancellable *cancellable,
+                  GError **error)
+{
+       GsPluginHelper helper;
+       guint i;
+       g_autoptr(GPtrArray) xrefs = NULL;
+
+       /* not us */
+       if ((flags & GS_PLUGIN_REFRESH_FLAGS_UPDATES) == 0)
+               return TRUE;
+
+       /* ensure we can set up the repo */
+       if (!gs_plugin_ensure_installation (plugin, cancellable, error))
+               return FALSE;
+
+       /* use helper: FIXME: new()&ref? */
+       helper.plugin = plugin;
+
+       /* get all the updates available from all remotes */
+       xrefs = xdg_app_installation_list_installed_refs_for_update (plugin->priv->installation,
+                                                                    cancellable,
+                                                                    error);
+       if (xrefs == NULL)
+               return FALSE;
+       for (i = 0; i < xrefs->len; i++) {
+               XdgAppInstalledRef *xref = g_ptr_array_index (xrefs, i);
+               const gchar *commit;
+               const gchar *latest_commit;
+               g_autoptr(GsApp) app = NULL;
+               g_autoptr(XdgAppInstalledRef) xref2 = NULL;
+
+               /* check the application has already been downloaded */
+               commit = xdg_app_ref_get_commit (XDG_APP_REF (xref));
+               latest_commit = xdg_app_installed_ref_get_latest_commit (xref);
+               if (g_strcmp0 (commit, latest_commit) == 0) {
+                       g_debug ("no update for %s",
+                                xdg_app_ref_get_name (XDG_APP_REF (xref)));
+                       continue;
+               }
+
+               /* try to create a GsApp so we can do progress reporting */
+               app = gs_plugin_xdg_app_create_installed (xref);
+               helper.app = app;
+
+               /* fetch but do not deploy */
+               g_debug ("pulling update for %s",
+                        xdg_app_ref_get_name (XDG_APP_REF (xref)));
+               xref2 = xdg_app_installation_update (plugin->priv->installation,
+                                                    XDG_APP_UPDATE_FLAGS_NO_DEPLOY,
+                                                    xdg_app_ref_get_kind (XDG_APP_REF (xref)),
+                                                    xdg_app_ref_get_name (XDG_APP_REF (xref)),
+                                                    xdg_app_ref_get_arch (XDG_APP_REF (xref)),
+                                                    xdg_app_ref_get_branch (XDG_APP_REF (xref)),
+                                                    gs_plugin_xdg_app_progress_cb, &helper,
+                                                    cancellable, error);
+               if (xref2 == NULL)
+                       return FALSE;
+       }
+
        return TRUE;
 }
 
@@ -281,40 +408,22 @@ gs_plugin_launch (GsPlugin *plugin,
                  GCancellable *cancellable,
                  GError **error)
 {
-       const gchar *version = NULL;
-       g_autoptr(XdgAppInstalledRef) xapp = NULL;
-
-       version = gs_app_get_version (app);
-       if (version == NULL)
-               version = "master";
-       xapp = xdg_app_installation_get_installed_ref (plugin->priv->installation,
-                                                      XDG_APP_REF_KIND_APP,
-                                                      gs_app_get_id (app),
-                                                      NULL,
-                                                      version,
-                                                      cancellable,
-                                                      error);
-       if (xapp == NULL)
-               return FALSE;
-       return xdg_app_installed_ref_launch (xapp, cancellable, error);
-}
+       const gchar *branch = NULL;
 
-typedef struct {
-       GsApp           *app;
-       GsPlugin        *plugin;
-} GsPluginHelper;
+       /* ensure we can set up the repo */
+       if (!gs_plugin_ensure_installation (plugin, cancellable, error))
+               return FALSE;
 
-/**
- * gs_plugin_xdg_app_progress_cb:
- */
-static void
-gs_plugin_xdg_app_progress_cb (const gchar *status,
-                              guint progress,
-                              gboolean estimating,
-                              gpointer user_data)
-{
-       GsPluginHelper *helper = (GsPluginHelper *) user_data;
-       gs_plugin_progress_update (helper->plugin, helper->app, progress);
+       branch = gs_app_get_metadata_item (app, "XgdApp::branch");
+       if (branch == NULL)
+               branch = "master";
+       return xdg_app_installation_launch (plugin->priv->installation,
+                                           gs_app_get_id (app),
+                                           NULL,
+                                           branch,
+                                           NULL,
+                                           cancellable,
+                                           error);
 }
 
 /**
@@ -332,6 +441,10 @@ gs_plugin_app_remove (GsPlugin *plugin,
        if (g_strcmp0 (gs_app_get_management_plugin (app), "XgdApp") != 0)
                return TRUE;
 
+       /* ensure we can set up the repo */
+       if (!gs_plugin_ensure_installation (plugin, cancellable, error))
+               return FALSE;
+
        /* use helper: FIXME: new()&ref? */
        helper.app = app;
        helper.plugin = plugin;
@@ -341,7 +454,7 @@ gs_plugin_app_remove (GsPlugin *plugin,
                                               XDG_APP_REF_KIND_APP,
                                               gs_app_get_id (app),
                                               gs_app_get_metadata_item (app, "XgdApp::arch"),
-                                              gs_app_get_version (app),
+                                              gs_app_get_metadata_item (app, "XgdApp::branch"),
                                               gs_plugin_xdg_app_progress_cb, &helper,
                                               cancellable, error);
 }
@@ -356,26 +469,30 @@ gs_plugin_app_install (GsPlugin *plugin,
                       GError **error)
 {
        GsPluginHelper helper;
-       g_autoptr(XdgAppInstalledRef) xapp = NULL;
+       g_autoptr(XdgAppInstalledRef) xref = NULL;
 
        /* only process this app if was created by this plugin */
        if (g_strcmp0 (gs_app_get_management_plugin (app), "XgdApp") != 0)
                return TRUE;
 
+       /* ensure we can set up the repo */
+       if (!gs_plugin_ensure_installation (plugin, cancellable, error))
+               return FALSE;
+
        /* use helper: FIXME: new()&ref? */
        helper.app = app;
        helper.plugin = plugin;
 
        /* install */
-       xapp = xdg_app_installation_install (plugin->priv->installation,
+       xref = xdg_app_installation_install (plugin->priv->installation,
                                             gs_app_get_origin (app),
                                             XDG_APP_REF_KIND_APP,
                                             gs_app_get_id (app),
                                             gs_app_get_metadata_item (app, "XgdApp::arch"),
-                                            gs_app_get_version (app),
+                                            gs_app_get_metadata_item (app, "XgdApp::branch"),
                                             gs_plugin_xdg_app_progress_cb, &helper,
                                             cancellable, error);
-       return xapp != NULL;
+       return xref != NULL;
 }
 
 /**
@@ -390,23 +507,28 @@ gs_plugin_app_update (GsPlugin *plugin,
                      GError **error)
 {
        GsPluginHelper helper;
-       g_autoptr(XdgAppInstalledRef) xapp = NULL;
+       g_autoptr(XdgAppInstalledRef) xref = NULL;
 
        /* only process this app if was created by this plugin */
        if (g_strcmp0 (gs_app_get_management_plugin (app), "XgdApp") != 0)
                return TRUE;
 
+       /* ensure we can set up the repo */
+       if (!gs_plugin_ensure_installation (plugin, cancellable, error))
+               return FALSE;
+
        /* use helper: FIXME: new()&ref? */
        helper.app = app;
        helper.plugin = plugin;
 
        /* install */
-       xapp = xdg_app_installation_update (plugin->priv->installation,
+       xref = xdg_app_installation_update (plugin->priv->installation,
+                                           XDG_APP_UPDATE_FLAGS_NONE,
                                            XDG_APP_REF_KIND_APP,
                                            gs_app_get_id (app),
                                            gs_app_get_metadata_item (app, "XgdApp::arch"),
-                                           gs_app_get_version (app),
+                                           gs_app_get_metadata_item (app, "XgdApp::branch"),
                                            gs_plugin_xdg_app_progress_cb, &helper,
                                            cancellable, error);
-       return xapp != NULL;
+       return xref != NULL;
 }


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