[gnome-builder] flatpak: query user before downloading runtimes
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder] flatpak: query user before downloading runtimes
- Date: Thu, 14 Mar 2019 19:01:29 +0000 (UTC)
commit d78e4050eae64d4797159d087ca07c6fa92b5f61
Author: Christian Hergert <chergert redhat com>
Date: Thu Mar 14 11:57:44 2019 -0700
flatpak: query user before downloading runtimes
This uses the new installation dialog as part of the async
workflow to initialize the build environment.
The user is queried to confirm the installation of sdk/runtime
as requested by the manifest for the target architecture.
It would be nice if we could add some more info to the
installation dialog in the future (like size, if it's missing
on the peer, etc)
src/plugins/flatpak/gbp-flatpak-runtime-provider.c | 246 +++++++++++++--------
1 file changed, 158 insertions(+), 88 deletions(-)
---
diff --git a/src/plugins/flatpak/gbp-flatpak-runtime-provider.c
b/src/plugins/flatpak/gbp-flatpak-runtime-provider.c
index 671886da6..dcc650cbe 100644
--- a/src/plugins/flatpak/gbp-flatpak-runtime-provider.c
+++ b/src/plugins/flatpak/gbp-flatpak-runtime-provider.c
@@ -24,7 +24,12 @@
#include <ostree.h>
#include <string.h>
+#include <libide-gui.h>
+
+#include "ide-gui-private.h"
+
#include "gbp-flatpak-application-addin.h"
+#include "gbp-flatpak-install-dialog.h"
#include "gbp-flatpak-manifest.h"
#include "gbp-flatpak-runtime.h"
#include "gbp-flatpak-runtime-provider.h"
@@ -46,11 +51,11 @@ typedef struct
typedef struct
{
IdeConfig *config;
- gchar *runtime_id;
- gchar *name;
- gchar *arch;
- gchar *branch;
- guint count;
+ gchar *runtime_id;
+ gchar *name;
+ gchar *arch;
+ gchar *branch;
+ gint count;
} BootstrapState;
struct _GbpFlatpakRuntimeProvider
@@ -489,7 +494,6 @@ gbp_flatpak_runtime_provider_install_async (IdeRuntimeProvider *provider,
task = ide_task_new (self, cancellable, callback, user_data);
ide_task_set_source_tag (task, gbp_flatpak_runtime_provider_install_async);
- ide_task_set_priority (task, G_PRIORITY_LOW);
if (!g_str_has_prefix (runtime_id, "flatpak:"))
IDE_GOTO (unknown_runtime_id);
@@ -541,21 +545,89 @@ gbp_flatpak_runtime_provider_install_finish (IdeRuntimeProvider *provider,
IDE_RETURN (ret);
}
+static void
+gbp_flatpak_runtime_provider_bootstrap_complete (IdeTask *task)
+{
+ IdeRuntimeManager *runtime_manager;
+ BootstrapState *state;
+ IdeContext *context;
+ IdeRuntime *runtime;
+ IdeObject *object;
+
+ g_assert (IDE_IS_MAIN_THREAD ());
+ g_assert (IDE_IS_TASK (task));
+
+ state = ide_task_get_task_data (task);
+
+ g_assert (state != NULL);
+ g_assert (state->count == 0);
+
+ object = ide_task_get_source_object (task);
+ context = ide_object_get_context (object);
+ runtime_manager = ide_runtime_manager_from_context (context);
+ runtime = ide_runtime_manager_get_runtime (runtime_manager, state->runtime_id);
+
+ if (runtime != NULL)
+ ide_task_return_pointer (task, g_object_ref (runtime), g_object_unref);
+ else
+ ide_task_return_new_error (task,
+ G_IO_ERROR,
+ G_IO_ERROR_FAILED,
+ "Failed to install runtime for build");
+}
+
+static void
+gbp_flatpak_runtime_provider_bootstrap_install_cb (GObject *object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ IdeTransferManager *transfer_manager = (IdeTransferManager *)object;
+ g_autoptr(IdeTask) task = user_data;
+ g_autoptr(GError) error = NULL;
+ BootstrapState *state;
+
+ g_assert (IDE_IS_MAIN_THREAD ());
+ g_assert (IDE_IS_TRANSFER_MANAGER (transfer_manager));
+ g_assert (G_IS_ASYNC_RESULT (result));
+ g_assert (IDE_IS_TASK (task));
+
+ state = ide_task_get_task_data (task);
+
+ g_assert (state != NULL);
+ g_assert (state->count > 0);
+
+ state->count--;
+
+ if (ide_task_had_error (task))
+ return;
+
+ /* We might still be able to find the runtime if the transfer fails */
+ ide_transfer_manager_execute_finish (transfer_manager, result, &error);
+
+ if (error != NULL)
+ g_debug ("Transfer failed: %s", error->message);
+
+ if (state->count == 0)
+ gbp_flatpak_runtime_provider_bootstrap_complete (task);
+}
+
static void
gbp_flatpak_runtime_provider_bootstrap_cb (GObject *object,
GAsyncResult *result,
gpointer user_data)
{
+ GbpFlatpakInstallDialog *dialog = (GbpFlatpakInstallDialog *)object;
GbpFlatpakRuntimeProvider *self;
g_autoptr(IdeTask) task = user_data;
g_autoptr(GError) error = NULL;
+ g_auto(GStrv) runtimes = NULL;
+ IdeTransferManager *transfer_manager;
BootstrapState *state;
g_assert (IDE_IS_MAIN_THREAD ());
- g_assert (GBP_IS_FLATPAK_RUNTIME_PROVIDER (object) ||
- IDE_IS_TRANSFER_MANAGER (object));
- g_assert (IDE_IS_TASK (task));
+ g_assert (GBP_IS_FLATPAK_INSTALL_DIALOG (dialog));
g_assert (G_IS_ASYNC_RESULT (result));
+ g_assert (IDE_IS_TASK (task));
if (ide_task_had_error (task))
return;
@@ -565,63 +637,48 @@ gbp_flatpak_runtime_provider_bootstrap_cb (GObject *object,
g_assert (GBP_IS_FLATPAK_RUNTIME_PROVIDER (self));
g_assert (state != NULL);
- g_assert (state->count > 0);
- state->count--;
-
- if (GBP_IS_FLATPAK_RUNTIME_PROVIDER (object))
+ if (!gbp_flatpak_install_dialog_run_finish (dialog, result, &error))
{
- if (!gbp_flatpak_runtime_provider_install_finish (IDE_RUNTIME_PROVIDER (object), result, &error))
- {
- g_warning ("Failed to install runtime: %s", error->message);
- if (!ide_task_get_completed (task))
- ide_task_return_error (task, g_steal_pointer (&error));
- return;
- }
+ gbp_flatpak_runtime_provider_bootstrap_complete (task);
+ return;
}
- else if (IDE_IS_TRANSFER_MANAGER (object))
+
+ runtimes = gbp_flatpak_install_dialog_get_runtimes (dialog);
+ transfer_manager = ide_transfer_manager_get_default ();
+
+ for (guint i = 0; runtimes[i]; i++)
{
- if (!ide_transfer_manager_execute_finish (IDE_TRANSFER_MANAGER (object), result, &error))
+ g_autofree gchar *name = NULL;
+ g_autofree gchar *arch = NULL;
+ g_autofree gchar *branch = NULL;
+
+ if (gbp_flatpak_split_id (runtimes[i], &name, &arch, &branch))
{
- g_warning ("Failed to install runtime: %s", error->message);
- if (!ide_task_get_completed (task))
- ide_task_return_error (task, g_steal_pointer (&error));
- return;
- }
- }
+ g_autoptr(GbpFlatpakTransfer) transfer = NULL;
+ g_autoptr(IdeNotification) notif = NULL;
- if (ide_task_return_error_if_cancelled (task))
- return;
+ state->count++;
- if (state->count == 0 && !ide_task_get_completed (task))
- {
- g_autofree gchar *runtime_id = NULL;
- IdeRuntimeManager *runtime_manager;
- IdeContext *context;
- IdeRuntime *runtime;
-
- runtime_id = g_strdup_printf ("flatpak:%s/%s/%s",
- state->name,
- state->arch,
- state->branch);
-
- context = ide_object_get_context (IDE_OBJECT (self->manager));
- runtime_manager = ide_runtime_manager_from_context (context);
- runtime = ide_runtime_manager_get_runtime (runtime_manager, runtime_id);
-
- if (runtime == NULL)
- ide_task_return_new_error (task,
- G_IO_ERROR,
- G_IO_ERROR_NOT_SUPPORTED,
- "Falling back to default runtime lookup");
- else
- ide_task_return_pointer (task, g_object_ref (runtime), g_object_unref);
+ transfer = gbp_flatpak_transfer_new (name, arch, branch, FALSE);
+ notif = ide_transfer_create_notification (IDE_TRANSFER (transfer));
+ ide_notification_attach (notif, IDE_OBJECT (self));
+
+ ide_transfer_manager_execute_async (transfer_manager,
+ IDE_TRANSFER (transfer),
+ ide_task_get_cancellable (task),
+ gbp_flatpak_runtime_provider_bootstrap_install_cb,
+ g_object_ref (task));
+ }
}
+
+ if (state->count == 0)
+ gbp_flatpak_runtime_provider_bootstrap_complete (task);
}
static void
gbp_flatpak_runtime_provider_bootstrap_async (IdeRuntimeProvider *provider,
- IdePipeline *pipeline,
+ IdePipeline *pipeline,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
@@ -630,11 +687,17 @@ gbp_flatpak_runtime_provider_bootstrap_async (IdeRuntimeProvider *provider,
g_autofree gchar *name = NULL;
g_autofree gchar *arch = NULL;
g_autofree gchar *branch = NULL;
+ g_autofree gchar *docs_id = NULL;
g_autoptr(IdeTask) task = NULL;
- IdeConfig *config;
+ g_auto(GStrv) runtimes = NULL;
+ GbpFlatpakApplicationAddin *addin;
+ GbpFlatpakInstallDialog *dialog;
BootstrapState *state;
+ IdeWorkbench *workbench;
const gchar *runtime_id;
const gchar *build_arch;
+ IdeContext *context;
+ IdeConfig *config;
IDE_ENTRY;
@@ -643,9 +706,10 @@ gbp_flatpak_runtime_provider_bootstrap_async (IdeRuntimeProvider *provider,
g_assert (!cancellable || G_IS_CANCELLABLE (cancellable));
task = ide_task_new (self, cancellable, callback, user_data);
+ ide_task_set_release_on_propagate (task, FALSE);
ide_task_set_source_tag (task, gbp_flatpak_runtime_provider_bootstrap_async);
- ide_task_set_priority (task, G_PRIORITY_LOW);
+ context = ide_object_get_context (IDE_OBJECT (self));
build_arch = ide_pipeline_get_arch (pipeline);
config = ide_pipeline_get_config (pipeline);
runtime_id = ide_config_get_runtime_id (config);
@@ -661,6 +725,13 @@ gbp_flatpak_runtime_provider_bootstrap_async (IdeRuntimeProvider *provider,
IDE_EXIT;
}
+ /* Create dialog to potentially query user if we are allowed to install */
+ dialog = gbp_flatpak_install_dialog_new ();
+ workbench = _ide_workbench_from_context (context);
+ gtk_window_group_add_window (GTK_WINDOW_GROUP (workbench), GTK_WINDOW (dialog));
+ gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
+
+ /* Create state for async op */
state = g_slice_new0 (BootstrapState);
state->config = g_object_ref (config);
state->runtime_id = g_strdup_printf ("flatpak:%s/%s/%s", name, build_arch, branch);
@@ -669,52 +740,51 @@ gbp_flatpak_runtime_provider_bootstrap_async (IdeRuntimeProvider *provider,
state->arch = g_strdup (build_arch);
ide_task_set_task_data (task, state, bootstrap_state_free);
+ addin = gbp_flatpak_application_addin_get_default ();
+
+ /* Add all the runtimes the manifest needs */
if (GBP_IS_FLATPAK_MANIFEST (state->config))
{
- IdeTransferManager *transfer_manager;
- GbpFlatpakApplicationAddin *addin;
- const gchar * const *sdk_exts;
+ g_auto(GStrv) all = NULL;
- transfer_manager = ide_transfer_manager_get_default ();
- addin = gbp_flatpak_application_addin_get_default ();
- sdk_exts = gbp_flatpak_manifest_get_sdk_extensions (GBP_FLATPAK_MANIFEST (state->config));
+ all = gbp_flatpak_manifest_get_runtimes (GBP_FLATPAK_MANIFEST (state->config),
+ state->arch);
- if (sdk_exts != NULL)
+ if (all != NULL)
{
- for (guint i = 0; sdk_exts[i] != NULL; i++)
+ for (guint i = 0; all[i]; i++)
{
- g_autofree gchar *ext_id = NULL;
- g_autofree gchar *ext_arch = NULL;
- g_autofree gchar *ext_branch = NULL;
+ g_autofree gchar *item_name = NULL;
+ g_autofree gchar *item_arch = NULL;
+ g_autofree gchar *item_branch = NULL;
- if (gbp_flatpak_split_id (sdk_exts[i], &ext_id, &ext_arch, &ext_branch))
+ if (gbp_flatpak_split_id (all[i], &item_name, &item_arch, &item_branch))
{
- /* Check for runtime with the arch of the device */
- if (!gbp_flatpak_application_addin_has_runtime (addin, ext_id, state->arch, ext_branch))
- {
- g_autoptr(GbpFlatpakTransfer) transfer = NULL;
-
- state->count++;
-
- transfer = gbp_flatpak_transfer_new (ext_id, arch, ext_branch, FALSE);
- ide_transfer_manager_execute_async (transfer_manager,
- IDE_TRANSFER (transfer),
- cancellable,
- gbp_flatpak_runtime_provider_bootstrap_cb,
- g_object_ref (task));
- }
+ if (!gbp_flatpak_application_addin_has_runtime (addin, item_name, item_arch, item_branch))
+ gbp_flatpak_install_dialog_add_runtime (dialog, all[i]);
}
}
}
}
- state->count++;
+ /* Add runtime specifically (in case no manifest is set) */
+ if (!gbp_flatpak_application_addin_has_runtime (addin, state->name, state->arch, state->branch))
+ gbp_flatpak_install_dialog_add_runtime_full (dialog, state->name, state->arch, state->branch);
- gbp_flatpak_runtime_provider_install_async (IDE_RUNTIME_PROVIDER (self),
- state->runtime_id,
- cancellable,
- gbp_flatpak_runtime_provider_bootstrap_cb,
- g_object_ref (task));
+ runtimes = gbp_flatpak_install_dialog_get_runtimes (dialog);
+
+ if (runtimes == NULL || runtimes[0] == NULL)
+ {
+ gtk_widget_destroy (GTK_WIDGET (dialog));
+ gbp_flatpak_runtime_provider_bootstrap_complete (task);
+ }
+ else
+ {
+ gbp_flatpak_install_dialog_run_async (dialog,
+ cancellable,
+ gbp_flatpak_runtime_provider_bootstrap_cb,
+ g_object_ref (task));
+ }
IDE_EXIT;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]