From 089a5bebd5ea1ca1746b1a9aa4fc6471c99061e0 Mon Sep 17 00:00:00 2001 From: Alexander Larsson Date: Wed, 4 Nov 2020 11:27:24 +0100 Subject: [PATCH] Add flatpak_dir_list_remote_refs_decomposed() --- common/flatpak-dir-private.h | 5 +++ common/flatpak-dir.c | 69 +++++++++++++++++++++++++++++++++--- 2 files changed, 70 insertions(+), 4 deletions(-) diff --git a/common/flatpak-dir-private.h b/common/flatpak-dir-private.h index e0a589c7..4cd779ff 100644 --- a/common/flatpak-dir-private.h +++ b/common/flatpak-dir-private.h @@ -920,6 +920,11 @@ gboolean flatpak_dir_list_remote_refs (FlatpakDir *self, GHashTable **refs, GCancellable *cancellable, GError **error); +gboolean flatpak_dir_list_remote_refs_decomposed (FlatpakDir *self, + FlatpakRemoteState *state, + GHashTable **refs, + GCancellable *cancellable, + GError **error); gboolean flatpak_dir_list_all_remote_refs (FlatpakDir *self, FlatpakRemoteState *state, GHashTable **out_all_refs, diff --git a/common/flatpak-dir.c b/common/flatpak-dir.c index 23c47646..266fa567 100644 --- a/common/flatpak-dir.c +++ b/common/flatpak-dir.c @@ -14136,9 +14136,9 @@ flatpak_dir_modify_remote (FlatpakDir *self, } static gboolean -remove_unless_in_hash (gpointer key, - gpointer value, - gpointer user_data) +remove_unless_ref_in_hash (gpointer key, + gpointer value, + gpointer user_data) { GHashTable *table = user_data; const char *ref_name = key; @@ -14190,13 +14190,74 @@ flatpak_dir_list_remote_refs (FlatpakDir *self, /* Then we remove all remote refs not in the local refs set */ g_hash_table_foreach_remove (*refs, - remove_unless_in_hash, + remove_unless_ref_in_hash, unprefixed_local_refs); } return TRUE; } +static gboolean +remove_unless_decomposed_in_hash (gpointer key, + gpointer value, + gpointer user_data) +{ + GHashTable *table = user_data; + const FlatpakDecomposed *d = key; + + return !g_hash_table_contains (table, d); +} + +gboolean +flatpak_dir_list_remote_refs_decomposed (FlatpakDir *self, + FlatpakRemoteState *state, + GHashTable **refs, + GCancellable *cancellable, + GError **error) +{ + g_autoptr(GError) my_error = NULL; + + if (error == NULL) + error = &my_error; + + if (!flatpak_dir_list_all_remote_refs_decomposed (self, state, refs, + cancellable, error)) + return FALSE; + + if (flatpak_dir_get_remote_noenumerate (self, state->remote_name)) + { + g_autoptr(GHashTable) decomposed_local_refs = + g_hash_table_new_full ((GHashFunc)flatpak_decomposed_hash, (GEqualFunc)flatpak_decomposed_equal, (GDestroyNotify)flatpak_decomposed_unref, NULL); + g_autoptr(GHashTable) local_refs = NULL; + GHashTableIter hash_iter; + gpointer key; + g_autofree char *refspec_prefix = g_strconcat (state->remote_name, ":.", NULL); + + /* For noenumerate remotes, only return data for already locally + * available refs */ + + if (!ostree_repo_list_refs (self->repo, refspec_prefix, &local_refs, + cancellable, error)) + return FALSE; + + g_hash_table_iter_init (&hash_iter, local_refs); + while (g_hash_table_iter_next (&hash_iter, &key, NULL)) + { + const char *refspec = key; + g_autoptr(FlatpakDecomposed) d = flatpak_decomposed_new_from_refspec (refspec, NULL); + if (d) + g_hash_table_insert (decomposed_local_refs, g_steal_pointer (&d), NULL); + } + + /* Then we remove all remote refs not in the local refs set */ + g_hash_table_foreach_remove (*refs, + remove_unless_decomposed_in_hash, + decomposed_local_refs); + } + + return TRUE; +} + static gboolean strv_contains_prefix (const gchar * const *strv, const gchar *str)