[gnome-software] flatpak: Always download the RuntimeRepo when processing a flatpakref file



commit dd005844f960ba0ee1eee3c96f49159d44fb61e0
Author: Richard Hughes <richard hughsie com>
Date:   Thu Jul 13 18:30:31 2017 +0100

    flatpak: Always download the RuntimeRepo when processing a flatpakref file

 plugins/flatpak/gs-flatpak-app.c |   21 ++++++
 plugins/flatpak/gs-flatpak-app.h |    3 +
 plugins/flatpak/gs-flatpak.c     |  125 +++++++++++++++++++++++---------------
 plugins/flatpak/gs-self-test.c   |    4 +-
 4 files changed, 102 insertions(+), 51 deletions(-)
---
diff --git a/plugins/flatpak/gs-flatpak-app.c b/plugins/flatpak/gs-flatpak-app.c
index baf551f..93e1dbb 100644
--- a/plugins/flatpak/gs-flatpak-app.c
+++ b/plugins/flatpak/gs-flatpak-app.c
@@ -38,6 +38,7 @@ struct _GsFlatpakApp
        gchar                   *repo_gpgkey;
        gchar                   *repo_url;
        GsFlatpakAppFileKind     file_kind;
+       GsApp                   *runtime_repo;
 };
 
 G_DEFINE_TYPE (GsFlatpakApp, gs_flatpak_app, GS_TYPE_APP)
@@ -105,6 +106,10 @@ gs_flatpak_app_to_string (GsApp *app, GString *str)
                gs_utils_append_key_value (str, 20, "flatpak::file-kind",
                                           gs_flatpak_app_file_kind_to_string (flatpak_app->file_kind));
        }
+       if (flatpak_app->runtime_repo != NULL) {
+               g_string_append (str, "\n\tRuntimeRepo:\n\t");
+               gs_app_to_string_append (flatpak_app->runtime_repo, str);
+       }
 }
 
 const gchar *
@@ -142,6 +147,13 @@ gs_flatpak_app_get_file_kind (GsApp *app)
        return flatpak_app->file_kind;
 }
 
+GsApp *
+gs_flatpak_app_get_runtime_repo (GsApp *app)
+{
+       GsFlatpakApp *flatpak_app = GS_FLATPAK_APP (app);
+       return flatpak_app->runtime_repo;
+}
+
 FlatpakRefKind
 gs_flatpak_app_get_ref_kind (GsApp *app)
 {
@@ -224,6 +236,13 @@ gs_flatpak_app_set_file_kind (GsApp *app, GsFlatpakAppFileKind file_kind)
 }
 
 void
