From 0da103748a060f70ab2777d2d2e82384fbb6ca3c Mon Sep 17 00:00:00 2001 From: Alexander Larsson Date: Mon, 28 Aug 2017 18:17:58 +0200 Subject: [PATCH] flatpakref: Add new SuggestRemoteName key support If a flatpakref has this set, for instance: SuggestRemoteName=gnome-apps Then flatpak install will ask if you want to configure this as a "real" remote, rather than an origin remote (which will only install that app). This is useful when creating flatpakref files for remotes that have multiple applications in them, such as e.g. flathub or the gnome nightly builds. However, it should not be set of one-application repositories. --- app/flatpak-builtins-install.c | 62 +++++++++++++++++++++++++++++++++- common/flatpak-dir.c | 22 ++++++++---- common/flatpak-dir.h | 5 +++ 3 files changed, 81 insertions(+), 8 deletions(-) diff --git a/app/flatpak-builtins-install.c b/app/flatpak-builtins-install.c index 0fd74b05..d3fa0f11 100644 --- a/app/flatpak-builtins-install.c +++ b/app/flatpak-builtins-install.c @@ -188,7 +188,7 @@ handle_runtime_repo_deps (FlatpakDir *dir, const char *dep_url, GError **error) } while (remotes != NULL && g_strv_contains ((const char * const*)remotes, new_remote)); - config = flatpak_dir_parse_repofile (dir, new_remote, dep_data, &gpg_key, NULL, error); + config = flatpak_dir_parse_repofile (dir, new_remote, FALSE, dep_data, &gpg_key, NULL, error); if (config == NULL) { g_prefix_error (error, "Can't parse dependent file %s: ", dep_url); @@ -297,6 +297,62 @@ install_bundle (FlatpakDir *dir, return TRUE; } +static gboolean +handle_suggested_remote_name (FlatpakDir *dir, GBytes *data, GError **error) +{ + g_autoptr(GKeyFile) keyfile = g_key_file_new (); + g_autofree char *suggested_name = NULL; + g_autofree char *url = NULL; + g_autofree char *collection_id = NULL; + g_autoptr(GKeyFile) config = NULL; + g_autoptr(GBytes) gpg_key = NULL; + + if (!g_key_file_load_from_data (keyfile, g_bytes_get_data (data, NULL), g_bytes_get_size (data), + 0, error)) + return FALSE; + + suggested_name = g_key_file_get_string (keyfile, FLATPAK_REF_GROUP, + FLATPAK_REF_SUGGEST_REMOTE_NAME_KEY, NULL); + if (suggested_name == NULL) + return TRUE; + + url = g_key_file_get_string (keyfile, FLATPAK_REF_GROUP, + FLATPAK_REF_URL_KEY, NULL); + if (url == NULL) + return TRUE; + +#ifdef FLATPAK_ENABLE_P2P + collection_id = g_key_file_get_string (keyfile, FLATPAK_REF_GROUP, FLATPAK_REF_COLLECTION_ID_KEY, NULL); +#endif /* FLATPAK_ENABLE_P2P */ + + if (remote_is_already_configured (dir, url, collection_id)) + return TRUE; + + /* The name is already used, ignore */ + if (ostree_repo_remote_get_url (flatpak_dir_get_repo (dir), suggested_name, NULL, NULL)) + return TRUE; + + if (opt_yes || + flatpak_yes_no_prompt (_("The remote '%s', at location %s contains additional applications.\nDo you want to install other applications from here?"), + suggested_name, url)) + { + if (opt_yes) + g_print (_("Configuring %s as new remote '%s'"), url, suggested_name); + + config = flatpak_dir_parse_repofile (dir, suggested_name, TRUE, data, &gpg_key, NULL, error); + if (config == NULL) + return FALSE; + + if (!flatpak_dir_modify_remote (dir, suggested_name, config, gpg_key, NULL, error)) + return FALSE; + + if (!flatpak_dir_recreate_repo (dir, NULL, error)) + return FALSE; + } + + return TRUE; +} + static gboolean handle_runtime_repo_deps_from_keyfile (FlatpakDir *dir, GBytes *data, GError **error) { @@ -365,6 +421,10 @@ install_from (FlatpakDir *dir, file_data = g_bytes_new_take (g_steal_pointer (&data), data_len); } + /* Handle this before the runtime deps, because they might be the same */ + if (!handle_suggested_remote_name (dir, file_data, error)) + return FALSE; + if (!handle_runtime_repo_deps_from_keyfile (dir, file_data, error)) return FALSE; diff --git a/common/flatpak-dir.c b/common/flatpak-dir.c index 4f808752..aa077096 100644 --- a/common/flatpak-dir.c +++ b/common/flatpak-dir.c @@ -8056,6 +8056,7 @@ flatpak_dir_create_origin_remote (FlatpakDir *self, GKeyFile * flatpak_dir_parse_repofile (FlatpakDir *self, const char *remote_name, + gboolean from_ref, GBytes *data, GBytes **gpg_data_out, GCancellable *cancellable, @@ -8070,6 +8071,13 @@ flatpak_dir_parse_repofile (FlatpakDir *self, g_autofree char *collection_id = NULL; g_autofree char *default_branch = NULL; gboolean nodeps; + const char *source_group; + + if (from_ref) + source_group = FLATPAK_REF_GROUP; + else + source_group = FLATPAK_REPO_GROUP; + GKeyFile *config = g_key_file_new (); g_autofree char *group = g_strdup_printf ("remote \"%s\"", remote_name); @@ -8082,13 +8090,13 @@ flatpak_dir_parse_repofile (FlatpakDir *self, return NULL; } - if (!g_key_file_has_group (keyfile, FLATPAK_REPO_GROUP)) + if (!g_key_file_has_group (keyfile, source_group)) { flatpak_fail (error, "Invalid .flatpakref\n"); return NULL; } - uri = g_key_file_get_string (keyfile, FLATPAK_REPO_GROUP, + uri = g_key_file_get_string (keyfile, source_group, FLATPAK_REPO_URL_KEY, NULL); if (uri == NULL) { @@ -8098,22 +8106,22 @@ flatpak_dir_parse_repofile (FlatpakDir *self, g_key_file_set_string (config, group, "url", uri); - title = g_key_file_get_locale_string (keyfile, FLATPAK_REPO_GROUP, + title = g_key_file_get_locale_string (keyfile, source_group, FLATPAK_REPO_TITLE_KEY, NULL, NULL); if (title != NULL) g_key_file_set_string (config, group, "xa.title", title); - default_branch = g_key_file_get_locale_string (keyfile, FLATPAK_REPO_GROUP, + default_branch = g_key_file_get_locale_string (keyfile, source_group, FLATPAK_REPO_DEFAULT_BRANCH_KEY, NULL, NULL); if (default_branch != NULL) g_key_file_set_string (config, group, "xa.default-branch", default_branch); - nodeps = g_key_file_get_boolean (keyfile, FLATPAK_REPO_GROUP, + nodeps = g_key_file_get_boolean (keyfile, source_group, FLATPAK_REPO_NODEPS_KEY, NULL); if (nodeps) g_key_file_set_boolean (config, group, "xa.nodeps", TRUE); - gpg_key = g_key_file_get_string (keyfile, FLATPAK_REPO_GROUP, + gpg_key = g_key_file_get_string (keyfile, source_group, FLATPAK_REPO_GPGKEY_KEY, NULL); if (gpg_key != NULL) { @@ -8133,7 +8141,7 @@ flatpak_dir_parse_repofile (FlatpakDir *self, } #ifdef FLATPAK_ENABLE_P2P - collection_id = g_key_file_get_string (keyfile, FLATPAK_REPO_GROUP, + collection_id = g_key_file_get_string (keyfile, source_group, FLATPAK_REPO_COLLECTION_ID_KEY, NULL); #else /* if !FLATPAK_ENABLE_P2P */ collection_id = NULL; diff --git a/common/flatpak-dir.h b/common/flatpak-dir.h index ff928c77..ba8465bb 100644 --- a/common/flatpak-dir.h +++ b/common/flatpak-dir.h @@ -41,6 +41,7 @@ GType flatpak_deploy_get_type (void); #define FLATPAK_REF_VERSION_KEY "Version" #define FLATPAK_REF_URL_KEY "Url" #define FLATPAK_REF_RUNTIME_REPO_KEY "RuntimeRepo" +#define FLATPAK_REF_SUGGEST_REMOTE_NAME_KEY "SuggestRemoteName" #define FLATPAK_REF_TITLE_KEY "Title" #define FLATPAK_REF_GPGKEY_KEY "GPGKey" #define FLATPAK_REF_IS_RUNTIME_KEY "IsRuntime" @@ -504,8 +505,12 @@ gboolean flatpak_dir_create_remote_for_ref_file (FlatpakDir *self, char **remote_name_out, char **ref_out, GError **error); +gboolean flatpak_dir_create_suggested_remote_for_ref_file (FlatpakDir *self, + GBytes *data, + GError **error); GKeyFile * flatpak_dir_parse_repofile (FlatpakDir *self, const char *remote_name, + gboolean from_ref, GBytes *data, GBytes **gpg_data_out, GCancellable *cancellable,