[gnome-builder/wip/chergert/pipeline] wip



commit aa15375b401ebd9f9ec965ce5b28648ca93f59b7
Author: Christian Hergert <chergert redhat com>
Date:   Tue Dec 20 13:26:04 2016 -0800

    wip

 libide/Makefile.am                               |    2 +
 libide/buildsystem/ide-build-pipeline-addin.c    |   51 +++++++++
 libide/buildsystem/ide-build-pipeline-addin.h    |    2 +
 libide/buildsystem/ide-build-pipeline.c          |   69 +++++++++----
 libide/buildsystem/ide-build-pipeline.h          |   66 ++++++------
 libide/buildsystem/ide-build-stage-mkdirs.c      |  118 ++++++++++++++++++++++
 libide/buildsystem/ide-build-stage-mkdirs.h      |   48 +++++++++
 libide/ide.h                                     |    1 +
 plugins/autotools/ide-autotools-pipeline-addin.c |   54 ++++-------
 plugins/flatpak/Makefile.am                      |    2 +
 plugins/flatpak/gbp-flatpak-pipeline-addin.c     |  106 +++++++++++++++-----
 plugins/flatpak/gbp-flatpak-util.c               |   69 +++++++++++++
 plugins/flatpak/gbp-flatpak-util.h               |   31 ++++++
 13 files changed, 508 insertions(+), 111 deletions(-)
---
diff --git a/libide/Makefile.am b/libide/Makefile.am
index 07008c8..50b32bb 100644
--- a/libide/Makefile.am
+++ b/libide/Makefile.am
@@ -38,6 +38,7 @@ libide_1_0_la_public_headers =                            \
        buildsystem/ide-build-pipeline-addin.h            \
        buildsystem/ide-build-stage.h                     \
        buildsystem/ide-build-stage-launcher.h            \
+       buildsystem/ide-build-stage-mkdirs.h              \
        buildsystem/ide-build-result-addin.h              \
        buildsystem/ide-build-result.h                    \
        buildsystem/ide-build-system.h                    \
@@ -217,6 +218,7 @@ libide_1_0_la_public_sources =                            \
        buildsystem/ide-build-pipeline-addin.c            \
        buildsystem/ide-build-stage.c                     \
        buildsystem/ide-build-stage-launcher.c            \
+       buildsystem/ide-build-stage-mkdirs.c              \
        buildsystem/ide-build-result-addin.c              \
        buildsystem/ide-build-result.c                    \
        buildsystem/ide-build-system.c                    \
diff --git a/libide/buildsystem/ide-build-pipeline-addin.c b/libide/buildsystem/ide-build-pipeline-addin.c
index 2531770..df9ca67 100644
--- a/libide/buildsystem/ide-build-pipeline-addin.c
+++ b/libide/buildsystem/ide-build-pipeline-addin.c
@@ -50,9 +50,60 @@ void
 ide_build_pipeline_addin_unload (IdeBuildPipelineAddin *self,
                                  IdeBuildPipeline      *pipeline)
 {
+  GArray *ar;
+
   g_return_if_fail (IDE_IS_BUILD_PIPELINE_ADDIN (self));
   g_return_if_fail (IDE_IS_BUILD_PIPELINE (pipeline));
 
   if (IDE_BUILD_PIPELINE_ADDIN_GET_IFACE (self)->unload)
     IDE_BUILD_PIPELINE_ADDIN_GET_IFACE (self)->unload (self, pipeline);
+
+  /* Unload any stages that are tracked by the addin */
+  ar = g_object_get_data (G_OBJECT (self), "IDE_BUILD_PIPELINE_ADDIN_STAGES");
+
+  if G_LIKELY (ar != NULL)
+    {
+      for (guint i = 0; i < ar->len; i++)
+        {
+          guint stage_id = g_array_index (ar, guint, i);
+
+          ide_build_pipeline_disconnect (pipeline, stage_id);
+        }
+    }
+}
+
+/**
+ * ide_build_pipeline_addin_track:
+ * @self: An #IdeBuildPipelineAddin
+ * @stage_id: a stage id returned from ide_build_pipeline_connect()
+ *
+ * This function will track the stage_id that was returned from
+ * ide_build_pipeline_connect() or similar functions. Doing so results in
+ * the stage being automatically disconnected when the addin is unloaded.
+ *
+ * This means that many #IdeBuildPipelineAddin implementations do not need
+ * an unload vfunc if they track all registered stages.
+ *
+ * You should not mix this function with manual pipeline disconnections.
+ * While it should work, that is not yet guaranteed.
+ */
+void
+ide_build_pipeline_addin_track (IdeBuildPipelineAddin *self,
+                                guint                  stage_id)
+{
+  GArray *ar;
+
+  g_return_if_fail (IDE_IS_BUILD_PIPELINE_ADDIN (self));
+  g_return_if_fail (stage_id > 0);
+
+  ar = g_object_get_data (G_OBJECT (self), "IDE_BUILD_PIPELINE_ADDIN_STAGES");
+
+  if (ar == NULL)
+    {
+      ar = g_array_new (FALSE, FALSE, sizeof (guint));
+      g_object_set_data_full (G_OBJECT (self), "IDE_BUILD_PIPELINE_ADDIN_STAGES",
+                              ar, (GDestroyNotify)g_array_unref);
+    }
+
+  g_array_append_val (ar, stage_id);
 }