+gs_flatpak_app_set_runtime_repo (GsApp *app, GsApp *runtime_repo)
+{
+       GsFlatpakApp *flatpak_app = GS_FLATPAK_APP (app);
+       g_set_object (&flatpak_app->runtime_repo, runtime_repo);
+}
+
+void
 gs_flatpak_app_set_ref_kind (GsApp *app, FlatpakRefKind ref_kind)
 {
        GsFlatpakApp *flatpak_app = GS_FLATPAK_APP (app);
@@ -262,6 +281,8 @@ static void
 gs_flatpak_app_finalize (GObject *object)
 {
        GsFlatpakApp *flatpak_app = GS_FLATPAK_APP (object);
+       if (flatpak_app->runtime_repo != NULL)
+               g_object_unref (flatpak_app->runtime_repo);
        g_free (flatpak_app->ref_arch);
        g_free (flatpak_app->ref_branch);
        g_free (flatpak_app->ref_display);
diff --git a/plugins/flatpak/gs-flatpak-app.h b/plugins/flatpak/gs-flatpak-app.h
index 7cdaca3..0336cbd 100644
--- a/plugins/flatpak/gs-flatpak-app.h
+++ b/plugins/flatpak/gs-flatpak-app.h
@@ -53,6 +53,7 @@ const gchar           *gs_flatpak_app_get_object_id           (GsApp          *app);
 const gchar            *gs_flatpak_app_get_repo_gpgkey         (GsApp          *app);
 const gchar            *gs_flatpak_app_get_repo_url            (GsApp          *app);
 GsFlatpakAppFileKind    gs_flatpak_app_get_file_kind           (GsApp          *app);
+GsApp                  *gs_flatpak_app_get_runtime_repo        (GsApp          *app);
 
 void                    gs_flatpak_app_set_ref_name            (GsApp          *app,
                                                                 const gchar    *val);
@@ -75,6 +76,8 @@ void                   gs_flatpak_app_set_repo_url            (GsApp          *app,
                                                                 const gchar    *val);
 void                    gs_flatpak_app_set_file_kind           (GsApp          *app,
                                                                 GsFlatpakAppFileKind   file_kind);
+void                    gs_flatpak_app_set_runtime_repo        (GsApp          *app,
+                                                                GsApp          *runtime_repo);
 
 G_END_DECLS
 
diff --git a/plugins/flatpak/gs-flatpak.c b/plugins/flatpak/gs-flatpak.c
index 273177d..3b13dda 100644
--- a/plugins/flatpak/gs-flatpak.c
+++ b/plugins/flatpak/gs-flatpak.c
@@ -2470,7 +2470,7 @@ install_runtime_for_app (GsFlatpak *self,
        }
 
        /* not installed */
-       if (gs_app_get_state (runtime) == AS_APP_STATE_AVAILABLE) {
+       if (gs_app_get_state (runtime) != AS_APP_STATE_INSTALLED) {
                g_autoptr(FlatpakInstalledRef) xref = NULL;
                g_autoptr(GsFlatpakProgressHelper) phelper = NULL;
 
@@ -2503,6 +2503,45 @@ install_runtime_for_app (GsFlatpak *self,
        return TRUE;
 }
 
+static GsApp *
+gs_flatpak_create_runtime_repo (GsFlatpak *self,
+                               const gchar *uri,
+                               GCancellable *cancellable,
+                               GError **error)
+{
+       g_autofree gchar *cache_basename = NULL;
+       g_autofree gchar *cache_fn = NULL;
+       g_autoptr(GFile) file = NULL;
+       g_autoptr(GsApp) app = NULL;
+       g_autoptr(GsApp) app_dl = gs_app_new (gs_plugin_get_name (self->plugin));
+
+       /* TRANSLATORS: status text when downloading the RuntimeRepo */
+       gs_app_set_summary_missing (app_dl, _("Getting runtime sourceā€¦"));
+       gs_plugin_status_update (self->plugin, app_dl, GS_PLUGIN_STATUS_DOWNLOADING);
+
+       /* download file */
+       cache_basename = g_path_get_basename (uri);
+       cache_fn = gs_utils_get_cache_filename ("flatpak",
+                                               cache_basename,
+                                               GS_UTILS_CACHE_FLAG_WRITEABLE,
+                                               error);
+       if (cache_fn == NULL)
+               return FALSE;
+       if (!gs_plugin_download_file (self->plugin, app_dl, uri, cache_fn, cancellable, error))
+               return FALSE;
+
+       /* get GsApp for local file */
+       file = g_file_new_for_path (cache_fn);
+       app = gs_flatpak_app_new_from_repo_file (file, cancellable, error);
+       if (app == NULL) {
+               g_prefix_error (error, "cannot create source from %s: ", cache_fn);
+               return FALSE;
+       }
+       gs_flatpak_app_set_object_id (app, gs_flatpak_get_id (self));
+       gs_app_set_management_plugin (app, gs_plugin_get_name (self->plugin));
+       return g_steal_pointer (&app);
+}
+
 gboolean
 gs_flatpak_app_install (GsFlatpak *self,
                        GsApp *app,
@@ -2553,13 +2592,10 @@ gs_flatpak_app_install (GsFlatpak *self,
 
                /* we have a missing remote and a RuntimeRef */
                runtime = gs_app_get_runtime (app);
-               if (runtime != NULL && gs_app_get_state (runtime) == AS_APP_STATE_UNKNOWN) {
-                       g_autofree gchar *cache_basename = NULL;
-                       g_autofree gchar *cache_fn = NULL;
-                       g_autoptr(GFile) file = NULL;
-                       g_autoptr(GsApp) app_src = NULL;
-                       const gchar *tmp = gs_app_get_metadata_item (app, "flatpak::runtime-repo");
-                       if (tmp == NULL) {
+               if (runtime != NULL &&
+                   gs_app_get_state (runtime) == AS_APP_STATE_AVAILABLE_LOCAL) {
+                       GsApp *app_src = gs_flatpak_app_get_runtime_repo (app);
+                       if (app_src == NULL) {
                                g_set_error (error,
                                             GS_PLUGIN_ERROR,
                                             GS_PLUGIN_ERROR_NOT_SUPPORTED,
@@ -2568,55 +2604,25 @@ gs_flatpak_app_install (GsFlatpak *self,
                                gs_utils_error_add_unique_id (error, runtime);
                                return FALSE;
                        }
-                       g_debug ("runtime %s not available, so installing RuntimeRepo %s",
-                                gs_app_get_unique_id (runtime), tmp);
-
-                       /* download file */
-                       cache_basename = g_path_get_basename (tmp);
-                       cache_fn = gs_utils_get_cache_filename ("flatpak",
-                                                               cache_basename,
-                                                               GS_UTILS_CACHE_FLAG_WRITEABLE,
-                                                               error);
-                       if (cache_fn == NULL)
-                               return FALSE;
-                       if (!gs_plugin_download_file (self->plugin,
-                                                     runtime,
-                                                     tmp,
-                                                     cache_fn,
-                                                     cancellable,
-                                                     error))
-                               return FALSE;
 
-                       /* get GsApp for local file */
-                       file = g_file_new_for_path (cache_fn);
-                       app_src = gs_flatpak_app_new_from_repo_file (file,
-                                                                    cancellable,
-                                                                    error);
-                       if (app_src == NULL) {
-                               g_prefix_error (error,
-                                               "cannot create source from %s: ",
-                                               cache_fn);
-                               return FALSE;
-                       }
-                       gs_flatpak_app_set_object_id (app, gs_flatpak_get_id (self));
-                       gs_app_set_management_plugin (app, gs_plugin_get_name (self->plugin));
+                       /* special case; we're moving from GsFlatpak-user-temp */
+                       gs_app_set_state (app_src, AS_APP_STATE_UNKNOWN);
+                       gs_app_set_state (app_src, AS_APP_STATE_AVAILABLE);
 
                        /* install the flatpakrepo */
                        if (!gs_flatpak_app_install_source (self,
                                                            app_src,
                                                            cancellable,
                                                            error)) {
-                               g_prefix_error (error,
-                                               "cannot install source from %s: ",
-                                               cache_fn);
+                               g_prefix_error (error, "cannot install source from %s: ",
+                                               gs_flatpak_app_get_repo_url (app_src));
                                return FALSE;
                        }
 
                        /* get the new state */
                        if (!gs_plugin_refine_item_state (self, runtime, cancellable, error)) {
-                               g_prefix_error (error,
-                                               "cannot refine runtime using %s: ",
-                                               cache_fn);
+                               g_prefix_error (error, "cannot refine runtime using %s: ",
+                                               gs_flatpak_app_get_repo_url (app_src));
                                return FALSE;
                        }
 
@@ -2986,6 +2992,7 @@ gs_flatpak_file_to_app_ref (GsFlatpak *self,
                            GCancellable *cancellable,
                            GError **error)
 {
+       GsApp *runtime;
        const gchar *remote_name;
        gsize len = 0;
        g_autofree gchar *contents = NULL;
@@ -3002,7 +3009,6 @@ gs_flatpak_file_to_app_ref (GsFlatpak *self,
        g_autofree gchar *ref_icon = NULL;
        g_autofree gchar *ref_title = NULL;
        g_autofree gchar *ref_name = NULL;
-       g_autofree gchar *ref_runtime_repo = NULL;
 
        /* get file data */
        if (!g_file_load_contents (file,
@@ -3084,9 +3090,6 @@ gs_flatpak_file_to_app_ref (GsFlatpak *self,
                as_icon_set_url (ic, ref_icon);
                gs_app_add_icon (app, ic);
        }
-       ref_runtime_repo = g_key_file_get_string (kf, "Flatpak Ref", "RuntimeRepo", NULL);
-       if (ref_runtime_repo != NULL)
-               gs_app_set_metadata (app, "flatpak::runtime-repo", ref_runtime_repo);
 
        /* set the origin data */
        remote_name = flatpak_remote_ref_get_remote_name (xref);
@@ -3126,6 +3129,30 @@ gs_flatpak_file_to_app_ref (GsFlatpak *self,
        if (!gs_plugin_refine_item_metadata (self, app, cancellable, error))
                return NULL;
 
+       /* if the runtime is not already installed, download the RuntimeRepo */
+       runtime = gs_app_get_runtime (app);
+       if (runtime != NULL && gs_app_get_state (runtime) != AS_APP_STATE_INSTALLED) {
+               g_autofree gchar *uri = NULL;
+               uri = g_key_file_get_string (kf, "Flatpak Ref", "RuntimeRepo", NULL);
+               if (uri != NULL) {
+                       g_autoptr(GsApp) app_src = NULL;
+                       app_src = gs_flatpak_create_runtime_repo (self, uri, cancellable, error);
+                       if (app_src == NULL)
+                               return FALSE;
+                       gs_flatpak_app_set_runtime_repo (app, app_src);
+
+                       /* lets install this, so we can get the size */
+                       if (!gs_flatpak_app_install_source (self, app_src, cancellable, error))
+                               return FALSE;
+
+                       /* this is now available to be installed if required */
+                       gs_app_set_state (runtime, AS_APP_STATE_AVAILABLE_LOCAL);
+
+                       /* we can install the runtime from this source */
+                       gs_app_set_origin (runtime, gs_app_get_id (app_src));
+               }
+       }
+
        /* parse it */
        if (!gs_flatpak_add_apps_from_xremote (self, xremote, cancellable, error))
                return NULL;
diff --git a/plugins/flatpak/gs-self-test.c b/plugins/flatpak/gs-self-test.c
index 5af23ee..3d2145f 100644
--- a/plugins/flatpak/gs-self-test.c
+++ b/plugins/flatpak/gs-self-test.c
@@ -644,8 +644,8 @@ gs_plugins_flatpak_runtime_repo_func (GsPluginLoader *plugin_loader)
 
        /* get runtime */
        runtime = gs_app_get_runtime (app);
-       g_assert_cmpstr (gs_app_get_unique_id (runtime), ==, 
"user/flatpak/*/runtime/org.test.Runtime/master");
-       g_assert_cmpint (gs_app_get_state (runtime), ==, AS_APP_STATE_UNKNOWN);
+       g_assert_cmpstr (gs_app_get_unique_id (runtime), ==, 
"user/flatpak/test/runtime/org.test.Runtime/master");
+       g_assert_cmpint (gs_app_get_state (runtime), ==, AS_APP_STATE_AVAILABLE_LOCAL);
 
        /* check the number of sources */
        g_object_unref (plugin_job);


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