[gnome-builder/wip/chergert/git-oop] add discover API and RPCs



commit 6c839d76fe9e5aa2b99e448651b5d3f49a1dfedc
Author: Christian Hergert <chergert redhat com>
Date:   Thu Mar 21 13:12:02 2019 -0700

    add discover API and RPCs

 src/plugins/git/gbp-git-client.c    | 136 +++++++++++++++++++++++++
 src/plugins/git/gbp-git-client.h    | 197 +++++++++++++++++++-----------------
 src/plugins/git/gbp-git.c           | 171 +++++++++++++++++++++++++++++++
 src/plugins/git/gbp-git.h           |  11 ++
 src/plugins/git/gnome-builder-git.c |  79 ++++++++++++++-
 5 files changed, 498 insertions(+), 96 deletions(-)
---
diff --git a/src/plugins/git/gbp-git-client.c b/src/plugins/git/gbp-git-client.c
index 0ae5857f4..e0a4d1852 100644
--- a/src/plugins/git/gbp-git-client.c
+++ b/src/plugins/git/gbp-git-client.c
@@ -1022,3 +1022,139 @@ gbp_git_client_create_repo_finish (GbpGitClient  *self,
 
   return ide_task_propagate_boolean (IDE_TASK (result), error);
 }
+
+typedef struct
+{
+  GFile *workdir;
+  gchar *branch;
+  guint  is_worktree : 1;
+} Discover;
+
+static void
+discover_free (Discover *state)
+{
+  g_clear_object (&state->workdir);
+  g_clear_pointer (&state->branch, g_free);
+  g_slice_free (Discover, state);
+}
+
+static void
+gbp_git_client_discover_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 *workdir = NULL;
+  const gchar *branch = NULL;
+  Discover *state;
+  gboolean is_worktree = FALSE;
+  gboolean r;
+
+  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));
+      return;
+    }
+
+  state = ide_task_get_task_data (task);
+
+  r = JSONRPC_MESSAGE_PARSE (reply,
+    "workdir", JSONRPC_MESSAGE_GET_STRING (&workdir),
+    "branch", JSONRPC_MESSAGE_GET_STRING (&branch),
+    "is-worktree", JSONRPC_MESSAGE_GET_BOOLEAN (&is_worktree)
+  );
+
+  if (!r)
+    {
+      ide_task_return_new_error (task,
+                                 G_IO_ERROR,
+                                 G_IO_ERROR_INVALID_DATA,
+                                 "Invalid reply from peer");
+      return;
+    }
+
+  state->workdir = g_file_new_for_uri (workdir);
+  state->branch = g_strdup (branch);
+  state->is_worktree = !!is_worktree;
+
+  ide_task_return_boolean (task, TRUE);
+}
+
+void
+gbp_git_client_discover_async (GbpGitClient        *self,
+                               GFile               *directory,
+                               GCancellable        *cancellable,
+                               GAsyncReadyCallback  callback,
+                               gpointer             user_data)
+{
+  g_autoptr(IdeTask) task = NULL;
+  g_autoptr(GVariant) command = NULL;
+  g_autofree gchar *uri = NULL;
+  Discover *state;
+
+  g_return_if_fail (GBP_IS_GIT_CLIENT (self));
+  g_return_if_fail (G_IS_FILE (directory));
+  g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
+
+  state = g_slice_new0 (Discover);
+
+  task = ide_task_new (self, cancellable, callback, user_data);
+  ide_task_set_source_tag (task, gbp_git_client_discover_async);
+  ide_task_set_task_data (task, state, discover_free);
+
+  uri = g_file_get_uri (directory);
+
+  command = JSONRPC_MESSAGE_NEW (
+    "location", JSONRPC_MESSAGE_PUT_STRING (uri)
+  );
+
+  gbp_git_client_call_async (self,
+                             "git/discover",
+                             command,
+                             cancellable,
+                             gbp_git_client_discover_cb,
+                             g_steal_pointer (&task));
+}
+
+gboolean
+gbp_git_client_discover_finish (GbpGitClient  *self,
+                                GAsyncResult  *result,
+                                GFile        **workdir,
+                                gchar        **branch,
+                                gboolean      *is_worktree,
+                                GError       **error)
+{
+  g_return_val_if_fail (GBP_IS_GIT_CLIENT (self), FALSE);
+  g_return_val_if_fail (IDE_IS_TASK (result), FALSE);
+
+  ide_clear_param (workdir, NULL);
+  ide_clear_param (branch, NULL);
+  ide_clear_param (is_worktree, FALSE);
+
+  if (ide_task_propagate_boolean (IDE_TASK (result), error))
+    {
+      Discover *state = ide_task_get_task_data (IDE_TASK (result));
+
+      g_assert (state != NULL);
+
+      if (workdir != NULL)
+        *workdir = g_steal_pointer (&state->workdir);
+
+      if (branch != NULL)
+        *branch = g_steal_pointer (&state->branch);
+
+      if (is_worktree != NULL)
+        *is_worktree = state->is_worktree;
+
+      return TRUE;
+    }
+
+  return FALSE;
+}
diff --git a/src/plugins/git/gbp-git-client.h b/src/plugins/git/gbp-git-client.h
index 493a6ca70..18d699c0f 100644
--- a/src/plugins/git/gbp-git-client.h
+++ b/src/plugins/git/gbp-git-client.h
@@ -35,98 +35,109 @@ typedef enum
 
 G_DECLARE_FINAL_TYPE (GbpGitClient, gbp_git_client, GBP, GIT_CLIENT, IdeObject)
 
