[gnome-builder] flatpak: Add GbpFlatpakRunner subclass of IdeRunner



commit 54a5db98315d23fa8ef8420e2ffcf67b2d77fffe
Author: Matthew Leeds <mleeds redhat com>
Date:   Mon Nov 14 22:50:57 2016 -0800

    flatpak: Add GbpFlatpakRunner subclass of IdeRunner
    
    GbpFlatpakRunner allows flatpak runtimes to use a separate launcher for
    running apps ("flatpak run ...") than the ones that's used for building
    them ("flatpak build ...").

 libide/runner/ide-runner.c           |   10 ++
 libide/runner/ide-runner.h           |    2 +
 plugins/flatpak/Makefile.am          |    2 +
 plugins/flatpak/gbp-flatpak-runner.c |  200 ++++++++++++++++++++++++++++++++++
 plugins/flatpak/gbp-flatpak-runner.h |   34 ++++++
 5 files changed, 248 insertions(+), 0 deletions(-)
---
diff --git a/libide/runner/ide-runner.c b/libide/runner/ide-runner.c
index 6e03c41..67a7f3a 100644
--- a/libide/runner/ide-runner.c
+++ b/libide/runner/ide-runner.c
@@ -886,6 +886,16 @@ ide_runner_set_run_on_host (IdeRunner *self,
     }
 }
 
+GSubprocessFlags
+ide_runner_get_flags (IdeRunner *self)
+{
+  IdeRunnerPrivate *priv = ide_runner_get_instance_private (self);
+
+  g_return_val_if_fail (IDE_IS_RUNNER (self), 0);
+
+  return priv->flags;
+}
+
 void
 ide_runner_set_flags (IdeRunner        *self,
                       GSubprocessFlags  flags)
