[gnome-builder/wip/chergert/gnome-builder-git: 4/4] git: add GbpGitClient
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder/wip/chergert/gnome-builder-git: 4/4] git: add GbpGitClient
- Date: Sat, 6 Apr 2019 16:57:08 +0000 (UTC)
commit 3b90278ed1c66beb7f300184bf5ee4a22369e59e
Author: Christian Hergert <chergert redhat com>
Date: Fri Apr 5 18:29:47 2019 -0700
git: add GbpGitClient
The GbpGitClient object prepares and maintains state using the
IdeSubprocessSupervisor to manage gnome-builder-git subprocesses. It
also provides access to the IpcGitService peer running in the daemon.
src/plugins/git/gbp-git-client.c | 275 +++++++++++++++++++++++++++++++++++++++
src/plugins/git/gbp-git-client.h | 42 ++++++
src/plugins/git/meson.build | 9 ++
3 files changed, 326 insertions(+)
---
diff --git a/src/plugins/git/gbp-git-client.c b/src/plugins/git/gbp-git-client.c
new file mode 100644
index 000000000..a20e5f639
--- /dev/null
+++ b/src/plugins/git/gbp-git-client.c
@@ -0,0 +1,275 @@
+/* gbp-git-client.c
+ *
+ * Copyright 2019 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/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#define G_LOG_DOMAIN "gbp-git-client"
+
+#include "config.h"
+
+#include <gio/gunixinputstream.h>
+#include <gio/gunixoutputstream.h>
+#include <glib-unix.h>
+#include <libide-threading.h>
+
+#include "gbp-git-client.h"
+
+struct _GbpGitClient
+{
+ IdeObject parent;
+ IdeSubprocessSupervisor *supervisor;
+ GDBusConnection *connection;
+ IpcGitService *service;
+ GQueue get_service;
+ gint state;
+};
+
+enum {
+ STATE_INITIAL,
+ STATE_SPAWNING,
+ STATE_RUNNING,
+ STATE_SHUTDOWN,
+};
+
+G_DEFINE_TYPE (GbpGitClient, gbp_git_client, IDE_TYPE_OBJECT)
+
+static void
+gbp_git_client_subprocess_spawned (GbpGitClient *self,
+ IdeSubprocess *subprocess,
+ IdeSubprocessSupervisor *supervisor)
+{
+ g_autoptr(GIOStream) stream = NULL;
+ g_autoptr(GVariant) params = NULL;
+ GOutputStream *output;
+ GInputStream *input;
+ GList *queued;
+ gint fd;
+
+ IDE_ENTRY;
+
+ g_assert (GBP_IS_GIT_CLIENT (self));
+ g_assert (IDE_IS_SUBPROCESS (subprocess));
+ g_assert (IDE_IS_SUBPROCESS_SUPERVISOR (supervisor));
+ g_assert (self->service == NULL);
+
+ if (self->state == STATE_SPAWNING)
+ self->state = STATE_RUNNING;
+
+ input = ide_subprocess_get_stdout_pipe (subprocess);
+ output = ide_subprocess_get_stdin_pipe (subprocess);
+ stream = g_simple_io_stream_new (input, output);
+
+ g_assert (G_IS_UNIX_INPUT_STREAM (input));
+ g_assert (G_IS_UNIX_OUTPUT_STREAM (output));
+
+ fd = g_unix_input_stream_get_fd (G_UNIX_INPUT_STREAM (input));
+ g_unix_set_fd_nonblocking (fd, TRUE, NULL);
+
+ fd = g_unix_output_stream_get_fd (G_UNIX_OUTPUT_STREAM (output));
+ g_unix_set_fd_nonblocking (fd, TRUE, NULL);
+
+ self->connection = g_dbus_connection_new_sync (stream, NULL,
+ G_DBUS_CONNECTION_FLAGS_DELAY_MESSAGE_PROCESSING,
+ NULL, NULL, NULL);
+ g_dbus_connection_set_exit_on_close (self->connection, FALSE);
+
+ self->service = ipc_git_service_proxy_new_sync (self->connection,
+ G_DBUS_PROXY_FLAGS_NONE,
+ NULL,
+ "/org/gnome/Builder/Git",
+ NULL,
+ NULL);
+
+ queued = g_steal_pointer (&self->get_service.head);
+
+ self->get_service.head = NULL;
+ self->get_service.tail = NULL;
+ self->get_service.length = 0;
+
+ for (const GList *iter = queued; iter != NULL; iter = iter->next)
+ {
+ IdeTask *task = iter->data;
+
+ ide_task_return_object (task, g_object_ref (self->service));
+ }
+
+ g_list_free_full (queued, g_object_unref);
+
+ IDE_EXIT;
+}
+
+static void
+gbp_git_client_subprocess_exited (GbpGitClient *self,
+ IdeSubprocess *subprocess,
+ IdeSubprocessSupervisor *supervisor)
+{
+ IDE_ENTRY;
+
+ g_assert (GBP_IS_GIT_CLIENT (self));
+ g_assert (IDE_IS_SUBPROCESS (subprocess));
+ g_assert (IDE_IS_SUBPROCESS_SUPERVISOR (supervisor));
+
+ if (self->state == STATE_RUNNING)
+ self->state = STATE_SPAWNING;
+
+ g_clear_object (&self->service);
+
+ IDE_EXIT;
+}
+
+static void
+gbp_git_client_destroy (IdeObject *object)
+{
+ GbpGitClient *self = (GbpGitClient *)object;
+
+ if (self->supervisor != NULL)
+ {
+ g_autoptr(IdeSubprocessSupervisor) supervisor = g_steal_pointer (&self->supervisor);
+
+ ide_subprocess_supervisor_stop (supervisor);
+ g_clear_object (&self->supervisor);
+ }
+
+ IDE_OBJECT_CLASS (gbp_git_client_parent_class)->destroy (object);
+}
+
+static void
+gbp_git_client_parent_set (IdeObject *object,
+ IdeObject *parent)
+{
+ GbpGitClient *self= (GbpGitClient *)object;
+ g_autoptr(IdeSubprocessLauncher) launcher = NULL;
+
+ g_assert (GBP_IS_GIT_CLIENT (self));
+ g_assert (!parent || IDE_IS_OBJECT (parent));
+
+ if (parent == NULL)
+ return;
+
+ launcher = ide_subprocess_launcher_new (G_SUBPROCESS_FLAGS_STDOUT_PIPE |
+ G_SUBPROCESS_FLAGS_STDIN_PIPE);
+ ide_subprocess_launcher_set_cwd (launcher, g_get_home_dir ());
+ ide_subprocess_launcher_set_clear_env (launcher, FALSE);
+#if 0
+ ide_subprocess_launcher_push_argv (launcher, "gdbserver");
+ ide_subprocess_launcher_push_argv (launcher, "localhost:8888");
+#endif
+ ide_subprocess_launcher_push_argv (launcher, PACKAGE_LIBEXECDIR"/gnome-builder-git");
+
+ self->supervisor = ide_subprocess_supervisor_new ();
+ ide_subprocess_supervisor_set_launcher (self->supervisor, launcher);
+
+ g_signal_connect_object (self->supervisor,
+ "spawned",
+ G_CALLBACK (gbp_git_client_subprocess_spawned),
+ self,
+ G_CONNECT_SWAPPED);
+
+ g_signal_connect_object (self->supervisor,
+ "exited",
+ G_CALLBACK (gbp_git_client_subprocess_exited),
+ self,
+ G_CONNECT_SWAPPED);
+}
+
+static void
+gbp_git_client_class_init (GbpGitClientClass *klass)
+{
+ IdeObjectClass *i_object_class = IDE_OBJECT_CLASS (klass);
+
+ i_object_class->destroy = gbp_git_client_destroy;
+ i_object_class->parent_set = gbp_git_client_parent_set;
+}
+
+static void
+gbp_git_client_init (GbpGitClient *self)
+{
+}
+
+GbpGitClient *
+gbp_git_client_from_context (IdeContext *context)
+{
+ GbpGitClient *ret;
+
+ g_return_val_if_fail (IDE_IS_CONTEXT (context), NULL);
+ g_return_val_if_fail (!ide_object_in_destruction (IDE_OBJECT (context)), NULL);
+
+ if (!(ret = ide_context_peek_child_typed (context, GBP_TYPE_GIT_CLIENT)))
+ {
+ g_autoptr(GbpGitClient) client = NULL;
+
+ client = ide_object_ensure_child_typed (IDE_OBJECT (context), GBP_TYPE_GIT_CLIENT);
+ ret = ide_context_peek_child_typed (context, GBP_TYPE_GIT_CLIENT);
+ }
+
+ return ret;
+}
+
+void
+gbp_git_client_get_service_async (GbpGitClient *self,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ g_autoptr(IdeTask) task = NULL;
+
+ g_assert (GBP_IS_GIT_CLIENT (self));
+ g_assert (!cancellable || G_IS_CANCELLABLE (cancellable));
+
+ task = ide_task_new (self, cancellable, callback, user_data);
+ ide_task_set_source_tag (task, gbp_git_client_get_service_async);
+
+ switch (self->state)
+ {
+ case STATE_INITIAL:
+ self->state = STATE_SPAWNING;
+ g_queue_push_tail (&self->get_service, g_steal_pointer (&task));
+ ide_subprocess_supervisor_start (self->supervisor);
+ break;
+
+ case STATE_SPAWNING:
+ g_queue_push_tail (&self->get_service, g_steal_pointer (&task));
+ break;
+
+ case STATE_RUNNING:
+ ide_task_return_object (task, g_object_ref (self->service));
+ break;
+
+ case STATE_SHUTDOWN:
+ ide_task_return_new_error (task,
+ G_IO_ERROR,
+ G_IO_ERROR_CLOSED,
+ "The client has been closed");
+ break;
+
+ default:
+ g_assert_not_reached ();
+ break;
+ }
+}
+
+IpcGitService *
+gbp_git_client_get_service_finish (GbpGitClient *self,
+ GAsyncResult *result,
+ GError **error)
+{
+ g_assert (GBP_IS_GIT_CLIENT (self));
+ g_assert (IDE_IS_TASK (result));
+
+ return ide_task_propagate_object (IDE_TASK (result), error);
+}
diff --git a/src/plugins/git/gbp-git-client.h b/src/plugins/git/gbp-git-client.h
new file mode 100644
index 000000000..72004c17c
--- /dev/null
+++ b/src/plugins/git/gbp-git-client.h
@@ -0,0 +1,42 @@
+/* gbp-git-client.h
+ *
+ * Copyright 2019 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/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#include <libide-core.h>
+
+#include "daemon/ipc-git-service.h"
+
+G_BEGIN_DECLS
+
+#define GBP_TYPE_GIT_CLIENT (gbp_git_client_get_type())
+
+G_DECLARE_FINAL_TYPE (GbpGitClient, gbp_git_client, GBP, GIT_CLIENT, IdeObject)
+
+GbpGitClient *gbp_git_client_from_context (IdeContext *context);
+void gbp_git_client_get_service_async (GbpGitClient *self,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+IpcGitService *gbp_git_client_get_service_finish (GbpGitClient *self,
+ GAsyncResult *result,
+ GError **error);
+
+G_END_DECLS
diff --git a/src/plugins/git/meson.build b/src/plugins/git/meson.build
index e501d517f..6bf39781f 100644
--- a/src/plugins/git/meson.build
+++ b/src/plugins/git/meson.build
@@ -7,6 +7,7 @@ plugins_sources += files([
'gbp-git-branch.c',
'gbp-git-buffer-addin.c',
'gbp-git-buffer-change-monitor.c',
+ 'gbp-git-client.c',
'gbp-git-dependency-updater.c',
'gbp-git-index-monitor.c',
'gbp-git-pipeline-addin.c',
@@ -21,6 +22,14 @@ plugins_sources += files([
'line-cache.c',
])
+plugins_sources += [
+ ipc_git_change_monitor_src,
+ ipc_git_config_src,
+ ipc_git_progress_src,
+ ipc_git_repository_src,
+ ipc_git_service_src,
+]
+
plugin_git_resources = gnome.compile_resources(
'git-resources',
'git.gresource.xml',
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]