[gnome-builder/wip/chergert/git-oop: 14/34] add api to update git config



commit c8ae7a260bc5c8c7129e53e35f3f56078f7fd965
Author: Christian Hergert <chergert redhat com>
Date:   Wed Mar 20 16:33:15 2019 -0700

    add api to update git config

 src/plugins/git/gbp-git-client.c    |  64 ++++++++++++++++
 src/plugins/git/gbp-git-client.h    |  10 +++
 src/plugins/git/gbp-git.c           | 143 ++++++++++++++++++++++++++++++++++++
 src/plugins/git/gbp-git.h           |  10 +++
 src/plugins/git/gnome-builder-git.c |  64 ++++++++++++++++
 5 files changed, 291 insertions(+)
---
diff --git a/src/plugins/git/gbp-git-client.c b/src/plugins/git/gbp-git-client.c
index d94d58aed..ba80d9c1a 100644
--- a/src/plugins/git/gbp-git-client.c
+++ b/src/plugins/git/gbp-git-client.c
@@ -817,3 +817,67 @@ gbp_git_client_update_submodules_finish (GbpGitClient  *self,
 
   return ide_task_propagate_boolean (IDE_TASK (result), error);
 }
+
+static void
+gbp_git_client_update_config_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;
+
+  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);
+}
+
+void
+gbp_git_client_update_config_async (GbpGitClient        *self,
+                                    gboolean             global,
+                                    const gchar         *key,
+                                    GVariant            *value,
+                                    GCancellable        *cancellable,
+                                    GAsyncReadyCallback  callback,
+                                    gpointer             user_data)
+{
+  g_autoptr(IdeTask) task = NULL;
+  GVariantDict dict;
+
+  g_return_if_fail (GBP_IS_GIT_CLIENT (self));
+  g_return_if_fail (key != NULL);
+  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_update_config_async);
+
+  g_variant_dict_init (&dict, NULL);
+  g_variant_dict_insert (&dict, "global", "b", global);
+  g_variant_dict_insert (&dict, "key", "s", key);
+  g_variant_dict_insert_value (&dict, "value", value);
+
+  gbp_git_client_call_async (self,
+                             "git/updateConfig",
+                             g_variant_dict_end (&dict),
+                             cancellable,
+                             gbp_git_client_update_config_cb,
+                             g_steal_pointer (&task));
+}
+
+gboolean
+gbp_git_client_update_config_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 a28792867..410ab7818 100644
--- a/src/plugins/git/gbp-git-client.h
+++ b/src/plugins/git/gbp-git-client.h
@@ -99,5 +99,15 @@ void          gbp_git_client_update_submodules_async  (GbpGitClient           *s
 gboolean      gbp_git_client_update_submodules_finish (GbpGitClient           *self,
                                                        GAsyncResult           *result,
                                                        GError                **error);
+void          gbp_git_client_update_config_async      (GbpGitClient           *self,
+                                                       gboolean                global,
+                                                       const gchar            *key,
+                                                       GVariant               *value,
+                                                       GCancellable           *cancellable,
+                                                       GAsyncReadyCallback     callback,
+                                                       gpointer                user_data);
+gboolean      gbp_git_client_update_config_finish     (GbpGitClient           *self,
+                                                       GAsyncResult           *result,
+                                                       GError                **error);
 
 G_END_DECLS
diff --git a/src/plugins/git/gbp-git.c b/src/plugins/git/gbp-git.c
index ef01c87f3..1ca86c530 100644
--- a/src/plugins/git/gbp-git.c
+++ b/src/plugins/git/gbp-git.c
@@ -460,3 +460,146 @@ gbp_git_update_submodules_finish (GbpGit        *self,
 
   return g_task_propagate_boolean (G_TASK (result), error);
 }
+
+typedef struct
+{
+  GFile    *workdir;
+  gchar    *key;
+  GVariant *value;
+  guint     global : 1;
+} UpdateConfig;
+
+static void
+update_config_free (UpdateConfig *state)
+{
+  g_clear_object (&state->workdir);
+  g_clear_pointer (&state->key, g_free);
+  g_clear_pointer (&state->value, g_variant_unref);
+  g_slice_free (UpdateConfig, state);
+}
+
+static void
+gbp_git_update_config_worker (GTask        *task,
+                              gpointer      source_object,
+                              gpointer      task_data,
+                              GCancellable *cancellable)
+{
+  UpdateConfig *state = task_data;
+  g_autoptr(GgitRepository) repository = NULL;
+  g_autoptr(GgitConfig) config = NULL;
+  g_autoptr(GError) error = NULL;
+
+  g_assert (G_IS_TASK (task));
+  g_assert (GBP_IS_GIT (source_object));
+  g_assert (state != NULL);
+  g_assert (state->key != NULL);
+  g_assert (G_IS_FILE (state->workdir) || state->global);
+  g_assert (!cancellable || G_IS_CANCELLABLE (cancellable));
+
+  if (!state->global)
+    {
+      if (!(repository = ggit_repository_open (state->workdir, &error)) ||
+          !(config = ggit_repository_get_config (repository, &error)))
+        {
+          g_task_return_error (task, g_steal_pointer (&error));
+          return;
+        }
+    }
+  else
+    {
+      if (!(config = ggit_config_new_default (&error)))
+        {
+          g_task_return_error (task, g_steal_pointer (&error));
+          return;
+        }
+    }
+
+  g_assert (config != NULL);
+  g_assert (GGIT_IS_CONFIG (config));
+
+  if (state->value == NULL)
+    {
+      if (!ggit_config_delete_entry (config, state->key, &error))
+        g_task_return_error (task, g_steal_pointer (&error));
+      else
+        g_task_return_boolean (task, TRUE);
+    }
+  else
+    {
+      if (g_variant_is_of_type (state->value, G_VARIANT_TYPE_STRING))
+        ggit_config_set_string (config,
+                                state->key,
+                                g_variant_get_string (state->value, NULL),
+                                &error);
+      else if (g_variant_is_of_type (state->value, G_VARIANT_TYPE_BOOLEAN))
+        ggit_config_set_bool (config,
+                              state->key,
+                              g_variant_get_boolean (state->value),
+                              &error);
+      else if (g_variant_is_of_type (state->value, G_VARIANT_TYPE_INT32))
+        ggit_config_set_int32 (config,
+                               state->key,
+                               g_variant_get_int32 (state->value),
+                               &error);
+      else if (g_variant_is_of_type (state->value, G_VARIANT_TYPE_INT64))
+        ggit_config_set_int64 (config,
+                               state->key,
+                               g_variant_get_int64 (state->value),
+                               &error);
+      else
+        error = g_error_new (G_IO_ERROR,
+                             G_IO_ERROR_NOT_SUPPORTED,
+                             "Unsupported data type: %s",
+                             g_variant_get_type_string (state->value));
+
+      if (error != NULL)
+        g_task_return_error (task, g_steal_pointer (&error));
+      else
+        g_task_return_boolean (task, TRUE);
+    }
+}
+
+void
+gbp_git_update_config_async (GbpGit              *self,
+                             gboolean             global,
+                             const gchar         *key,
+                             GVariant            *value,
+                             GCancellable        *cancellable,
+                             GAsyncReadyCallback  callback,
+                             gpointer             user_data)
+{
+  g_autoptr(GTask) task = NULL;
+  UpdateConfig *state;
+
+  g_assert (GBP_IS_GIT (self));
+  g_assert (!cancellable || G_IS_CANCELLABLE (cancellable));
+
+  state = g_slice_new0 (UpdateConfig);
+  state->workdir = self->workdir ? g_file_dup (self->workdir) : NULL;
+  state->key = g_strdup (key);
+  state->value = value ? g_variant_ref (value) : NULL;
+  state->global = !!global;
+
+  task = g_task_new (self, cancellable, callback, user_data);
+  g_task_set_source_tag (task, gbp_git_update_config_async);
+  g_task_set_task_data (task, state, (GDestroyNotify)update_config_free);
+
+  if (!global && self->workdir == NULL)
+    g_task_return_new_error (task,
+                             G_IO_ERROR,
+                             G_IO_ERROR_NOT_INITIALIZED,
+                             "Repository not initialized");
+  else
+    g_task_run_in_thread (task, gbp_git_update_config_worker);
+}
+
+gboolean
+gbp_git_update_config_finish (GbpGit        *self,
+                              GAsyncResult  *result,
+                              GError       **error)
+{
+  g_assert (GBP_IS_GIT (self));
+  g_assert (G_IS_TASK (result));
+
+  return g_task_propagate_boolean (G_TASK (result), error);
+}
diff --git a/src/plugins/git/gbp-git.h b/src/plugins/git/gbp-git.h
index b117e1780..724ef9e85 100644
--- a/src/plugins/git/gbp-git.h
+++ b/src/plugins/git/gbp-git.h
@@ -107,5 +107,15 @@ void       gbp_git_update_submodules_async  (GbpGit                      *self,
 gboolean   gbp_git_update_submodules_finish (GbpGit                      *self,
                                              GAsyncResult                *result,
                                              GError                     **error);
+void       gbp_git_update_config_async      (GbpGit                      *self,
+                                             gboolean                     global,
+                                             const gchar                 *key,
+                                             GVariant                    *value,
+                                             GCancellable                *cancellable,
+                                             GAsyncReadyCallback          callback,
+                                             gpointer                     user_data);
+gboolean   gbp_git_update_config_finish     (GbpGit                      *self,
+                                             GAsyncResult                *result,
+                                             GError                     **error);
 
 G_END_DECLS
diff --git a/src/plugins/git/gnome-builder-git.c b/src/plugins/git/gnome-builder-git.c
index 560e15d0f..210ddeca2 100644
--- a/src/plugins/git/gnome-builder-git.c
+++ b/src/plugins/git/gnome-builder-git.c
@@ -727,6 +727,69 @@ handle_update_submodules (JsonrpcServer *server,
   g_clear_pointer (&fetch_options, ggit_fetch_options_free);
 }
 
+static void
+handle_update_config_cb (GObject      *object,
+                         GAsyncResult *result,
+                         gpointer      user_data)
+{
+  GbpGit *git = (GbpGit *)object;
+  g_autoptr(ClientOp) op = user_data;
+  g_autoptr(GError) error = NULL;
+
+  g_assert (GBP_IS_GIT (git));
+  g_assert (G_IS_ASYNC_RESULT (result));
+  g_assert (op != NULL);
+
+  if (!gbp_git_update_config_finish (git, result, &error))
+    client_op_error (op, error);
+  else
+    client_op_reply (op, g_variant_new_boolean (TRUE));
+}
+
+static void
+handle_update_config (JsonrpcServer *server,
+                      JsonrpcClient *client,
+                      const gchar   *method,
+                      GVariant      *id,
+                      GVariant      *params,
+                      GbpGit        *git)
+{
+  g_autoptr(ClientOp) op = NULL;
+  g_autoptr(GVariant) value = NULL;
+  const gchar *key;
+  gboolean global;
+  gboolean r;
+
+  g_assert (JSONRPC_IS_SERVER (server));
+  g_assert (JSONRPC_IS_CLIENT (client));
+  g_assert (g_str_equal (method, "git/updateConfig"));
+  g_assert (id != NULL);
+  g_assert (GBP_IS_GIT (git));
+
+  op = client_op_new (client, id);
+
+  r = JSONRPC_MESSAGE_PARSE (params,
+    "global", JSONRPC_MESSAGE_GET_BOOLEAN (&global),
+    "key", JSONRPC_MESSAGE_GET_STRING (&key)
+  );
+
+  if (!r)
+    {
+      client_op_bad_params (op);
+      return;
+    }
+
+  value = g_variant_lookup_value (params, "value", NULL);
+
+  gbp_git_update_config_async (git,
+                               global,
+                               key,
+                               value,
+                               op->cancellable,
+                               (GAsyncReadyCallback)handle_update_config_cb,
+                               client_op_ref (op));
+}
+
 /* Main Loop and Setup {{{1 */
 
 gint
@@ -772,6 +835,7 @@ main (gint argc,
   ADD_HANDLER ("git/isIgnored", handle_is_ignored);
   ADD_HANDLER ("git/listRefsByKind", handle_list_refs_by_kind);
   ADD_HANDLER ("git/switchBranch", handle_switch_branch);
+  ADD_HANDLER ("git/updateConfig", handle_update_config);
   ADD_HANDLER ("git/updateSubmodules", handle_update_submodules);
   ADD_HANDLER ("$/cancelRequest", handle_cancel_request);
 


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