diff --git a/libide/runner/ide-runner.h b/libide/runner/ide-runner.h
index 3d6bb5b..d28ff82 100644
--- a/libide/runner/ide-runner.h
+++ b/libide/runner/ide-runner.h
@@ -59,6 +59,8 @@ void            ide_runner_run_async       (IdeRunner            *self,
 gboolean        ide_runner_run_finish      (IdeRunner            *self,
                                             GAsyncResult         *result,
                                             GError              **error);
+GSubprocessFlags
+                ide_runner_get_flags       (IdeRunner            *self);
 void            ide_runner_set_flags       (IdeRunner            *self,
                                             GSubprocessFlags      flags);
 gboolean        ide_runner_get_clear_env   (IdeRunner            *self);
diff --git a/plugins/flatpak/Makefile.am b/plugins/flatpak/Makefile.am
index be3fea1..147f210 100644
--- a/plugins/flatpak/Makefile.am
+++ b/plugins/flatpak/Makefile.am
@@ -17,6 +17,8 @@ libflatpak_plugin_la_SOURCES = \
        gbp-flatpak-subprocess-launcher.c \
        gbp-flatpak-subprocess-launcher.h \
        gbp-flatpak-plugin.c \
+       gbp-flatpak-runner.c \
+       gbp-flatpak-runner.h \
        $(NULL)
 
 libflatpak_plugin_la_CFLAGS = $(PLUGIN_CFLAGS) $(FLATPAK_CFLAGS)
diff --git a/plugins/flatpak/gbp-flatpak-runner.c b/plugins/flatpak/gbp-flatpak-runner.c
new file mode 100644
index 0000000..42ab776
--- /dev/null
+++ b/plugins/flatpak/gbp-flatpak-runner.c
@@ -0,0 +1,200 @@
+/* gbp-flatpak-runner.c
+ *
+ * Copyright (C) 2016 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define G_LOG_DOMAIN "gbp-flatpak-runner"
+
+#include <stdlib.h>
+#include <glib/gi18n.h>
+
+#include "gbp-flatpak-runner.h"
+
+struct _GbpFlatpakRunner
+{
+  IdeRunner parent_instance;
+};
+
+G_DEFINE_TYPE (GbpFlatpakRunner, gbp_flatpak_runner, IDE_TYPE_RUNNER)
+
+static void
+gbp_flatpak_runner_run_wait_cb (GObject      *object,
+                                GAsyncResult *result,
+                                gpointer      user_data)
+{
+  IdeSubprocess *subprocess = (IdeSubprocess *)object;
+  g_autoptr(GTask) task = user_data;
+  GError *error = NULL;
+  GbpFlatpakRunner *self;
+
+  IDE_ENTRY;
+
+  g_assert (IDE_IS_SUBPROCESS (subprocess));
+  g_assert (G_IS_ASYNC_RESULT (result));
+  g_assert (G_IS_TASK (task));
+
+  self = g_task_get_source_object (task);
+
+  g_assert (GBP_IS_FLATPAK_RUNNER (self));
+
+  g_signal_emit_by_name (&self->parent_instance, "exited");
+
+  if (!ide_subprocess_wait_finish (subprocess, result, &error))
+    {
+      g_task_return_error (task, error);
+      IDE_EXIT;
+    }
+
+  if (ide_subprocess_get_if_exited (subprocess))
+    {
+      gint exit_code;
+
+      exit_code = ide_subprocess_get_exit_status (subprocess);
+
+      if (exit_code == EXIT_SUCCESS)
+        {
+          g_task_return_boolean (task, TRUE);
+          IDE_EXIT;
+        }
+    }
+
+  g_task_return_new_error (task,
+                           G_IO_ERROR,
+                           G_IO_ERROR_FAILED,
+                           "%s",
+                           _("Process quit unexpectedly"));
+
+  IDE_EXIT;
+}
+
+static void
+gbp_flatpak_runner_run_async (IdeRunner           *runner,
+                              GCancellable        *cancellable,
+                              GAsyncReadyCallback  callback,
+                              gpointer             user_data)
+{
+  GbpFlatpakRunner *self = (GbpFlatpakRunner *)runner;
+  g_autoptr(GTask) task = NULL;
+  g_autoptr(IdeSubprocessLauncher) launcher = NULL;
+  g_autoptr(IdeSubprocess) subprocess = NULL;
+  g_auto(GStrv) argv = NULL;
+  const gchar *identifier;
+  GError *error = NULL;
+  guint argpos = 0;
+
+  IDE_ENTRY;
+
+  g_assert (GBP_IS_FLATPAK_RUNNER (self));
+  g_assert (!cancellable || G_IS_CANCELLABLE (cancellable));
+
+  task = g_task_new (self, cancellable, callback, user_data);
+  g_task_set_source_tag (task, gbp_flatpak_runner_run_async);
+
+  launcher = ide_subprocess_launcher_new (0);
+
+  ide_subprocess_launcher_set_flags (launcher, ide_runner_get_flags (&self->parent_instance));
+
+  /*
+   * We want the runners to run on the host so that we aren't captive to
+   * our containing system (flatpak, jhbuild, etc).
+   */
+  ide_subprocess_launcher_set_run_on_host (launcher, ide_runner_get_run_on_host (&self->parent_instance));
+
+  /*
+   * We don't want the environment cleared because we need access to
+   * things like DISPLAY, WAYLAND_DISPLAY, and DBUS_SESSION_BUS_ADDRESS.
+   */
+  ide_subprocess_launcher_set_clear_env (launcher, ide_runner_get_clear_env (&self->parent_instance));
+
+  /*
+   * Overlay the environment provided.
+   */
+  ide_subprocess_launcher_overlay_environment (launcher, ide_runner_get_environment 
(&self->parent_instance));
+
+  /*
+   * Push all of our configured arguments in order.
+   */
+  argv = ide_runner_get_argv (&self->parent_instance);
+  for (argpos = 0; argv[argpos] != NULL; argpos++)
+    ide_subprocess_launcher_push_argv (launcher, argv[argpos]);
+
+  /*
+   * Set the working directory for the process.
+   * FIXME: Allow this to be configurable! Add IdeRunner::cwd.
+   */
+  ide_subprocess_launcher_set_cwd (launcher, g_get_home_dir ());
+
+  subprocess = ide_subprocess_launcher_spawn (launcher, cancellable, &error);
+
+  g_assert (subprocess == NULL || IDE_IS_SUBPROCESS (subprocess));
+
+  if (subprocess == NULL)
+    {
+      g_task_return_error (task, error);
+      IDE_GOTO (failure);
+    }
+
+  identifier = ide_subprocess_get_identifier (subprocess);
+
+  g_signal_emit_by_name (&self->parent_instance, "spawned", identifier);
+
+  ide_subprocess_wait_async (subprocess,
+                             cancellable,
+                             gbp_flatpak_runner_run_wait_cb,
+                             g_steal_pointer (&task));
+
+failure:
+  IDE_EXIT;
+}
+
+static gboolean
+gbp_flatpak_runner_run_finish (IdeRunner     *runner,
+                               GAsyncResult  *result,
+                               GError       **error)
+{
+  GbpFlatpakRunner *self = (GbpFlatpakRunner *)runner;
+
+  g_assert (GBP_IS_FLATPAK_RUNNER (self));
+  g_assert (G_IS_TASK (result));
+  g_assert (g_task_is_valid (G_TASK (result), self));
+  g_assert (g_task_get_source_tag (G_TASK (result)) == gbp_flatpak_runner_run_async);
+
+  return g_task_propagate_boolean (G_TASK (result), error);
+}
+
+GbpFlatpakRunner *
+gbp_flatpak_runner_new (IdeContext *context)
+{
+  g_return_val_if_fail (IDE_IS_CONTEXT (context), NULL);
+
+  return g_object_new (GBP_TYPE_FLATPAK_RUNNER,
+                       "context", context,
+                       NULL);
+}
+
+static void
+gbp_flatpak_runner_class_init (GbpFlatpakRunnerClass *klass)
+{
+  IdeRunnerClass *runner_class = IDE_RUNNER_CLASS (klass);
+
+  runner_class->run_async = gbp_flatpak_runner_run_async;
+  runner_class->run_finish = gbp_flatpak_runner_run_finish;
+}
+
+static void
+gbp_flatpak_runner_init (GbpFlatpakRunner *self)
+{
+}
diff --git a/plugins/flatpak/gbp-flatpak-runner.h b/plugins/flatpak/gbp-flatpak-runner.h
new file mode 100644
index 0000000..50aecfb
--- /dev/null
+++ b/plugins/flatpak/gbp-flatpak-runner.h
@@ -0,0 +1,34 @@
+/* gbp-flatpak-runner.h
+ *
+ * Copyright (C) 2016 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GBP_FLATPAK_RUNNER_H
+#define GBP_FLATPAK_RUNNER_H
+
+#include <ide.h>
+
+G_BEGIN_DECLS
+
+#define GBP_TYPE_FLATPAK_RUNNER (gbp_flatpak_runner_get_type())
+
+G_DECLARE_FINAL_TYPE (GbpFlatpakRunner, gbp_flatpak_runner, GBP, FLATPAK_RUNNER, IdeRunner)
+
+GbpFlatpakRunner *gbp_flatpak_runner_new (IdeContext *context);
+
+G_END_DECLS
+
+#endif /* GBP_FLATPAK_RUNNER_H */


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