[gnome-builder] flatpak: add support for --state-dir in flatpak-builder 0.10.5



commit d38671fc1bb128480ff4db6588ef285811331c0d
Author: Christian Hergert <chergert redhat com>
Date:   Sat Nov 25 14:39:13 2017 -0800

    flatpak: add support for --state-dir in flatpak-builder 0.10.5
    
    If we have a new enough flatpak-builder, then try to use --state-dir so
    that we can share build sources between multiple projects for reduced
    downloads in common projects.

 src/plugins/flatpak/gbp-flatpak-download-stage.c |   56 +++++++++++++
 src/plugins/flatpak/gbp-flatpak-pipeline-addin.c |   93 +++++++++++++++++++++-
 2 files changed, 147 insertions(+), 2 deletions(-)
---
diff --git a/src/plugins/flatpak/gbp-flatpak-download-stage.c 
b/src/plugins/flatpak/gbp-flatpak-download-stage.c
index b078608..478f98b 100644
--- a/src/plugins/flatpak/gbp-flatpak-download-stage.c
+++ b/src/plugins/flatpak/gbp-flatpak-download-stage.c
@@ -28,12 +28,22 @@ struct _GbpFlatpakDownloadStage
 {
   IdeBuildStageLauncher parent_instance;
 
+  gchar *state_dir;
+
   guint invalid : 1;
   guint force_update : 1;
 };
 
 G_DEFINE_TYPE (GbpFlatpakDownloadStage, gbp_flatpak_download_stage, IDE_TYPE_BUILD_STAGE_LAUNCHER)
 
