From c538509a2a28db0ddac6fe87026da1d02a546343 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20Ter=C3=A4s?= Date: Mon, 28 Sep 2020 17:34:01 +0300 Subject: [PATCH] Implement upgrade --prune to remove stale world dependencies --- doc/apk-upgrade.8.scd | 4 ++++ src/app_upgrade.c | 32 ++++++++++++++++++++++++++------ test/upgrade4.repo | 26 ++++++++++++++++++++++++++ test/upgrade4.test | 12 ++++++++++++ 4 files changed, 68 insertions(+), 6 deletions(-) create mode 100644 test/upgrade4.repo create mode 100644 test/upgrade4.test diff --git a/doc/apk-upgrade.8.scd b/doc/apk-upgrade.8.scd index a7c77f4..bc12d98 100644 --- a/doc/apk-upgrade.8.scd +++ b/doc/apk-upgrade.8.scd @@ -42,6 +42,10 @@ following options: *--no-self-upgrade* Do not do an early upgrade of the 'apk-tools' package. +*--prune* + Prune the _world_ by removing packages which are no longer available + from any configured repository. + *--self-upgrade-only* Only perform a self-upgrade of the 'apk-tools' package. diff --git a/src/app_upgrade.c b/src/app_upgrade.c index b9c50d5..8645d21 100644 --- a/src/app_upgrade.c +++ b/src/app_upgrade.c @@ -21,6 +21,7 @@ struct upgrade_ctx { int no_self_upgrade : 1; int self_upgrade_only : 1; int ignore : 1; + int prune : 1; int errors; }; @@ -29,6 +30,7 @@ struct upgrade_ctx { OPT(OPT_UPGRADE_ignore, "ignore") \ OPT(OPT_UPGRADE_latest, APK_OPT_SH("l") "latest") \ OPT(OPT_UPGRADE_no_self_upgrade, "no-self-upgrade") \ + OPT(OPT_UPGRADE_prune, "prune") \ OPT(OPT_UPGRADE_self_upgrade_only, "self-upgrade-only") APK_OPT_APPLET(option_desc, UPGRADE_OPTIONS); @@ -47,6 +49,9 @@ static int option_parse_applet(void *ctx, struct apk_db_options *dbopts, int opt case OPT_UPGRADE_ignore: uctx->ignore = 1; break; + case OPT_UPGRADE_prune: + uctx->prune = 1; + break; case OPT_UPGRADE_available: uctx->solver_flags |= APK_SOLVERF_AVAILABLE; break; @@ -149,6 +154,7 @@ static int upgrade_main(void *ctx, struct apk_database *db, struct apk_string_ar struct upgrade_ctx *uctx = (struct upgrade_ctx *) ctx; unsigned short solver_flags; struct apk_dependency *dep; + struct apk_provider *p; struct apk_dependency_array *world = NULL; int r = 0; @@ -167,14 +173,28 @@ static int upgrade_main(void *ctx, struct apk_database *db, struct apk_string_ar if (uctx->self_upgrade_only) return 0; - if (solver_flags & APK_SOLVERF_AVAILABLE) { + if (uctx->prune || (solver_flags & APK_SOLVERF_AVAILABLE)) { apk_dependency_array_copy(&world, db->world); - foreach_array_item(dep, world) { - if (dep->result_mask == APK_DEPMASK_CHECKSUM) { - dep->result_mask = APK_DEPMASK_ANY; - dep->version = &apk_atom_null; + if (solver_flags & APK_SOLVERF_AVAILABLE) { + foreach_array_item(dep, world) { + if (dep->result_mask == APK_DEPMASK_CHECKSUM) { + dep->result_mask = APK_DEPMASK_ANY; + dep->version = &apk_atom_null; + } } } + if (uctx->prune) { + int i, j; + for (i = j = 0; i < world->num; i++) { + foreach_array_item(p, world->item[i].name->providers) { + if (p->pkg->repos & ~APK_REPOSITORY_CACHED) { + world->item[j++] = world->item[i]; + break; + } + } + } + apk_dependency_array_resize(&world, j); + } } else { world = db->world; } @@ -188,7 +208,7 @@ static int upgrade_main(void *ctx, struct apk_database *db, struct apk_string_ar r = apk_solver_commit(db, solver_flags, world); - if (solver_flags & APK_SOLVERF_AVAILABLE) + if (world != db->world) apk_dependency_array_free(&world); return r; diff --git a/test/upgrade4.repo b/test/upgrade4.repo new file mode 100644 index 0000000..cc3a84e --- /dev/null +++ b/test/upgrade4.repo @@ -0,0 +1,26 @@ +C:Q1EyN5AdpAOBJWKMR89pp/C66o+OE= +P:libold +V:1 +S:1 +I:1 + +C:Q1EyN5AdpAOBJWKMR89pp/C66o+FE= +P:libnew +V:1 +S:1 +I:1 +D:!libold + +C:Q1eVpkasfqZAukAXFYbgwt4xAEEEe= +P:app +V:1 +S:1 +I:1 +D:libold + +C:Q1EyN5AdpAOBJWKMR89pp/C77FFFF= +P:app +V:2 +S:1 +I:1 +D:libnew diff --git a/test/upgrade4.test b/test/upgrade4.test new file mode 100644 index 0000000..dcffe28 --- /dev/null +++ b/test/upgrade4.test @@ -0,0 +1,12 @@ +@ARGS +--test-repo upgrade4.repo +--test-instdb upgrade3.installed +--test-world "app b" +--prune +upgrade +@EXPECT +(1/4) Purging b (1) +(2/4) Purging libold (1) +(3/4) Installing libnew (1) +(4/4) Upgrading app (1 -> 2) +OK: 0 MiB in 3 packages