[gnome-builder/wip/gtk4-port] libide/vcs: add in IdeVcsCloneRequest object



commit 98b120871a3e86ed11d83cfd903f254136be6e27
Author: Christian Hergert <chergert redhat com>
Date:   Tue May 31 16:04:22 2022 -0700

    libide/vcs: add in IdeVcsCloneRequest object
    
    The goal here is to simplify cloning a repo into a helper object like we
    did for creating project templates. It's really a "controller", if you
    will, for the clone flow.
    
    There is still additional work to do the actual clone, and I'd like to
    add some busy state here for tracking progress with branch loading.
    
    Additionally, we'll probably want to plumb a PTY through for clone
    operations so subprocesses have access to that instead of shuttling
    strings to us w/o any shell/control/etc.

 src/libide/vcs/ide-vcs-clone-request.c | 508 +++++++++++++++++++++++++++++++++
 src/libide/vcs/ide-vcs-clone-request.h |  72 +++++
 src/libide/vcs/libide-vcs.h            |   1 +
 src/libide/vcs/meson.build             |   3 +
 4 files changed, 584 insertions(+)
---
diff --git a/src/libide/vcs/ide-vcs-clone-request.c b/src/libide/vcs/ide-vcs-clone-request.c
new file mode 100644
index 000000000..558ebe767
--- /dev/null
+++ b/src/libide/vcs/ide-vcs-clone-request.c
@@ -0,0 +1,508 @@
+/* ide-vcs-clone-request.c
+ *
+ * Copyright 2022 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 "ide-vcs-clone-request"
+
+#include "config.h"
+
+#include <libide-plugins.h>
+
+#include "ide-vcs-cloner.h"
+#include "ide-vcs-clone-request.h"
+#include "ide-vcs-uri.h"
+
+struct _IdeVcsCloneRequest
+{
+  IdeObject     parent_instance;
+
+  GListModel   *branch_model;
+  GCancellable *cancellable;
+  GFile        *directory;
+
+  IdeVcsCloner *cloner;
+
+  char         *author_email;
+  char         *author_name;
+  char         *branch_name;
+  char         *module_name;
+  char         *uri;
+};
+
+enum {
+  PROP_0,
+  PROP_AUTHOR_EMAIL,
+  PROP_AUTHOR_NAME,
+  PROP_CAN_SELECT_BRANCH,
+  PROP_BRANCH_MODEL,
+  PROP_BRANCH_NAME,
+  PROP_DIRECTORY,
+  PROP_MODULE_NAME,
+  PROP_URI,
+  N_PROPS
+};
+
+G_DEFINE_FINAL_TYPE (IdeVcsCloneRequest, ide_vcs_clone_request, IDE_TYPE_OBJECT)
+
+static GParamSpec *properties [N_PROPS];
+
+static gboolean
+ide_vcs_clone_request_get_can_select_branch (IdeVcsCloneRequest *self)
+{
+  g_assert (IDE_IS_VCS_CLONE_REQUEST (self));
+
+  return !ide_str_empty0 (self->uri) &&
+         self->cloner != NULL &&
+         IDE_VCS_CLONER_GET_IFACE (self->cloner)->list_branches_async != NULL;
+}
+
+static void
+ide_vcs_clone_request_set_cloner (IdeVcsCloneRequest *self,
+                                  IdeVcsCloner       *cloner)
+{
+  IDE_ENTRY;
+
+  g_assert (IDE_IS_VCS_CLONE_REQUEST (self));
+  g_assert (!cloner || IDE_IS_VCS_CLONER (cloner));
+
+  g_debug ("Setting cloner to %s",
+           cloner ? G_OBJECT_TYPE_NAME (cloner) : "NULL");
+
+  if (g_set_object (&self->cloner, cloner))
+    {
+      g_clear_object (&self->branch_model);
+      g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_BRANCH_MODEL]);
+      g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_CAN_SELECT_BRANCH]);
+    }
+
+  IDE_EXIT;
+}
+
+static void
+ide_vcs_clone_request_dispose (GObject *object)
+{
+  IdeVcsCloneRequest *self = (IdeVcsCloneRequest *)object;
+
+  g_clear_object (&self->branch_model);
+  g_clear_object (&self->cancellable);
+  g_clear_object (&self->directory);
+
+  ide_clear_and_destroy_object (&self->cloner);
+
+  ide_clear_string (&self->author_email);
+  ide_clear_string (&self->author_name);
+  ide_clear_string (&self->branch_name);
+  ide_clear_string (&self->module_name);
+  ide_clear_string (&self->uri);
+
+  G_OBJECT_CLASS (ide_vcs_clone_request_parent_class)->dispose (object);
+}
+
+static void
+ide_vcs_clone_request_get_property (GObject    *object,
+                                    guint       prop_id,
+                                    GValue     *value,
+                                    GParamSpec *pspec)
+{
+  IdeVcsCloneRequest *self = IDE_VCS_CLONE_REQUEST (object);
+
+  switch (prop_id)
+    {
+    case PROP_AUTHOR_EMAIL:
+      g_value_set_string (value, ide_vcs_clone_request_get_author_email (self));
+      break;
+
+    case PROP_AUTHOR_NAME:
+      g_value_set_string (value, ide_vcs_clone_request_get_author_name (self));
+      break;
+
+    case PROP_BRANCH_MODEL:
+      g_value_set_object (value, ide_vcs_clone_request_get_branch_model (self));
+      break;
+
+    case PROP_BRANCH_NAME:
+      g_value_set_string (value, ide_vcs_clone_request_get_branch_name (self));
+      break;
+
+    case PROP_CAN_SELECT_BRANCH:
+      g_value_set_boolean (value, ide_vcs_clone_request_get_can_select_branch (self));
+      break;
+
+    case PROP_DIRECTORY:
+      g_value_set_object (value, ide_vcs_clone_request_get_directory (self));
+      break;
+
+    case PROP_MODULE_NAME:
+      g_value_set_string (value, ide_vcs_clone_request_get_module_name (self));
+      break;
+
+    case PROP_URI:
+      g_value_set_string (value, ide_vcs_clone_request_get_uri (self));
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+}
+
+static void
+ide_vcs_clone_request_set_property (GObject      *object,
+                                    guint         prop_id,
+                                    const GValue *value,
+                                    GParamSpec   *pspec)
+{
+  IdeVcsCloneRequest *self = IDE_VCS_CLONE_REQUEST (object);
+
+  switch (prop_id)
+    {
+    case PROP_AUTHOR_EMAIL:
+      ide_vcs_clone_request_set_author_email (self, g_value_get_string (value));
+      break;
+
+    case PROP_AUTHOR_NAME:
+      ide_vcs_clone_request_set_author_name (self, g_value_get_string (value));
+      break;
+
+    case PROP_BRANCH_NAME:
+      ide_vcs_clone_request_set_branch_name (self, g_value_get_string (value));
+      break;
+
+    case PROP_DIRECTORY:
+      ide_vcs_clone_request_set_directory (self, g_value_get_object (value));
+      break;
+
+    case PROP_MODULE_NAME:
+      ide_vcs_clone_request_set_module_name (self, g_value_get_string (value));
+      break;
+
+    case PROP_URI:
+      ide_vcs_clone_request_set_uri (self, g_value_get_string (value));
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+}
+
+static void
+ide_vcs_clone_request_class_init (IdeVcsCloneRequestClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->dispose = ide_vcs_clone_request_dispose;
+  object_class->get_property = ide_vcs_clone_request_get_property;
+  object_class->set_property = ide_vcs_clone_request_set_property;
+
+  properties [PROP_AUTHOR_EMAIL] =
+    g_param_spec_string ("author-email", NULL, NULL, NULL,
+                         (G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS));
+
+  properties [PROP_AUTHOR_NAME] =
+    g_param_spec_string ("author-name", NULL, NULL, NULL,
+                         (G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS));
+
+  /**
+   * IdeVcsCloneRequest:branch-model:
+   *
+   * The "branch-model" contains a #GListModel of #IdeVcsBranch that
+   * represents the names of branches that may be available on the peer.
+   *
+   * This model is not automatically updated until
+   * ide_vcs_clone_request_populate_branches() is called. This is to make it
+   * clear to the user that it is being done in response to an action (such
+   * as showing a popover) since user/password information may be requested
+   * from the user.
+   *
+   * The UI may use this to show a popover/selection of branches for the
+   * user to select.
+   */
+  properties [PROP_BRANCH_MODEL] =
+    g_param_spec_object ("branch-model", NULL, NULL, G_TYPE_LIST_MODEL,
+                         (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+
+  properties [PROP_CAN_SELECT_BRANCH] =
+    g_param_spec_boolean ("can-select-branch", NULL, NULL, FALSE,
+                          (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+
+  properties [PROP_BRANCH_NAME] =
+    g_param_spec_string ("branch-name", NULL, NULL, NULL,
+                         (G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS));
+
+  properties [PROP_DIRECTORY] =
+    g_param_spec_object ("directory", NULL, NULL, G_TYPE_FILE,
+                         (G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS));
+
+  properties [PROP_MODULE_NAME] =
+    g_param_spec_string ("module-name", NULL, NULL, NULL,
+                         (G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS));
+
+  properties [PROP_URI] =
+    g_param_spec_string ("uri", NULL, NULL, NULL,
+                         (G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS));
+
+  g_object_class_install_properties (object_class, N_PROPS, properties);
+}
+
+static void
+ide_vcs_clone_request_init (IdeVcsCloneRequest *self)
+{
+  /* Set to default projects directory */
+  ide_vcs_clone_request_set_directory (self, NULL);
+}
+
+const char *
+ide_vcs_clone_request_get_author_email (IdeVcsCloneRequest *self)
+{
+  g_return_val_if_fail (IDE_IS_VCS_CLONE_REQUEST (self), NULL);
+
+  return self->author_email ? self->author_email : "";
+}
+
+const char *
+ide_vcs_clone_request_get_author_name (IdeVcsCloneRequest *self)
+{
+  const char *ret;
+
+  g_return_val_if_fail (IDE_IS_VCS_CLONE_REQUEST (self), NULL);
+
+  ret = self->author_name;
+
+  if (ide_str_empty0 (ret))
+    ret = g_get_real_name ();
+
+  if (ide_str_empty0 (ret))
+    return "";
+
+  return ret;
+}
+
+const char *
+ide_vcs_clone_request_get_branch_name (IdeVcsCloneRequest *self)
+{
+  g_return_val_if_fail (IDE_IS_VCS_CLONE_REQUEST (self), NULL);
+
+  return self->branch_name ? self->branch_name : "";
+}
+
+const char *
+ide_vcs_clone_request_get_module_name (IdeVcsCloneRequest *self)
+{
+  g_return_val_if_fail (IDE_IS_VCS_CLONE_REQUEST (self), NULL);
+
+  return self->module_name;
+}
+
+/**
+ * ide_vcs_clone_request_get_directory:
+ * @self: a #IdeVcsCloneRequest
+ *
+ * Gets the directory to use which will contain the new subdirectory
+ * created when checking out the project.
+ *
+ * Returns: (transfer none) (not nullable): a #GFile
+ */
+GFile *
+ide_vcs_clone_request_get_directory (IdeVcsCloneRequest *self)
+{
+  g_return_val_if_fail (IDE_IS_VCS_CLONE_REQUEST (self), NULL);
+  g_return_val_if_fail (G_IS_FILE (self->directory), NULL);
+
+  return self->directory;
+}
+
+const char *
+ide_vcs_clone_request_get_uri (IdeVcsCloneRequest *self)
+{
+  g_return_val_if_fail (IDE_IS_VCS_CLONE_REQUEST (self), NULL);
+
+  return self->uri ? self->uri : "";
+}
+
+void
+ide_vcs_clone_request_set_author_email (IdeVcsCloneRequest *self,
+                                        const char         *author_email)
+{
+  g_return_if_fail (IDE_IS_VCS_CLONE_REQUEST (self));
+
+  if (ide_set_string (&self->author_email, author_email))
+    g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_AUTHOR_EMAIL]);
+}
+
+void
+ide_vcs_clone_request_set_author_name (IdeVcsCloneRequest *self,
+                                       const char         *author_name)
+{
+  g_return_if_fail (IDE_IS_VCS_CLONE_REQUEST (self));
+
+  if (ide_set_string (&self->author_name, author_name))
+    g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_AUTHOR_NAME]);
+}
+
+void
+ide_vcs_clone_request_set_branch_name (IdeVcsCloneRequest *self,
+                                       const char         *branch_name)
+{
+  g_return_if_fail (IDE_IS_VCS_CLONE_REQUEST (self));
+
+  if (ide_set_string (&self->branch_name, branch_name))
+    g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_BRANCH_NAME]);
+}
+
+void
+ide_vcs_clone_request_set_module_name (IdeVcsCloneRequest *self,
+                                       const char         *module_name)
+{
+  g_return_if_fail (IDE_IS_VCS_CLONE_REQUEST (self));
+
+  if (ide_set_string (&self->module_name, module_name))
+    {
+      g_autoptr(PeasExtension) exten = NULL;
+
+      if (module_name != NULL)
+        {
+          PeasEngine *engine = peas_engine_get_default ();
+          PeasPluginInfo *plugin_info = peas_engine_get_plugin_info (engine, module_name);
+
+          if (plugin_info != NULL &&
+              peas_engine_provides_extension (engine, plugin_info, IDE_TYPE_VCS_CLONER))
+            exten = peas_engine_create_extension (engine,
+                                                  plugin_info,
+                                                  IDE_TYPE_VCS_CLONER,
+                                                  "parent", IDE_OBJECT (self),
+                                                  NULL);
+        }
+
+      ide_vcs_clone_request_set_cloner (self, IDE_VCS_CLONER (exten));
+      g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_MODULE_NAME]);
+    }
+}
+
+void
+ide_vcs_clone_request_set_directory (IdeVcsCloneRequest *self,
+                                     GFile              *directory)
+{
+  g_autoptr(GFile) default_directory = NULL;
+
+  g_return_if_fail (IDE_IS_VCS_CLONE_REQUEST (self));
+  g_return_if_fail (!directory || G_IS_FILE (directory));
+
+  if (directory == NULL)
+    {
+      default_directory = g_file_new_for_path (ide_get_projects_dir ());
+      directory = default_directory;
+    }
+
+  g_assert (G_IS_FILE (directory));
+
+  if (g_set_object (&self->directory, directory))
+    g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_DIRECTORY]);
+}
+
+void
+ide_vcs_clone_request_set_uri (IdeVcsCloneRequest *self,
+                               const char         *uri)
+{
+  g_return_if_fail (IDE_IS_VCS_CLONE_REQUEST (self));
+
+  if (ide_set_string (&self->uri, uri))
+    {
+      g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_CAN_SELECT_BRANCH]);
+      g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_URI]);
+    }
+}
+
+/**
+ * ide_vcs_clone_request_get_branch_model:
+ * @self: a #IdeVcsCloneRequest
+ *
+ * Gets the #GListModel of #IdeVcsBranch once available.
+ *
+ * Returns: (transfer none): a #GListModel of #IdeVcsBranch, or %NULL
+ *   if the model has not yet been created.
+ */
+GListModel *
+ide_vcs_clone_request_get_branch_model (IdeVcsCloneRequest *self)
+{
+  g_return_val_if_fail (IDE_IS_VCS_CLONE_REQUEST (self), NULL);
+
+  return self->branch_model;
+}
+
+static void
+ide_vcs_clone_request_populate_branches_cb (GObject *object,
+                                            GAsyncResult *result,
+                                            gpointer user_data)
+{
+  IdeVcsCloner *cloner = (IdeVcsCloner *)object;
+  g_autoptr(IdeVcsCloneRequest) self = user_data;
+  g_autoptr(GListModel) branches = NULL;
+  g_autoptr(GError) error = NULL;
+
+  IDE_ENTRY;
+
+  g_assert (IDE_IS_VCS_CLONER (cloner));
+  g_assert (G_IS_ASYNC_RESULT (result));
+  g_assert (IDE_IS_VCS_CLONE_REQUEST (self));
+
+  if (!(branches = ide_vcs_cloner_list_branches_finish (cloner, result, &error)))
+    g_warning ("Failed to list branches: %s", error->message);
+
+  if (g_set_object (&self->branch_model, branches))
+    g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_BRANCH_MODEL]);
+
+  IDE_EXIT;
+}
+
+void
+ide_vcs_clone_request_populate_branches (IdeVcsCloneRequest *self)
+{
+  g_autoptr(IdeVcsUri) uri = NULL;
+  const char *uri_str;
+
+  IDE_ENTRY;
+
+  g_return_if_fail (IDE_IS_VCS_CLONE_REQUEST (self));
+  g_return_if_fail (IDE_IS_VCS_CLONER (self->cloner));
+
+  if (!ide_vcs_clone_request_get_can_select_branch (self))
+    {
+      g_message ("IdeVcsCloner does not support listing branches");
+      IDE_EXIT;
+    }
+
+  if (!(uri_str = ide_vcs_clone_request_get_uri (self)) ||
+      !ide_vcs_uri_is_valid (uri_str) ||
+      !(uri = ide_vcs_uri_new (uri_str)))
+    {
+      g_debug ("Unvalid VCS uri, cannot populate branches");
+      IDE_EXIT;
+    }
+
+  g_cancellable_cancel (self->cancellable);
+  g_clear_object (&self->cancellable);
+  self->cancellable = g_cancellable_new ();
+
+  ide_vcs_cloner_list_branches_async (self->cloner,
+                                      uri,
+                                      self->cancellable,
+                                      ide_vcs_clone_request_populate_branches_cb,
+                                      g_object_ref (self));
+
+  IDE_EXIT;
+}
diff --git a/src/libide/vcs/ide-vcs-clone-request.h b/src/libide/vcs/ide-vcs-clone-request.h
new file mode 100644
index 000000000..839fbc2d9
--- /dev/null
+++ b/src/libide/vcs/ide-vcs-clone-request.h
@@ -0,0 +1,72 @@
+/* ide-vcs-clone-request.h
+ *
+ * Copyright 2022 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
+
+#if !defined (IDE_VCS_INSIDE) && !defined (IDE_VCS_COMPILATION)
+# error "Only <libide-vcs.h> can be included directly."
+#endif
+
+#include <libide-core.h>
+
+G_BEGIN_DECLS
+
+#define IDE_TYPE_VCS_CLONE_REQUEST (ide_vcs_clone_request_get_type())
+
+IDE_AVAILABLE_IN_ALL
+G_DECLARE_FINAL_TYPE (IdeVcsCloneRequest, ide_vcs_clone_request, IDE, VCS_CLONE_REQUEST, IdeObject)
+
+IDE_AVAILABLE_IN_ALL
+IdeVcsCloneRequest *ide_vcs_clone_request_new               (void);
+IDE_AVAILABLE_IN_ALL
+const char         *ide_vcs_clone_request_get_module_name   (IdeVcsCloneRequest *self);
+IDE_AVAILABLE_IN_ALL
+void                ide_vcs_clone_request_set_module_name   (IdeVcsCloneRequest *self,
+                                                             const char         *module_name);
+IDE_AVAILABLE_IN_ALL
+const char         *ide_vcs_clone_request_get_author_name   (IdeVcsCloneRequest *self);
+IDE_AVAILABLE_IN_ALL
+void                ide_vcs_clone_request_set_author_name   (IdeVcsCloneRequest *self,
+                                                             const char         *author_name);
+IDE_AVAILABLE_IN_ALL
+const char         *ide_vcs_clone_request_get_author_email  (IdeVcsCloneRequest *self);
+IDE_AVAILABLE_IN_ALL
+void                ide_vcs_clone_request_set_author_email  (IdeVcsCloneRequest *self,
+                                                             const char         *author_email);
+GListModel         *ide_vcs_clone_request_get_branch_model  (IdeVcsCloneRequest *self);
+IDE_AVAILABLE_IN_ALL
+const char         *ide_vcs_clone_request_get_branch_name   (IdeVcsCloneRequest *self);
+IDE_AVAILABLE_IN_ALL
+void                ide_vcs_clone_request_set_branch_name   (IdeVcsCloneRequest *self,
+                                                             const char         *branch_name);
+IDE_AVAILABLE_IN_ALL
+const char         *ide_vcs_clone_request_get_uri           (IdeVcsCloneRequest *self);
+IDE_AVAILABLE_IN_ALL
+void                ide_vcs_clone_request_set_uri           (IdeVcsCloneRequest *self,
+                                                             const char         *uri);
+IDE_AVAILABLE_IN_ALL
+GFile              *ide_vcs_clone_request_get_directory     (IdeVcsCloneRequest *self);
+IDE_AVAILABLE_IN_ALL
+void                ide_vcs_clone_request_set_directory     (IdeVcsCloneRequest *self,
+                                                             GFile              *directory);
+IDE_AVAILABLE_IN_ALL
+void                ide_vcs_clone_request_populate_branches (IdeVcsCloneRequest *self);
+
+G_END_DECLS
diff --git a/src/libide/vcs/libide-vcs.h b/src/libide/vcs/libide-vcs.h
index aafb4ed38..4f1a48c0d 100644
--- a/src/libide/vcs/libide-vcs.h
+++ b/src/libide/vcs/libide-vcs.h
@@ -28,6 +28,7 @@
 #include "ide-directory-vcs.h"
 #include "ide-vcs-branch.h"
 #include "ide-vcs-cloner.h"
+#include "ide-vcs-clone-request.h"
 #include "ide-vcs-config.h"
 #include "ide-vcs-enums.h"
 #include "ide-vcs-initializer.h"
diff --git a/src/libide/vcs/meson.build b/src/libide/vcs/meson.build
index c762afb64..4f7fda4a3 100644
--- a/src/libide/vcs/meson.build
+++ b/src/libide/vcs/meson.build
@@ -11,6 +11,7 @@ libide_vcs_public_headers = [
   'ide-vcs-branch.h',
   'ide-vcs-config.h',
   'ide-vcs-cloner.h',
+  'ide-vcs-clone-request.h',
   'ide-vcs-file-info.h',
   'ide-vcs-initializer.h',
   'ide-vcs-monitor.h',
@@ -36,6 +37,7 @@ libide_vcs_public_sources = [
   'ide-vcs-branch.c',
   'ide-vcs-config.c',
   'ide-vcs-cloner.c',
+  'ide-vcs-clone-request.c',
   'ide-vcs-file-info.c',
   'ide-vcs-initializer.c',
   'ide-vcs-monitor.c',
@@ -69,6 +71,7 @@ libide_vcs_deps = [
 
   libide_core_dep,
   libide_io_dep,
+  libide_plugins_dep,
   libide_threading_dep,
 ]
 


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