[gnome-builder] build-commands: add prebuild and postbuild commands



commit 76d352536c25d8fb93e6cc0a8d0b3fc2f07e7878
Author: Christian Hergert <chergert redhat com>
Date:   Fri Sep 2 19:41:38 2016 -0700

    build-commands: add prebuild and postbuild commands
    
    This allows a configuration to specify additional commands that can be
    run before or after the build system has executed its build. This might
    be handy to setup various command hooks around a build system.
    
    Additionally, these should be usable by Nil build systems that just need
    to execute some commands as part of the build. (More on that later).

 libide/Makefile.am                           |    4 +
 libide/buildsystem/ide-build-command-queue.c |  275 +++++++++++++++++++
 libide/buildsystem/ide-build-command-queue.h |   52 ++++
 libide/buildsystem/ide-build-command.c       |  376 ++++++++++++++++++++++++++
 libide/buildsystem/ide-build-command.h       |   86 ++++++
 libide/ide-types.h                           |    4 +
 libide/ide.h                                 |    2 +
 7 files changed, 799 insertions(+), 0 deletions(-)
---
diff --git a/libide/Makefile.am b/libide/Makefile.am
index 3f03fb2..dddce43 100644
--- a/libide/Makefile.am
+++ b/libide/Makefile.am
@@ -30,6 +30,8 @@ libide_1_0_la_public_headers =                            \
        buffers/ide-buffer.h                              \
        buffers/ide-unsaved-file.h                        \
        buffers/ide-unsaved-files.h                       \
+       buildsystem/ide-build-command.h                   \
+       buildsystem/ide-build-command-queue.h             \
        buildsystem/ide-build-manager.h                   \
        buildsystem/ide-build-result-addin.h              \
        buildsystem/ide-build-result.h                    \
@@ -187,6 +189,8 @@ libide_1_0_la_public_sources =                            \
        buffers/ide-buffer.c                              \
        buffers/ide-unsaved-file.c                        \
        buffers/ide-unsaved-files.c                       \
+       buildsystem/ide-build-command.c                   \
+       buildsystem/ide-build-command-queue.c             \
        buildsystem/ide-build-manager.c                   \
        buildsystem/ide-build-result-addin.c              \
        buildsystem/ide-build-result.c                    \
