]> git.ipfire.org Git - pakfire.git/commitdiff
transaction: Add a unified progress meter
authorMichael Tremer <michael.tremer@ipfire.org>
Sat, 15 Mar 2025 11:09:08 +0000 (11:09 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Sat, 15 Mar 2025 11:09:08 +0000 (11:09 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/pakfire/transaction.c

index d71270edde864f1459ddf14d9414eab245d6ce82..68d7168c7f4ed5601a8c50d6324364c11acda728 100644 (file)
@@ -39,6 +39,7 @@
 #include <pakfire/package.h>
 #include <pakfire/pakfire.h>
 #include <pakfire/path.h>
+#include <pakfire/progress.h>
 #include <pakfire/repo.h>
 #include <pakfire/string.h>
 #include <pakfire/transaction.h>
@@ -64,7 +65,9 @@ struct pakfire_transaction {
        struct pakfire_archive** archives;
        struct pakfire_package** packages;
        size_t num;
-       size_t progress;
+
+       // Progress
+       struct pakfire_progress* progress;
 
        // Callbacks
        struct pakfire_transaction_callbacks {
@@ -376,6 +379,11 @@ int pakfire_transaction_create(struct pakfire_transaction** transaction,
        // Allocate a job queue
        queue_init(&t->jobs);
 
+       // Create a progress indicator
+       r = pakfire_progress_create(&t->progress, t->ctx, PAKFIRE_PROGRESS_SHOW_PERCENTAGE, NULL);
+       if (r < 0)
+               goto ERROR;
+
        // Set the default status callback
        t->callbacks.status = pakfire_transaction_default_status_callback;
 
@@ -412,6 +420,8 @@ static void pakfire_transaction_free(struct pakfire_transaction* transaction) {
                pakfire_packagelist_unref(transaction->new_packages);
        if (transaction->userinstalled)
                pakfire_strings_free(transaction->userinstalled);
+       if (transaction->progress)
+               pakfire_progress_unref(transaction->progress);
        if (transaction->transaction)
                transaction_free(transaction->transaction);
        if (transaction->solver)
@@ -440,13 +450,12 @@ struct pakfire_transaction* pakfire_transaction_unref(
        return NULL;
 }
 
-static int pakfire_transaction_get_progress(struct pakfire_transaction* transaction) {
-       return transaction->progress * 100 / transaction->num;
-}
-
 static void pakfire_transaction_status(struct pakfire_transaction* transaction,
        const char* message, ...) __attribute__((format(printf, 2, 3)));
 
+/*
+       Move this into the progress stuff
+*/
 static void pakfire_transaction_status(struct pakfire_transaction* transaction,
                const char* message, ...) {
        char* buffer = NULL;
@@ -468,7 +477,7 @@ static void pakfire_transaction_status(struct pakfire_transaction* transaction,
        }
 
        // Fetch progress
-       const int progress = pakfire_transaction_get_progress(transaction);
+       const int progress = pakfire_progress_get_percentage(transaction->progress);
 
        // Call the callback
        transaction->callbacks.status(transaction->pakfire,
@@ -1376,7 +1385,7 @@ static int pakfire_transaction_extract(struct pakfire_transaction* transaction,
        pakfire_transaction_status(transaction, _("Installing %s..."), nevra);
 
        // Extract payload
-       r = pakfire_archive_extract(archive, NULL, 0);
+       r = pakfire_archive_extract(archive, NULL, 0, transaction->progress);
        if (r) {
                ERROR(transaction->ctx, "Could not extract package %s: %m\n",
                        nevra);
@@ -1592,7 +1601,7 @@ static int pakfire_transaction_run_step(struct pakfire_transaction* transaction,
                // Execute the action of this script
                case PAKFIRE_ACTION_EXECUTE:
                        // Increment progress
-                       transaction->progress++;
+                       pakfire_progress_increment(transaction->progress, 1);
 
                        // Update progress callback
                        pakfire_transaction_status(transaction, NULL);
@@ -1750,7 +1759,9 @@ static int pakfire_transaction_run_steps(struct pakfire_transaction* transaction
        return r;
 }
 
-static int pakfire_transaction_open_archives(struct pakfire_transaction* transaction) {
+static int pakfire_transaction_open_archives(
+               struct pakfire_transaction* transaction, size_t* total_size) {
+       struct pakfire_archive* archive = NULL;
        int r;
 
        for (unsigned int i = 0; i < transaction->num; i++) {
@@ -1776,9 +1787,16 @@ static int pakfire_transaction_open_archives(struct pakfire_transaction* transac
                }
 
                // Open the archive
-               r = pakfire_package_get_archive(pkg, &transaction->archives[i]);
+               r = pakfire_package_get_archive(pkg, &archive);
                if (r < 0)
                        return r;
+
+               // Reference the archive
+               transaction->archives[i] = archive;
+
+               // Count the total size if requested
+               if (total_size)
+                       *total_size += pakfire_archive_get_size(archive);
        }
 
        return 0;
@@ -1851,15 +1869,26 @@ static int pakfire_usrmove(struct pakfire_ctx* ctx, struct pakfire* pakfire) {
 static int pakfire_transaction_perform(struct pakfire_transaction* transaction) {
        struct pakfire_repo* repo = NULL;
        struct pakfire_db* db;
+       size_t total_size = 0;
        int r;
 
        DEBUG(transaction->ctx, "Running Transaction %p\n", transaction);
 
        // Open all archives
-       r = pakfire_transaction_open_archives(transaction);
+       r = pakfire_transaction_open_archives(transaction, &total_size);
        if (r)
                return r;
 
+       // Set the title
+       r = pakfire_progress_set_title(transaction->progress, "%s", _("Installing Packages..."));
+       if (r < 0)
+               return r;
+
+       // Start the progress...
+       r = pakfire_progress_start(transaction->progress, total_size);
+       if (r < 0)
+               return r;
+
        // Open the database
        r = pakfire_db_open(&db, transaction->pakfire, PAKFIRE_DB_READWRITE);
        if (r) {
@@ -1891,6 +1920,11 @@ static int pakfire_transaction_perform(struct pakfire_transaction* transaction)
        if (r)
                goto ERROR;
 
+       // Finish progress
+       r = pakfire_progress_finish(transaction->progress);
+       if (r < 0)
+               goto ERROR;
+
        DEBUG(transaction->ctx, "The transaction has finished successfully\n");
 
        // Reload database for next transaction
@@ -2081,7 +2115,7 @@ int pakfire_transaction_compose_repo(struct pakfire_transaction* transaction,
        DEBUG(transaction->ctx, "Writing transaction to %s...\n", path);
 
        // Open all archives
-       r = pakfire_transaction_open_archives(transaction);
+       r = pakfire_transaction_open_archives(transaction, NULL);
        if (r)
                return r;