[gnome-builder/wip/chergert/git-oop: 4/12] wip on git callbacks
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder/wip/chergert/git-oop: 4/12] wip on git callbacks
- Date: Thu, 21 Mar 2019 05:13:40 +0000 (UTC)
commit 7d044e1f92835261c4d8570e811adc528730ec7c
Author: Christian Hergert <chergert redhat com>
Date: Wed Mar 20 12:51:43 2019 -0700
wip on git callbacks
src/plugins/git/gbp-git-client.c | 162 ++++++++++++++++++++++++-
src/plugins/git/gbp-git-client.h | 7 +-
src/plugins/git/gbp-git-remote-callbacks.c | 185 ++---------------------------
src/plugins/git/gbp-git-remote-callbacks.h | 7 +-
src/plugins/git/gbp-git-vcs-cloner.c | 2 +-
src/plugins/git/gnome-builder-git.c | 7 +-
src/plugins/git/meson.build | 3 +-
7 files changed, 178 insertions(+), 195 deletions(-)
---
diff --git a/src/plugins/git/gbp-git-client.c b/src/plugins/git/gbp-git-client.c
index 018ffc481..7a15c0b88 100644
--- a/src/plugins/git/gbp-git-client.c
+++ b/src/plugins/git/gbp-git-client.c
@@ -22,6 +22,8 @@
#include "config.h"
+#include <glib/gi18n.h>
+
#include <gio/gunixinputstream.h>
#include <gio/gunixoutputstream.h>
#include <glib-unix.h>
@@ -38,6 +40,7 @@ struct _GbpGitClient
JsonrpcClient *rpc_client;
GFile *root_uri;
gint state;
+ GHashTable *notif_by_token;
};
enum {
@@ -77,6 +80,62 @@ call_free (gpointer data)
g_slice_free (Call, c);
}
+static void
+gbp_git_client_notification_cb (GbpGitClient *self,
+ const gchar *command,
+ GVariant *reply,
+ JsonrpcClient *client)
+{
+ const gchar *token = NULL;
+ IdeNotification *notif;
+
+ g_assert (IDE_IS_MAIN_THREAD ());
+ g_assert (GBP_IS_GIT_CLIENT (client));
+ g_assert (command != NULL);
+ g_assert (JSONRPC_IS_CLIENT (client));
+
+ if (reply == NULL)
+ return;
+
+ if (g_str_equal (command, "$/progress") &&
+ JSONRPC_MESSAGE_PARSE (reply, "token", JSONRPC_MESSAGE_GET_STRING (&token)) &&
+ (notif = g_hash_table_lookup (self->notif_by_token, token)))
+ {
+ gdouble progress;
+ const gchar *message;
+
+ if (!JSONRPC_MESSAGE_PARSE (reply, "progress", JSONRPC_MESSAGE_GET_DOUBLE (&progress)))
+ progress = 0.0;
+
+ if (!JSONRPC_MESSAGE_PARSE (reply, "message", JSONRPC_MESSAGE_GET_STRING (&message)))
+ message = NULL;
+
+ if (message != NULL)
+ ide_notification_set_body (notif, message);
+
+ if (progress > 0.0)
+ ide_notification_set_progress (notif, CLAMP (progress, 0.0, 1.0));
+ }
+}
+
+static gchar *
+gbp_git_client_track_progress (GbpGitClient *self,
+ IdeNotification *notif)
+{
+ g_autofree gchar *token = NULL;
+
+ g_assert (GBP_IS_GIT_CLIENT (self));
+ g_assert (IDE_IS_NOTIFICATION (notif));
+
+ if (self->notif_by_token == NULL)
+ self->notif_by_token = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
+
+ token = g_uuid_string_random ();
+ g_hash_table_insert (self->notif_by_token, g_strdup (token), g_object_ref (notif));
+
+ return g_steal_pointer (&token);
+}
+
static void
gbp_git_client_subprocess_exited (GbpGitClient *self,
IdeSubprocess *subprocess,
@@ -136,6 +195,12 @@ gbp_git_client_subprocess_spawned (GbpGitClient *self,
self->rpc_client = jsonrpc_client_new (stream);
jsonrpc_client_set_use_gvariant (self->rpc_client, TRUE);
+ g_signal_connect_object (self->rpc_client,
+ "notification",
+ G_CALLBACK (gbp_git_client_notification_cb),
+ self,
+ G_CONNECT_SWAPPED);
+
queued = g_steal_pointer (&self->get_client.head);
self->get_client.head = NULL;
@@ -160,10 +225,7 @@ gbp_git_client_subprocess_spawned (GbpGitClient *self,
"capabilities", "{", "}"
);
- jsonrpc_client_call_async (self->rpc_client,
- "initialize",
- params,
- NULL, NULL, NULL);
+ jsonrpc_client_call_async (self->rpc_client, "initialize", params, NULL, NULL, NULL);
IDE_EXIT;
}
@@ -319,6 +381,7 @@ gbp_git_client_finalize (GObject *object)
g_clear_object (&self->rpc_client);
g_clear_object (&self->root_uri);
g_clear_object (&self->supervisor);
+ g_clear_pointer (&self->notif_by_token, g_hash_table_unref);
g_assert (self->get_client.head == NULL);
g_assert (self->get_client.tail == NULL);
@@ -588,3 +651,94 @@ gbp_git_client_is_ignored_finish (GbpGitClient *self,
return FALSE;
}
+
+static void
+gbp_git_client_clone_url_cb (GObject *object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ GbpGitClient *self = (GbpGitClient *)object;
+ g_autoptr(IdeTask) task = user_data;
+ g_autoptr(GVariant) reply = NULL;
+ g_autoptr(GError) error = NULL;
+ const gchar *token = NULL;
+
+ g_assert (IDE_IS_MAIN_THREAD ());
+ g_assert (GBP_IS_GIT_CLIENT (self));
+ g_assert (G_IS_ASYNC_RESULT (result));
+ g_assert (IDE_IS_TASK (task));
+
+ if (!gbp_git_client_call_finish (self, result, &reply, &error))
+ ide_task_return_error (task, g_steal_pointer (&error));
+ else
+ ide_task_return_boolean (task, TRUE);
+
+ if ((token = ide_task_get_task_data (task)) && self->notif_by_token)
+ g_hash_table_remove (self->notif_by_token, token);
+}
+
+void
+gbp_git_client_clone_url_async (GbpGitClient *self,
+ const gchar *url,
+ GFile *destination,
+ const gchar *branch,
+ IdeNotification *notif,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ g_autoptr(IdeTask) task = NULL;
+ g_autoptr(GVariant) command = NULL;
+ g_autofree gchar *token = NULL;
+ g_autofree gchar *dest_uri = NULL;
+
+ g_return_if_fail (GBP_IS_GIT_CLIENT (self));
+ g_return_if_fail (url != NULL);
+ g_return_if_fail (G_IS_FILE (destination));
+ g_return_if_fail (!notif || IDE_IS_NOTIFICATION (notif));
+ g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
+
+ task = ide_task_new (self, cancellable, callback, user_data);
+ ide_task_set_source_tag (task, gbp_git_client_clone_url_async);
+
+ if (notif != NULL)
+ {
+ token = gbp_git_client_track_progress (self, notif);
+ ide_notification_set_title (notif, _("Cloning Repository"));
+ ide_notification_set_icon_name (notif, "builder-vcs-git-symbolic");
+ ide_notification_set_progress (notif, 0.0);
+ }
+
+ if (branch == NULL)
+ branch = "master";
+
+ dest_uri = g_file_get_uri (destination);
+
+ command = JSONRPC_MESSAGE_NEW (
+ "token", JSONRPC_MESSAGE_PUT_STRING (token),
+ "url", JSONRPC_MESSAGE_PUT_STRING (url),
+ "destination", JSONRPC_MESSAGE_PUT_STRING (dest_uri),
+ "branch", JSONRPC_MESSAGE_PUT_STRING (branch)
+ );
+
+ if (token != NULL)
+ ide_task_set_task_data (task, g_strdup (token), g_free);
+
+ gbp_git_client_call_async (self,
+ "git/cloneUrl",
+ command,
+ cancellable,
+ gbp_git_client_clone_url_cb,
+ g_steal_pointer (&task));
+}
+
+gboolean
+gbp_git_client_clone_url_finish (GbpGitClient *self,
+ GAsyncResult *result,
+ GError **error)
+{
+ g_return_val_if_fail (GBP_IS_GIT_CLIENT (self), FALSE);
+ g_return_val_if_fail (IDE_IS_TASK (result), FALSE);
+
+ return ide_task_propagate_boolean (IDE_TASK (result), error);
+}
diff --git a/src/plugins/git/gbp-git-client.h b/src/plugins/git/gbp-git-client.h
index cb9cd2c53..299a2be64 100644
--- a/src/plugins/git/gbp-git-client.h
+++ b/src/plugins/git/gbp-git-client.h
@@ -82,10 +82,9 @@ gboolean gbp_git_client_switch_branch_finish (GbpGitClient *s
GError **error);
void gbp_git_client_clone_url_async (GbpGitClient *self,
const gchar *url,
- GFile *destination,
- GFileProgressCallback progress,
- gpointer progress_data,
- GDestroyNotify progress_notify,
+ GFile *destination,
+ const gchar *branch,
+ IdeNotification *notif,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
diff --git a/src/plugins/git/gbp-git-remote-callbacks.c b/src/plugins/git/gbp-git-remote-callbacks.c
index 4bdb9b3e7..ea15e1f96 100644
--- a/src/plugins/git/gbp-git-remote-callbacks.c
+++ b/src/plugins/git/gbp-git-remote-callbacks.c
@@ -20,143 +20,25 @@
#define G_LOG_DOMAIN "gbp-git-remote-callbacks"
-#include <dazzle.h>
#include <glib/gi18n.h>
#include "gbp-git-remote-callbacks.h"
-#define ANIMATION_DURATION_MSEC 250
-
struct _GbpGitRemoteCallbacks
{
- GgitRemoteCallbacks parent_instance;
-
- GMutex mutex;
- GString *body;
- gdouble progress;
- guint status_source;
-
- /* bitflags of what we've tried */
- GgitCredtype tried;
-
- guint cancelled : 1;
+ GgitRemoteCallbacks parent_instance;
+ GgitCredtype tried;
+ guint cancelled : 1;
};
G_DEFINE_TYPE (GbpGitRemoteCallbacks, gbp_git_remote_callbacks, GGIT_TYPE_REMOTE_CALLBACKS)
-enum {
- STATUS,
- N_SIGNALS
-};
-
-static guint signals [N_SIGNALS];
-
GgitRemoteCallbacks *
gbp_git_remote_callbacks_new (void)
{
return g_object_new (GBP_TYPE_GIT_REMOTE_CALLBACKS, NULL);
}
-static gboolean
-gbp_git_remote_callbacks_do_emit_status (GbpGitRemoteCallbacks *self)
-{
- g_autofree gchar *message = NULL;
- gdouble progress = 0.0;
-
- g_assert (GBP_IS_GIT_REMOTE_CALLBACKS (self));
-
- g_mutex_lock (&self->mutex);
-
- self->status_source = 0;
-
- progress = self->progress;
-
- if (self->body->len > 1)
- {
- const gchar *endptr;
-
- endptr = &self->body->str[self->body->len - 1];
-
- if (*endptr == '\n')
- endptr--;
-
- while (endptr >= self->body->str)
- {
- if (*endptr == '\n' || *endptr == '\r')
- {
- message = g_strdup (endptr + 1);
- break;
- }
-
- endptr--;
- }
- }
-
- g_mutex_unlock (&self->mutex);
-
- g_signal_emit (self, signals [STATUS], 0, message, progress);
-
- return G_SOURCE_REMOVE;
-}
-
-static void
-gbp_git_remote_callbacks_emit_status (GbpGitRemoteCallbacks *self)
-{
- g_assert (GBP_IS_GIT_REMOTE_CALLBACKS (self));
-
- g_mutex_lock (&self->mutex);
- if (self->status_source == 0)
- self->status_source = g_idle_add_full (G_PRIORITY_HIGH,
- (GSourceFunc)gbp_git_remote_callbacks_do_emit_status,
- g_object_ref (self),
- g_object_unref);
- g_mutex_unlock (&self->mutex);
-}
-
-static void
-gbp_git_remote_callbacks_real_progress (GgitRemoteCallbacks *callbacks,
- const gchar *message)
-{
- GbpGitRemoteCallbacks *self = (GbpGitRemoteCallbacks *)callbacks;
-
- g_assert (GBP_IS_GIT_REMOTE_CALLBACKS (self));
-
- g_mutex_lock (&self->mutex);
- if (self->body == NULL)
- self->body = g_string_new (message);
- else
- g_string_append (self->body, message);
- g_mutex_unlock (&self->mutex);
-
- gbp_git_remote_callbacks_emit_status (self);
-}
-
-static void
-gbp_git_remote_callbacks_real_transfer_progress (GgitRemoteCallbacks *callbacks,
- GgitTransferProgress *stats)
-{
- GbpGitRemoteCallbacks *self = (GbpGitRemoteCallbacks *)callbacks;
- guint total;
- guint received;
-
- g_assert (GBP_IS_GIT_REMOTE_CALLBACKS (self));
- g_assert (stats != NULL);
-
- if (self->cancelled)
- return;
-
- total = ggit_transfer_progress_get_total_objects (stats);
- received = ggit_transfer_progress_get_received_objects (stats);
- if (total == 0)
- return;
-
- g_mutex_lock (&self->mutex);
- self->progress = (gdouble)received / (gdouble)total;
- g_mutex_unlock (&self->mutex);
-
- gbp_git_remote_callbacks_emit_status (self);
-}
-
static GgitCred *
gbp_git_remote_callbacks_real_credentials (GgitRemoteCallbacks *callbacks,
const gchar *url,
@@ -167,12 +49,10 @@ gbp_git_remote_callbacks_real_credentials (GgitRemoteCallbacks *callbacks,
GbpGitRemoteCallbacks *self = (GbpGitRemoteCallbacks *)callbacks;
GgitCred *ret = NULL;
- IDE_ENTRY;
-
g_assert (GBP_IS_GIT_REMOTE_CALLBACKS (self));
g_assert (url != NULL);
- IDE_TRACE_MSG ("username=%s url=%s", username_from_url ?: "", url);
+ g_debug ("username=%s url=%s", username_from_url ?: "", url);
if (self->cancelled)
{
@@ -180,7 +60,7 @@ gbp_git_remote_callbacks_real_credentials (GgitRemoteCallbacks *callbacks,
G_IO_ERROR,
G_IO_ERROR_CANCELLED,
"The operation has been canceled");
- IDE_RETURN (NULL);
+ return NULL;
}
allowed_types &= ~self->tried;
@@ -194,7 +74,7 @@ gbp_git_remote_callbacks_real_credentials (GgitRemoteCallbacks *callbacks,
self->tried |= GGIT_CREDTYPE_SSH_KEY;
if (ret != NULL)
- IDE_RETURN (ret);
+ return g_steal_pointer (&ret);
}
if ((allowed_types & GGIT_CREDTYPE_SSH_INTERACTIVE) != 0)
@@ -206,75 +86,28 @@ gbp_git_remote_callbacks_real_credentials (GgitRemoteCallbacks *callbacks,
self->tried |= GGIT_CREDTYPE_SSH_INTERACTIVE;
if (ret != NULL)
- IDE_RETURN (ret);
+ return g_steal_pointer (&ret);
}
g_set_error (error,
G_IO_ERROR,
G_IO_ERROR_NOT_SUPPORTED,
- _("Builder failed to provide appropriate credentials when cloning repository."));
-
- IDE_RETURN (NULL);
-}
-
-static void
-gbp_git_remote_callbacks_finalize (GObject *object)
-{
- GbpGitRemoteCallbacks *self = (GbpGitRemoteCallbacks *)object;
+ _("Builder failed to provide appropriate credentials when cloning the repository."));
- g_clear_object (&self->progress);
-
- if (self->body != NULL)
- {
- g_string_free (self->body, TRUE);
- self->body = NULL;
- }
-
- g_clear_handle_id (&self->status_source, g_source_remove);
-
- g_mutex_clear (&self->mutex);
-
- G_OBJECT_CLASS (gbp_git_remote_callbacks_parent_class)->finalize (object);
+ return NULL;
}
static void
gbp_git_remote_callbacks_class_init (GbpGitRemoteCallbacksClass *klass)
{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
GgitRemoteCallbacksClass *callbacks_class = GGIT_REMOTE_CALLBACKS_CLASS (klass);
- object_class->finalize = gbp_git_remote_callbacks_finalize;
-
- callbacks_class->transfer_progress = gbp_git_remote_callbacks_real_transfer_progress;
- callbacks_class->progress = gbp_git_remote_callbacks_real_progress;
callbacks_class->credentials = gbp_git_remote_callbacks_real_credentials;
-
- /**
- * GbpGitRemoteCallbacks::status:
- * @self: a GbpGitRemoteCallbacks
- * @message: the status message string
- * @progress: the progress for the operation
- *
- * This signal is emitted when the progress or the status message changes
- * for the operation.
- *
- * Since: 3.34
- */
- signals [STATUS] =
- g_signal_new ("status",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST,
- 0, NULL, NULL, NULL,
- G_TYPE_NONE,
- 2,
- G_TYPE_STRING | G_SIGNAL_TYPE_STATIC_SCOPE,
- G_TYPE_DOUBLE);
}
static void
gbp_git_remote_callbacks_init (GbpGitRemoteCallbacks *self)
{
- g_mutex_init (&self->mutex);
}
/**
diff --git a/src/plugins/git/gbp-git-remote-callbacks.h b/src/plugins/git/gbp-git-remote-callbacks.h
index 7ddfbb51c..7af902519 100644
--- a/src/plugins/git/gbp-git-remote-callbacks.h
+++ b/src/plugins/git/gbp-git-remote-callbacks.h
@@ -21,7 +21,6 @@
#pragma once
#include <libgit2-glib/ggit.h>
-#include <libide-core.h>
G_BEGIN_DECLS
@@ -29,9 +28,7 @@ G_BEGIN_DECLS
G_DECLARE_FINAL_TYPE (GbpGitRemoteCallbacks, gbp_git_remote_callbacks, GBP, GIT_REMOTE_CALLBACKS,
GgitRemoteCallbacks)
-GgitRemoteCallbacks *gbp_git_remote_callbacks_new (void);
-gdouble gbp_git_remote_callbacks_get_fraction (GbpGitRemoteCallbacks *self);
-IdeNotification *gbp_git_remote_callbacks_get_progress (GbpGitRemoteCallbacks *self);
-void gbp_git_remote_callbacks_cancel (GbpGitRemoteCallbacks *self);
+GgitRemoteCallbacks *gbp_git_remote_callbacks_new (void);
+void gbp_git_remote_callbacks_cancel (GbpGitRemoteCallbacks *self);
G_END_DECLS
diff --git a/src/plugins/git/gbp-git-vcs-cloner.c b/src/plugins/git/gbp-git-vcs-cloner.c
index 0a03b7b4c..4bcdc6a6f 100644
--- a/src/plugins/git/gbp-git-vcs-cloner.c
+++ b/src/plugins/git/gbp-git-vcs-cloner.c
@@ -172,7 +172,7 @@ gbp_git_vcs_cloner_worker (IdeTask *task,
g_assert (req != NULL);
g_assert (!cancellable || G_IS_CANCELLABLE (cancellable));
- callbacks = gbp_git_remote_callbacks_new (req->notif);
+ callbacks = gbp_git_remote_callbacks_new ();
g_signal_connect_object (cancellable,
"cancelled",
diff --git a/src/plugins/git/gnome-builder-git.c b/src/plugins/git/gnome-builder-git.c
index 88a4fe735..76686d426 100644
--- a/src/plugins/git/gnome-builder-git.c
+++ b/src/plugins/git/gnome-builder-git.c
@@ -626,9 +626,8 @@ handle_clone_url (JsonrpcServer *server,
"token", JSONRPC_MESSAGE_GET_STRING (&token)
);
- JSONRPC_MESSAGE_PARSE (params,
- "branch", JSONRPC_MESSAGE_GET_STRING (&branch)
- );
+ if (!JSONRPC_MESSAGE_PARSE (params, "branch", JSONRPC_MESSAGE_GET_STRING (&branch)))
+ branch = "master";
if (!r || !(destination = g_file_new_for_uri (dest_uri)))
{
@@ -659,7 +658,7 @@ handle_clone_url (JsonrpcServer *server,
options = ggit_clone_options_new ();
ggit_clone_options_set_is_bare (options, FALSE);
- ggit_clone_options_set_checkout_branch (options, branch ? branch : "master");
+ ggit_clone_options_set_checkout_branch (options, branch);
ggit_clone_options_set_fetch_options (options, fetch_options);
gbp_git_clone_url_async (git,
diff --git a/src/plugins/git/meson.build b/src/plugins/git/meson.build
index a89cde277..6fcf0358d 100644
--- a/src/plugins/git/meson.build
+++ b/src/plugins/git/meson.build
@@ -21,8 +21,9 @@ plugins_sources += files([
])
gnome_builder_git_sources = [
- 'gnome-builder-git.c',
'gbp-git.c',
+ 'gbp-git-remote-callbacks.c',
+ 'gnome-builder-git.c',
]
plugin_git_resources = gnome.compile_resources(
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]