-GbpGitClient *gbp_git_client_from_context             (IdeContext             *context);
-void          gbp_git_client_call_async               (GbpGitClient           *self,
-                                                       const gchar            *method,
-                                                       GVariant               *params,
-                                                       GCancellable           *cancellable,
-                                                       GAsyncReadyCallback     callback,
-                                                       gpointer                user_data);
-gboolean      gbp_git_client_call_finish              (GbpGitClient           *self,
-                                                       GAsyncResult           *result,
-                                                       GVariant              **reply,
-                                                       GError                **error);
-void          gbp_git_client_is_ignored_async         (GbpGitClient           *self,
-                                                       const gchar            *path,
-                                                       GCancellable           *cancellable,
-                                                       GAsyncReadyCallback     callback,
-                                                       gpointer                user_data);
-gboolean      gbp_git_client_is_ignored_finish        (GbpGitClient           *self,
-                                                       GAsyncResult           *result,
-                                                       GError                **error);
-void          gbp_git_client_list_status_async        (GbpGitClient           *self,
-                                                       const gchar            *directory_or_file,
-                                                       gboolean                include_descendants,
-                                                       GCancellable           *cancellable,
-                                                       GAsyncReadyCallback     callback,
-                                                       gpointer                user_data);
-GPtrArray    *gbp_git_client_list_status_finish       (GbpGitClient           *self,
-                                                       GAsyncResult           *result,
-                                                       GError                **error);
-void          gbp_git_client_list_refs_by_kind_async  (GbpGitClient           *self,
-                                                       GbpGitRefKind           kind,
-                                                       GCancellable           *cancellable,
-                                                       GAsyncReadyCallback     callback,
-                                                       gpointer                user_data);
-GPtrArray    *gbp_git_client_list_refs_by_kind_finish (GbpGitClient           *self,
-                                                       GAsyncResult           *result,
-                                                       GError                **error);
-void          gbp_git_client_switch_branch_async      (GbpGitClient           *self,
-                                                       const gchar            *branch_name,
-                                                       GCancellable           *cancellable,
-                                                       GAsyncReadyCallback     callback,
-                                                       gpointer                user_data);
-gboolean      gbp_git_client_switch_branch_finish     (GbpGitClient           *self,
-                                                       GAsyncResult           *result,
-                                                       gchar                 **switch_to_directory,
-                                                       GError                **error);
-void          gbp_git_client_create_repo_async        (GbpGitClient           *self,
-                                                       GFile                  *in_directory,
-                                                       gboolean                bare,
-                                                       GCancellable           *cancellable,
-                                                       GAsyncReadyCallback     callback,
-                                                       gpointer                user_data);
-gboolean      gbp_git_client_create_repo_finish       (GbpGitClient           *self,
-                                                       GAsyncResult           *result,
-                                                       GError                **error);
-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);
-gboolean      gbp_git_client_clone_url_finish         (GbpGitClient           *self,
-                                                       GAsyncResult           *result,
-                                                       GError                **error);
-void          gbp_git_client_update_submodules_async  (GbpGitClient           *self,
-                                                       IdeNotification        *notif,
-                                                       GCancellable           *cancellable,
-                                                       GAsyncReadyCallback     callback,
-                                                       gpointer                user_data);
-gboolean      gbp_git_client_update_submodules_finish (GbpGitClient           *self,
-                                                       GAsyncResult           *result,
-                                                       GError                **error);
-GVariant     *gbp_git_client_read_config              (GbpGitClient           *self,
-                                                       const gchar            *key,
-                                                       GCancellable           *cancellable,
-                                                       GError                **error);
-gboolean      gbp_git_client_update_config            (GbpGitClient           *self,
-                                                       gboolean                global,
-                                                       const gchar            *key,
-                                                       GVariant               *value,
-                                                       GCancellable           *cancellable,
-                                                       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);
+GbpGitClient *gbp_git_client_from_context             (IdeContext           *context);
+void          gbp_git_client_call_async               (GbpGitClient         *self,
+                                                       const gchar          *method,
+                                                       GVariant             *params,
+                                                       GCancellable         *cancellable,
+                                                       GAsyncReadyCallback   callback,
+                                                       gpointer              user_data);
+gboolean      gbp_git_client_call_finish              (GbpGitClient         *self,
+                                                       GAsyncResult         *result,
+                                                       GVariant            **reply,
+                                                       GError              **error);
+void          gbp_git_client_is_ignored_async         (GbpGitClient         *self,
+                                                       const gchar          *path,
+                                                       GCancellable         *cancellable,
+                                                       GAsyncReadyCallback   callback,
+                                                       gpointer              user_data);
+gboolean      gbp_git_client_is_ignored_finish        (GbpGitClient         *self,
+                                                       GAsyncResult         *result,
+                                                       GError              **error);
+void          gbp_git_client_list_status_async        (GbpGitClient         *self,
+                                                       const gchar          *directory_or_file,
+                                                       gboolean              include_descendants,
+                                                       GCancellable         *cancellable,
+                                                       GAsyncReadyCallback   callback,
+                                                       gpointer              user_data);
+GPtrArray    *gbp_git_client_list_status_finish       (GbpGitClient         *self,
+                                                       GAsyncResult         *result,
+                                                       GError              **error);
+void          gbp_git_client_list_refs_by_kind_async  (GbpGitClient         *self,
+                                                       GbpGitRefKind         kind,
+                                                       GCancellable         *cancellable,
+                                                       GAsyncReadyCallback   callback,
+                                                       gpointer              user_data);
+GPtrArray    *gbp_git_client_list_refs_by_kind_finish (GbpGitClient         *self,
+                                                       GAsyncResult         *result,
+                                                       GError              **error);
+void          gbp_git_client_switch_branch_async      (GbpGitClient         *self,
+                                                       const gchar          *branch_name,
+                                                       GCancellable         *cancellable,
+                                                       GAsyncReadyCallback   callback,
+                                                       gpointer              user_data);
+gboolean      gbp_git_client_switch_branch_finish     (GbpGitClient         *self,
+                                                       GAsyncResult         *result,
+                                                       gchar               **switch_to_directory,
+                                                       GError              **error);
+void          gbp_git_client_create_repo_async        (GbpGitClient         *self,
+                                                       GFile                *in_directory,
+                                                       gboolean              bare,
+                                                       GCancellable         *cancellable,
+                                                       GAsyncReadyCallback   callback,
+                                                       gpointer              user_data);
+gboolean      gbp_git_client_create_repo_finish       (GbpGitClient         *self,
+                                                       GAsyncResult         *result,
+                                                       GError              **error);
+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);
+gboolean      gbp_git_client_clone_url_finish         (GbpGitClient         *self,
+                                                       GAsyncResult         *result,
+                                                       GError              **error);
+void          gbp_git_client_update_submodules_async  (GbpGitClient         *self,
+                                                       IdeNotification      *notif,
+                                                       GCancellable         *cancellable,
+                                                       GAsyncReadyCallback   callback,
+                                                       gpointer              user_data);
+gboolean      gbp_git_client_update_submodules_finish (GbpGitClient         *self,
+                                                       GAsyncResult         *result,
+                                                       GError              **error);
+GVariant     *gbp_git_client_read_config              (GbpGitClient         *self,
+                                                       const gchar          *key,
+                                                       GCancellable         *cancellable,
+                                                       GError              **error);
+gboolean      gbp_git_client_update_config            (GbpGitClient         *self,
+                                                       gboolean              global,
+                                                       const gchar          *key,
+                                                       GVariant             *value,
+                                                       GCancellable         *cancellable,
+                                                       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);
+void          gbp_git_client_discover_async           (GbpGitClient         *self,
+                                                       GFile                *directory,
+                                                       GCancellable         *cancellable,
+                                                       GAsyncReadyCallback   callback,
+                                                       gpointer              user_data);
+gboolean      gbp_git_client_discover_finish          (GbpGitClient         *self,
+                                                       GAsyncResult         *result,
+                                                       GFile               **workdir,
+                                                       gchar               **branch,
+                                                       gboolean             *is_worktree,
+                                                       GError              **error);
 
 G_END_DECLS