diff --git a/libide/buildsystem/ide-build-pipeline-addin.h b/libide/buildsystem/ide-build-pipeline-addin.h
index 3b8f3df..b182ddd 100644
--- a/libide/buildsystem/ide-build-pipeline-addin.h
+++ b/libide/buildsystem/ide-build-pipeline-addin.h
@@ -43,6 +43,8 @@ void ide_build_pipeline_addin_load   (IdeBuildPipelineAddin *self,
                                       IdeBuildPipeline      *pipeline);
 void ide_build_pipeline_addin_unload (IdeBuildPipelineAddin *self,
                                       IdeBuildPipeline      *pipeline);
+void ide_build_pipeline_addin_track  (IdeBuildPipelineAddin *self,
+                                      guint                  stage_id);
 
 G_END_DECLS
 
diff --git a/libide/buildsystem/ide-build-pipeline.c b/libide/buildsystem/ide-build-pipeline.c
index b3f9a6b..5d749d8 100644
--- a/libide/buildsystem/ide-build-pipeline.c
+++ b/libide/buildsystem/ide-build-pipeline.c
@@ -30,6 +30,7 @@
 #include "buildsystem/ide-build-pipeline-addin.h"
 #include "buildsystem/ide-build-stage-launcher.h"
 #include "projects/ide-project.h"
+#include "runtimes/ide-runtime.h"
 #include "vcs/ide-vcs.h"
 
 /**
@@ -650,7 +651,7 @@ ide_build_pipeline_execute_finish (IdeBuildPipeline  *self,
 }
 
 /**
- * ide_build_pipeline_insert_stage:
+ * ide_build_pipeline_connect:
  * @self: A #IdeBuildPipeline
  * @phase: An #IdeBuildPhase
  * @priority: an optional priority for sorting within the phase
@@ -661,13 +662,13 @@ ide_build_pipeline_execute_finish (IdeBuildPipeline  *self,
  * If priority is non-zero, it will be used to sort the stage among other
  * stages that are part of the same phase.
  *
- * Returns: A stage_id that may be passed to ide_build_pipeline_remove().
+ * Returns: A stage_id that may be passed to ide_build_pipeline_disconnect().
  */
 guint
-ide_build_pipeline_insert_stage (IdeBuildPipeline *self,
-                                 IdeBuildPhase     phase,
-                                 gint              priority,
-                                 IdeBuildStage    *stage)
+ide_build_pipeline_connect (IdeBuildPipeline *self,
+                            IdeBuildPhase     phase,
+                            gint              priority,
+                            IdeBuildStage    *stage)
 {
   GFlagsClass *klass;
   guint ret = 0;
@@ -728,7 +729,7 @@ cleanup:
 }
 
 /**
- * ide_build_pipeline_insert_stage_from_launcher:
+ * ide_build_pipeline_connect_launcher:
  * @self: A #IdeBuildPipeline
  * @phase: An #IdeBuildPhase
  * @priority: an optional priority for sorting within the phase
@@ -743,10 +744,10 @@ cleanup:
  * Returns: A stage_id that may be passed to ide_build_pipeline_remove().
  */
 guint
