From 16e0f6df7f0d632976d788fb3829280a39dabfaf Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timo=20Ter=C3=A4s?= <timo.teras@iki.fi>
Date: Mon, 15 Nov 2021 13:35:59 +0200
Subject: [PATCH] fix fetching of depdencies only packages

Remove the APK_REPOSITORY_CACHED bit from dependencies only
packages (that is, installed_size == 0). For fetch, the problem
is that apk_db_select_repo() would return the cache repository,
but the package would not be there. Update also the locations
needed to handle these packages correctly without the cached
repository bit being set.
---
 src/app_add.c   |  1 +
 src/app_cache.c |  2 +-
 src/commit.c    |  2 +-
 src/database.c  | 23 +++++++++--------------
 4 files changed, 12 insertions(+), 16 deletions(-)

diff --git a/src/app_add.c b/src/app_add.c
index 614dfb47..d12d2a37 100644
--- a/src/app_add.c
+++ b/src/app_add.c
@@ -101,6 +101,7 @@ static struct apk_package *create_virtual_package(struct apk_database *db, struc
 	virtpkg->version = apk_atomize_dup(&db->atoms, APK_BLOB_STR(ver));
 	virtpkg->description = strdup("virtual meta package");
 	virtpkg->arch = apk_atomize(&db->atoms, APK_BLOB_STR("noarch"));
+	virtpkg->repos |= BIT(APK_REPOSITORY_CACHED);
 
 	apk_digest_ctx_init(&dctx, APK_DIGEST_SHA1);
 	apk_digest_ctx_update(&dctx, &tm, sizeof tm);
diff --git a/src/app_cache.c b/src/app_cache.c
index b744f250..95eae7a9 100644
--- a/src/app_cache.c
+++ b/src/app_cache.c
@@ -91,7 +91,7 @@ static int cache_download(struct cache_ctx *cctx, struct apk_database *db)
 
 	foreach_array_item(change, changeset.changes) {
 		pkg = change->new_pkg;
-		if ((pkg == NULL) || (pkg->repos & db->local_repos))
+		if (!pkg || (pkg->repos & db->local_repos) || !pkg->installed_size)
 			continue;
 
 		repo = apk_db_select_repo(db, pkg);
diff --git a/src/commit.c b/src/commit.c
index d53ae8ad..08c24804 100644
--- a/src/commit.c
+++ b/src/commit.c
@@ -425,7 +425,7 @@ static void print_pinning_errors(struct print_state *ps, struct apk_package *pkg
 	if (!(pkg->repos & db->available_repos)) {
 		label_start(ps, "masked in:");
 		apk_print_indented_fmt(&ps->i, "--no-network");
-	} else if (pkg->repos == BIT(APK_REPOSITORY_CACHED) && !(pkg->filename != NULL || pkg->installed_size == 0)) {
+	} else if (pkg->repos == BIT(APK_REPOSITORY_CACHED) && !pkg->filename) {
 		label_start(ps, "masked in:");
 		apk_print_indented_fmt(&ps->i, "cache");
 	} else {
diff --git a/src/database.c b/src/database.c
index 4f0722bc..535df5ee 100644
--- a/src/database.c
+++ b/src/database.c
@@ -533,10 +533,8 @@ struct apk_package *apk_db_pkg_add(struct apk_database *db, struct apk_package *
 
 	if (!pkg->license) pkg->license = &apk_atom_null;
 
-	/* Set as "cached" if installing from specified file, and
-	 * for virtual packages */
-	if (pkg->filename != NULL || pkg->installed_size == 0)
-		pkg->repos |= BIT(APK_REPOSITORY_CACHED);
+	// Set as "cached" if installing from specified file
+	if (pkg->filename) pkg->repos |= BIT(APK_REPOSITORY_CACHED);
 
 	idb = apk_hash_get(&db->available.packages, APK_BLOB_CSUM(pkg->csum));
 	if (idb == NULL) {
@@ -1227,8 +1225,7 @@ static int apk_db_index_write_nr_cache(struct apk_database *db)
 	struct apk_ostream *os;
 	int r;
 
-	if (!apk_db_cache_active(db))
-		return 0;
+	if (!apk_db_cache_active(db)) return 0;
 
 	/* Write list of installed non-repository packages to
 	 * cached index file */
@@ -1238,16 +1235,14 @@ static int apk_db_index_write_nr_cache(struct apk_database *db)
 	ctx.os = os;
 	list_for_each_entry(ipkg, &db->installed.packages, installed_pkgs_list) {
 		struct apk_package *pkg = ipkg->pkg;
-		if (pkg->repos != BIT(APK_REPOSITORY_CACHED))
-			continue;
-		r = write_index_entry(pkg, &ctx);
-		if (r != 0)
-			return r;
+		if ((pkg->repos == BIT(APK_REPOSITORY_CACHED) ||
+		     (pkg->repos == 0 && !pkg->installed_size))) {
+			r = write_index_entry(pkg, &ctx);
+			if (r != 0) return r;
+		}
 	}
 	r = apk_ostream_close(os);
-	if (r < 0)
-		return r;
-
+	if (r < 0) return r;
 	return ctx.count;
 }
 
-- 
GitLab