[gnome-builder] flatpak: reload config when the manifest file is modified
- From: Matthew Leeds <mwleeds src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder] flatpak: reload config when the manifest file is modified
- Date: Mon, 27 Feb 2017 21:46:28 +0000 (UTC)
commit 73cf5de8bc3d06a1cb00240ddfa451520b9abaa2
Author: Matthew Leeds <mleeds redhat com>
Date: Sun Feb 26 15:35:35 2017 -0800
flatpak: reload config when the manifest file is modified
If the user edits the manifest file while Builder is running, the
GbpFlatpakConfiguration based on that manifest should automatically
update. This commit implements that behavior by adding a GFileMonitor on
each manifest file in GbpFlatpakConfigurationProvider. It also attempts
to have reasonable behavior if the file is deleted or moved.
https://bugzilla.gnome.org/show_bug.cgi?id=779330
.../flatpak/gbp-flatpak-configuration-provider.c | 179 ++++++++++++++++++--
1 files changed, 162 insertions(+), 17 deletions(-)
---
diff --git a/plugins/flatpak/gbp-flatpak-configuration-provider.c
b/plugins/flatpak/gbp-flatpak-configuration-provider.c
index e52c488..2cd59d6 100644
--- a/plugins/flatpak/gbp-flatpak-configuration-provider.c
+++ b/plugins/flatpak/gbp-flatpak-configuration-provider.c
@@ -38,6 +38,7 @@ struct _GbpFlatpakConfigurationProvider
IdeConfigurationManager *manager;
GCancellable *cancellable;
GPtrArray *configurations;
+ GPtrArray *manifest_monitors;
gulong writeback_handler;
guint change_count;
@@ -577,8 +578,8 @@ gbp_flatpak_configuration_provider_queue_writeback (GbpFlatpakConfigurationProvi
}
static void
-gbp_flatpak_configuration_provider_changed (GbpFlatpakConfigurationProvider *self,
- IdeConfiguration *configuration)
+gbp_flatpak_configuration_provider_config_changed (GbpFlatpakConfigurationProvider *self,
+ IdeConfiguration *configuration)
{
g_assert (GBP_IS_FLATPAK_CONFIGURATION_PROVIDER (self));
g_assert (IDE_IS_CONFIGURATION (configuration));
@@ -608,6 +609,144 @@ contains_id (GPtrArray *ar,
return FALSE;
}
+static gchar *
+get_manifest_id (const gchar *path,
+ const gchar *filename)
+{
+ g_autofree gchar *manifest_data = NULL;
+ g_autofree gchar *hash = NULL;
+ gsize manifest_data_len = 0;
+
+ g_assert (!ide_str_empty0 (path));
+
+ if (g_file_get_contents (path, &manifest_data, &manifest_data_len, NULL))
+ {
+ g_autoptr(GChecksum) checksum = NULL;
+
+ checksum = g_checksum_new (G_CHECKSUM_SHA1);
+ g_checksum_update (checksum, (const guint8 *)manifest_data, manifest_data_len);
+ hash = g_strdup (g_checksum_get_string (checksum));
+ }
+
+ if (hash != NULL)
+ return g_strdup_printf ("%s@%s", filename, hash);
+ else
+ return g_strdup (filename);
+}
+
+static void
+gbp_flatpak_configuration_provider_manifest_changed (GbpFlatpakConfigurationProvider *self,
+ GFile *file,
+ GFile *other_file,
+ GFileMonitorEvent event,
+ GFileMonitor *file_monitor)
+{
+ GbpFlatpakConfiguration *relevant_config = NULL;
+ IdeContext *context;
+ GFile *new_config_file;
+ g_autofree gchar *filename = NULL;
+ g_autofree gchar *path = NULL;
+ g_autofree gchar *id = NULL;
+
+ IDE_ENTRY;
+
+ g_assert (GBP_IS_FLATPAK_CONFIGURATION_PROVIDER (self));
+ g_assert (G_IS_FILE (file));
+ g_assert (G_IS_FILE_MONITOR (file_monitor));
+
+ context = ide_object_get_context (IDE_OBJECT (self->manager));
+
+ if (self->configurations != NULL)
+ {
+ for (guint i = 0; i < self->configurations->len; i++)
+ {
+ GbpFlatpakConfiguration *configuration = g_ptr_array_index (self->configurations, i);
+ GFile *config_manifest;
+ config_manifest = gbp_flatpak_configuration_get_manifest (configuration);
+ if (g_file_equal (file, config_manifest) ||
+ (event == G_FILE_MONITOR_EVENT_RENAMED && g_file_equal (other_file, config_manifest)))
+ {
+ relevant_config = configuration;
+ break;
+ }
+ }
+ }
+
+ if (relevant_config == NULL)
+ IDE_EXIT;
+
+ new_config_file = file;
+ switch (event)
+ {
+ case G_FILE_MONITOR_EVENT_DELETED:
+ case G_FILE_MONITOR_EVENT_MOVED_OUT:
+ ide_configuration_manager_remove (self->manager, IDE_CONFIGURATION (relevant_config));
+ g_ptr_array_remove_fast (self->configurations, relevant_config);
+ g_ptr_array_remove_fast (self->manifest_monitors, file_monitor);
+ break;
+ case G_FILE_MONITOR_EVENT_RENAMED:
+ filename = g_file_get_basename (other_file);
+ /* The "rename" is just a temporary file created by an editor */
+ if (g_str_has_suffix (filename, "~"))
+ IDE_EXIT;
+ else
+ g_free (filename);
+ new_config_file = other_file;
+ /* Don't break so we can reuse the code below to add the new config */
+ case G_FILE_MONITOR_EVENT_CREATED:
+ case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT:
+ case G_FILE_MONITOR_EVENT_MOVED_IN:
+ path = g_file_get_path (new_config_file);
+ filename = g_file_get_basename (new_config_file);
+ id = get_manifest_id (path, filename);
+ if (!contains_id (self->configurations, id))
+ {
+ g_autoptr(GbpFlatpakConfiguration) new_config = NULL;
+ new_config = gbp_flatpak_configuration_new (context, id, filename);
+ if (gbp_flatpak_configuration_load_from_file (new_config, new_config_file))
+ {
+ g_autoptr(GFileMonitor) manifest_monitor = NULL;
+ g_autoptr(GError) local_error = NULL;
+ g_signal_connect_object (new_config,
+ "changed",
+ G_CALLBACK (gbp_flatpak_configuration_provider_config_changed),
+ self,
+ G_CONNECT_SWAPPED);
+
+ manifest_monitor = g_file_monitor_file (file, G_FILE_MONITOR_WATCH_MOVES, NULL,
&local_error);
+ if (manifest_monitor == NULL)
+ g_warning ("Error encountered trying to monitor flatpak manifest %s: %s", path,
local_error->message);
+ else
+ {
+ g_signal_connect_object (manifest_monitor,
+ "changed",
+ G_CALLBACK
(gbp_flatpak_configuration_provider_manifest_changed),
+ self,
+ G_CONNECT_SWAPPED);
+ g_ptr_array_add (self->manifest_monitors, g_steal_pointer (&manifest_monitor));
+ }
+ ide_configuration_manager_remove (self->manager, IDE_CONFIGURATION (relevant_config));
+ g_ptr_array_remove_fast (self->configurations, relevant_config);
+ g_ptr_array_remove_fast (self->manifest_monitors, file_monitor);
+ ide_configuration_manager_add (self->manager, IDE_CONFIGURATION (new_config));
+ ide_configuration_manager_set_current (self->manager, IDE_CONFIGURATION (new_config));
+ g_ptr_array_add (self->configurations, g_steal_pointer (&new_config));
+ }
+ }
+ break;
+
+ case G_FILE_MONITOR_EVENT_CHANGED:
+ case G_FILE_MONITOR_EVENT_MOVED:
+ case G_FILE_MONITOR_EVENT_PRE_UNMOUNT:
+ case G_FILE_MONITOR_EVENT_UNMOUNTED:
+ case G_FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED:
+ default:
+ break;
+ }
+
+ IDE_EXIT;
+}
+
static gboolean
gbp_flatpak_configuration_provider_find_manifests (GbpFlatpakConfigurationProvider *self,
GFile *directory,
@@ -639,14 +778,13 @@ gbp_flatpak_configuration_provider_find_manifests (GbpFlatpakConfigurationProvid
GFileType file_type;
g_autofree gchar *filename = NULL;
g_autofree gchar *path = NULL;
- g_autofree gchar *hash = NULL;
g_autofree gchar *id = NULL;
- g_autofree gchar *manifest_data = NULL;
- gsize manifest_data_len = 0;
g_autoptr(GRegex) filename_regex = NULL;
g_autoptr(GMatchInfo) match_info = NULL;
g_autoptr(GFile) file = NULL;
g_autoptr(GbpFlatpakConfiguration) possible_config = NULL;
+ g_autoptr(GFileMonitor) manifest_monitor = NULL;
+ g_autoptr(GError) local_error = NULL;
file_type = g_file_info_get_file_type (file_info);
filename = g_strdup (g_file_info_get_name (file_info));
@@ -678,17 +816,7 @@ gbp_flatpak_configuration_provider_find_manifests (GbpFlatpakConfigurationProvid
/* Check if the file has already been loaded as a config */
path = g_file_get_path (file);
- if (g_file_get_contents (path, &manifest_data, &manifest_data_len, NULL))
- {
- g_autoptr(GChecksum) checksum = NULL;
-
- checksum = g_checksum_new (G_CHECKSUM_SHA1);
- g_checksum_update (checksum, (const guint8 *)manifest_data, manifest_data_len);
- hash = g_strdup (g_checksum_get_string (checksum));
- }
-
- id = (hash != NULL) ? g_strdup_printf ("%s@%s", filename, hash) : g_strdup (filename);
-
+ id = get_manifest_id (path, filename);
if (contains_id (configs, id))
continue;
@@ -699,10 +827,23 @@ gbp_flatpak_configuration_provider_find_manifests (GbpFlatpakConfigurationProvid
g_signal_connect_object (possible_config,
"changed",
- G_CALLBACK (gbp_flatpak_configuration_provider_changed),
+ G_CALLBACK (gbp_flatpak_configuration_provider_config_changed),
self,
G_CONNECT_SWAPPED);
+ manifest_monitor = g_file_monitor_file (file, G_FILE_MONITOR_WATCH_MOVES, NULL, &local_error);
+ if (manifest_monitor == NULL)
+ g_warning ("Error encountered trying to monitor flatpak manifest %s: %s", path,
local_error->message);
+ else
+ {
+ g_signal_connect_object (manifest_monitor,
+ "changed",
+ G_CALLBACK (gbp_flatpak_configuration_provider_manifest_changed),
+ self,
+ G_CONNECT_SWAPPED);
+ g_ptr_array_add (self->manifest_monitors, g_steal_pointer (&manifest_monitor));
+ }
+
g_ptr_array_add (configs, g_steal_pointer (&possible_config));
}
@@ -835,6 +976,8 @@ gbp_flatpak_configuration_provider_load (IdeConfigurationProvider *provider,
ide_set_weak_pointer (&self->manager, manager);
+ self->manifest_monitors = g_ptr_array_new_with_free_func (g_object_unref);
+
self->cancellable = g_cancellable_new ();
task = g_task_new (self, self->cancellable, gbp_flatpak_configuration_provider_load_cb, NULL);
@@ -868,6 +1011,8 @@ gbp_flatpak_configuration_provider_unload (IdeConfigurationProvider *provider,
g_clear_pointer (&self->configurations, g_ptr_array_unref);
+ g_clear_pointer (&self->manifest_monitors, g_ptr_array_unref);
+
if (self->cancellable != NULL)
g_cancellable_cancel (self->cancellable);
g_clear_object (&self->cancellable);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]