[gnome-software/uajain/resolve-ref] flatpak: Introduce a utility to resolve default arch for refs



commit 6f1f3af6bae01f800e54a91091ab68b8f72f5ac4
Author: Umang Jain <umang endlessm com>
Date:   Tue Aug 6 16:54:31 2019 +0530

    flatpak: Introduce a utility to resolve default arch for refs
    
    This is originated to address the case of external-appstream
    that can be used to mention additional appdata for a given GsApp.
    However, the `source` parameter for a flatpak GsApp is dependent
    on the arch of the system. This patch allows the external appstream
    to optionally omit the arch and gnome-software will assume the
    default arch and re-create the source parameter with the correct ref.
    The corrected ref is parsed through `flatpak_ref_parse` for sanity.
    
    Example of an external appstream 'source' parameter resolution:
    <bundle type="flatpak">app/org.telegram.desktop//stable</flatpak>
    resolves to: `app/org.telegram.desktop/x86_64/stable` for a
    x86_64 platform.
    
    https://phabricator.endlessm.com/T26507

 plugins/flatpak/gs-flatpak-utils.c | 14 ++++++++++++++
 plugins/flatpak/gs-flatpak-utils.h |  1 +
 plugins/flatpak/gs-flatpak.c       | 23 +++++++++++++++++------
 3 files changed, 32 insertions(+), 6 deletions(-)
---
diff --git a/plugins/flatpak/gs-flatpak-utils.c b/plugins/flatpak/gs-flatpak-utils.c
index 89cc3cf2..a0c1feb5 100644
--- a/plugins/flatpak/gs-flatpak-utils.c
+++ b/plugins/flatpak/gs-flatpak-utils.c
@@ -206,3 +206,17 @@ gs_flatpak_app_new_from_repo_file (GFile *file,
        /* success */
        return g_steal_pointer (&app);
 }
+
+char *
+gs_flatpak_app_source_resolve_default_arch (const gchar *source)
+{
+       g_auto(GStrv) split = g_strsplit (source, "/", -1);
+
+       if (g_strv_length (split) != 4)
+               return NULL;
+
+       if (strlen (split[2]) != 0)
+               return NULL;
+
+       return g_strjoin ("/", split[0], split[1], flatpak_get_default_arch (), split[3], NULL);
+}
diff --git a/plugins/flatpak/gs-flatpak-utils.h b/plugins/flatpak/gs-flatpak-utils.h
index 64f7713a..aff47911 100644
--- a/plugins/flatpak/gs-flatpak-utils.h
+++ b/plugins/flatpak/gs-flatpak-utils.h
@@ -16,5 +16,6 @@ GsApp         *gs_flatpak_app_new_from_remote         (FlatpakRemote  *xremote);
 GsApp          *gs_flatpak_app_new_from_repo_file      (GFile          *file,
                                                         GCancellable   *cancellable,
                                                         GError         **error);
+char           *gs_flatpak_app_source_resolve_default_arch (const gchar *source);
 
 G_END_DECLS
diff --git a/plugins/flatpak/gs-flatpak.c b/plugins/flatpak/gs-flatpak.c
index a8fb5f59..c6caf580 100644
--- a/plugins/flatpak/gs-flatpak.c
+++ b/plugins/flatpak/gs-flatpak.c
@@ -1549,6 +1549,7 @@ gs_refine_item_metadata (GsFlatpak *self, GsApp *app,
                         GError **error)
 {
        g_autoptr(FlatpakRef) xref = NULL;
+       const gchar *source;
 
        /* already set */
        if (gs_flatpak_app_get_ref_name (app) != NULL)
@@ -1558,9 +1559,10 @@ gs_refine_item_metadata (GsFlatpak *self, GsApp *app,
        if (gs_app_get_kind (app) == AS_APP_KIND_SOURCE)
                return TRUE;
 
+       source = gs_app_get_source_default (app);
        /* AppStream sets the source to appname/arch/branch, if this isn't set
         * we can't break out the fields */
-       if (gs_app_get_source_default (app) == NULL) {
+       if (source == NULL) {
                g_autofree gchar *tmp = gs_app_to_string (app);
                g_warning ("no source set by appstream for %s: %s",
                           gs_plugin_get_name (self->plugin), tmp);
@@ -1568,12 +1570,21 @@ gs_refine_item_metadata (GsFlatpak *self, GsApp *app,
        }
 
        /* parse the ref */
-       xref = flatpak_ref_parse (gs_app_get_source_default (app), error);
+       xref = flatpak_ref_parse (source, error);
        if (xref == NULL) {
-               gs_flatpak_error_convert (error);
-               g_prefix_error (error, "failed to parse '%s': ",
-                               gs_app_get_source_default (app));
-               return FALSE;
+               g_autofree gchar *resolved_source;
+               resolved_source = gs_flatpak_app_source_resolve_default_arch (source);
+
+               /* Sources mentioned in external-appstream might use refs without specifying
+                * the arch. Hence, try to parse the arch-resolved ref and see if it succeeds */
+               xref = flatpak_ref_parse (resolved_source, NULL);
+               if (xref == NULL) {
+                       gs_flatpak_error_convert (error);
+                       g_prefix_error (error, "failed to parse '%s': ",
+                                       gs_app_get_source_default (app));
+                       return FALSE;
+               }
+               g_clear_error (error);
        }
        gs_flatpak_set_metadata (self, app, xref);
 


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