+enum {
+  PROP_0,
+  PROP_STATE_DIR,
+  N_PROPS
+};
+
+static GParamSpec *properties [N_PROPS];
+
 static void
 gbp_flatpak_download_stage_query (IdeBuildStage    *stage,
                                   IdeBuildPipeline *pipeline,
@@ -78,6 +88,11 @@ gbp_flatpak_download_stage_query (IdeBuildStage    *stage,
       ide_subprocess_launcher_push_argv (launcher, "flatpak-builder");
       ide_subprocess_launcher_push_argv (launcher, "--ccache");
       ide_subprocess_launcher_push_argv (launcher, "--force-clean");
+      if (!ide_str_empty0 (self->state_dir))
+        {
+          ide_subprocess_launcher_push_argv (launcher, "--state-dir");
+          ide_subprocess_launcher_push_argv (launcher, self->state_dir);
+        }
       ide_subprocess_launcher_push_argv (launcher, "--download-only");
       if (!self->force_update)
         ide_subprocess_launcher_push_argv (launcher, "--disable-updates");
@@ -106,11 +121,52 @@ gbp_flatpak_download_stage_query (IdeBuildStage    *stage,
 }
 
 static void
+gbp_flatpak_download_stage_finalize (GObject *object)
+{
+  GbpFlatpakDownloadStage *self = (GbpFlatpakDownloadStage *)object;
+
+  g_assert (GBP_IS_FLATPAK_DOWNLOAD_STAGE (self));
+
+  g_clear_pointer (&self->state_dir, g_free);
+
+  G_OBJECT_CLASS (gbp_flatpak_download_stage_parent_class)->finalize (object);
+}
+
+static void
+gbp_flatpak_download_stage_set_property (GObject      *object,
+                                         guint         prop_id,
+                                         const GValue *value,
+                                         GParamSpec   *pspec)
+{
+  GbpFlatpakDownloadStage *self = GBP_FLATPAK_DOWNLOAD_STAGE (object);
+
+  switch (prop_id)
+    {
+    case PROP_STATE_DIR:
+      self->state_dir = g_value_dup_string (value);
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+}
+
+static void
 gbp_flatpak_download_stage_class_init (GbpFlatpakDownloadStageClass *klass)
 {
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
   IdeBuildStageClass *stage_class = IDE_BUILD_STAGE_CLASS (klass);
 
+  object_class->finalize = gbp_flatpak_download_stage_finalize;
+  object_class->set_property = gbp_flatpak_download_stage_set_property;
+
   stage_class->query = gbp_flatpak_download_stage_query;
+
+  properties [PROP_STATE_DIR] =
+    g_param_spec_string ("state-dir", NULL, NULL, NULL,
+                         G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
+
+  g_object_class_install_properties (object_class, N_PROPS, properties);
 }
 
 static void
diff --git a/src/plugins/flatpak/gbp-flatpak-pipeline-addin.c 
b/src/plugins/flatpak/gbp-flatpak-pipeline-addin.c
index 9e65744..7924f64 100644
--- a/src/plugins/flatpak/gbp-flatpak-pipeline-addin.c
+++ b/src/plugins/flatpak/gbp-flatpak-pipeline-addin.c
@@ -27,6 +27,24 @@
 #include "gbp-flatpak-transfer.h"
 #include "gbp-flatpak-util.h"
 
+#define VERSION_CHECK(v,a,b,c)                                         \
+  (((v)->major > (a)) ||                                               \
+   (((v)->major == (a)) && ((v)->minor > (b))) ||                      \
+   (((v)->major == (a)) && ((v)->minor == (b)) && ((v)->micro >= (c))))
+
+struct _GbpFlatpakPipelineAddin
+{
+  IdeObject parent_instance;
+
+  gchar *state_dir;
+
+  struct {
+    int major;
+    int minor;
+    int micro;
+  } version;
+};
+
 G_DEFINE_QUARK (gb-flatpak-pipeline-error-quark, gb_flatpak_pipeline_error)
 
 enum {
@@ -41,6 +59,40 @@ enum {
 };
 
 static void
+sniff_flatpak_builder_version (GbpFlatpakPipelineAddin *self)
+{
+  g_autoptr(IdeSubprocessLauncher) launcher = NULL;
+  g_autoptr(IdeSubprocess) subprocess = NULL;
+  g_autofree gchar *stdout_buf = NULL;
+  int major = 0;
+  int minor = 0;
+  int micro = 0;
+
+  g_assert (GBP_IS_FLATPAK_PIPELINE_ADDIN (self));
+
+  launcher = ide_subprocess_launcher_new (G_SUBPROCESS_FLAGS_STDOUT_PIPE);
+  ide_subprocess_launcher_set_run_on_host (launcher, TRUE);
+  ide_subprocess_launcher_set_clear_env (launcher, FALSE);
+  ide_subprocess_launcher_setenv (launcher, "LANG", "C", TRUE);
+  ide_subprocess_launcher_push_argv (launcher, "flatpak-builder");
+  ide_subprocess_launcher_push_argv (launcher, "--version");
+
+  subprocess = ide_subprocess_launcher_spawn (launcher, NULL, NULL);
+  if (subprocess == NULL)
+    return;
+
+  if (!ide_subprocess_communicate_utf8 (subprocess, NULL, NULL, &stdout_buf, NULL, NULL))
+    return;
+
+  if (sscanf (stdout_buf, "flatpak-builder %d.%d.%d", &major, &minor, &micro) != 3)
+    return;
+
+  self->version.major = major;
+  self->version.minor = minor;
+  self->version.micro = micro;
+}
+
+static void
 always_run_query_handler (IdeBuildStage    *stage,
                           IdeBuildPipeline *pipeline)
 {
@@ -233,6 +285,7 @@ register_downloads_stage (GbpFlatpakPipelineAddin  *self,
 
   stage = g_object_new (GBP_TYPE_FLATPAK_DOWNLOAD_STAGE,
                         "context", context,
+                        "state-dir", self->state_dir,
                         NULL);
   stage_id = ide_build_pipeline_connect (pipeline, IDE_BUILD_PHASE_DOWNLOADS, 0, stage);
   ide_build_pipeline_addin_track (IDE_BUILD_PIPELINE_ADDIN (self), stage_id);
@@ -282,6 +335,11 @@ register_dependencies_stage (GbpFlatpakPipelineAddin  *self,
   ide_subprocess_launcher_push_argv (launcher, "--ccache");
   ide_subprocess_launcher_push_argv (launcher, "--force-clean");
   ide_subprocess_launcher_push_argv (launcher, "--disable-updates");
+  if (self->state_dir != NULL)
+    {
+      ide_subprocess_launcher_push_argv (launcher, "--state-dir");
+      ide_subprocess_launcher_push_argv (launcher, self->state_dir);
+    }
   stop_at_option = g_strdup_printf ("--stop-at=%s", primary_module);
   ide_subprocess_launcher_push_argv (launcher, stop_at_option);
   ide_subprocess_launcher_push_argv (launcher, staging_dir);
@@ -489,6 +547,26 @@ gbp_flatpak_pipeline_addin_load (IdeBuildPipelineAddin *addin,
   g_assert (GBP_IS_FLATPAK_PIPELINE_ADDIN (self));
   g_assert (IDE_IS_BUILD_PIPELINE (pipeline));
 
+  sniff_flatpak_builder_version (self);
+
+  if (VERSION_CHECK (&self->version, 0, 10, 5))
+    {
+      /* Use a single flatpak-builder state directory that is
+       * kept within .cache (or appropriate mapping directory)
+       * instead of littering it within the project checkout.
+       * It also allows us to share checkouts and clones between
+       * projects instead lots of duplicates.
+       *
+       * It does have the side effect that it is harder to
+       * prune existing data and we may want to address that
+       * in the future (either upstream or in here).
+       */
+      self->state_dir = g_build_filename (g_get_user_cache_dir (),
+                                          ide_get_program_name (),
+                                          "flatpak-builder",
+                                          NULL);
+    }
+
   config = ide_build_pipeline_get_configuration (pipeline);
 
   /* TODO: Once we have GbpFlatpakConfiguration, we can check for
@@ -521,16 +599,27 @@ gbp_flatpak_pipeline_addin_load (IdeBuildPipelineAddin *addin,
     g_warning ("%s", error->message);
 }
 
+static void
+gbp_flatpak_pipeline_addin_unload (IdeBuildPipelineAddin *addin,
+                                   IdeBuildPipeline      *pipeline)
+{
+  GbpFlatpakPipelineAddin *self = (GbpFlatpakPipelineAddin *)addin;
+
+  g_assert (GBP_IS_FLATPAK_PIPELINE_ADDIN (self));
+  g_assert (IDE_IS_BUILD_PIPELINE (pipeline));
+
+  g_clear_pointer (&self->state_dir, g_free);
+}
+
 /* GObject boilerplate */
 
 static void
 build_pipeline_addin_iface_init (IdeBuildPipelineAddinInterface *iface)
 {
   iface->load = gbp_flatpak_pipeline_addin_load;
+  iface->unload = gbp_flatpak_pipeline_addin_unload;
 }
 
-struct _GbpFlatpakPipelineAddin { IdeObject parent_instance; };
-
 G_DEFINE_TYPE_WITH_CODE (GbpFlatpakPipelineAddin, gbp_flatpak_pipeline_addin, IDE_TYPE_OBJECT,
                          G_IMPLEMENT_INTERFACE (IDE_TYPE_BUILD_PIPELINE_ADDIN,
                                                 build_pipeline_addin_iface_init))


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