diff --git a/src/plugins/git/gbp-git.c b/src/plugins/git/gbp-git.c
index 69b9ba89f..463029015 100644
--- a/src/plugins/git/gbp-git.c
+++ b/src/plugins/git/gbp-git.c
@@ -774,3 +774,174 @@ gbp_git_create_repo_finish (GbpGit        *self,
 
   return g_task_propagate_boolean (G_TASK (result), error);
 }
+
+typedef struct
+{
+  GFile *directory;
+  GFile *workdir;
+  gchar *branch;
+  guint  is_worktree : 1;
+} Discover;
+
+static void
+discover_free (Discover *state)
+{
+  g_clear_object (&state->directory);
+  g_clear_object (&state->workdir);
+  g_clear_pointer (&state->branch, g_free);
+  g_slice_free (Discover, state);
+}
+
+static void
+gbp_git_discover_worker (GTask        *task,
+                         gpointer      source_object,
+                         gpointer      task_data,
+                         GCancellable *cancellable)
+{
+  Discover *state = task_data;
+  g_autoptr(GError) error = NULL;
+  g_autoptr(GFile) location = NULL;
+  g_autoptr(GFile) workdir = NULL;
+  g_autoptr(GgitRepository) repository = NULL;
+  g_autofree gchar *worktree_branch = NULL;
+  gboolean is_worktree = FALSE;
+
+  g_assert (G_IS_TASK (task));
+  g_assert (GBP_IS_GIT (source_object));
+  g_assert (state != NULL);
+  g_assert (G_IS_FILE (state->directory));
+  g_assert (!cancellable || G_IS_CANCELLABLE (cancellable));
+
+  /* Short-circuit if we don't .git */
+  if (!(location = ggit_repository_discover_full (state->directory, TRUE, NULL, &error)))
+    {
+      g_task_return_new_error (task,
+                               G_IO_ERROR,
+                               G_IO_ERROR_NOT_SUPPORTED,
+                               "Failed to locate git repository location");
+      return;
+    }
+
+  /* If @location is a regular file, we might have a git-worktree link */
+  if (g_file_query_file_type (location, 0, NULL) == G_FILE_TYPE_REGULAR)
+    {
+      g_autofree gchar *contents = NULL;
+      gsize len;
+
+      if (g_file_load_contents (location, NULL, &contents, &len, NULL, NULL))
+        {
+          /* g_file_load_contents() provides a suffix \0 */
+          g_auto(GStrv) lines = g_strsplit (contents, "\n", 0);
+
+          for (guint i = 0; lines[i] != NULL; i++)
+            {
+              gchar *line = lines[i];
+
+              if (g_str_has_prefix (line, "gitdir: "))
+                {
+                  g_autoptr(GFile) location_parent = g_file_get_parent (location);
+                  const gchar *path = line + strlen ("gitdir: ");
+                  const gchar *branch;
+
+                  is_worktree = TRUE;
+
+                  g_clear_object (&location);
+
+                  if (g_path_is_absolute (path))
+                    location = g_file_new_for_path (path);
+                  else
+                    location = g_file_resolve_relative_path (location_parent, path);
+
+                  /*
+                   * Worktrees only have a single branch, and it is the name
+                   * of the suffix of .git/worktrees/<name>
+                   */
+                  if ((branch = strrchr (line, G_DIR_SEPARATOR)))
+                    worktree_branch = g_strdup (branch + 1);
+
+                  break;
+                }
+            }
+        }
+    }
+
+  if (!(repository = ggit_repository_open (location, &error)))
+    {
+      g_task_return_error (task, g_steal_pointer (&error));
+      return;
+    }
+
+  workdir = ggit_repository_get_workdir (repository);
+
+  g_assert (G_IS_FILE (location));
+  g_assert (G_IS_FILE (workdir));
+  g_assert (GGIT_IS_REPOSITORY (repository));
+
+  if (worktree_branch == NULL)
+    {
+      g_autoptr(GgitRef) ref = NULL;
+
+      if ((ref = ggit_repository_get_head (repository, NULL)))
+        worktree_branch = g_strdup (ggit_ref_get_shorthand (ref));
+
+      if (worktree_branch == NULL)
+        worktree_branch = g_strdup ("master");
+    }
+
+  state->workdir = g_file_dup (workdir);
+  state->branch = g_steal_pointer (&worktree_branch);
+  state->is_worktree = !!is_worktree;
+
+  g_task_return_boolean (task, TRUE);
+}
+
+void
+gbp_git_discover_async (GbpGit                      *self,
+                        GFile                       *directory,
+                        GCancellable                *cancellable,
+                        GAsyncReadyCallback          callback,
+                        gpointer                     user_data)
+{
+  g_autoptr(GTask) task = NULL;
+  Discover *state;
+
+  g_return_if_fail (GBP_IS_GIT (self));
+  g_return_if_fail (G_IS_FILE (directory));
+  g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
+
+  state = g_slice_new0 (Discover);
+  state->directory = g_file_dup (directory);
+
+  task = g_task_new (self, cancellable, callback, user_data);
+  g_task_set_source_tag (task, gbp_git_discover_async);
+  g_task_set_task_data (task, state, (GDestroyNotify)discover_free);
+  g_task_run_in_thread (task, gbp_git_discover_worker);
+}
+
+gboolean
+gbp_git_discover_finish (GbpGit        *self,
+                         GAsyncResult  *result,
+                         GFile        **workdir,
+                         gchar        **branch,
+                         gboolean      *is_worktree,
+                         GError       **error)
+{
+  g_return_val_if_fail (GBP_IS_GIT (self), FALSE);
+  g_return_val_if_fail (G_IS_TASK (result), FALSE);
+  g_return_val_if_fail (workdir != NULL, FALSE);
+  g_return_val_if_fail (branch != NULL, FALSE);
+  g_return_val_if_fail (is_worktree != NULL, FALSE);
+
+  if (g_task_propagate_boolean (G_TASK (result), error))
+    {
+      Discover *state = g_task_get_task_data (G_TASK (result));
+
+      *workdir = g_steal_pointer (&state->workdir);
+      *branch = g_steal_pointer (&state->branch);
+      *is_worktree = state->is_worktree;
+
+      return TRUE;
+    }
+
+  return FALSE;
+}
diff --git a/src/plugins/git/gbp-git.h b/src/plugins/git/gbp-git.h
index 1d9bad1c9..04120bd8b 100644
--- a/src/plugins/git/gbp-git.h
+++ b/src/plugins/git/gbp-git.h
@@ -134,5 +134,16 @@ void       gbp_git_update_config_async      (GbpGit                      *self,
 gboolean   gbp_git_update_config_finish     (GbpGit                      *self,
                                              GAsyncResult                *result,
                                              GError                     **error);
+void       gbp_git_discover_async           (GbpGit                      *self,
+                                             GFile                       *directory,
+                                             GCancellable                *cancellable,
+                                             GAsyncReadyCallback          callback,
+                                             gpointer                     user_data);
+gboolean   gbp_git_discover_finish          (GbpGit                      *self,
+                                             GAsyncResult                *result,
+                                             GFile                      **workdir,
+                                             gchar                      **branch,
+                                             gboolean                    *is_worktree,
+                                             GError                     **error);
 
 G_END_DECLS
diff --git a/src/plugins/git/gnome-builder-git.c b/src/plugins/git/gnome-builder-git.c
index 8c929a922..4e1a58b43 100644
--- a/src/plugins/git/gnome-builder-git.c
+++ b/src/plugins/git/gnome-builder-git.c
@@ -906,6 +906,78 @@ handle_create_repo (JsonrpcServer *server,
                              client_op_ref (op));
 }
 
