[gnome-builder] build: add `ide build` command line tool



commit 04d9c6dd3b65ffc99fa1ec3b2f8b5b22fd5645f5
Author: Christian Hergert <christian hergert me>
Date:   Sun Dec 27 17:38:54 2015 -0800

    build: add `ide build` command line tool
    
    Doesn't support man features yet like clean, rebuild, -j, etc, but basic
    example of creating a command line tool using libide.

 plugins/build-tools/Makefile.am        |    2 +
 plugins/build-tools/build-tools.plugin |    2 +
 plugins/build-tools/gbp-build-plugin.c |    4 +
 plugins/build-tools/gbp-build-tool.c   |  235 ++++++++++++++++++++++++++++++++
 plugins/build-tools/gbp-build-tool.h   |   32 +++++
 5 files changed, 275 insertions(+), 0 deletions(-)
---
diff --git a/plugins/build-tools/Makefile.am b/plugins/build-tools/Makefile.am
index dcd2b8c..7c7da83 100644
--- a/plugins/build-tools/Makefile.am
+++ b/plugins/build-tools/Makefile.am
@@ -17,6 +17,8 @@ libbuild_tools_plugin_la_SOURCES = \
        gbp-build-panel-row.c \
        gbp-build-panel-row.h \
        gbp-build-plugin.c \
+       gbp-build-tool.c \
+       gbp-build-tool.h \
        gbp-build-workbench-addin.c \
        gbp-build-workbench-addin.h \
        $(NULL)
diff --git a/plugins/build-tools/build-tools.plugin b/plugins/build-tools/build-tools.plugin
index 4121e6e..30d0ba2 100644
--- a/plugins/build-tools/build-tools.plugin
+++ b/plugins/build-tools/build-tools.plugin
@@ -7,3 +7,5 @@ Copyright=Copyright © 2015 Christian Hergert
 Depends=editor
 Hidden=true
 Builtin=true
+X-Tool-Name=build
+X-Tool-Description=Build a project
diff --git a/plugins/build-tools/gbp-build-plugin.c b/plugins/build-tools/gbp-build-plugin.c
index e030fc2..251631c 100644
--- a/plugins/build-tools/gbp-build-plugin.c
+++ b/plugins/build-tools/gbp-build-plugin.c
@@ -19,12 +19,16 @@
 #include <libpeas/peas.h>
 #include <ide.h>
 
+#include "gbp-build-tool.h"
 #include "gbp-build-workbench-addin.h"
 
 void
 peas_register_types (PeasObjectModule *module)
 {
   peas_object_module_register_extension_type (module,
+                                              IDE_TYPE_APPLICATION_TOOL,
+                                              GBP_TYPE_BUILD_TOOL);
+  peas_object_module_register_extension_type (module,
                                               IDE_TYPE_WORKBENCH_ADDIN,
                                               GBP_TYPE_BUILD_WORKBENCH_ADDIN);
 }
