1 /* gbp-git-workbench-addin.c
2 *
3 * Copyright 2019 Christian Hergert <chergert@redhat.com>
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 * SPDX-License-Identifier: GPL-3.0-or-later
19 */
20
21 #define G_LOG_DOMAIN "gbp-git-workbench-addin"
22
23 #include "config.h"
24
25 #include <libide-vcs.h>
26
27 #include "daemon/ipc-git-service.h"
28
29 #include "gbp-git-client.h"
30 #include "gbp-git-workbench-addin.h"
31 #include "gbp-git-vcs.h"
32
33 struct _GbpGitWorkbenchAddin
34 {
35 GObject parent_instance;
36 IdeWorkbench *workbench;
37 };
38
39 static void
gbp_git_workbench_addin_load_project_new_cb(GObject * object,GAsyncResult * result,gpointer user_data)40 gbp_git_workbench_addin_load_project_new_cb (GObject *object,
41 GAsyncResult *result,
42 gpointer user_data)
43 {
44 GbpGitWorkbenchAddin *self;
45 g_autoptr(IpcGitRepository) repository = NULL;
46 g_autoptr(IdeTask) task = user_data;
47 g_autoptr(GError) error = NULL;
48
49 g_assert (G_IS_ASYNC_RESULT (result));
50 g_assert (IDE_IS_TASK (task));
51
52 if (!(repository = ipc_git_repository_proxy_new_finish (result, &error)))
53 {
54 ide_task_return_error (task, g_steal_pointer (&error));
55 return;
56 }
57
58 self = ide_task_get_source_object (task);
59
60 if (self->workbench != NULL)
61 {
62 g_autoptr(GbpGitVcs) vcs = gbp_git_vcs_new (repository);
63
64 ide_workbench_set_vcs (self->workbench, IDE_VCS (vcs));
65 }
66
67 ide_task_return_boolean (task, TRUE);
68 }
69
70 static void
gbp_git_workbench_addin_load_project_open_cb(GObject * object,GAsyncResult * result,gpointer user_data)71 gbp_git_workbench_addin_load_project_open_cb (GObject *object,
72 GAsyncResult *result,
73 gpointer user_data)
74 {
75 IpcGitService *service = (IpcGitService *)object;
76 g_autofree gchar *obj_path = NULL;
77 g_autoptr(IdeTask) task = user_data;
78 g_autoptr(GError) error = NULL;
79 GDBusConnection *connection;
80
81 g_assert (IPC_IS_GIT_SERVICE (service));
82 g_assert (G_IS_ASYNC_RESULT (result));
83 g_assert (IDE_IS_TASK (task));
84
85 connection = g_dbus_proxy_get_connection (G_DBUS_PROXY (service));
86
87 if (!ipc_git_service_call_open_finish (service, &obj_path, result, &error))
88 ide_task_return_error (task, g_steal_pointer (&error));
89 else
90 ipc_git_repository_proxy_new (connection,
91 G_DBUS_PROXY_FLAGS_NONE,
92 NULL,
93 obj_path,
94 ide_task_get_cancellable (task),
95 gbp_git_workbench_addin_load_project_new_cb,
96 g_object_ref (task));
97 }
98
99 static void
gbp_git_workbench_addin_load_project_discover_cb(GObject * object,GAsyncResult * result,gpointer user_data)100 gbp_git_workbench_addin_load_project_discover_cb (GObject *object,
101 GAsyncResult *result,
102 gpointer user_data)
103 {
104 IpcGitService *service = (IpcGitService *)object;
105 g_autofree gchar *git_location = NULL;
106 g_autoptr(IdeTask) task = user_data;
107 g_autoptr(GError) error = NULL;
108
109 g_assert (IPC_IS_GIT_SERVICE (service));
110 g_assert (G_IS_ASYNC_RESULT (result));
111 g_assert (IDE_IS_TASK (task));
112
113 if (!ipc_git_service_call_discover_finish (service, &git_location, result, &error))
114 {
115 g_dbus_error_strip_remote_error (error);
116 ide_task_return_error (task, g_steal_pointer (&error));
117 return;
118 }
119
120 ipc_git_service_call_open (service,
121 git_location,
122 ide_task_get_cancellable (task),
123 gbp_git_workbench_addin_load_project_open_cb,
124 g_object_ref (task));
125 }
126
127 static void
gbp_git_workbench_addin_load_project_service_cb(GObject * object,GAsyncResult * result,gpointer user_data)128 gbp_git_workbench_addin_load_project_service_cb (GObject *object,
129 GAsyncResult *result,
130 gpointer user_data)
131 {
132 GbpGitClient *client = (GbpGitClient *)object;
133 g_autoptr(IpcGitService) service = NULL;
134 g_autoptr(IdeTask) task = user_data;
135 g_autoptr(GError) error = NULL;
136 IdeProjectInfo *project_info;
137 GFile *directory;
138
139 g_assert (GBP_IS_GIT_CLIENT (client));
140 g_assert (G_IS_ASYNC_RESULT (result));
141 g_assert (IDE_IS_TASK (task));
142
143 if (!(service = gbp_git_client_get_service_finish (client, result, &error)))
144 {
145 ide_task_return_error (task, g_steal_pointer (&error));
146 return;
147 }
148
149 project_info = ide_task_get_task_data (task);
150 directory = ide_project_info_get_directory (project_info);
151
152 if (!g_file_is_native (directory))
153 {
154 ide_task_return_new_error (task,
155 G_IO_ERROR,
156 G_IO_ERROR_NOT_SUPPORTED,
157 "Cannot initialize git, not a local file-system");
158 return;
159 }
160
161 ipc_git_service_call_discover (service,
162 g_file_peek_path (directory),
163 ide_task_get_cancellable (task),
164 gbp_git_workbench_addin_load_project_discover_cb,
165 g_object_ref (task));
166 }
167
168 static void
gbp_git_workbench_addin_load_project_async(IdeWorkbenchAddin * addin,IdeProjectInfo * project_info,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)169 gbp_git_workbench_addin_load_project_async (IdeWorkbenchAddin *addin,
170 IdeProjectInfo *project_info,
171 GCancellable *cancellable,
172 GAsyncReadyCallback callback,
173 gpointer user_data)
174 {
175 GbpGitWorkbenchAddin *self = (GbpGitWorkbenchAddin *)addin;
176 g_autoptr(IdeTask) task = NULL;
177 GbpGitClient *client;
178 IdeContext *context;
179
180 g_assert (GBP_IS_GIT_WORKBENCH_ADDIN (self));
181 g_assert (IDE_IS_PROJECT_INFO (project_info));
182 g_assert (!cancellable || G_IS_CANCELLABLE (cancellable));
183
184 task = ide_task_new (self, cancellable, callback, user_data);
185 ide_task_set_source_tag (task, gbp_git_workbench_addin_load_project_async);
186 ide_task_set_task_data (task, g_object_ref (project_info), g_object_unref);
187
188 context = ide_workbench_get_context (self->workbench);
189 client = gbp_git_client_from_context (context);
190
191 gbp_git_client_get_service_async (client,
192 cancellable,
193 gbp_git_workbench_addin_load_project_service_cb,
194 g_steal_pointer (&task));
195 }
196
197 static gboolean
gbp_git_workbench_addin_load_project_finish(IdeWorkbenchAddin * addin,GAsyncResult * result,GError ** error)198 gbp_git_workbench_addin_load_project_finish (IdeWorkbenchAddin *addin,
199 GAsyncResult *result,
200 GError **error)
201 {
202 g_assert (GBP_IS_GIT_WORKBENCH_ADDIN (addin));
203 g_assert (IDE_IS_TASK (result));
204
205 return ide_task_propagate_boolean (IDE_TASK (result), error);
206 }
207
208 static void
gbp_git_workbench_addin_load(IdeWorkbenchAddin * addin,IdeWorkbench * workbench)209 gbp_git_workbench_addin_load (IdeWorkbenchAddin *addin,
210 IdeWorkbench *workbench)
211 {
212 GbpGitWorkbenchAddin *self = (GbpGitWorkbenchAddin *)addin;
213
214 g_assert (GBP_IS_GIT_WORKBENCH_ADDIN (self));
215 g_assert (IDE_IS_WORKBENCH (workbench));
216
217 self->workbench = workbench;
218 }
219
220 static void
gbp_git_workbench_addin_unload(IdeWorkbenchAddin * addin,IdeWorkbench * workbench)221 gbp_git_workbench_addin_unload (IdeWorkbenchAddin *addin,
222 IdeWorkbench *workbench)
223 {
224 GbpGitWorkbenchAddin *self = (GbpGitWorkbenchAddin *)addin;
225
226 g_assert (GBP_IS_GIT_WORKBENCH_ADDIN (self));
227 g_assert (IDE_IS_WORKBENCH (workbench));
228
229 self->workbench = NULL;
230 }
231
232 static void
workbench_addin_iface_init(IdeWorkbenchAddinInterface * iface)233 workbench_addin_iface_init (IdeWorkbenchAddinInterface *iface)
234 {
235 iface->load = gbp_git_workbench_addin_load;
236 iface->unload = gbp_git_workbench_addin_unload;
237 iface->load_project_async = gbp_git_workbench_addin_load_project_async;
238 iface->load_project_finish = gbp_git_workbench_addin_load_project_finish;
239 }
240
G_DEFINE_FINAL_TYPE_WITH_CODE(GbpGitWorkbenchAddin,gbp_git_workbench_addin,G_TYPE_OBJECT,G_IMPLEMENT_INTERFACE (IDE_TYPE_WORKBENCH_ADDIN,workbench_addin_iface_init))241 G_DEFINE_FINAL_TYPE_WITH_CODE (GbpGitWorkbenchAddin, gbp_git_workbench_addin, G_TYPE_OBJECT,
242 G_IMPLEMENT_INTERFACE (IDE_TYPE_WORKBENCH_ADDIN, workbench_addin_iface_init))
243
244 static void
245 gbp_git_workbench_addin_class_init (GbpGitWorkbenchAddinClass *klass)
246 {
247 }
248
249 static void
gbp_git_workbench_addin_init(GbpGitWorkbenchAddin * self)250 gbp_git_workbench_addin_init (GbpGitWorkbenchAddin *self)
251 {
252 }
253