From: Michael Schroeder Date: Mon, 13 Mar 2017 14:58:05 +0000 (+0100) Subject: Deal with installed packages with both "forcebest" and "allowuninstall" X-Git-Tag: 0.6.27~12 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=22623468dcdfeeaafeec3bd6789dfaf739eb7664;p=thirdparty%2Flibsolv.git Deal with installed packages with both "forcebest" and "allowuninstall" In this case we're using negative best rules to turn off all packages that are not in the best set. This allows allowuninstall to do its job. (We're not always using negative rules to save rule space. Maywe we need to revisit this in the future.) --- diff --git a/src/rules.c b/src/rules.c index 33f5350a..3413c496 100644 --- a/src/rules.c +++ b/src/rules.c @@ -3485,6 +3485,12 @@ solver_addbestrules(Solver *solv, int havebestinstalljobs) if (solv->bestupdatemap_all || solv->bestupdatemap.size) { + Map m; + + if (solv->allowuninstall || solv->allowuninstall_all || solv->allowuninstallmap.size) + map_init(&m, pool->nsolvables); + else + map_init(&m, 0); FOR_REPO_SOLVABLES(installed, p, s) { Id d, p2, pp2; @@ -3543,6 +3549,25 @@ solver_addbestrules(Solver *solv, int havebestinstalljobs) queue_pushunique(&q, q2.elements[j]); } } + if (solv->allowuninstall || solv->allowuninstall_all || (solv->allowuninstallmap.size && MAPTST(&solv->allowuninstallmap, p - installed->start))) + { + /* package is flagged both for allowuninstall and best, add negative rules */ + for (i = 0; i < q.count; i++) + MAPSET(&m, q.elements[i]); + r = solv->rules + solv->featurerules + (p - installed->start); + if (!r->p) /* identical to update rule? */ + r = solv->rules + solv->updaterules + (p - installed->start); + FOR_RULELITERALS(p2, pp2, r) + { + if (MAPTST(&m, p2)) + continue; + solver_addrule(solv, -p2, 0, 0); + queue_push(&r2pkg, p); + } + for (i = 0; i < q.count; i++) + MAPCLR(&m, q.elements[i]); + continue; + } p2 = queue_shift(&q); if (q.count < 2) solver_addrule(solv, p2, q.count ? q.elements[0] : 0, 0); @@ -3550,6 +3575,7 @@ solver_addbestrules(Solver *solv, int havebestinstalljobs) solver_addrule(solv, p2, 0, pool_queuetowhatprovides(pool, &q)); queue_push(&r2pkg, p); } + map_free(&m); } if (r2pkg.count) solv->bestrules_pkg = solv_memdup2(r2pkg.elements, r2pkg.count, sizeof(Id));