From: Jaroslav Mracek Date: Tue, 22 Jun 2021 14:30:45 +0000 (+0200) Subject: Add mechanisms to ignore pkgs for weak dependencies X-Git-Tag: 0.7.20~3^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=refs%2Fpull%2F454%2Fhead;p=thirdparty%2Flibsolv.git Add mechanisms to ignore pkgs for weak dependencies It adds mechanism to avoid installation of certain packages to satisfy recommends and supplemented. --- diff --git a/bindings/solv.i b/bindings/solv.i index abfb5e15..61c6fc82 100644 --- a/bindings/solv.i +++ b/bindings/solv.i @@ -1283,6 +1283,7 @@ typedef struct { static const Id SOLVER_ALLOWUNINSTALL = SOLVER_ALLOWUNINSTALL; static const Id SOLVER_FAVOR = SOLVER_FAVOR; static const Id SOLVER_DISFAVOR = SOLVER_DISFAVOR; + static const Id SOLVER_EXCLUDEFROMWEAK = SOLVER_EXCLUDEFROMWEAK; static const Id SOLVER_JOBMASK = SOLVER_JOBMASK; static const Id SOLVER_WEAK = SOLVER_WEAK; static const Id SOLVER_ESSENTIAL = SOLVER_ESSENTIAL; diff --git a/doc/libsolv-bindings.txt b/doc/libsolv-bindings.txt index ac112cfd..0fa313bf 100644 --- a/doc/libsolv-bindings.txt +++ b/doc/libsolv-bindings.txt @@ -2076,6 +2076,10 @@ Avoid the specified packages if the solver encounters an alternative. This can also be used to block recommended or supplemented packages from being installed. +*SOLVER_EXCLUDEFROMWEAK*:: +Avoid the specified packages to satisfy recommended or supplemented dependencies. +Unlike SOLVER_DISFAVOR, it does not interfere with other rules. + *SOLVER_JOBMASK*:: A mask containing all the above action bits. diff --git a/ext/testcase.c b/ext/testcase.c index 20b0c48f..055452f8 100644 --- a/ext/testcase.c +++ b/ext/testcase.c @@ -60,6 +60,7 @@ static struct job2str { { SOLVER_FAVOR, "favor" }, { SOLVER_DISFAVOR, "disfavor" }, { SOLVER_BLACKLIST, "blacklist" }, + { SOLVER_EXCLUDEFROMWEAK, "excludefromweak" }, { 0, 0 } }; diff --git a/src/solver.c b/src/solver.c index 89a2ed10..1dc2c783 100644 --- a/src/solver.c +++ b/src/solver.c @@ -1398,6 +1398,8 @@ solver_free(Solver *solv) map_free(&solv->droporphanedmap); map_free(&solv->cleandepsmap); map_free(&solv->allowuninstallmap); + map_free(&solv->excludefromweakmap); + solv_free(solv->favormap); solv_free(solv->decisionmap); @@ -2202,6 +2204,20 @@ prune_disfavored(Solver *solv, Queue *plist) queue_truncate(plist, j); } +static void +prune_exclude_from_weak(Solver *solv, Queue *plist) +{ + int i, j; + for (i = j = 0; i < plist->count; i++) + { + Id p = plist->elements[i]; + if (!MAPTST(&solv->excludefromweakmap, p)) + plist->elements[j++] = p; + } + if (i != j) + queue_truncate(plist, j); +} + static int resolve_weak(Solver *solv, int level, int disablerules, Queue *dq, Queue *dqs, int *rerunp) { @@ -2275,6 +2291,8 @@ resolve_weak(Solver *solv, int level, int disablerules, Queue *dq, Queue *dqs, i continue; if (solv->havedisfavored && solv->favormap[i] < 0) continue; /* disfavored supplements, do not install */ + if (solv->excludefromweakmap.size && MAPTST(&solv->excludefromweakmap, i)) + continue; /* excluded for weak deps, do not install */ queue_push(dqs, i); } } @@ -2283,6 +2301,10 @@ resolve_weak(Solver *solv, int level, int disablerules, Queue *dq, Queue *dqs, i if (dq->count && solv->havedisfavored) prune_disfavored(solv, dq); + /* filter out weak_excluded recommended packages */ + if (solv->excludefromweakmap.size) + prune_exclude_from_weak(solv, dq); + /* filter out all packages obsoleted by installed packages */ /* this is no longer needed if we have (and trust) reverse obsoletes */ if ((dqs->count || dq->count) && solv->installed) @@ -3319,6 +3341,37 @@ add_complex_jobrules(Solver *solv, Id dep, int flags, int jobidx, int weak) } #endif +static void +solver_add_exclude_from_weak(Solver *solv) +{ + Queue *job = &solv->job; + Pool *pool = solv->pool; + int i; + Id p, pp, how, what, select; +for (i = 0; i < job->count; i += 2) + { + how = job->elements[i]; + if ((how & SOLVER_JOBMASK) != SOLVER_EXCLUDEFROMWEAK) + continue; + if (!solv->excludefromweakmap.size) + map_grow(&solv->excludefromweakmap, pool->nsolvables); + what = job->elements[i + 1]; + select = how & SOLVER_SELECTMASK; + if (select == SOLVER_SOLVABLE_REPO) + { + Repo *repo = pool_id2repo(pool, what); + if (repo) + { + Solvable *s; + FOR_REPO_SOLVABLES(repo, p, s) + MAPSET(&solv->excludefromweakmap, p); + } + } + FOR_JOB_SELECT(p, pp, select, what) + MAPSET(&solv->excludefromweakmap, p); + } +} + static void setup_favormap(Solver *solv) { @@ -3385,6 +3438,7 @@ solver_solve(Solver *solv, Queue *job) int hasfavorjob = 0; int haslockjob = 0; int hasblacklistjob = 0; + int hasexcludefromweakjob = 0; solve_start = solv_timems(0); @@ -3436,6 +3490,7 @@ solver_solve(Solver *solv, Queue *job) map_zerosize(&solv->droporphanedmap); solv->allowuninstall_all = 0; map_zerosize(&solv->allowuninstallmap); + map_zerosize(&solv->excludefromweakmap); map_zerosize(&solv->cleandepsmap); map_zerosize(&solv->weakrulemap); solv->favormap = solv_free(solv->favormap); @@ -3999,6 +4054,10 @@ solver_solve(Solver *solv, Queue *job) POOL_DEBUG(SOLV_DEBUG_JOB, "job: blacklist %s\n", solver_select2str(pool, select, what)); hasblacklistjob = 1; break; + case SOLVER_EXCLUDEFROMWEAK: + POOL_DEBUG(SOLV_DEBUG_JOB, "job: excludefromweak %s\n", solver_select2str(pool, select, what)); + hasexcludefromweakjob = 1; + break; default: POOL_DEBUG(SOLV_DEBUG_JOB, "job: unknown job\n"); break; @@ -4057,6 +4116,9 @@ solver_solve(Solver *solv, Queue *job) else solv->blackrules = solv->blackrules_end = solv->nrules; + if (hasexcludefromweakjob) + solver_add_exclude_from_weak(solv); + if (solv->havedisfavored && solv->strongrecommends && solv->recommendsruleq) solver_addrecommendsrules(solv); else diff --git a/src/solver.h b/src/solver.h index 2dec2590..d30ae361 100644 --- a/src/solver.h +++ b/src/solver.h @@ -208,6 +208,8 @@ struct s_Solver { Map allowuninstallmap; /* ok to uninstall those */ int allowuninstall_all; + Map excludefromweakmap; /* remove them from candidates for supplements and recommends */ + Id *favormap; /* favor job index, > 0: favored, < 0: disfavored */ int havedisfavored; /* do we have disfavored packages? */ @@ -248,6 +250,7 @@ typedef struct s_Solver Solver; #define SOLVER_FAVOR 0x0c00 #define SOLVER_DISFAVOR 0x0d00 #define SOLVER_BLACKLIST 0x0e00 +#define SOLVER_EXCLUDEFROMWEAK 0x1000 #define SOLVER_JOBMASK 0xff00 diff --git a/test/testcases/excludefromweak/excludefromweak-obsoletes.t b/test/testcases/excludefromweak/excludefromweak-obsoletes.t new file mode 100644 index 00000000..adc20d5d --- /dev/null +++ b/test/testcases/excludefromweak/excludefromweak-obsoletes.t @@ -0,0 +1,35 @@ +repo @System 0 testtags +#>=Pkg: pkg-A 1.0 1 noarch +#>=Prv: pkg-A = 1.0-1 +#>=Rec: pkg-C +#>=Pkg: pkg-B 1.0 1 noarch +#>=Prv: pkg-B = 1.0-1 + +repo available -99.-1000 testtags +#>=Pkg: pkg-A 1.0 3 noarch +#>=Prv: pkg-A = 1.0-3 +#>=Rec: pkg-B +#>=Pkg: pkg-B 1.0 2 noarch +#>=Prv: pkg-B = 1.0-2 +#>=Pkg: pkg-C 1.0 1 noarch +#>=Prv: pkg-C = 1.0-1 +#>=Obs: pkg-B + +system x86_64 rpm @System +poolflags implicitobsoleteusescolors +solverflags allowvendorchange keepexplicitobsoletes bestobeypolicy keeporphans yumobsoletes + +job update all packages [forcebest] +job excludefromweak name pkg-C +result transaction,problems +#>erase pkg-B-1.0-1.noarch@@System pkg-C-1.0-1.noarch@available +#>install pkg-C-1.0-1.noarch@available +#>upgrade pkg-A-1.0-1.noarch@@System pkg-A-1.0-3.noarch@available + +nextjob +job update oneof pkg-A-1.0-1.noarch@@System pkg-B-1.0-1.noarch@@System pkg-A-1.0-3.noarch@available pkg-B-1.0-2.noarch@available pkg-C-1.0-1.noarch@available [forcebest,targeted,setevr,setarch] +job excludefromweak name pkg-C +result transaction,problems +#>erase pkg-B-1.0-1.noarch@@System pkg-C-1.0-1.noarch@available +#>install pkg-C-1.0-1.noarch@available +#>upgrade pkg-A-1.0-1.noarch@@System pkg-A-1.0-3.noarch@available diff --git a/test/testcases/excludefromweak/excludefromweak.t b/test/testcases/excludefromweak/excludefromweak.t new file mode 100644 index 00000000..4d6d859b --- /dev/null +++ b/test/testcases/excludefromweak/excludefromweak.t @@ -0,0 +1,24 @@ +repo @System 0 testtags + +repo available -99.-1000 testtags +#>=Pkg: pkg-A 1 1 noarch +#>=Prv: pkg-A = 1-1 +#>=Rec: pkg-B +#>=Pkg: pkg-B 1 1 noarch +#>=Prv: pkg-B = 1-1 + +system x86_64 rpm @System +poolflags implicitobsoleteusescolors +solverflags allowvendorchange keepexplicitobsoletes bestobeypolicy keeporphans yumobsoletes + +job install oneof pkg-A-1-1.noarch@available [forcebest,targeted,setevr,setarch] +job excludefromweak name pkg-B +result transaction,problems +#>install pkg-A-1-1.noarch@available + +nextjob +job install oneof pkg-A-1-1.noarch@available [forcebest,targeted,setevr,setarch] +job excludefromweak name pkg-A +job excludefromweak name pkg-B +result transaction,problems +#>install pkg-A-1-1.noarch@available