diff --git a/plugins/build-tools/gbp-build-tool.c b/plugins/build-tools/gbp-build-tool.c
new file mode 100644
index 0000000..83d68e1
--- /dev/null
+++ b/plugins/build-tools/gbp-build-tool.c
@@ -0,0 +1,235 @@
+/* gbp-build-tool.c
+ *
+ * Copyright (C) 2015 Christian Hergert <christian hergert me>
+ *
+ * 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/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <glib/gi18n.h>
+
+#include "gbp-build-tool.h"
+
+struct _GbpBuildTool
+{
+  GObject parent_instance;
+};
+
+static void application_tool_init (IdeApplicationToolInterface *iface);
+
+G_DEFINE_TYPE_EXTENDED (GbpBuildTool, gbp_build_tool, G_TYPE_OBJECT, 0,
+                        G_IMPLEMENT_INTERFACE (IDE_TYPE_APPLICATION_TOOL,
+                                               application_tool_init))
+
+static void
+gbp_build_tool_class_init (GbpBuildToolClass *klass)
+{
+}
+
+static void
+gbp_build_tool_init (GbpBuildTool *self)
+{
+}
+
+static void
+gbp_build_tool_log (GbpBuildTool      *self,
+                    IdeBuildResultLog  log,
+                    const gchar       *message,
+                    IdeBuildResult    *build_result)
+{
+  if (log == IDE_BUILD_RESULT_LOG_STDERR)
+    g_printerr ("%s", message);
+  else
+    g_print ("%s", message);
+}
+
+static void
+gbp_build_tool_build_cb (GObject      *object,
+                         GAsyncResult *result,
+                         gpointer      user_data)
+{
+  g_autoptr(GTask) task = user_data;
+  IdeBuilder *builder = (IdeBuilder *)object;
+  GError *error = NULL;
+
+  g_assert (G_IS_TASK (task));
+  g_assert (IDE_IS_BUILDER (builder));
+
+  if (!ide_builder_build_finish (builder, result, &error))
+    {
+      g_task_return_error (task, error);
+      return;
+    }
+
+  /*
+   * TODO: We should consider supporting packaging/xdg-app/deployment stuff
+   *       here too. It would be nice if we could say, go build this project,
+   *       for this device, and then deploy.
+   */
+
+  g_print (_("Success.\n"));
+
+  g_task_return_boolean (task, TRUE);
+}
+
+static void
+gbp_build_tool_new_context_cb (GObject      *object,
+                               GAsyncResult *result,
+                               gpointer      user_data)
+{
+  g_autoptr(GTask) task = user_data;
+  g_autoptr(IdeContext) context = NULL;
+  g_autoptr(IdeBuilder) builder = NULL;
+  g_autoptr(IdeBuildResult) build_result = NULL;
+  g_autoptr(IdeDevice) device = NULL;
+  IdeDeviceManager *device_manager;
+  IdeBuildSystem *build_system;
+  const gchar *device_id;
+  GError *error = NULL;
+
+  g_assert (G_IS_TASK (task));
+
+  context = ide_context_new_finish (result, &error);
+
+  if (context == NULL)
+    {
+      g_task_return_error (task, error);
+      return;
+    }
+
+  device_id = g_object_get_data (G_OBJECT (task), "DEVICE_ID");
+  device_manager = ide_context_get_device_manager (context);
+  device = ide_device_manager_get_device (device_manager, device_id);
+
+  if (device == NULL)
+    {
+      /* TODO: Wait for devices to settle. */
+      g_task_return_new_error (task,
+                               G_IO_ERROR,
+                               G_IO_ERROR_NOT_FOUND,
+                               _("Failed to locate device \"%s\""),
+                               device_id);
+      return;
+    }
+
+  /* TODO: Support custom configs */
+
+  build_system = ide_context_get_build_system (context);
+  builder = ide_build_system_get_builder (build_system, NULL, device, &error);
+
+  if (builder == NULL)
+    {
+      g_task_return_error (task, error);
+      return;
+    }
+
+  ide_builder_build_async (builder,
+                           IDE_BUILDER_BUILD_FLAGS_NONE,
+                           &build_result,
+                           g_task_get_cancellable (task),
+                           gbp_build_tool_build_cb,
+                           g_object_ref (task));
+
+  if (build_result != NULL)
+    {
+      /*
+       * XXX: Technically we could lose some log lines unless we
+       * guarantee that the build can't start until the main loop
+       * is reached. (Which is probably reasonable).
+       */
+      g_signal_connect_object (build_result,
+                               "log",
+                               G_CALLBACK (gbp_build_tool_log),
+                               g_task_get_source_object (task),
+                               G_CONNECT_SWAPPED);
+    }
+}
+
+static void
+gbp_build_tool_run_async (IdeApplicationTool  *tool,
+                          const gchar * const *arguments,
+                          GCancellable        *cancellable,
+                          GAsyncReadyCallback  callback,
+                          gpointer             user_data)
+{
+  GbpBuildTool *self = (GbpBuildTool *)tool;
+  g_autoptr(GTask) task = NULL;
+  g_autofree gchar *project_path = NULL;
+  g_autofree gchar *device_id = NULL;
+  g_autoptr(GFile) project_file = NULL;
+  g_autoptr(GOptionContext) opt_context = NULL;
+  g_auto(GStrv) strv = NULL;
+  GError *error = NULL;
+  const GOptionEntry entries[] = {
+    { "device", 'd', 0, G_OPTION_ARG_STRING, &device_id,
+      N_("The id of the device to build for"),
+      N_("local") },
+    { "project", 'p', 0, G_OPTION_ARG_FILENAME, &project_path,
+      N_("Path to project file, defaults to current directory"),
+      N_("PATH") },
+    { NULL }
+  };
+
+  g_assert (GBP_IS_BUILD_TOOL (self));
+  g_assert (arguments != NULL);
+  g_assert (!cancellable || G_IS_CANCELLABLE (cancellable));
+
+  task = g_task_new (self, cancellable, callback, user_data);
+
+  opt_context = g_option_context_new ("build [OPTIONS]");
+  g_option_context_add_main_entries (opt_context, entries, GETTEXT_PACKAGE);
+  strv = g_strdupv ((gchar **)arguments);
+
+  if (!g_option_context_parse_strv (opt_context, &strv, &error))
+    {
+      g_task_return_error (task, error);
+      return;
+    }
+
+  if (project_path == NULL)
+    project_path = g_strdup (".");
+
+  project_file = g_file_new_for_commandline_arg (project_path);
+
+  if (device_id == NULL)
+    device_id = g_strdup ("local");
+
+  g_object_set_data_full (G_OBJECT (task), "DEVICE_ID", g_strdup (device_id), g_free);
+
+  ide_context_new_async (project_file,
+                         cancellable,
+                         gbp_build_tool_new_context_cb,
+                         g_object_ref (task));
+}
+
+static gboolean
+gbp_build_tool_run_finish (IdeApplicationTool  *tool,
+                           GAsyncResult        *result,
+                           GError             **error)
+{
+  g_assert (GBP_IS_BUILD_TOOL (tool));
+  g_assert (G_IS_TASK (result));
+
+  return g_task_propagate_boolean (G_TASK (result), error);
+}
+
+static void
+application_tool_init (IdeApplicationToolInterface *iface)
+{
+  iface->run_async = gbp_build_tool_run_async;
+  iface->run_finish = gbp_build_tool_run_finish;
+}
diff --git a/plugins/build-tools/gbp-build-tool.h b/plugins/build-tools/gbp-build-tool.h
new file mode 100644
index 0000000..478c6de
--- /dev/null
+++ b/plugins/build-tools/gbp-build-tool.h
@@ -0,0 +1,32 @@
+/* gbp-build-tool.h
+ *
+ * Copyright (C) 2015 Christian Hergert <christian hergert me>
+ *
+ * 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 GBP_BUILD_TOOL_H
+#define GBP_BUILD_TOOL_H
+
+#include <ide.h>
+
+G_BEGIN_DECLS
+
+#define GBP_TYPE_BUILD_TOOL (gbp_build_tool_get_type())
+
+G_DECLARE_FINAL_TYPE (GbpBuildTool, gbp_build_tool, GBP, BUILD_TOOL, GObject)
+
+G_END_DECLS
+
+#endif /* GBP_BUILD_TOOL_H */


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