diff --git a/libide/buildsystem/ide-build-command-queue.c b/libide/buildsystem/ide-build-command-queue.c
new file mode 100644
index 0000000..f60c14b
--- /dev/null
+++ b/libide/buildsystem/ide-build-command-queue.c
@@ -0,0 +1,275 @@
+/* ide-build-command-queue.c
+ *
+ * Copyright (C) 2016 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/>.
+ */
+
+#define G_LOG_DOMAIN "ide-build-command-queue"
+
+#include "ide-debug.h"
+
+#include "buildsystem/ide-build-command.h"
+#include "buildsystem/ide-build-command-queue.h"
+#include "buildsystem/ide-build-result.h"
+#include "buildsystem/ide-configuration.h"
+#include "buildsystem/ide-environment.h"
+#include "runtimes/ide-runtime.h"
+
+typedef struct
+{
+  const GList    *iter;
+  IdeRuntime     *runtime;
+  IdeEnvironment *environment;
+  IdeBuildResult *build_result;
+} ExecuteState;
+
+struct _IdeBuildCommandQueue
+{
+  GObject parent_instance;
+  GQueue  queue;
+};
+
+static void list_model_iface_init                (GListModelInterface *iface);
+static void ide_build_command_queue_execute_pump (GTask               *task);
+
+G_DEFINE_TYPE_EXTENDED (IdeBuildCommandQueue, ide_build_command_queue, G_TYPE_OBJECT, 0,
+                        G_IMPLEMENT_INTERFACE (G_TYPE_LIST_MODEL, list_model_iface_init))
+
+static void
+execute_state_free (gpointer data)
+{
+  ExecuteState *state = data;
+
+  if (state != NULL)
+    {
+      g_clear_object (&state->runtime);
+      g_clear_object (&state->environment);
+      g_clear_object (&state->build_result);
+      g_slice_free (ExecuteState, state);
+    }
+}
+
+static void
+ide_build_command_queue_finalize (GObject *object)
+{
+  IdeBuildCommandQueue *self = (IdeBuildCommandQueue *)object;
+
+  g_queue_foreach (&self->queue, (GFunc)g_object_unref, NULL);
+  g_queue_clear (&self->queue);
+
+  G_OBJECT_CLASS (ide_build_command_queue_parent_class)->finalize (object);
+}
+
+static void
+ide_build_command_queue_class_init (IdeBuildCommandQueueClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->finalize = ide_build_command_queue_finalize;
+}
+
+static void
+ide_build_command_queue_init (IdeBuildCommandQueue *self)
+{
+  g_queue_init (&self->queue);
+}
+
+void
+ide_build_command_queue_append (IdeBuildCommandQueue *self,
+                                IdeBuildCommand      *command)
+{
+  g_return_if_fail (IDE_IS_BUILD_COMMAND_QUEUE (self));
+  g_return_if_fail (IDE_IS_BUILD_COMMAND (command));
+
+  g_queue_push_tail (&self->queue, g_object_ref (command));
+}
+
+static GType
+ide_build_command_queue_get_item_type (GListModel *model)
+{
+  return IDE_TYPE_BUILD_COMMAND;
+}
+
+static guint
+ide_build_command_queue_get_n_items (GListModel *model)
+{
+  IdeBuildCommandQueue *self = (IdeBuildCommandQueue *)model;
+
+  g_return_val_if_fail (IDE_IS_BUILD_COMMAND_QUEUE (self), 0);
+
+  return self->queue.length;
+}
+
+static gpointer
+ide_build_command_queue_get_item (GListModel *model,
+                                  guint       position)
+{
+  IdeBuildCommandQueue *self = (IdeBuildCommandQueue *)model;
+
+  g_return_val_if_fail (IDE_IS_BUILD_COMMAND_QUEUE (self), NULL);
+  g_return_val_if_fail (position < self->queue.length, NULL);
+
+  return g_object_ref (g_queue_peek_nth (&self->queue, position));
+}
+
+static void
+list_model_iface_init (GListModelInterface *iface)
+{
+  iface->get_item_type = ide_build_command_queue_get_item_type;
+  iface->get_n_items = ide_build_command_queue_get_n_items;
+  iface->get_item = ide_build_command_queue_get_item;
+}
+
+IdeBuildCommandQueue *
+ide_build_command_queue_new (void)
+{
+  return g_object_new (IDE_TYPE_BUILD_COMMAND_QUEUE, NULL);
+}
+
+static void
+ide_build_command_queue_execute_run_cb (GObject      *object,
+                                        GAsyncResult *result,
+                                        gpointer      user_data)
+{
+  IdeBuildCommand *build_command = (IdeBuildCommand *)object;
+  g_autoptr(GTask) task = user_data;
+  GError *error = NULL;
+
+  g_assert (IDE_IS_BUILD_COMMAND (build_command));
+  g_assert (G_IS_TASK (task));
+
+  if (!ide_build_command_run_finish (build_command, result, &error))
+    {
+      g_task_return_error (task, error);
+      return;
+    }
+
+  ide_build_command_queue_execute_pump (task);
+}
+
+static void
+ide_build_command_queue_execute_pump (GTask *task)
+{
+  ExecuteState *state;
+  IdeBuildCommand *command;
+
+  g_assert (G_IS_TASK (task));
+
+  state = g_task_get_task_data (task);
+
+  g_assert (state != NULL);
+  g_assert (IDE_IS_RUNTIME (state->runtime));
+  g_assert (IDE_IS_ENVIRONMENT (state->environment));
+  g_assert (IDE_IS_BUILD_RESULT (state->build_result));
+
+  if (state->iter == NULL)
+    {
+      g_task_return_boolean (task, TRUE);
+      return;
+    }
+
+  command = state->iter->data;
+  state->iter = state->iter->next;
+
+  ide_build_command_run_async (command,
+                               state->runtime,
+                               state->environment,
+                               state->build_result,
+                               g_task_get_cancellable (task),
+                               ide_build_command_queue_execute_run_cb,
+                               g_object_ref (task));
+}
+
+gboolean
+ide_build_command_queue_execute (IdeBuildCommandQueue  *self,
+                                 IdeRuntime            *runtime,
+                                 IdeEnvironment        *environment,
+                                 IdeBuildResult        *build_result,
+                                 GCancellable          *cancellable,
+                                 GError               **error)
+{
+  IDE_ENTRY;
+
+  g_return_val_if_fail (IDE_IS_BUILD_COMMAND_QUEUE (self), FALSE);
+  g_return_val_if_fail (IDE_IS_RUNTIME (runtime), FALSE);
+  g_return_val_if_fail (IDE_IS_ENVIRONMENT (environment), FALSE);
+  g_return_val_if_fail (IDE_IS_BUILD_RESULT (build_result), FALSE);
+  g_return_val_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable), FALSE);
+
+  for (const GList *iter = self->queue.head; iter != NULL; iter = iter->next)
+    {
+      IdeBuildCommand *build_command = iter->data;
+
+      g_assert (IDE_IS_BUILD_COMMAND (build_command));
+
+      if (!ide_build_command_run (build_command, runtime, environment, build_result, cancellable, error))
+        IDE_RETURN (FALSE);
+    }
+
+  IDE_RETURN (TRUE);
+}
+
+void
+ide_build_command_queue_execute_async (IdeBuildCommandQueue *self,
+                                       IdeRuntime           *runtime,
+                                       IdeEnvironment       *environment,
+                                       IdeBuildResult       *build_result,
+                                       GCancellable         *cancellable,
+                                       GAsyncReadyCallback   callback,
+                                       gpointer              user_data)
+{
+  g_autoptr(GTask) task = NULL;
+  ExecuteState *state;
+
+  IDE_ENTRY;
+
+  g_return_if_fail (IDE_IS_BUILD_COMMAND_QUEUE (self));
+  g_return_if_fail (IDE_IS_RUNTIME (runtime));
+  g_return_if_fail (IDE_IS_ENVIRONMENT (environment));
+  g_return_if_fail (IDE_IS_BUILD_RESULT (build_result));
+  g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
+
+  task = g_task_new (self, cancellable, callback, user_data);
+  g_task_set_source_tag (task, ide_build_command_queue_execute_async);
+
+  state = g_slice_new (ExecuteState);
+  state->runtime = g_object_ref (runtime);
+  state->environment = g_object_ref (environment);
+  state->build_result = g_object_ref (build_result);
+  state->iter = self->queue.head;
+
+  g_task_set_task_data (task, state, execute_state_free);
+
+  ide_build_command_queue_execute_pump (task);
+
+  IDE_EXIT;
+}
+
+gboolean
+ide_build_command_queue_execute_finish (IdeBuildCommandQueue  *self,
+                                        GAsyncResult          *result,
+                                        GError               **error)
+{
+  gboolean ret;
+
+  IDE_ENTRY;
+
+  g_return_val_if_fail (IDE_IS_BUILD_COMMAND_QUEUE (self), FALSE);
+  g_return_val_if_fail (G_IS_TASK (result), FALSE);
+
+  ret = g_task_propagate_boolean (G_TASK (result), error);
+
+  IDE_RETURN (ret);
+}
diff --git a/libide/buildsystem/ide-build-command-queue.h b/libide/buildsystem/ide-build-command-queue.h
new file mode 100644
index 0000000..583a5d7
--- /dev/null
+++ b/libide/buildsystem/ide-build-command-queue.h
@@ -0,0 +1,52 @@
+/* ide-build-command-queue.h
+ *
+ * Copyright (C) 2016 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/>.
+ */
+
+#ifndef IDE_BUILD_COMMAND_QUEUE_H
+#define IDE_BUILD_COMMAND_QUEUE_H
+
+#include "ide-types.h"
+
+G_BEGIN_DECLS
+
+#define IDE_TYPE_BUILD_COMMAND_QUEUE (ide_build_command_queue_get_type())
+
+G_DECLARE_FINAL_TYPE (IdeBuildCommandQueue, ide_build_command_queue, IDE, BUILD_COMMAND_QUEUE, GObject)
+
+IdeBuildCommandQueue *ide_build_command_queue_new            (void);
+void                  ide_build_command_queue_append         (IdeBuildCommandQueue  *self,
+                                                              IdeBuildCommand       *command);
+gboolean              ide_build_command_queue_execute        (IdeBuildCommandQueue  *self,
+                                                              IdeRuntime            *runtime,
+                                                              IdeEnvironment        *environment,
+                                                              IdeBuildResult        *build_result,
+                                                              GCancellable          *cancellable,
+                                                              GError               **error);
+void                  ide_build_command_queue_execute_async  (IdeBuildCommandQueue  *self,
+                                                              IdeRuntime            *runtime,
+                                                              IdeEnvironment        *environment,
+                                                              IdeBuildResult        *build_result,
+                                                              GCancellable          *cancellable,
+                                                              GAsyncReadyCallback    callback,
+                                                              gpointer               user_data);
+gboolean              ide_build_command_queue_execute_finish (IdeBuildCommandQueue  *self,
+                                                              GAsyncResult          *result,
+                                                              GError               **error);
+
+G_END_DECLS
+
+#endif /* IDE_BUILD_COMMAND_QUEUE_H */
diff --git a/libide/buildsystem/ide-build-command.c b/libide/buildsystem/ide-build-command.c
new file mode 100644
index 0000000..6002636
--- /dev/null
+++ b/libide/buildsystem/ide-build-command.c
@@ -0,0 +1,376 @@
+/* ide-build-command.c
+ *
+ * Copyright (C) 2016 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/>.
+ */
+
+#define G_LOG_DOMAIN "ide-build-command"
+
+#include "ide-debug.h"
+
+#include "buildsystem/ide-build-command.h"
+#include "buildsystem/ide-build-result.h"
+#include "buildsystem/ide-environment.h"
+#include "runtimes/ide-runtime.h"
+#include "workers/ide-subprocess-launcher.h"
+
+typedef struct
+{
+  gchar *command_text;
+} IdeBuildCommandPrivate;
+
+G_DEFINE_TYPE_WITH_PRIVATE (IdeBuildCommand, ide_build_command, G_TYPE_OBJECT)
+
+enum {
+  PROP_0,
+  PROP_COMMAND_TEXT,
+  N_PROPS
+};
+
+static GParamSpec *properties [N_PROPS];
+
+static void
+ide_build_command_wait_cb (GObject      *object,
+                           GAsyncResult *result,
+                           gpointer      user_data)
+{
+  GSubprocess *subprocess = (GSubprocess *)object;
+  g_autoptr(GTask) task = user_data;
+  GError *error = NULL;
+
+  IDE_ENTRY;
+
+  g_assert (G_IS_SUBPROCESS (subprocess));
+  g_assert (G_IS_ASYNC_RESULT (result));
+  g_assert (G_IS_TASK (task));
+
+  if (!g_subprocess_wait_finish (subprocess, result, &error))
+    {
+      g_task_return_error (task, error);
+      IDE_EXIT;
+    }
+
+  g_task_return_boolean (task, TRUE);
+
+  IDE_EXIT;
+}
+
+static IdeSubprocessLauncher *
+create_launcher (IdeBuildCommand  *self,
+                 IdeRuntime       *runtime,
+                 IdeEnvironment   *environment,
+                 IdeBuildResult   *build_result,
+                 const gchar      *command_text,
+                 GError          **error)
+{
+  g_autoptr(IdeSubprocessLauncher) launcher = NULL;
+  g_auto(GStrv) argv = NULL;
+  gint argc;
+
+  g_assert (IDE_IS_BUILD_COMMAND (self));
+  g_assert (IDE_IS_RUNTIME (runtime));
+  g_assert (IDE_IS_ENVIRONMENT (environment));
+  g_assert (IDE_IS_BUILD_RESULT (build_result));
+
+  if (command_text == NULL)
+    {
+      g_set_error (error,
+                   G_IO_ERROR,
+                   G_IO_ERROR_INVAL,
+                   "No command was specified");
+      return NULL;
+    }
+
+  if (NULL == (launcher = ide_runtime_create_launcher (runtime, error)))
+    return NULL;
+
+  ide_subprocess_launcher_set_flags (launcher,
+                                     (G_SUBPROCESS_FLAGS_STDERR_PIPE | G_SUBPROCESS_FLAGS_STDOUT_PIPE));
+  ide_subprocess_launcher_overlay_environment (launcher, environment);
+
+  /* TODO: ide_subprocess_launcher_set_cwd (launcher, builddir); */
+  /* TODO: set $BUILDDIR and $SRCDIR for scripts? */
+
+  if (!g_shell_parse_argv (command_text, &argc, &argv, error))
+    return NULL;
+
+  ide_subprocess_launcher_push_args (launcher, (const gchar * const *)argv);
+
+  return g_steal_pointer (&launcher);
+}
+
+static gboolean
+ide_build_command_real_run (IdeBuildCommand  *self,
+                            IdeRuntime       *runtime,
+                            IdeEnvironment   *environment,
+                            IdeBuildResult   *build_result,
+                            GCancellable     *cancellable,
+                            GError          **error)
+{
+  IdeBuildCommandPrivate *priv = ide_build_command_get_instance_private (self);
+  g_autoptr(IdeSubprocessLauncher) launcher = NULL;
+  g_autoptr(GSubprocess) subprocess = NULL;
+  gboolean ret;
+
+  IDE_ENTRY;
+
+  g_assert (IDE_IS_BUILD_COMMAND (self));
+  g_assert (IDE_IS_RUNTIME (runtime));
+  g_assert (IDE_IS_ENVIRONMENT (environment));
+  g_assert (IDE_IS_BUILD_RESULT (build_result));
+  g_assert (!cancellable || G_IS_CANCELLABLE (cancellable));
+
+  launcher = create_launcher (self,
+                              runtime,
+                              environment,
+                              build_result,
+                              priv->command_text,
+                              error);
+  if (launcher == NULL)
+    IDE_RETURN (FALSE);
+
+  subprocess = ide_subprocess_launcher_spawn_sync (launcher, cancellable, error);
+  if (subprocess == NULL)
+    return FALSE;
+
+  ide_build_result_log_subprocess (build_result, subprocess);
+
+  ret = g_subprocess_wait (subprocess, cancellable, error);
+
+  IDE_RETURN (ret);
+}
+
+static void
+ide_build_command_real_run_async (IdeBuildCommand     *self,
+                                  IdeRuntime          *runtime,
+                                  IdeEnvironment      *environment,
+                                  IdeBuildResult      *build_result,
+                                  GCancellable        *cancellable,
+                                  GAsyncReadyCallback  callback,
+                                  gpointer             user_data)
+{
+  IdeBuildCommandPrivate *priv = ide_build_command_get_instance_private (self);
+  g_autoptr(IdeSubprocessLauncher) launcher = NULL;
+  g_autoptr(GSubprocess) subprocess = NULL;
+  g_autoptr(GTask) task = NULL;
+  GError *error = NULL;
+
+  IDE_ENTRY;
+
+  g_assert (IDE_IS_BUILD_COMMAND (self));
+  g_assert (IDE_IS_RUNTIME (runtime));
+  g_assert (IDE_IS_ENVIRONMENT (environment));
+  g_assert (IDE_IS_BUILD_RESULT (build_result));
+  g_assert (!cancellable || G_IS_CANCELLABLE (cancellable));
+
+  task = g_task_new (self, cancellable, callback, user_data);
+  g_task_set_source_tag (task, ide_build_command_real_run_async);
+
+  launcher = create_launcher (self,
+                              runtime,
+                              environment,
+                              build_result,
+                              priv->command_text,
+                              &error);
+
+  if (launcher == NULL)
+    {
+      g_task_return_error (task, error);
+      IDE_EXIT;
+    }
+
+  subprocess = ide_subprocess_launcher_spawn_sync (launcher, cancellable, &error);
+
+  if (subprocess == NULL)
+    {
+      g_task_return_error (task, error);
+      IDE_EXIT;
+    }
+
+  ide_build_result_log_subprocess (build_result, subprocess);
+
+  g_subprocess_wait_async (subprocess,
+                           cancellable,
+                           ide_build_command_wait_cb,
+                           g_steal_pointer (&task));
+
+  IDE_EXIT;
+}
+
+static gboolean
+ide_build_command_real_run_finish (IdeBuildCommand  *self,
+                                   GAsyncResult     *result,
+                                   GError          **error)
+{
+  g_assert (IDE_IS_BUILD_COMMAND (self));
+  g_assert (G_IS_TASK (result));
+
+  return g_task_propagate_boolean (G_TASK (result), error);
+}
+
+static void
+ide_build_command_finalize (GObject *object)
+{
+  IdeBuildCommand *self = (IdeBuildCommand *)object;
+  IdeBuildCommandPrivate *priv = ide_build_command_get_instance_private (self);
+
+  g_clear_pointer (&priv->command_text, g_free);
+
+  G_OBJECT_CLASS (ide_build_command_parent_class)->finalize (object);
+}
+
+static void
+ide_build_command_get_property (GObject    *object,
+                                guint       prop_id,
+                                GValue     *value,
+                                GParamSpec *pspec)
+{
+  IdeBuildCommand *self = IDE_BUILD_COMMAND (object);
+
+  switch (prop_id)
+    {
+    case PROP_COMMAND_TEXT:
+      g_value_set_string (value, ide_build_command_get_command_text (self));
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+}
+
+static void
+ide_build_command_set_property (GObject      *object,
+                                guint         prop_id,
+                                const GValue *value,
+                                GParamSpec   *pspec)
+{
+  IdeBuildCommand *self = IDE_BUILD_COMMAND (object);
+
+  switch (prop_id)
+    {
+    case PROP_COMMAND_TEXT:
+      ide_build_command_set_command_text (self, g_value_get_string (value));
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+}
+
+static void
+ide_build_command_class_init (IdeBuildCommandClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->finalize = ide_build_command_finalize;
+  object_class->get_property = ide_build_command_get_property;
+  object_class->set_property = ide_build_command_set_property;
+
+  klass->run = ide_build_command_real_run;
+  klass->run_async = ide_build_command_real_run_async;
+  klass->run_finish = ide_build_command_real_run_finish;
+
+  properties [PROP_COMMAND_TEXT] =
+    g_param_spec_string ("command-text",
+                         "Command Text",
+                         "Command Text",
+                         NULL,
+                         (G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
+
+  g_object_class_install_properties (object_class, N_PROPS, properties);
+}
+
+static void
+ide_build_command_init (IdeBuildCommand *self)
+{
+}
+
+gboolean
+ide_build_command_run (IdeBuildCommand  *self,
+                       IdeRuntime       *runtime,
+                       IdeEnvironment   *environment,
+                       IdeBuildResult   *build_result,
+                       GCancellable     *cancellable,
+                       GError          **error)
+{
+  g_return_val_if_fail (IDE_IS_BUILD_COMMAND (self), FALSE);
+  g_return_val_if_fail (IDE_IS_RUNTIME (runtime), FALSE);
+  g_return_val_if_fail (IDE_IS_ENVIRONMENT (environment), FALSE);
+  g_return_val_if_fail (IDE_IS_BUILD_RESULT (build_result), FALSE);
+  g_return_val_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable), FALSE);
+
+  return IDE_BUILD_COMMAND_GET_CLASS (self)->run (self, runtime, environment, build_result, cancellable, 
error);
+}
+
+void
+ide_build_command_run_async (IdeBuildCommand     *self,
+                             IdeRuntime          *runtime,
+                             IdeEnvironment      *environment,
+                             IdeBuildResult      *build_result,
+                             GCancellable        *cancellable,
+                             GAsyncReadyCallback  callback,
+                             gpointer             user_data)
+{
+  g_return_if_fail (IDE_IS_BUILD_COMMAND (self));
+  g_return_if_fail (IDE_IS_RUNTIME (runtime));
+  g_return_if_fail (IDE_IS_ENVIRONMENT (environment));
+  g_return_if_fail (IDE_IS_BUILD_RESULT (build_result));
+  g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
+
+  IDE_BUILD_COMMAND_GET_CLASS (self)->run_async (self, runtime, environment, build_result, cancellable, 
callback, user_data);
+}
+
+gboolean
+ide_build_command_run_finish (IdeBuildCommand  *self,
+                              GAsyncResult     *result,
+                              GError          **error)
+{
+  g_return_val_if_fail (IDE_IS_BUILD_COMMAND (self), FALSE);
+  g_return_val_if_fail (G_IS_TASK (result), FALSE);
+
+  return IDE_BUILD_COMMAND_GET_CLASS (self)->run_finish (self, result, error);
+}
+
+IdeBuildCommand *
+ide_build_command_new (void)
+{
+  return g_object_new (IDE_TYPE_BUILD_COMMAND, NULL);
+}
+
+const gchar *
+ide_build_command_get_command_text (IdeBuildCommand *self)
+{
+  IdeBuildCommandPrivate *priv = ide_build_command_get_instance_private (self);
+
+  g_return_val_if_fail (IDE_IS_BUILD_COMMAND (self), NULL);
+
+  return priv->command_text;
+}
+
+void
+ide_build_command_set_command_text (IdeBuildCommand *self,
+                                    const gchar     *command_text)
+{
+  IdeBuildCommandPrivate *priv = ide_build_command_get_instance_private (self);
+
+  g_return_if_fail (IDE_IS_BUILD_COMMAND (self));
+
+  if (command_text != priv->command_text)
+    {
+      g_free (priv->command_text);
+      priv->command_text = g_strdup (command_text);
+      g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_COMMAND_TEXT]);
+    }
+}
diff --git a/libide/buildsystem/ide-build-command.h b/libide/buildsystem/ide-build-command.h
new file mode 100644
index 0000000..c62cfdd
--- /dev/null
+++ b/libide/buildsystem/ide-build-command.h
@@ -0,0 +1,86 @@
+/* ide-build-command.h
+ *
+ * Copyright (C) 2016 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/>.
+ */
+
+#ifndef IDE_BUILD_COMMAND_H
+#define IDE_BUILD_COMMAND_H
+
+#include <gio/gio.h>
+
+#include "ide-types.h"
+
+G_BEGIN_DECLS
+
+#define IDE_TYPE_BUILD_COMMAND (ide_build_command_get_type())
+
+G_DECLARE_DERIVABLE_TYPE (IdeBuildCommand, ide_build_command, IDE, BUILD_COMMAND, GObject)
+
+struct _IdeBuildCommandClass
+{
+  GObjectClass parent_class;
+
+  gboolean  (*run)        (IdeBuildCommand     *self,
+                           IdeRuntime          *runtime,
+                           IdeEnvironment      *environment,
+                           IdeBuildResult      *build_result,
+                           GCancellable        *cancellable,
+                           GError             **error);
+  void      (*run_async)  (IdeBuildCommand     *self,
+                           IdeRuntime          *runtime,
+                           IdeEnvironment      *environment,
+                           IdeBuildResult      *build_result,
+                           GCancellable        *cancellable,
+                           GAsyncReadyCallback  callback,
+                           gpointer             user_data);
+  gboolean  (*run_finish) (IdeBuildCommand     *self,
+                           GAsyncResult        *result,
+                           GError             **error);
+
+  gpointer _reserved1;
+  gpointer _reserved2;
+  gpointer _reserved3;
+  gpointer _reserved4;
+  gpointer _reserved5;
+  gpointer _reserved6;
+  gpointer _reserved7;
+  gpointer _reserved8;
+};
+
+IdeBuildCommand *ide_build_command_new              (void);
+const gchar     *ide_build_command_get_command_text (IdeBuildCommand      *self);
+void             ide_build_command_set_command_text (IdeBuildCommand      *self,
+                                                     const gchar          *command_text);
+gboolean         ide_build_command_run              (IdeBuildCommand      *self,
+                                                     IdeRuntime           *runtime,
+                                                     IdeEnvironment       *environment,
+                                                     IdeBuildResult       *build_result,
+                                                     GCancellable         *cancellable,
+                                                     GError              **error);
+void             ide_build_command_run_async        (IdeBuildCommand      *self,
+                                                     IdeRuntime           *runtime,
+                                                     IdeEnvironment       *environment,
+                                                     IdeBuildResult       *build_result,
+                                                     GCancellable         *cancellable,
+                                                     GAsyncReadyCallback   callback,
+                                                     gpointer              user_data);
+gboolean         ide_build_command_run_finish       (IdeBuildCommand      *self,
+                                                     GAsyncResult         *result,
+                                                     GError              **error);
+
+G_END_DECLS
+
+#endif /* IDE_BUILD_COMMAND_H */
diff --git a/libide/ide-types.h b/libide/ide-types.h
index 871fb38..c5afe50 100644
--- a/libide/ide-types.h
+++ b/libide/ide-types.h
@@ -36,6 +36,8 @@ typedef struct _IdeBufferChangeMonitor         IdeBufferChangeMonitor;
 typedef struct _IdeBufferManager               IdeBufferManager;
 
 typedef struct _IdeBuilder                     IdeBuilder;