+/* Handle Discover {{{1 */
+
+static void
+handle_discover_cb (GObject      *object,
+                    GAsyncResult *result,
+                    gpointer      user_data)
+{
+  GbpGit *git = (GbpGit *)object;
+  g_autoptr(ClientOp) op = user_data;
+  g_autoptr(GVariant) reply = NULL;
+  g_autoptr(GError) error = NULL;
+  g_autoptr(GFile) workdir = NULL;
+  g_autofree gchar *branch = NULL;
+  g_autofree gchar *uri = NULL;
+  gboolean is_worktree = FALSE;
+
+  g_assert (GBP_IS_GIT (git));
+  g_assert (G_IS_ASYNC_RESULT (result));
+  g_assert (op != NULL);
+
+  if (!gbp_git_discover_finish (git, result, &workdir, &branch, &is_worktree, &error))
+    {
+      client_op_error (op, error);
+      return;
+    }
+
+  uri = g_file_get_uri (workdir);
+
+  reply = JSONRPC_MESSAGE_NEW (
+    "workdir", JSONRPC_MESSAGE_PUT_STRING (uri),
+    "branch", JSONRPC_MESSAGE_PUT_STRING (branch),
+    "is-worktree", JSONRPC_MESSAGE_PUT_BOOLEAN (is_worktree)
+  );
+
+  client_op_reply (op, reply);
+}
+
+static void
+handle_discover (JsonrpcServer *server,
+                 JsonrpcClient *client,
+                 const gchar   *method,
+                 GVariant      *id,
+                 GVariant      *params,
+                 GbpGit        *git)
+{
+  g_autoptr(ClientOp) op = NULL;
+  g_autoptr(GFile) location = NULL;
+  const gchar *uri;
+
+  g_assert (JSONRPC_IS_SERVER (server));
+  g_assert (JSONRPC_IS_CLIENT (client));
+  g_assert (g_str_equal (method, "git/discover"));
+  g_assert (id != NULL);
+  g_assert (GBP_IS_GIT (git));
+
+  op = client_op_new (client, id);
+
+  if (!JSONRPC_MESSAGE_PARSE (params, "location", JSONRPC_MESSAGE_GET_STRING (&uri)))
+    {
+      client_op_bad_params (op);
+      return;
+    }
+
+  location = g_file_new_for_uri (uri);
+
+  gbp_git_discover_async (git,
+                          location,
+                          op->cancellable,
+                          (GAsyncReadyCallback)handle_discover_cb,
+                          client_op_ref (op));
+}
+
 /* Main Loop and Setup {{{1 */
 
 gint
@@ -946,16 +1018,17 @@ main (gint argc,
 #define ADD_HANDLER(method, func) \
   jsonrpc_server_add_handler (server, method, (JsonrpcServerHandler)func, g_object_ref (git), g_object_unref)
 
-  ADD_HANDLER ("initialize", handle_initialize);
+  ADD_HANDLER ("$/cancelRequest", handle_cancel_request);
   ADD_HANDLER ("git/cloneUrl", handle_clone_url);
   ADD_HANDLER ("git/createRepo", handle_create_repo);
-  ADD_HANDLER ("git/readConfig", handle_read_config);
+  ADD_HANDLER ("git/discover", handle_discover);
   ADD_HANDLER ("git/isIgnored", handle_is_ignored);
   ADD_HANDLER ("git/listRefsByKind", handle_list_refs_by_kind);
+  ADD_HANDLER ("git/readConfig", handle_read_config);
   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);
+  ADD_HANDLER ("initialize", handle_initialize);
 
 #undef ADD_HANDLER
 


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