From c01fdee171d292c7f59be7de3f41937e7878bcbb Mon Sep 17 00:00:00 2001 From: Alexander Larsson Date: Wed, 8 May 2019 11:59:35 +0200 Subject: [PATCH] lib Add flatpak_remote_new_from_file() to add remotes from flatpakrefs Closes: #2888 Approved by: alexlarsson --- common/flatpak-remote.c | 86 ++++++++++++++++++++++++- common/flatpak-remote.h | 3 + doc/reference/flatpak-sections.txt | 1 + tests/testlibrary.c | 100 +++++++++++++++++++++++++++++ 4 files changed, 189 insertions(+), 1 deletion(-) diff --git a/common/flatpak-remote.c b/common/flatpak-remote.c index 72b0bfe1..16e00eb2 100644 --- a/common/flatpak-remote.c +++ b/common/flatpak-remote.c @@ -1089,6 +1089,90 @@ flatpak_remote_new (const char *name) return flatpak_remote_new_with_dir (name, NULL); } + +#define read_str_option(_key, _field) \ + { \ + char *val = g_key_file_get_string (config, group, _key, NULL); \ + if (val != NULL) { \ + priv->local_ ## _field = val; \ + priv->local_ ## _field ## _set = TRUE; \ + } \ + } + +#define read_bool_option(_key, _field) \ + if (g_key_file_has_key (config, group, _key, NULL)) { \ + priv->local_ ## _field = g_key_file_get_boolean (config, group, _key, NULL); \ + priv->local_ ## _field ## _set = TRUE; \ + } + +#define read_int_option(_key, _field) \ + if (g_key_file_has_key (config, group, _key, NULL)) { \ + priv->local_ ## _field = g_key_file_get_integer (config, group, _key, NULL); \ + priv->local_ ## _field ## _set = TRUE; \ + } + + +/** + * flatpak_remote_new_from_file: + * @name: a name + * @data: The content of a flatpakrepo file + * @error: return location for a #GError + * + * Returns a new pre-filled remote object which can be used to configure a new remote. + * The fields in the remote are filled in according to the values in the + * passed in flatpakrepo file. + * + * Note: This is a local configuration object, you must commit changes + * using flatpak_installation_modify_remote() or flatpak_installation_add_remote() for the changes to take + * effect. + * + * Returns: (transfer full): a new #FlatpakRemote, or %NULL on error + * + * Since: 1.3.4 + **/ +FlatpakRemote * +flatpak_remote_new_from_file (const char *name, GBytes *data, GError **error) +{ + FlatpakRemote *remote = flatpak_remote_new (name); + FlatpakRemotePrivate *priv = flatpak_remote_get_instance_private (remote); + g_autofree char *group = g_strdup_printf ("remote \"%s\"", name); + g_autoptr(GKeyFile) keyfile = g_key_file_new (); + g_autoptr(GKeyFile) config = NULL; + g_autoptr(GBytes) gpg_data = NULL; + + if (!g_key_file_load_from_data (keyfile, g_bytes_get_data (data, NULL), g_bytes_get_size (data), 0, error)) + return NULL; + + config = flatpak_parse_repofile (name, FALSE, keyfile, &gpg_data, NULL, error); + if (config == NULL) + return NULL; + + priv->local_gpg_key = g_steal_pointer (&gpg_data); + + read_str_option("url", url); + read_str_option("collection-id", collection_id); + read_str_option("xa.title", title); + read_str_option("xa.filter", filter); + /* Canonicalize empty to null-but-is-set */ + if (priv->local_filter && priv->local_filter[0] == 0) + g_free (g_steal_pointer (&priv->local_filter)); + read_str_option("xa.comment", comment); + read_str_option("xa.description", description); + read_str_option("xa.homepage", homepage); + read_str_option("xa.icon", icon); + read_str_option("xa.default-branch", default_branch); + read_str_option("xa.main-ref", main_ref); + + read_bool_option("xa.gpg-verify", gpg_verify); + read_bool_option("xa.noenumerate", noenumerate); + read_bool_option("xa.disable", disabled); + read_bool_option("xa.nodeps", nodeps); + + read_int_option("xa.prio", prio); + + return remote; +} + /* copied from GLib */ static gboolean g_key_file_is_group_name (const gchar *name) @@ -1192,7 +1276,7 @@ flatpak_remote_commit (FlatpakRemote *self, g_key_file_set_string (config, group, "xa.title", priv->local_title); if (priv->local_filter_set) - g_key_file_set_string (config, group, "xa.filter", priv->local_filter); + g_key_file_set_string (config, group, "xa.filter", priv->local_filter ? priv->local_filter : ""); if (priv->local_comment_set) g_key_file_set_string (config, group, "xa.comment", priv->local_comment); diff --git a/common/flatpak-remote.h b/common/flatpak-remote.h index 80fe2292..fa223d33 100644 --- a/common/flatpak-remote.h +++ b/common/flatpak-remote.h @@ -65,6 +65,9 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC (FlatpakRemote, g_object_unref) #endif FLATPAK_EXTERN FlatpakRemote * flatpak_remote_new (const char *name); +FLATPAK_EXTERN FlatpakRemote * flatpak_remote_new_from_file (const char *name, + GBytes *data, + GError **error); FLATPAK_EXTERN const char * flatpak_remote_get_name (FlatpakRemote *self); FLATPAK_EXTERN GFile * flatpak_remote_get_appstream_dir (FlatpakRemote *self, diff --git a/doc/reference/flatpak-sections.txt b/doc/reference/flatpak-sections.txt index db585b75..08f7b22e 100644 --- a/doc/reference/flatpak-sections.txt +++ b/doc/reference/flatpak-sections.txt @@ -151,6 +151,7 @@ flatpak_ref_get_type FlatpakRemote FlatpakRemote flatpak_remote_new +flatpak_remote_new_from_file flatpak_remote_get_name flatpak_remote_get_appstream_dir flatpak_remote_get_appstream_timestamp diff --git a/tests/testlibrary.c b/tests/testlibrary.c index 64c33401..f2773dc8 100644 --- a/tests/testlibrary.c +++ b/tests/testlibrary.c @@ -683,6 +683,105 @@ test_remote_new (void) g_clear_error (&error); } +static void +test_remote_new_from_file (void) +{ + g_autoptr(FlatpakInstallation) inst = NULL; + g_autoptr(FlatpakRemote) remote = NULL; + g_autoptr(GError) error = NULL; + gboolean res; + const char *_data = + "[Flatpak Repo]\n" + "Url=http://127.0.0.1/repo\n" + "Title=The Title\n" + "Comment=The Comment\n" + "Description=The Description\n" + "Homepage=https://the.homepage/\n" + "Icon=https://the.icon/\n" + "DefaultBranch=default-branch\n" + "NoDeps=true\n"; + g_autoptr(GBytes) data = g_bytes_new_static (_data, strlen (_data)); + + inst = flatpak_installation_new_user (NULL, &error); + g_assert_no_error (error); + + remote = flatpak_installation_get_remote_by_name (inst, "file-remote", NULL, &error); + g_assert_null (remote); + g_assert_error (error, FLATPAK_ERROR, FLATPAK_ERROR_REMOTE_NOT_FOUND); + g_clear_error (&error); + + remote = flatpak_remote_new_from_file ("file-remote", data, &error); + g_assert_nonnull (remote); + g_assert_no_error (error); + + res = flatpak_installation_add_remote (inst, remote, FALSE, NULL, &error); + g_assert_no_error (error); + g_assert_true (res); + + g_clear_object (&remote); + + remote = flatpak_installation_get_remote_by_name (inst, "file-remote", NULL, &error); + g_assert_no_error (error); + + g_assert_cmpstr (flatpak_remote_get_url (remote), ==, "http://127.0.0.1/repo"); + g_assert_cmpstr (flatpak_remote_get_title (remote), ==, "The Title"); + g_assert_cmpstr (flatpak_remote_get_comment (remote), ==, "The Comment"); + g_assert_cmpstr (flatpak_remote_get_description (remote), ==, "The Description"); + g_assert_cmpstr (flatpak_remote_get_homepage (remote), ==, "https://the.homepage/"); + g_assert_cmpstr (flatpak_remote_get_icon (remote), ==, "https://the.icon/"); + g_assert_cmpstr (flatpak_remote_get_default_branch (remote), ==, "default-branch"); + g_assert_cmpint (flatpak_remote_get_nodeps (remote), ==, TRUE); + + g_clear_object (&remote); + + remote = flatpak_installation_get_remote_by_name (inst, "file-remote", NULL, &error); + g_assert_no_error (error); + + g_assert_cmpstr (flatpak_remote_get_filter (remote), ==, NULL); + + flatpak_remote_set_url (remote, "http://127.0.0.1/other"); + flatpak_remote_set_filter (remote, "/some/path/to/filter"); + + res = flatpak_installation_modify_remote (inst, remote, NULL, &error); + g_assert_no_error (error); + g_assert_true (res); + + g_clear_object (&remote); + + remote = flatpak_installation_get_remote_by_name (inst, "file-remote", NULL, &error); + g_assert_no_error (error); + + g_assert_cmpstr (flatpak_remote_get_url (remote), ==, "http://127.0.0.1/other"); + g_assert_cmpstr (flatpak_remote_get_filter (remote), ==, "/some/path/to/filter"); + + g_clear_object (&remote); + + remote = flatpak_remote_new_from_file ("file-remote", data, &error); + g_assert_nonnull (remote); + g_assert_no_error (error); + + /* regular add fails */ + res = flatpak_installation_add_remote (inst, remote, FALSE, NULL, &error); + g_assert_error (error, FLATPAK_ERROR, FLATPAK_ERROR_ALREADY_INSTALLED); + g_clear_error (&error); + g_assert_false (res); + + /* add if needed succeeds and resets filter */ + res = flatpak_installation_add_remote (inst, remote, TRUE, NULL, &error); + g_assert_no_error (error); + g_assert_true (res); + + g_clear_object (&remote); + + remote = flatpak_installation_get_remote_by_name (inst, "file-remote", NULL, &error); + g_assert_no_error (error); + + g_assert_cmpstr (flatpak_remote_get_url (remote), ==, "http://127.0.0.1/other"); + g_assert_cmpstr (flatpak_remote_get_filter (remote), ==, NULL); + + g_clear_object (&remote); +} + static void test_list_refs (void) { @@ -3544,6 +3643,7 @@ main (int argc, char *argv[]) g_test_add_func ("/library/remote-by-name", test_remote_by_name); g_test_add_func ("/library/remote", test_remote); g_test_add_func ("/library/remote-new", test_remote_new); + g_test_add_func ("/library/remote-new-from-file", test_remote_new_from_file); g_test_add_func ("/library/list-remote-refs", test_list_remote_refs); g_test_add_func ("/library/list-remote-related-refs", test_list_remote_related_refs); g_test_add_func ("/library/list-refs", test_list_refs);