diff options
author | Richard Hughes <richard@hughsie.com> | 2019-07-16 17:08:13 +0100 |
---|---|---|
committer | Richard Hughes <richard@hughsie.com> | 2019-07-17 09:44:18 +0100 |
commit | 34b870169aebe6b1bb2661b58adc3323fb057c55 (patch) | |
tree | 77796204f0eb4983da0c9976391c5660146b1625 | |
parent | 69824ae559e2b615f432d645bc5d941581007026 (diff) | |
download | appstream-glib-wip/hughsie/save-writes.tar.gz |
Do not trigger an inotity event when the AppStream XML data is unchangedwip/hughsie/save-writes
Do not modify the ctime or mtime in as_utils_install_xml() if the SHA1
checksums are identical. This means gnome-software starts without triggering an
XbSilo rebuild if we refresh the repos with PackageKit as dnf is so keen to do.
-rw-r--r-- | libappstream-glib/as-utils.c | 62 |
1 files changed, 46 insertions, 16 deletions
diff --git a/libappstream-glib/as-utils.c b/libappstream-glib/as-utils.c index 366bff9..db25334 100644 --- a/libappstream-glib/as-utils.c +++ b/libappstream-glib/as-utils.c @@ -1143,8 +1143,12 @@ as_utils_install_xml (const gchar *filename, { gchar *tmp; g_autofree gchar *basename = NULL; + g_autofree gchar *checksum_dest = NULL; + g_autofree gchar *checksum_src = NULL; g_autofree gchar *path_dest = NULL; g_autofree gchar *path_parent = NULL; + g_autoptr(GBytes) blob_dest = NULL; + g_autoptr(GBytes) blob_src = NULL; g_autoptr(GFile) file_dest = NULL; g_autoptr(GFile) file_src = NULL; @@ -1179,28 +1183,54 @@ as_utils_install_xml (const gchar *filename, path_dest = g_build_filename (path_parent, basename, NULL); } - /* actually copy file */ - file_dest = g_file_new_for_path (path_dest); - if (!g_file_copy (file_src, file_dest, - G_FILE_COPY_OVERWRITE | - G_FILE_COPY_TARGET_DEFAULT_PERMS, - NULL, NULL, NULL, error)) - return FALSE; - /* fix the origin */ if (origin != NULL) { - g_autoptr(AsStore) store = NULL; - store = as_store_new (); - if (!as_store_from_file (store, file_dest, NULL, NULL, error)) + g_autoptr(GString) xml = NULL; + g_autoptr(GOutputStream) out2 = NULL; + g_autoptr(GOutputStream) out = NULL; + g_autoptr(GZlibCompressor) compressor = NULL; + g_autoptr(AsStore) store = as_store_new (); + + /* load file */ + if (!as_store_from_file (store, file_src, NULL, NULL, error)) return FALSE; as_store_set_origin (store, origin); - if (!as_store_to_file (store, file_dest, - AS_NODE_TO_XML_FLAG_ADD_HEADER | - AS_NODE_TO_XML_FLAG_FORMAT_MULTILINE, - NULL, error)) + xml = as_store_to_xml (store, AS_NODE_TO_XML_FLAG_ADD_HEADER | + AS_NODE_TO_XML_FLAG_FORMAT_MULTILINE); + + /* recompress */ + compressor = g_zlib_compressor_new (G_ZLIB_COMPRESSOR_FORMAT_GZIP, -1); + out = g_memory_output_stream_new_resizable (); + out2 = g_converter_output_stream_new (out, G_CONVERTER (compressor)); + if (!g_output_stream_write_all (out2, xml->str, xml->len, NULL, NULL, error)) + return FALSE; + if (!g_output_stream_close (out2, NULL, error)) + return FALSE; + blob_src = g_memory_output_stream_steal_as_bytes (G_MEMORY_OUTPUT_STREAM (out)); + } else { + blob_src = g_file_load_bytes (file_src, NULL, NULL, error); + if (blob_src == NULL) return FALSE; } - return TRUE; + + /* get the checksum of the existing file (ignoring errors) */ + file_dest = g_file_new_for_path (path_dest); + blob_dest = g_file_load_bytes (file_dest, NULL, NULL, NULL); + if (blob_dest != NULL) + checksum_dest = g_compute_checksum_for_bytes (G_CHECKSUM_SHA1, blob_dest); + + /* actually write the blob only if different */ + checksum_src = g_compute_checksum_for_bytes (G_CHECKSUM_SHA1, blob_src); + if (g_strcmp0 (checksum_dest, checksum_src) == 0) { + g_debug ("skipping file copy as same contents"); + return TRUE; + } + return g_file_replace_contents (file_dest, + g_bytes_get_data (blob_src, NULL), + g_bytes_get_size (blob_src), + NULL, FALSE, + G_FILE_CREATE_REPLACE_DESTINATION, + NULL, NULL, error); } /** |