From: Michael Tremer Date: Thu, 30 Jan 2025 20:51:06 +0000 (+0000) Subject: repo: Automatically sync local repositories with their index X-Git-Tag: 0.9.30~239 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9c872a85567a8c1dd7a1e80734da81cb2d0e5dcf;p=pakfire.git repo: Automatically sync local repositories with their index Signed-off-by: Michael Tremer --- diff --git a/src/pakfire/repo.c b/src/pakfire/repo.c index e3c86ea5..31c8a651 100644 --- a/src/pakfire/repo.c +++ b/src/pakfire/repo.c @@ -1668,10 +1668,15 @@ struct pakfire_repo_scan_ctx { struct pakfire_progress* progress; // Flags - int flags; + enum pakfire_repo_scan_flags { + PAKFIRE_REPO_SCAN_SKIP_EXISTING = (1 << 0), + } flags; // Counter unsigned int num_archives; + + // Packages + struct pakfire_packagelist* packages; }; typedef int (*pakfire_repo_scan_callback)( @@ -1738,7 +1743,14 @@ static int __pakfire_repo_scan_archive(struct pakfire_repo* repo, struct pakfire_repo_scan_ctx* scan_ctx, FTSENT* entry) { struct pakfire_archive* archive = NULL; struct pakfire_package* package = NULL; - int r; + int r = 0; + + // Skip this package if it already exists + if (scan_ctx->flags & PAKFIRE_REPO_SCAN_SKIP_EXISTING) { + if (pakfire_packagelist_has_path(scan_ctx->packages, entry->fts_path)) { + goto DONE; + } + } // Open archive r = pakfire_archive_open(&archive, repo->pakfire, entry->fts_path); @@ -1746,10 +1758,11 @@ static int __pakfire_repo_scan_archive(struct pakfire_repo* repo, goto ERROR; // Import package into the repository - r = pakfire_archive_make_package(archive, repo, &package); + r = pakfire_repo_import_archive(repo, archive, &package); if (r < 0) goto ERROR; +DONE: // Increment progress bar pakfire_progress_increment(scan_ctx->progress, 1); @@ -1789,6 +1802,13 @@ int pakfire_repo_scan(struct pakfire_repo* repo, int flags) { if (r) goto ERROR; + // Load all existing packages + if (scan_ctx.flags & PAKFIRE_REPO_SCAN_SKIP_EXISTING) { + r = pakfire_repo_to_packagelist(repo, &scan_ctx.packages); + if (r < 0) + goto ERROR; + } + // Start progress (so that we will let the user know something is happening if // scanning for files takes a little bit longer...) r = pakfire_progress_start(scan_ctx.progress, 0); @@ -1820,12 +1840,56 @@ int pakfire_repo_scan(struct pakfire_repo* repo, int flags) { r = 0; ERROR: + if (scan_ctx.packages) + pakfire_packagelist_unref(scan_ctx.packages); if (scan_ctx.progress) pakfire_progress_unref(scan_ctx.progress); return r; } +static int pakfire_repo_sync_remove(struct pakfire_ctx* ctx, struct pakfire_package* pkg, void* data) { + int r; + + // Check if the package is available + r = pakfire_package_is_available(pkg); + switch (r) { + // The package is not available + case 0: + // Destroy the package + return pakfire_package_destroy(pkg); + + // The package is available + case 1: + return 0; + + // Error + default: + return r; + } + + return 0; +} + +static int pakfire_repo_sync(struct pakfire_repo* self) { + int r; + + // Log action + DEBUG(self->ctx, "Syncing %s...\n", pakfire_repo_get_name(self)); + + // Remove all packages that have disappeared + r = pakfire_repo_walk_packages(self, pakfire_repo_sync_remove, NULL, 0); + if (r < 0) + return r; + + // We need to find all new packages + r = pakfire_repo_scan(self, PAKFIRE_REPO_SCAN_SKIP_EXISTING); + if (r < 0) + return r; + + return 0; +} + int pakfire_repo_refresh(struct pakfire_repo* repo, int force) { const char* name = pakfire_repo_get_name(repo); int r; @@ -1852,7 +1916,18 @@ int pakfire_repo_refresh(struct pakfire_repo* repo, int force) { } // Refresh metadata - return pakfire_repo_refresh_metadata(repo, force); + r = pakfire_repo_refresh_metadata(repo, force); + if (r < 0) + return r; + + // Perform a sync for all local repositories + if (pakfire_repo_is_local(repo)) { + r = pakfire_repo_sync(repo); + if (r < 0) + return r; + } + + return 0; } static int pakfire_repo_sign_database(struct pakfire_repo* repo, struct pakfire_key* key,