[gnome-software/wip/hughsie/xdg-app] f
- From: Richard Hughes <rhughes src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-software/wip/hughsie/xdg-app] f
- Date: Fri, 18 Dec 2015 17:18:49 +0000 (UTC)
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]