-ide_build_pipeline_insert_stage_from_launcher (IdeBuildPipeline      *self,
-                                               IdeBuildPhase          phase,
-                                               gint                   priority,
-                                               IdeSubprocessLauncher *launcher)
+ide_build_pipeline_connect_launcher (IdeBuildPipeline      *self,
+                                     IdeBuildPhase          phase,
+                                     gint                   priority,
+                                     IdeSubprocessLauncher *launcher)
 {
   g_autoptr(IdeBuildStage) stage = NULL;
   IdeContext *context;
@@ -760,7 +761,7 @@ ide_build_pipeline_insert_stage_from_launcher (IdeBuildPipeline      *self,
   context = ide_object_get_context (IDE_OBJECT (self));
   stage = ide_build_stage_launcher_new (context, launcher);
 
-  return ide_build_pipeline_insert_stage (self, phase, priority, stage);
+  return ide_build_pipeline_connect (self, phase, priority, stage);
 }
 
 /**
@@ -933,20 +934,20 @@ ide_build_pipeline_build_builddir_path (IdeBuildPipeline *self,
 }
 
 /**
- * ide_build_pipeline_remove:
+ * ide_build_pipeline_disconnect:
  * @self: An #IdeBuildPipeline
  * @stage_id: An identifier returned from adding a stage
  *
  * This removes the stage matching @stage_id. You are returned a @stage_id when
- * inserting a stage with functions such as ide_build_pipeline_insert_stage()
- * or ide_build_pipeline_insert_stage_from_launcher().
+ * inserting a stage with functions such as ide_build_pipeline_connect()
+ * or ide_build_pipeline_connect_launcher().
  *
  * Plugins should use this function to remove their stages when the plugin
  * is unloading.
  */
 void
-ide_build_pipeline_remove (IdeBuildPipeline *self,
-                           guint             stage_id)
+ide_build_pipeline_disconnect (IdeBuildPipeline *self,
+                               guint             stage_id)
 {
   g_return_if_fail (IDE_IS_BUILD_PIPELINE (self));
   g_return_if_fail (self->pipeline != NULL);
@@ -1000,7 +1001,7 @@ ide_build_pipeline_invalidate_phase (IdeBuildPipeline *self,
  * @stage_id: the identfier of the stage
  *
  * Gets the stage matching the identifier @stage_id as returned from
- * ide_build_pipeline_insert_stage().
+ * ide_build_pipeline_connect().
  *
  * Returns: (transfer none) (nullable): An #IdeBuildStage or %NULL if the
  *   stage could not be found.
@@ -1021,3 +1022,35 @@ ide_build_pipeline_get_stage_by_id (IdeBuildPipeline *self,
 
   return NULL;
 }
+
+/**
+ * ide_build_pipeline_create_launcher:
+ * @self: An #IdeBuildPipeline
+ *
+ * This is a convenience function to create a new #IdeSubprocessLauncher
+ * using the configuration and runtime associated with the pipeline.
+ *
+ * Returns: (transfer full): An #IdeSubprocessLauncher.
+ */
+IdeSubprocessLauncher *
+ide_build_pipeline_create_launcher (IdeBuildPipeline  *self,
+                                    GError           **error)
+{
+  IdeRuntime *runtime;
+
+  g_return_val_if_fail (IDE_IS_BUILD_PIPELINE (self), NULL);
+
+  runtime = ide_configuration_get_runtime (self->configuration);
+
+  if (runtime == NULL)
+    {
+      g_set_error (error,
+                   G_IO_ERROR,
+                   G_IO_ERROR_FAILED,
+                   "The runtime %s is missing",
+                   ide_configuration_get_runtime_id (self->configuration));
+      return NULL;
+    }
+
+  return ide_runtime_create_launcher (runtime, error);
+}
diff --git a/libide/buildsystem/ide-build-pipeline.h b/libide/buildsystem/ide-build-pipeline.h
index d88a855..e477f12 100644
--- a/libide/buildsystem/ide-build-pipeline.h
+++ b/libide/buildsystem/ide-build-pipeline.h
@@ -53,38 +53,40 @@ typedef enum
 
 G_DECLARE_FINAL_TYPE (IdeBuildPipeline, ide_build_pipeline, IDE, BUILD_PIPELINE, IdeObject)
 
-IdeConfiguration *ide_build_pipeline_get_configuration          (IdeBuildPipeline       *self);
-const gchar      *ide_build_pipeline_get_builddir               (IdeBuildPipeline       *self);
-const gchar      *ide_build_pipeline_get_srcdir                 (IdeBuildPipeline       *self);
-gchar            *ide_build_pipeline_build_srcdir_path          (IdeBuildPipeline       *self,
-                                                                 const gchar            *first_part,
-                                                                 ...) G_GNUC_NULL_TERMINATED;
-gchar            *ide_build_pipeline_build_builddir_path        (IdeBuildPipeline       *self,
-                                                                 const gchar            *first_part,
-                                                                 ...) G_GNUC_NULL_TERMINATED;
-void              ide_build_pipeline_invalidate_phase           (IdeBuildPipeline       *self,
-                                                                 IdeBuildPhase           phases);
-void              ide_build_pipeline_request_phase              (IdeBuildPipeline       *self,
-                                                                 IdeBuildPhase           phase);
-guint             ide_build_pipeline_insert_stage               (IdeBuildPipeline       *self,
-                                                                 IdeBuildPhase           phase,
-                                                                 gint                    priority,
-                                                                 IdeBuildStage          *stage);
-guint             ide_build_pipeline_insert_stage_from_launcher (IdeBuildPipeline       *self,
-                                                                 IdeBuildPhase           phase,
-                                                                 gint                    priority,
-                                                                 IdeSubprocessLauncher  *launcher);
-void              ide_build_pipeline_remove                     (IdeBuildPipeline       *self,
-                                                                 guint                   stage_id);
-IdeBuildStage    *ide_build_pipeline_get_stage_by_id            (IdeBuildPipeline       *self,
-                                                                 guint                   stage_id);
-void              ide_build_pipeline_execute_async              (IdeBuildPipeline       *self,
-                                                                 GCancellable           *cancellable,
-                                                                 GAsyncReadyCallback     callback,
-                                                                 gpointer                user_data);
-gboolean          ide_build_pipeline_execute_finish             (IdeBuildPipeline       *self,
-                                                                 GAsyncResult           *result,
-                                                                 GError                **error);
+IdeConfiguration      *ide_build_pipeline_get_configuration   (IdeBuildPipeline       *self);
+const gchar           *ide_build_pipeline_get_builddir        (IdeBuildPipeline       *self);
+const gchar           *ide_build_pipeline_get_srcdir          (IdeBuildPipeline       *self);
+IdeSubprocessLauncher *ide_build_pipeline_create_launcher     (IdeBuildPipeline       *self,
+                                                               GError                **error);
+gchar                 *ide_build_pipeline_build_srcdir_path   (IdeBuildPipeline       *self,
+                                                               const gchar            *first_part,
+                                                               ...) G_GNUC_NULL_TERMINATED;
+gchar                 *ide_build_pipeline_build_builddir_path (IdeBuildPipeline       *self,
+                                                               const gchar            *first_part,
+                                                               ...) G_GNUC_NULL_TERMINATED;
+void                   ide_build_pipeline_invalidate_phase    (IdeBuildPipeline       *self,
+                                                               IdeBuildPhase           phases);
+void                   ide_build_pipeline_request_phase       (IdeBuildPipeline       *self,
+                                                               IdeBuildPhase           phase);
+guint                  ide_build_pipeline_connect             (IdeBuildPipeline       *self,
+                                                               IdeBuildPhase           phase,
+                                                               gint                    priority,
+                                                               IdeBuildStage          *stage);
+guint                  ide_build_pipeline_connect_launcher    (IdeBuildPipeline       *self,
+                                                               IdeBuildPhase           phase,
+                                                               gint                    priority,
+                                                               IdeSubprocessLauncher  *launcher);
+void                   ide_build_pipeline_disconnect          (IdeBuildPipeline       *self,
+                                                               guint                   stage_id);
+IdeBuildStage         *ide_build_pipeline_get_stage_by_id     (IdeBuildPipeline       *self,
+                                                               guint                   stage_id);
+void                   ide_build_pipeline_execute_async       (IdeBuildPipeline       *self,
+                                                               GCancellable           *cancellable,
+                                                               GAsyncReadyCallback     callback,
+                                                               gpointer                user_data);
+gboolean               ide_build_pipeline_execute_finish      (IdeBuildPipeline       *self,
+                                                               GAsyncResult           *result,
+                                                               GError                **error);
 
 G_END_DECLS
 
diff --git a/libide/buildsystem/ide-build-stage-mkdirs.c b/libide/buildsystem/ide-build-stage-mkdirs.c
new file mode 100644
index 0000000..631605e
--- /dev/null
+++ b/libide/buildsystem/ide-build-stage-mkdirs.c
@@ -0,0 +1,118 @@
+/* ide-build-stage-mkdirs.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-stage-mkdirs"
+
+#include <glib.h>
+#include <glib/gprintf.h>
+#include <glib/gstdio.h>
+#include <errno.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include "ide-build-stage-mkdirs.h"
+
+typedef struct
+{
+  gchar    *path;
+  gboolean  with_parents;
+  gint      mode;
+} Path;
+
+typedef struct
+{
+  GArray *paths;
+} IdeBuildStageMkdirsPrivate;
+
+G_DEFINE_TYPE_WITH_PRIVATE (IdeBuildStageMkdirs, ide_build_stage_mkdirs, IDE_TYPE_BUILD_STAGE)
+
+static void
+clear_path (gpointer data)
+{
+  Path *p = data;
+
+  g_clear_pointer (&p->path, g_free);
+}
+
+static gboolean
+ide_build_stage_mkdirs_execute (IdeBuildStage  *stage,
+                                GCancellable   *cancellable,
+                                GError        **error)
+{
+  IdeBuildStageMkdirs *self = (IdeBuildStageMkdirs *)stage;
+  IdeBuildStageMkdirsPrivate *priv = ide_build_stage_mkdirs_get_instance_private (self);
+
+  g_assert (IDE_IS_BUILD_STAGE_MKDIRS (self));
+  g_assert (!cancellable || G_IS_CANCELLABLE (cancellable));
+
+  for (guint i = 0; i < priv->paths->len; i++)
+    {
+      const Path *path = &g_array_index (priv->paths, Path, i);
+      gboolean r;
+
+      if (g_file_test (path->path, G_FILE_TEST_IS_DIR))
+        continue;
+
+      if (path->with_parents)
+        r = g_mkdir_with_parents (path->path, path->mode);
+      else
+        r = g_mkdir (path->path, path->mode);
+
+      if (r != 0)
+        {
+          g_set_error_literal (error,
+                               G_FILE_ERROR,
+                               g_file_error_from_errno (errno),
+                               g_strerror (errno));
+          return FALSE;
+        }
+    }
+
+  return TRUE;
+}
+
+static void
+ide_build_stage_mkdirs_finalize (GObject *object)
+{
+  IdeBuildStageMkdirs *self = (IdeBuildStageMkdirs *)object;
+  IdeBuildStageMkdirsPrivate *priv = ide_build_stage_mkdirs_get_instance_private (self);
+
+  g_clear_pointer (&priv->paths, g_array_unref);
+
+  G_OBJECT_CLASS (ide_build_stage_mkdirs_parent_class)->finalize (object);
+}
+
+static void
+ide_build_stage_mkdirs_class_init (IdeBuildStageMkdirsClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+  IdeBuildStageClass *stage_class = IDE_BUILD_STAGE_CLASS (klass);
+
+  object_class->finalize = ide_build_stage_mkdirs_finalize;
+
+  stage_class->execute = ide_build_stage_mkdirs_execute;
+}
+
+static void
+ide_build_stage_mkdirs_init (IdeBuildStageMkdirs *self)
+{
+  IdeBuildStageMkdirsPrivate *priv = ide_build_stage_mkdirs_get_instance_private (self);
+
+  priv->paths = g_array_new (FALSE, FALSE, sizeof (Path));
+  g_array_set_clear_func (priv->paths, clear_path);
+}
diff --git a/libide/buildsystem/ide-build-stage-mkdirs.h b/libide/buildsystem/ide-build-stage-mkdirs.h
new file mode 100644
index 0000000..ebfe5e0
--- /dev/null
+++ b/libide/buildsystem/ide-build-stage-mkdirs.h
@@ -0,0 +1,48 @@
+/* ide-build-stage-mkdirs.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_STAGE_MKDIRS_H
+#define IDE_BUILD_STAGE_MKDIRS_H
+
+#include "ide-build-stage.h"
+
+G_BEGIN_DECLS
+
+#define IDE_TYPE_BUILD_STAGE_MKDIRS (ide_build_stage_mkdirs_get_type())
+
+G_DECLARE_DERIVABLE_TYPE (IdeBuildStageMkdirs, ide_build_stage_mkdirs, IDE, BUILD_STAGE_MKDIRS, 
IdeBuildStage)
+
+struct _IdeBuildStageMkdirsClass
+{
+  IdeBuildStageClass parent_class;
+
+  gpointer _reserved1;
+  gpointer _reserved2;
+  gpointer _reserved3;
+  gpointer _reserved4;
+};
+
+IdeBuildStage *ide_build_stage_mkdirs_new      (void);
+void           ide_build_stage_mkdirs_add_path (IdeBuildStageMkdirs *self,
+                                                const gchar         *path,
+                                                gboolean             with_parents,
+                                                gint                 mode);
+
+G_END_DECLS
+
+#endif /* IDE_BUILD_STAGE_MKDIRS_H */
diff --git a/libide/ide.h b/libide/ide.h
index 415b24b..7000159 100644
--- a/libide/ide.h
+++ b/libide/ide.h
@@ -44,6 +44,7 @@ G_BEGIN_DECLS
 #include "buildsystem/ide-build-result.h"
 #include "buildsystem/ide-build-stage.h"
 #include "buildsystem/ide-build-stage-launcher.h"
+#include "buildsystem/ide-build-stage-mkdirs.h"
 #include "buildsystem/ide-build-system.h"
 #include "buildsystem/ide-build-target.h"
 #include "buildsystem/ide-builder.h"
diff --git a/plugins/autotools/ide-autotools-pipeline-addin.c 
b/plugins/autotools/ide-autotools-pipeline-addin.c
index 76541ae..b05fecf 100644
--- a/plugins/autotools/ide-autotools-pipeline-addin.c
+++ b/plugins/autotools/ide-autotools-pipeline-addin.c
@@ -21,12 +21,6 @@
 #include "ide-autotools-pipeline-addin.h"
 #include "ide-autotools-build-system.h"
 
-struct _IdeAutotoolsPipelineAddin
-{
-  IdeObject  parent;
-  GArray    *stage_ids;
-};
-
 static gboolean
 register_autogen_stage (IdeAutotoolsPipelineAddin  *self,
                         IdeBuildPipeline           *pipeline,
@@ -54,7 +48,9 @@ register_autogen_stage (IdeAutotoolsPipelineAddin  *self,
    * autogen as well (by explicitely invalidating the autogen phase).
    */
 
-  if (NULL == (launcher = ide_runtime_create_launcher (runtime, error)))
+  launcher = ide_build_pipeline_create_launcher (pipeline, error);
+
+  if (launcher == NULL)
     return FALSE;
 
   autogen_path = ide_build_pipeline_build_srcdir_path (pipeline, "autogen.sh", NULL);
@@ -71,9 +67,9 @@ register_autogen_stage (IdeAutotoolsPipelineAddin  *self,
                         "launcher", launcher,
                         NULL);
 
-  stage_id = ide_build_pipeline_insert_stage (pipeline, IDE_BUILD_PHASE_AUTOGEN, 0, stage);
+  stage_id = ide_build_pipeline_connect (pipeline, IDE_BUILD_PHASE_AUTOGEN, 0, stage);
 
-  g_array_append_val (self->stage_ids, stage_id);
+  ide_build_pipeline_addin_track (IDE_BUILD_PIPELINE_ADDIN (self), stage_id);
 
   return TRUE;
 }
@@ -97,7 +93,9 @@ register_configure_stage (IdeAutotoolsPipelineAddin  *self,
   g_assert (IDE_IS_BUILD_PIPELINE (pipeline));
   g_assert (IDE_IS_RUNTIME (runtime));
 
-  if (NULL == (launcher = ide_runtime_create_launcher (runtime, error)))
+  launcher = ide_build_pipeline_create_launcher (pipeline, error);
+
+  if (launcher == NULL)
     return FALSE;
 
   configure_path = ide_build_pipeline_build_srcdir_path (pipeline, "configure", NULL);
@@ -146,9 +144,9 @@ register_configure_stage (IdeAutotoolsPipelineAddin  *self,
                         "launcher", launcher,
                         NULL);
 
-  stage_id = ide_build_pipeline_insert_stage (pipeline, IDE_BUILD_PHASE_AUTOGEN, 0, stage);
+  stage_id = ide_build_pipeline_connect (pipeline, IDE_BUILD_PHASE_AUTOGEN, 0, stage);
 
-  g_array_append_val (self->stage_ids, stage_id);
+  ide_build_pipeline_addin_track (IDE_BUILD_PIPELINE_ADDIN (self), stage_id);
 
   return TRUE;
 }
@@ -173,7 +171,9 @@ register_make_stage (IdeAutotoolsPipelineAddin  *self,
   g_assert (IDE_IS_BUILD_PIPELINE (pipeline));
   g_assert (IDE_IS_RUNTIME (runtime));
 
-  if (NULL == (launcher = ide_runtime_create_launcher (runtime, error)))
+  launcher = ide_build_pipeline_create_launcher (pipeline, error);
+
+  if (launcher == NULL)
     return FALSE;
 
   if (ide_runtime_contains_program_in_path (runtime, "gmake", NULL))
@@ -194,9 +194,9 @@ register_make_stage (IdeAutotoolsPipelineAddin  *self,
   ide_subprocess_launcher_push_argv (launcher, target);
   ide_subprocess_launcher_push_argv (launcher, j);
 
-  stage_id = ide_build_pipeline_insert_stage_from_launcher (pipeline, phase, 0, launcher);
+  stage_id = ide_build_pipeline_connect_launcher (pipeline, phase, 0, launcher);
 
-  g_array_append_val (self->stage_ids, stage_id);
+  ide_build_pipeline_addin_track (IDE_BUILD_PIPELINE_ADDIN (self), stage_id);
 
   return TRUE;
 }
@@ -215,8 +215,6 @@ ide_autotools_pipeline_addin_load (IdeBuildPipelineAddin *addin,
   g_assert (IDE_IS_AUTOTOOLS_PIPELINE_ADDIN (self));
   g_assert (IDE_IS_BUILD_PIPELINE (pipeline));
 
-  self->stage_ids = g_array_new (FALSE, FALSE, sizeof (guint));
-
   context = ide_object_get_context (IDE_OBJECT (addin));
   build_system = ide_context_get_build_system (context);
   config = ide_build_pipeline_get_configuration (pipeline);
@@ -236,32 +234,16 @@ ide_autotools_pipeline_addin_load (IdeBuildPipelineAddin *addin,
     }
 }
 
-static void
-ide_autotools_pipeline_addin_unload (IdeBuildPipelineAddin *addin,
-                                     IdeBuildPipeline      *pipeline)
-{
-  IdeAutotoolsPipelineAddin *self = (IdeAutotoolsPipelineAddin *)addin;
-
-  g_assert (IDE_IS_AUTOTOOLS_PIPELINE_ADDIN (self));
-  g_assert (IDE_IS_BUILD_PIPELINE (pipeline));
-
-  for (guint i = 0; i < self->stage_ids->len; i++)
-    {
-      guint stage_id = g_array_index (self->stage_ids, guint, i);
-
-      ide_build_pipeline_remove (pipeline, stage_id);
-    }
-
-  g_clear_pointer (&self->stage_ids, g_array_unref);
-}
+/* GObject Boilerplate */
 
 static void
 addin_iface_init (IdeBuildPipelineAddinInterface *iface)
 {
   iface->load = ide_autotools_pipeline_addin_load;
-  iface->unload = ide_autotools_pipeline_addin_unload;
 }
 
+struct _IdeAutotoolsPipelineAddin { IdeObject parent; };
+
 G_DEFINE_TYPE_WITH_CODE (IdeAutotoolsPipelineAddin, ide_autotools_pipeline_addin, IDE_TYPE_OBJECT,
                          G_IMPLEMENT_INTERFACE (IDE_TYPE_BUILD_PIPELINE_ADDIN, addin_iface_init))
 
diff --git a/plugins/flatpak/Makefile.am b/plugins/flatpak/Makefile.am
index 89a7528..8d3e95e 100644
--- a/plugins/flatpak/Makefile.am
+++ b/plugins/flatpak/Makefile.am
@@ -29,6 +29,8 @@ libflatpak_plugin_la_SOURCES = \
        gbp-flatpak-sources.h \
        gbp-flatpak-subprocess-launcher.c \
        gbp-flatpak-subprocess-launcher.h \
+       gbp-flatpak-util.c \
+       gbp-flatpak-util.h \
        $(NULL)
 
 nodist_libflatpak_plugin_la_SOURCES = \
diff --git a/plugins/flatpak/gbp-flatpak-pipeline-addin.c b/plugins/flatpak/gbp-flatpak-pipeline-addin.c
index 88527ba..582b041 100644
--- a/plugins/flatpak/gbp-flatpak-pipeline-addin.c
+++ b/plugins/flatpak/gbp-flatpak-pipeline-addin.c
@@ -24,45 +24,101 @@ struct _GbpFlatpakPipelineAddin
 {
   IdeObject  parent_instance;
   GArray    *stage_ids;
-  gchar     *repo_path;
 };
 
+static IdeSubprocessLauncher *
+create_subprocess_launcher (IdeBuildPipeline  *pipeline,
+                            GError           **error)
+{
+  g_autoptr(IdeSubprocessLauncher) launcher = NULL;
+  IdeConfiguration *config;
+  IdeRuntime *runtime;
+
+  g_assert (IDE_IS_BUILD_PIPELINE (pipeline));
+
+  config = ide_build_pipeline_get_configuration (pipeline);
+  runtime = ide_configuration_get_runtime (config);
+
+  launcher = ide_subprocess_launcher_new (0);
+  ide_subprocess_launcher_set_run_on_host (launcher, TRUE);
+  ide_subprocess_launcher_set_clear_env (launcher, FALSE);
+
+  return launcher;
+}
+
 static gboolean
-create_directories_task (IdeBuildStage     *stage,
-                         IdeBuildPipeline  *pipeline,
-                         GCancellable      *cancellable,
-                         GError           **error)
+register_prepare_phase (GbpFlatpakPipelineAddin  *self,
+                        IdeBuildPipeline         *pipeline,
+                        GError                  **error)
 {
-  g_autoptr(GTask) task = NULL;
-  g_autofree gchar *flatpak_build_dir = NULL;
-  g_autofree gchar *flatpak_repo_dir = NULL;
-
-  task = g_task_new (stage, NULL, NULL, NULL);
-  g_task_set_source_func (task, create_directories_task);
-
-  repo_dir = g_build_filename (g_get_user_cache_dir (),
-                               "gnome-builder",
-                               "builds",
-                               ide_project_get_id (project),
-                               "flatpak",
-                               ide_runtime_get_id (IDE_RUNTIME (self)),
-                               NULL);
+  g_autoptr(IdeBuildStageMkdirs) mkdirs = NULL;
+  g_autofree gchar *repo_dir = NULL;
+  g_autofree gchar *staging_dir = NULL;
+  guint stage_id;
+
+  g_assert (GBP_IS_FLATPAK_PIPELINE_ADDIN (self));
+  g_assert (IDE_IS_BUILD_PIPELINE (pipeline));
+
+  mkdirs = g_object_new (IDE_TYPE_BUILD_STAGE_MKDIRS, NULL);
+
+  repo_dir = gbp_flatpak_get_repo_dir (configuration);
+  staging_dir = gbp_flatpak_get_staging_dir (configuration);
+
+  ide_build_stage_mkdirs_add_path (mkdirs, repo_dir, TRUE, 0750);
+  ide_build_stage_mkdirs_add_path (mkdirs, staging_dir, TRUE, 0750);
+
+  stage_id = ide_build_pipeline_connect (pipeline,
+                                         IDE_BUILD_PHASE_PREPARE,
+                                         0,
+                                         IDE_BUILD_STAGE (mkdirs));
+  g_array_append_val (self->stage_ids, stage_id);
+}
+
+static gboolean
+register_add_remotes_stage (GbpFlatpakPipelineAddin  *self,
+                            IdeBuildPipeline         *pipeline,
+                            GError                  **error)
+{
+  g_autoptr(IdeSubprocessLauncher) launcher = NULL;
+  guint stage_id;
+
+  g_assert (GBP_IS_FLATPAK_PIPELINE_ADDIN (self));
+  g_assert (IDE_IS_BUILD_PIPELINE (pipeline));
+
+  if (NULL == (launcher = create_subprocess_launcher (pipeline, error)))
+    return FALSE;
+
+  ide_subprocess_launcher_push_argv (launcher, "flatpak");
+  ide_subprocess_launcher_push_argv (launcher, "remote-add");
+  ide_subprocess_launcher_push_argv (launcher, "--user");
+  ide_subprocess_launcher_push_argv (launcher, "--no-gpg-verify");
+  ide_subprocess_launcher_push_argv (launcher, "--if-not-exists");
+  ide_subprocess_launcher_push_argv (launcher, flatpak_repo_name);
+  ide_subprocess_launcher_push_argv (launcher, flatpak_repo_path);
+
+  stage_id = ide_build_pipeline_insert_stage_from_launcher (pipeline,
+                                                            IDE_BUILD_PHASE_DOWNLOADS,
+                                                            0,
+                                                            launcher);
+  g_array_append_val (self->stage_ids, stage_id);
 }
 
 static void
 gbp_flatpak_pipeline_addin_load (IdeBuildPipelineAddin *addin,
                                  IdeBuildPipeline      *pipeline)
 {
+  g_autoptr(GError) error = NULL;
+
   g_assert (GBP_IS_FLATPAK_PIPELINE_ADDIN (self));
   g_assert (IDE_IS_BUILD_PIPELINE (pipeline));
 
   self->stage_ids = g_array_new (FALSE, FALSE, sizeof (guint));
 
-  stage_id = ide_build_pipeline_add_stage_from_callback (pipeline,
-                                                         IDE_BUILD_PHASE_PREPARE,
-                                                         0,
-                                                         create_directories);
-  g_array_append_val (self->stage_ids, stage_id);
+  if (!register_prepare_phase (self, pipeline, &error))
+    {
+      g_warning ("%s", error->message);
+      return;
+    }
 }
 
 static void
@@ -78,7 +134,7 @@ gbp_flatpak_pipeline_addin_unload (IdeBuildPipelineAddin *addin,
     {
       guint stage_id = g_array_index (self->stage_ids, guint i);
 
-      ide_build_pipeline_remove (pipeline, stage_id);
+      ide_build_pipeline_disconnect (pipeline, stage_id);
     }
 
   g_clear_pointer (&self->stage_ids, g_array_unref);
diff --git a/plugins/flatpak/gbp-flatpak-util.c b/plugins/flatpak/gbp-flatpak-util.c
new file mode 100644
index 0000000..c67a1bd
--- /dev/null
+++ b/plugins/flatpak/gbp-flatpak-util.c
@@ -0,0 +1,69 @@
+/* gbp-flatpak-util.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 "gbp-flatpak-util"
+
+#include "gbp-flatpak-util.h"
+
+gchar *
+gbp_flatpak_get_repo_dir (IdeConfiguration *configuration)
+{
+  const gchar *project_id;
+  const gchar *runtime_id;
+  IdeContext *context;
+  IdeProject *project;
+
+  g_assert (IDE_IS_CONFIGURATION (configuration));
+
+  runtime_id = ide_configuration_get_runtime_id (configuration);
+  context = ide_object_get_context (IDE_OBJECT (configuration));
+  project = ide_context_get_project (context);
+  project_id = ide_project_get_id (project);
+
+  return g_build_filename (g_get_user_cache_dir (),
+                           "gnome-builder",
+                           "flatpak",
+                           "repos",
+                           project_id,
+                           runtime_id,
+                           NULL);
+}
+
+gchar *
+gbp_flatpak_get_staging_dir (IdeConfiguration *configuration)
+{
+  const gchar *project_id;
+  const gchar *runtime_id;
+  IdeContext *context;
+  IdeProject *project;
+
+  g_assert (IDE_IS_CONFIGURATION (configuration));
+
+  runtime_id = ide_configuration_get_runtime_id (configuration);
+  context = ide_object_get_context (IDE_OBJECT (configuration));
+  project = ide_context_get_project (context);
+  project_id = ide_project_get_id (project);
+
+  return g_build_filename (g_get_user_cache_dir (),
+                           "gnome-builder",
+                           "flatpak",
+                           "staging",
+                           project_id,
+                           runtime_id,
+                           NULL);
+}
diff --git a/plugins/flatpak/gbp-flatpak-util.h b/plugins/flatpak/gbp-flatpak-util.h
new file mode 100644
index 0000000..f3afc22
--- /dev/null
+++ b/plugins/flatpak/gbp-flatpak-util.h
@@ -0,0 +1,31 @@
+/* gbp-flatpak-util.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 GBP_FLATPAK_UTIL_H
+#define GBP_FLATPAK_UTIL_H
+
+#include <ide.h>
+
+G_BEGIN_DECLS
+
+gchar *gbp_flatpak_get_repo_dir    (IdeConfiguration *configuration);
+gchar *gbp_flatpak_get_staging_dir (IdeConfiguration *configuration);
+
+G_END_DECLS
+
+#endif /* GBP_FLATPAK_UTIL_H */



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