diff --git a/common/xdg-app-dir.c b/common/xdg-app-dir.c index f29fff92..7c9b8d32 100644 --- a/common/xdg-app-dir.c +++ b/common/xdg-app-dir.c @@ -2803,26 +2803,16 @@ unpack_sizes (GVariant *entry, return TRUE; } -/** xdg_app_dir_fetch_sizes - * @self: a #XdgAppDir - * @new_archived: total size of new (to be downloaded) objects in compressed form - * @new_unpacked: total size of new (to be downloaded) objects in uncompressed form - * @total_archived: total size of all objects in compressed form - * @total_unpacked: total size of all objects in uncompressed form - */ gboolean -xdg_app_dir_fetch_sizes (XdgAppDir *self, - const char *remote_name, - const char *commit, - guint64 *new_archived, - guint64 *new_unpacked, - guint64 *total_archived, - guint64 *total_unpacked, - GCancellable *cancellable, - GError **error) +calc_sizes (XdgAppDir *self, + GVariant *commit_variant, + guint64 *new_archived, + guint64 *new_unpacked, + guint64 *total_archived, + guint64 *total_unpacked, + GCancellable *cancellable, + GError **error) { - g_autoptr(GBytes) commit_bytes = NULL; - g_autoptr(GVariant) commit_variant = NULL; g_autoptr(GVariant) metadata = NULL; g_autoptr(GVariant) sizes = NULL; g_autoptr(GVariant) object = NULL; @@ -2832,21 +2822,6 @@ xdg_app_dir_fetch_sizes (XdgAppDir *self, guint64 t_archived = 0; guint64 t_unpacked = 0; - if (!xdg_app_dir_ensure_repo (self, cancellable, error)) - return FALSE; - - commit_bytes = xdg_app_dir_fetch_remote_object (self, remote_name, - commit, "commit", - cancellable, error); - if (commit_bytes == NULL) - return FALSE; - - commit_variant = g_variant_new_from_bytes (OSTREE_COMMIT_GVARIANT_FORMAT, - commit_bytes, FALSE); - - if (!ostree_validate_structureof_commit (commit_variant, error)) - return FALSE; - metadata = g_variant_get_child_value (commit_variant, 0); sizes = g_variant_lookup_value (metadata, "ostree.sizes", G_VARIANT_TYPE("aay")); @@ -2866,19 +2841,25 @@ xdg_app_dir_fetch_sizes (XdgAppDir *self, if (!unpack_sizes (object, &entry, csum)) return xdg_app_fail (error, "Invalid object size metadata"); + /* Round up to 4k, which is what most fs:es use. */ + entry.unpacked = ((entry.unpacked + 4095) / 4096) * 4096; + g_variant_unref (g_steal_pointer (&object)); t_archived += entry.archived; t_unpacked += entry.unpacked; - if (!ostree_repo_has_object (self->repo, OSTREE_OBJECT_TYPE_FILE, - csum, &exists, cancellable, error)) - return FALSE; - - if (!exists) + if (new_archived != NULL || new_unpacked != NULL) { - n_archived += entry.archived; - n_unpacked += entry.unpacked; + if (!ostree_repo_has_object (self->repo, OSTREE_OBJECT_TYPE_FILE, + csum, &exists, cancellable, error)) + return FALSE; + + if (!exists) + { + n_archived += entry.archived; + n_unpacked += entry.unpacked; + } } } @@ -2894,6 +2875,79 @@ xdg_app_dir_fetch_sizes (XdgAppDir *self, return TRUE; } +gboolean +xdg_app_dir_get_installed_size (XdgAppDir *self, + const char *commit, + guint64 *installed_size, + GCancellable *cancellable, + GError **error) +{ + g_autoptr(GVariant) commit_variant = NULL; + + if (!ostree_repo_load_variant (self->repo, + OSTREE_OBJECT_TYPE_COMMIT, + commit, + &commit_variant, + error)) + return FALSE; + + return calc_sizes (self, + commit_variant, + NULL, + NULL, + NULL, + installed_size, + cancellable, + error); +} + +/** xdg_app_dir_fetch_sizes + * @self: a #XdgAppDir + * @new_archived: total size of new (to be downloaded) objects in compressed form + * @new_unpacked: total size of new (to be downloaded) objects in uncompressed form + * @total_archived: total size of all objects in compressed form + * @total_unpacked: total size of all objects in uncompressed form + */ +gboolean +xdg_app_dir_fetch_sizes (XdgAppDir *self, + const char *remote_name, + const char *commit, + guint64 *new_archived, + guint64 *new_unpacked, + guint64 *total_archived, + guint64 *total_unpacked, + GCancellable *cancellable, + GError **error) +{ + g_autoptr(GBytes) commit_bytes = NULL; + g_autoptr(GVariant) commit_variant = NULL; + + if (!xdg_app_dir_ensure_repo (self, cancellable, error)) + return FALSE; + + commit_bytes = xdg_app_dir_fetch_remote_object (self, remote_name, + commit, "commit", + cancellable, error); + if (commit_bytes == NULL) + return FALSE; + + commit_variant = g_variant_new_from_bytes (OSTREE_COMMIT_GVARIANT_FORMAT, + commit_bytes, FALSE); + + + if (!ostree_validate_structureof_commit (commit_variant, error)) + return FALSE; + + return calc_sizes (self, + commit_variant, + new_archived, + new_unpacked, + total_archived, + total_unpacked, + cancellable, + error); +} + GBytes * xdg_app_dir_fetch_metadata (XdgAppDir *self, const char *remote_name, diff --git a/common/xdg-app-dir.h b/common/xdg-app-dir.h index 6c7dec90..38a61295 100644 --- a/common/xdg-app-dir.h +++ b/common/xdg-app-dir.h @@ -262,6 +262,11 @@ GBytes * xdg_app_dir_fetch_metadata (XdgAppDir *self, const char *commit, GCancellable *cancellable, GError **error); +gboolean xdg_app_dir_get_installed_size (XdgAppDir *self, + const char *commit, + guint64 *installed_size, + GCancellable *cancellable, + GError **error); gboolean xdg_app_dir_fetch_sizes (XdgAppDir *self, const char *remote_name, const char *commit, diff --git a/lib/test-lib.c b/lib/test-lib.c index 5e55f51f..6b2a14a4 100644 --- a/lib/test-lib.c +++ b/lib/test-lib.c @@ -104,7 +104,7 @@ main (int argc, char *argv[]) for (i = 0; i < updates->len; i++) { XdgAppInstalledRef *ref = g_ptr_array_index(updates,i); - g_print ("%d %s %s %s %s %s %s %s %d\n", + g_print ("%d %s %s %s %s %s %s %s %d %"G_GUINT64_FORMAT"\n", xdg_app_ref_get_kind (XDG_APP_REF(ref)), xdg_app_ref_get_name (XDG_APP_REF(ref)), xdg_app_ref_get_arch (XDG_APP_REF(ref)), @@ -113,7 +113,8 @@ main (int argc, char *argv[]) xdg_app_installed_ref_get_latest_commit (ref), xdg_app_installed_ref_get_origin (ref), xdg_app_installed_ref_get_deploy_dir (ref), - xdg_app_installed_ref_get_is_current (ref)); + xdg_app_installed_ref_get_is_current (ref), + xdg_app_installed_ref_get_installed_size (ref)); } } } @@ -128,7 +129,7 @@ main (int argc, char *argv[]) for (i = 0; i < refs->len; i++) { XdgAppInstalledRef *ref = g_ptr_array_index(refs,i); - g_print ("%d %s %s %s %s %s %s %s %d\n", + g_print ("%d %s %s %s %s %s %s %s %d %"G_GUINT64_FORMAT"\n", xdg_app_ref_get_kind (XDG_APP_REF(ref)), xdg_app_ref_get_name (XDG_APP_REF(ref)), xdg_app_ref_get_arch (XDG_APP_REF(ref)), @@ -137,7 +138,8 @@ main (int argc, char *argv[]) xdg_app_installed_ref_get_latest_commit (ref), xdg_app_installed_ref_get_origin (ref), xdg_app_installed_ref_get_deploy_dir (ref), - xdg_app_installed_ref_get_is_current (ref)); + xdg_app_installed_ref_get_is_current (ref), + xdg_app_installed_ref_get_installed_size (ref)); } } @@ -153,7 +155,7 @@ main (int argc, char *argv[]) { XdgAppInstalledRef *app = g_ptr_array_index(apps,i); - g_print ("%d %s %s %s %s %s %s %s %d\n", + g_print ("%d %s %s %s %s %s %s %s %d %"G_GUINT64_FORMAT"\n", xdg_app_ref_get_kind (XDG_APP_REF(app)), xdg_app_ref_get_name (XDG_APP_REF(app)), xdg_app_ref_get_arch (XDG_APP_REF(app)), @@ -162,7 +164,8 @@ main (int argc, char *argv[]) xdg_app_installed_ref_get_latest_commit (app), xdg_app_installed_ref_get_origin (app), xdg_app_installed_ref_get_deploy_dir (app), - xdg_app_installed_ref_get_is_current (app)); + xdg_app_installed_ref_get_is_current (app), + xdg_app_installed_ref_get_installed_size (app)); g_print ("metadata:\n%s\n", xdg_app_installed_ref_load_metadata (app, NULL, NULL)); } } diff --git a/lib/xdg-app-installation.c b/lib/xdg-app-installation.c index 72d57247..67134a7f 100644 --- a/lib/xdg-app-installation.c +++ b/lib/xdg-app-installation.c @@ -216,6 +216,7 @@ get_ref (XdgAppInstallation *self, g_autofree char *deploy_path = NULL; g_autofree char *latest_commit = NULL; gboolean is_current = FALSE; + guint64 installed_size = 0; parts = g_strsplit (full_ref, "/", -1); @@ -238,11 +239,18 @@ get_ref (XdgAppInstallation *self, latest_commit = xdg_app_dir_read_latest (priv->dir, origin, full_ref, NULL, NULL); + if (!xdg_app_dir_get_installed_size (priv->dir, + commit, &installed_size, + cancellable, + NULL)) + installed_size = 0; + return xdg_app_installed_ref_new (full_ref, commit, latest_commit, origin, deploy_path, + installed_size, is_current); } diff --git a/lib/xdg-app-installed-ref-private.h b/lib/xdg-app-installed-ref-private.h index fb5ca516..691f4901 100644 --- a/lib/xdg-app-installed-ref-private.h +++ b/lib/xdg-app-installed-ref-private.h @@ -33,6 +33,7 @@ XdgAppInstalledRef *xdg_app_installed_ref_new (const char *full_ref, const char *latest_commit, const char *origin, const char *deploy_dir, - gboolean current); + guint64 installed_size, + gboolean current); #endif /* __XDG_APP_INSTALLED_REF_PRIVATE_H__ */ diff --git a/lib/xdg-app-installed-ref.c b/lib/xdg-app-installed-ref.c index 14bf3943..98931945 100644 --- a/lib/xdg-app-installed-ref.c +++ b/lib/xdg-app-installed-ref.c @@ -34,6 +34,7 @@ struct _XdgAppInstalledRefPrivate char *origin; char *latest_commit; char *deploy_dir; + guint64 installed_size; }; G_DEFINE_TYPE_WITH_PRIVATE (XdgAppInstalledRef, xdg_app_installed_ref, XDG_APP_TYPE_REF) @@ -44,7 +45,8 @@ enum { PROP_IS_CURRENT, PROP_ORIGIN, PROP_LATEST_COMMIT, - PROP_DEPLOY_DIR + PROP_DEPLOY_DIR, + PROP_INSTALLED_SIZE }; static void @@ -74,6 +76,10 @@ xdg_app_installed_ref_set_property (GObject *object, priv->is_current = g_value_get_boolean (value); break; + case PROP_INSTALLED_SIZE: + priv->installed_size = g_value_get_uint64 (value); + break; + case PROP_ORIGIN: g_clear_pointer (&priv->origin, g_free); priv->origin = g_value_dup_string (value); @@ -110,6 +116,10 @@ xdg_app_installed_ref_get_property (GObject *object, g_value_set_boolean (value, priv->is_current); break; + case PROP_INSTALLED_SIZE: + g_value_set_uint64 (value, priv->installed_size); + break; + case PROP_ORIGIN: g_value_set_string (value, priv->origin); break; @@ -144,6 +154,13 @@ xdg_app_installed_ref_class_init (XdgAppInstalledRefClass *klass) "", FALSE, G_PARAM_READWRITE)); + g_object_class_install_property (object_class, + PROP_INSTALLED_SIZE, + g_param_spec_uint64 ("installed-size", + "", + "", + 0, G_MAXUINT64, 0, + G_PARAM_READWRITE)); g_object_class_install_property (object_class, PROP_ORIGIN, g_param_spec_string ("origin", @@ -204,6 +221,14 @@ xdg_app_installed_ref_get_is_current (XdgAppInstalledRef *self) return priv->is_current; } +guint64 +xdg_app_installed_ref_get_installed_size (XdgAppInstalledRef *self) +{ + XdgAppInstalledRefPrivate *priv = xdg_app_installed_ref_get_instance_private (self); + + return priv->installed_size; +} + char * xdg_app_installed_ref_load_metadata (XdgAppInstalledRef *self, GCancellable *cancellable, @@ -233,7 +258,8 @@ xdg_app_installed_ref_new (const char *full_ref, const char *latest_commit, const char *origin, const char *deploy_dir, - gboolean is_current) + guint64 installed_size, + gboolean is_current) { XdgAppRefKind kind = XDG_APP_REF_KIND_APP; XdgAppInstalledRef *ref; @@ -253,6 +279,7 @@ xdg_app_installed_ref_new (const char *full_ref, "latest-commit", latest_commit, "origin", origin, "is-current", is_current, + "installed-size", installed_size, "deploy-dir", deploy_dir, NULL); diff --git a/lib/xdg-app-installed-ref.h b/lib/xdg-app-installed-ref.h index d97e0f44..94dbbab8 100644 --- a/lib/xdg-app-installed-ref.h +++ b/lib/xdg-app-installed-ref.h @@ -48,12 +48,13 @@ typedef struct { G_DEFINE_AUTOPTR_CLEANUP_FUNC(XdgAppInstalledRef, g_object_unref) #endif -XDG_APP_EXTERN const char *xdg_app_installed_ref_get_origin (XdgAppInstalledRef *self); -XDG_APP_EXTERN const char *xdg_app_installed_ref_get_deploy_dir (XdgAppInstalledRef *self); -XDG_APP_EXTERN const char *xdg_app_installed_ref_get_latest_commit (XdgAppInstalledRef *self); -XDG_APP_EXTERN gboolean xdg_app_installed_ref_get_is_current (XdgAppInstalledRef *self); -XDG_APP_EXTERN char *xdg_app_installed_ref_load_metadata (XdgAppInstalledRef *self, - GCancellable *cancellable, - GError **error); +XDG_APP_EXTERN const char *xdg_app_installed_ref_get_origin (XdgAppInstalledRef *self); +XDG_APP_EXTERN guint64 xdg_app_installed_ref_get_installed_size (XdgAppInstalledRef *self); +XDG_APP_EXTERN const char *xdg_app_installed_ref_get_deploy_dir (XdgAppInstalledRef *self); +XDG_APP_EXTERN const char *xdg_app_installed_ref_get_latest_commit (XdgAppInstalledRef *self); +XDG_APP_EXTERN gboolean xdg_app_installed_ref_get_is_current (XdgAppInstalledRef *self); +XDG_APP_EXTERN char *xdg_app_installed_ref_load_metadata (XdgAppInstalledRef *self, + GCancellable *cancellable, + GError **error); #endif /* __XDG_APP_INSTALLED_REF_H__ */