From: Michael Schroeder Date: Fri, 15 Oct 2021 09:03:12 +0000 (+0200) Subject: Finish strict repo priority support X-Git-Tag: 0.7.21~22 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e79734abf6042a2a683c3d46ec0d7ecdb2b36be6;p=thirdparty%2Flibsolv.git Finish strict repo priority support - add flag to bindings - support flag/ruletype in testcases - support strict repo prio problems in solution generation - implement automatic disabling of strict repo rules due to install jobs - add a testcase --- diff --git a/bindings/solv.i b/bindings/solv.i index 61c6fc82..3a6bac46 100644 --- a/bindings/solv.i +++ b/bindings/solv.i @@ -3571,6 +3571,7 @@ returnself(matchsolvable) static const int SOLVER_FLAG_STRONG_RECOMMENDS = SOLVER_FLAG_STRONG_RECOMMENDS; static const int SOLVER_FLAG_INSTALL_ALSO_UPDATES = SOLVER_FLAG_INSTALL_ALSO_UPDATES; static const int SOLVER_FLAG_ONLY_NAMESPACE_RECOMMENDED = SOLVER_FLAG_ONLY_NAMESPACE_RECOMMENDED; + static const int SOLVER_FLAG_STRICT_REPO_PRIORITY = SOLVER_FLAG_STRICT_REPO_PRIORITY; static const int SOLVER_REASON_UNRELATED = SOLVER_REASON_UNRELATED; static const int SOLVER_REASON_UNIT_RULE = SOLVER_REASON_UNIT_RULE; diff --git a/ext/testcase.c b/ext/testcase.c index e3b245c8..7a9e7859 100644 --- a/ext/testcase.c +++ b/ext/testcase.c @@ -135,6 +135,7 @@ static struct solverflags2str { { SOLVER_FLAG_STRONG_RECOMMENDS, "strongrecommends", 0 }, { SOLVER_FLAG_INSTALL_ALSO_UPDATES, "installalsoupdates", 0 }, { SOLVER_FLAG_ONLY_NAMESPACE_RECOMMENDED, "onlynamespacerecommended", 0 }, + { SOLVER_FLAG_STRICT_REPO_PRIORITY, "strictrepopriority", 0 }, { 0, 0, 0 } }; @@ -1194,6 +1195,7 @@ static struct rclass2str { { SOLVER_RULE_YUMOBS, "yumobs" }, { SOLVER_RULE_BLACK, "black" }, { SOLVER_RULE_RECOMMENDS, "recommends" }, + { SOLVER_RULE_STRICT_REPO_PRIORITY, "strictrepoprio" }, { 0, 0 } }; diff --git a/src/problems.c b/src/problems.c index a4960ef4..558eb206 100644 --- a/src/problems.c +++ b/src/problems.c @@ -725,6 +725,12 @@ convertsolution(Solver *solv, Id why, Queue *solutionq) assert(solv->rules[why].p < 0); queue_push(solutionq, -solv->rules[why].p); } + if (why >= solv->strictrepopriorules && why < solv->strictrepopriorules_end) + { + queue_push(solutionq, SOLVER_SOLUTION_STRICTREPOPRIORITY); + assert(solv->rules[why].p < 0); + queue_push(solutionq, -solv->rules[why].p); + } } /* @@ -1360,7 +1366,7 @@ solver_problemruleinfo2str(Solver *solv, SolverRuleinfo type, Id source, Id targ case SOLVER_RULE_BLACK: return pool_tmpjoin(pool, "package ", pool_solvid2str(pool, source), " can only be installed by a direct request"); case SOLVER_RULE_STRICT_REPO_PRIORITY: - return pool_tmpjoin(pool, "package '", pool_solvid2str(pool, source), "' is excluded by strict repo priority"); + return pool_tmpjoin(pool, "package ", pool_solvid2str(pool, source), " is excluded by strict repo priority"); case SOLVER_RULE_PKG_CONSTRAINS: s = pool_tmpjoin(pool, "package ", pool_solvid2str(pool, source), 0); s = pool_tmpappend(pool, s, " has constraint ", pool_dep2str(pool, dep)); @@ -1426,6 +1432,11 @@ solver_solutionelement2str(Solver *solv, Id p, Id rp) } else if (p > 0 && rp == 0) return pool_tmpjoin(pool, "allow deinstallation of ", pool_solvid2str(pool, p), 0); + else if (p == SOLVER_SOLUTION_STRICTREPOPRIORITY) + { + Solvable *s = pool->solvables + rp; + return pool_tmpjoin(pool, "install ", pool_solvable2str(pool, s), " despite the repo priority"); + } else if (p > 0 && rp > 0) { const char *sp = pool_solvid2str(pool, p); diff --git a/src/problems.h b/src/problems.h index 45e4e7c6..f9b1efc3 100644 --- a/src/problems.h +++ b/src/problems.h @@ -28,6 +28,7 @@ struct s_Solver; #define SOLVER_SOLUTION_BEST (-3) #define SOLVER_SOLUTION_POOLJOB (-4) #define SOLVER_SOLUTION_BLACK (-5) +#define SOLVER_SOLUTION_STRICTREPOPRIORITY (-6) void solver_recordproblem(struct s_Solver *solv, Id rid); void solver_fixproblem(struct s_Solver *solv, Id rid); diff --git a/src/rules.c b/src/rules.c index 94a0bb6e..a260c2de 100644 --- a/src/rules.c +++ b/src/rules.c @@ -2255,6 +2255,89 @@ solver_addblackrules(Solver *solv) solv->blackrules_end = solv->nrules; } +/*********************************************************************** + *** + *** Strict repo prio rule part + ***/ + +/* add rules to exclude solvables provided by lower + * precedence repositories */ +void solver_addstrictrepopriorules(struct s_Solver *solv, Map *addedmap) +{ + Pool *pool = solv->pool; + Solvable *s; + Id p, p2, pp2; + Map priomap; + int max_prio; + + map_init_clone(&priomap, addedmap); + solv->strictrepopriorules = solv->nrules; + + FOR_POOL_SOLVABLES(p) + { + if (!MAPTST(&priomap, p)) + continue; + + s = pool->solvables + p; + max_prio = s->repo->priority; + FOR_PROVIDES(p2, pp2, s->name) + { + Solvable *s2 = pool->solvables + p2; + if (s->name != s2->name) + continue; + if (s2->repo->priority > max_prio) + max_prio = s2->repo->priority; + } + + FOR_PROVIDES(p2, pp2, s->name) + { + Solvable *s2 = pool->solvables + p2; + if (s->name != s2->name || !MAPTST(&priomap, p2)) + continue; + MAPCLR(&priomap, p2); + if (pool->installed && s2->repo == pool->installed) + continue; + if (s2->repo->priority < max_prio) + solver_addrule(solv, -p2, 0, 0); + } + } + solv->strictrepopriorules_end = solv->nrules; + map_free(&priomap); +} + +static inline void +disablerepopriorule(Solver *solv, Id name) +{ + Pool *pool = solv->pool; + Rule *r; + int i; + for (i = solv->strictrepopriorules, r = solv->rules + i; i < solv->strictrepopriorules_end; i++, r++) + { + if (r->p < 0 && r->d >= 0 && pool->solvables[-r->p].name == name) + solver_disablerule(solv, r); + } +} + +static inline void +reenablerepopriorule(Solver *solv, Id name) +{ + Pool *pool = solv->pool; + Rule *r; + int i; + for (i = solv->strictrepopriorules, r = solv->rules + i; i < solv->strictrepopriorules_end; i++, r++) + { + if (r->p < 0 && r->d < 0 && pool->solvables[-r->p].name == name) + { + solver_enablerule(solv, r); + IF_POOLDEBUG (SOLV_DEBUG_SOLUTIONS) + { + POOL_DEBUG(SOLV_DEBUG_SOLUTIONS, "@@@ re-enabling "); + solver_printruleclass(solv, SOLV_DEBUG_SOLUTIONS, r); + } + } + } +} + /*********************************************************************** *** *** Policy rule disabling/reenabling @@ -2264,10 +2347,11 @@ solver_addblackrules(Solver *solv) *** ***/ -#define DISABLE_UPDATE 1 -#define DISABLE_INFARCH 2 -#define DISABLE_DUP 3 -#define DISABLE_BLACK 4 +#define DISABLE_UPDATE 1 +#define DISABLE_INFARCH 2 +#define DISABLE_DUP 3 +#define DISABLE_BLACK 4 +#define DISABLE_REPOPRIO 5 static void jobtodisablelist(Solver *solv, Id how, Id what, Queue *q) @@ -2367,6 +2451,26 @@ jobtodisablelist(Solver *solv, Id how, Id what, Queue *q) } } } + if ((set & SOLVER_SETREPO) != 0 && solv->strictrepopriorules != solv->strictrepopriorules_end) + { + if (select == SOLVER_SOLVABLE) + queue_push2(q, DISABLE_REPOPRIO, pool->solvables[what].name); + else + { + int qcnt = q->count; + FOR_JOB_SELECT(p, pp, select, what) + { + s = pool->solvables + p; + /* unify names */ + for (i = qcnt; i < q->count; i += 2) + if (q->elements[i + 1] == s->name) + break; + if (i < q->count) + continue; + queue_push2(q, DISABLE_REPOPRIO, s->name); + } + } + } if ((set & SOLVER_SETEVR) != 0 && solv->blackrules != solv->blackrules_end) { if (select == SOLVER_SOLVABLE) @@ -2553,6 +2657,9 @@ solver_disablepolicyrules(Solver *solv) case DISABLE_BLACK: disableblackrule(solv, arg); break; + case DISABLE_REPOPRIO: + disablerepopriorule(solv, arg); + break; default: break; } @@ -2659,6 +2766,9 @@ solver_reenablepolicyrules(Solver *solv, int jobidx) case DISABLE_BLACK: reenableblackrule(solv, arg); break; + case DISABLE_REPOPRIO: + reenablerepopriorule(solv, arg); + break; } } queue_free(&q); @@ -4141,51 +4251,6 @@ solver_addrecommendsrules(Solver *solv) solv->recommendsrules_end = solv->nrules; } -/* add rules to exclude solvables provided by lower - * precedence repositories */ -void solver_addstrictrepopriorules(struct s_Solver *solv, Map *addedmap) -{ - Pool *pool = solv->pool; - Solvable *s; - Id p, p2, pp2; - Map priomap; - int max_prio; - - map_init_clone(&priomap, addedmap); - solv->strictrepopriorules = solv->nrules; - - FOR_POOL_SOLVABLES(p) - { - if (!MAPTST(&priomap, p)) - continue; - - s = pool->solvables + p; - max_prio = s->repo->priority; - FOR_PROVIDES(p2, pp2, s->name) - { - Solvable *s2 = pool->solvables + p2; - if (s->name != s2->name) - continue; - if (s2->repo->priority > max_prio) - max_prio = s2->repo->priority; - } - - FOR_PROVIDES(p2, pp2, s->name) - { - Solvable *s2 = pool->solvables + p2; - if (s->name != s2->name || !MAPTST(&priomap, p2)) - continue; - MAPCLR(&priomap, p2); - if (pool->installed && s2->repo == pool->installed) - continue; - if (s2->repo->priority < max_prio) - solver_addrule(solv, -p2, 0, 0); - } - } - solv->strictrepopriorules_end = solv->nrules; - map_free(&priomap); -} - void solver_breakorphans(Solver *solv) { diff --git a/src/solverdebug.c b/src/solverdebug.c index 040d9e5d..5902cdb4 100644 --- a/src/solverdebug.c +++ b/src/solverdebug.c @@ -131,7 +131,7 @@ solver_printruleclass(Solver *solv, int type, Rule *r) else if (p >= solv->blackrules && p < solv->blackrules_end) POOL_DEBUG(type, "BLACK "); else if (p >= solv->strictrepopriorules && p < solv->strictrepopriorules_end) - POOL_DEBUG(type, "PRIOS "); + POOL_DEBUG(type, "REPOPRIO "); else if (p >= solv->recommendsrules && p < solv->recommendsrules_end) POOL_DEBUG(type, "RECOMMENDS "); solver_printrule(solv, type, r); diff --git a/test/testcases/strictrepoprio/strictrepoprio.t b/test/testcases/strictrepoprio/strictrepoprio.t new file mode 100644 index 00000000..d749d191 --- /dev/null +++ b/test/testcases/strictrepoprio/strictrepoprio.t @@ -0,0 +1,22 @@ +repo system 0 empty +repo available 0 testtags +#>=Pkg: A 2 1 noarch +repo available 1 testtags +#>=Pkg: A 1 1 noarch +#>=Req: B +system i686 rpm system + +solverflags strictrepopriority +job install name A +result transaction,problems +#>problem 30c1639e info nothing provides B needed by A-1-1.noarch +#>problem 30c1639e solution 23f73f5b deljob install name A +#>problem 30c1639e solution 5dd1416b allow A-2-1.noarch@available + +nextjob + +solverflags strictrepopriority +job install pkg A-2-1.noarch@available +result transaction,problems +#>install A-2-1.noarch@available +