+typedef struct _IdeBuildCommand                IdeBuildCommand;
+typedef struct _IdeBuildCommandQueue           IdeBuildCommandQueue;
 typedef struct _IdeBuildManager                IdeBuildManager;
 typedef struct _IdeBuildResult                 IdeBuildResult;
 typedef struct _IdeBuildSystem                 IdeBuildSystem;
@@ -83,7 +85,9 @@ typedef struct _IdeProjectFile                 IdeProjectFile;
 
 typedef struct _IdeProjectFiles                IdeProjectFiles;
 
+typedef struct _IdeRunner                      IdeRunner;
 typedef struct _IdeRunManager                  IdeRunManager;
+
 typedef struct _IdeRuntime                     IdeRuntime;
 typedef struct _IdeRuntimeManager              IdeRuntimeManager;
 typedef struct _IdeRuntimeProvider             IdeRuntimeProvider;
diff --git a/libide/ide.h b/libide/ide.h
index 45ccf6a..20258c0 100644
--- a/libide/ide.h
+++ b/libide/ide.h
@@ -35,6 +35,8 @@ G_BEGIN_DECLS
 #include "buffers/ide-buffer.h"
 #include "buffers/ide-unsaved-file.h"
 #include "buffers/ide-unsaved-files.h"
+#include "buildsystem/ide-build-command.h"
+#include "buildsystem/ide-build-command-queue.h"
 #include "buildsystem/ide-build-manager.h"
 #include "buildsystem/ide-build-result-addin.h"
 #include "buildsystem/ide-build-result.h"


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