1
0
mirror of https://github.com/openSUSE/libsolv.git synced 2026-02-05 12:45:46 +01:00

Add experimental SOLVER_FLAG_ONLY_NAMESPACE_RECOMMENDED flag

This limits the recommends/supplements to namespace dependencies.
This commit is contained in:
Michael Schroeder
2018-11-22 16:18:56 +01:00
parent 97bf32fa56
commit 93d10488ad
5 changed files with 137 additions and 69 deletions

View File

@@ -121,6 +121,7 @@ static struct solverflags2str {
{ SOLVER_FLAG_FOCUS_BEST, "focusbest", 0 },
{ SOLVER_FLAG_STRONG_RECOMMENDS, "strongrecommends", 0 },
{ SOLVER_FLAG_INSTALL_ALSO_UPDATES, "installalsoupdates", 0 },
{ SOLVER_FLAG_ONLY_NAMESPACE_RECOMMENDED, "onlynamespacerecommended", 0 },
{ 0, 0, 0 }
};

View File

@@ -1443,6 +1443,8 @@ solver_get_flag(Solver *solv, int flag)
return solv->strongrecommends;
case SOLVER_FLAG_INSTALL_ALSO_UPDATES:
return solv->install_also_updates;
case SOLVER_FLAG_ONLY_NAMESPACE_RECOMMENDED:
return solv->only_namespace_recommended;
default:
break;
}
@@ -1533,6 +1535,9 @@ solver_set_flag(Solver *solv, int flag, int value)
case SOLVER_FLAG_INSTALL_ALSO_UPDATES:
solv->install_also_updates = value;
break;
case SOLVER_FLAG_ONLY_NAMESPACE_RECOMMENDED:
solv->only_namespace_recommended = value;
break;
default:
break;
}
@@ -2090,9 +2095,10 @@ resolve_weak(Solver *solv, int level, int disablerules, Queue *dq, Queue *dqs, i
{
/* installed, check for recommends */
Id *recp, rec, pp, p;
if (solv->only_namespace_recommended)
continue;
if (!solv->addalreadyrecommended && s->repo == solv->installed)
continue;
/* XXX need to special case AND ? */
if (s->recommends)
{
recp = s->repo->idarraydata + s->recommends;
@@ -2186,7 +2192,7 @@ resolve_weak(Solver *solv, int level, int disablerules, Queue *dq, Queue *dqs, i
}
/* filter out all already supplemented packages if requested */
if (!solv->addalreadyrecommended && dqs->count)
if ((!solv->addalreadyrecommended || solv->only_namespace_recommended) && dqs->count)
{
/* filter out old supplements */
for (i = j = 0; i < dqs->count; i++)
@@ -3245,7 +3251,7 @@ solver_solve(Solver *solv, Queue *job)
POOL_DEBUG(SOLV_DEBUG_STATS, "allowuninstall=%d, allowdowngrade=%d, allownamechange=%d, allowarchchange=%d, allowvendorchange=%d\n", solv->allowuninstall, solv->allowdowngrade, solv->allownamechange, solv->allowarchchange, solv->allowvendorchange);
POOL_DEBUG(SOLV_DEBUG_STATS, "promoteepoch=%d, forbidselfconflicts=%d\n", pool->promoteepoch, pool->forbidselfconflicts);
POOL_DEBUG(SOLV_DEBUG_STATS, "obsoleteusesprovides=%d, implicitobsoleteusesprovides=%d, obsoleteusescolors=%d, implicitobsoleteusescolors=%d\n", pool->obsoleteusesprovides, pool->implicitobsoleteusesprovides, pool->obsoleteusescolors, pool->implicitobsoleteusescolors);
POOL_DEBUG(SOLV_DEBUG_STATS, "dontinstallrecommended=%d, addalreadyrecommended=%d\n", solv->dontinstallrecommended, solv->addalreadyrecommended);
POOL_DEBUG(SOLV_DEBUG_STATS, "dontinstallrecommended=%d, addalreadyrecommended=%d onlynamespacerecommended=%d\n", solv->dontinstallrecommended, solv->addalreadyrecommended, solv->only_namespace_recommended);
/* create whatprovides if not already there */
if (!pool->whatprovides)

View File

@@ -167,6 +167,7 @@ struct s_Solver {
int urpmreorder; /* true: do special urpm package reordering */
int strongrecommends; /* true: create weak rules for recommends */
int install_also_updates; /* true: do not prune install job rules to installed packages */
int only_namespace_recommended; /* true: only install packages recommended by namespace */
int process_orphans; /* true: do special orphan processing */
Map dupmap; /* dup to those packages */
@@ -317,6 +318,7 @@ typedef struct s_Solver Solver;
#define SOLVER_FLAG_FOCUS_BEST 24
#define SOLVER_FLAG_STRONG_RECOMMENDS 25
#define SOLVER_FLAG_INSTALL_ALSO_UPDATES 26
#define SOLVER_FLAG_ONLY_NAMESPACE_RECOMMENDED 27
#define GET_USERINSTALLED_NAMES (1 << 0) /* package names instead of ids */
#define GET_USERINSTALLED_INVERTED (1 << 1) /* autoinstalled */

View File

@@ -181,6 +181,76 @@ solver_dep_fulfilled_cplx(Solver *solv, Reldep *rd)
return 0;
}
static int
solver_dep_fulfilled_complex_func(Solver *solv, Reldep *rd, int (*dep_fullfilled)(Solver *, Id))
{
Pool *pool = solv->pool;
int r1, r2;
if (rd->flags == REL_COND)
{
if (ISRELDEP(rd->evr))
{
Reldep *rd2 = GETRELDEP(pool, rd->evr);
if (rd2->flags == REL_ELSE)
{
r1 = dep_fullfilled(solv, rd2->name);
if (r1)
{
r2 = dep_fullfilled(solv, rd->name);
return r2 && r1 == 2 ? 2 : r2;
}
return dep_fullfilled(solv, rd2->evr);
}
}
r1 = dep_fullfilled(solv, rd->name);
r2 = !dep_fullfilled(solv, rd->evr);
if (!r1 && !r2)
return 0;
return r1 == 2 ? 2 : 1;
}
if (rd->flags == REL_UNLESS)
{
if (ISRELDEP(rd->evr))
{
Reldep *rd2 = GETRELDEP(pool, rd->evr);
if (rd2->flags == REL_ELSE)
{
r1 = dep_fullfilled(solv, rd2->name);
if (r1)
{
r2 = dep_fullfilled(solv, rd2->evr);
return r2 && r1 == 2 ? 2 : r2;
}
return dep_fullfilled(solv, rd->name);
}
}
/* A AND NOT(B) */
r1 = dep_fullfilled(solv, rd->name);
r2 = !dep_fullfilled(solv, rd->evr);
if (!r1 || !r2)
return 0;
return r1 == 2 ? 2 : 1;
}
if (rd->flags == REL_AND)
{
r1 = dep_fullfilled(solv, rd->name);
if (!r1)
return 0;
r2 = dep_fullfilled(solv, rd->evr);
if (!r2)
return 0;
return r1 == 2 || r2 == 2 ? 2 : 1;
}
if (rd->flags == REL_OR)
{
r1 = dep_fullfilled(solv, rd->name);
r2 = dep_fullfilled(solv, rd->evr);
if (!r1 && !r2)
return 0;
return r1 == 2 || r2 == 2 ? 2 : 1;
}
return 0;
}
/* mirrors solver_dep_fulfilled, but returns 2 if a new package
* was involved */
@@ -194,71 +264,8 @@ solver_dep_fulfilled_alreadyinstalled(Solver *solv, Id dep)
if (ISRELDEP(dep))
{
Reldep *rd = GETRELDEP(pool, dep);
if (rd->flags == REL_COND)
{
int r1, r2;
if (ISRELDEP(rd->evr))
{
Reldep *rd2 = GETRELDEP(pool, rd->evr);
if (rd2->flags == REL_ELSE)
{
r1 = solver_dep_fulfilled_alreadyinstalled(solv, rd2->name);
if (r1)
{
r2 = solver_dep_fulfilled_alreadyinstalled(solv, rd->name);
return r2 && r1 == 2 ? 2 : r2;
}
return solver_dep_fulfilled_alreadyinstalled(solv, rd2->evr);
}
}
r1 = solver_dep_fulfilled_alreadyinstalled(solv, rd->name);
r2 = !solver_dep_fulfilled_alreadyinstalled(solv, rd->evr);
if (!r1 && !r2)
return 0;
return r1 == 2 ? 2 : 1;
}
if (rd->flags == REL_UNLESS)
{
int r1, r2;
if (ISRELDEP(rd->evr))
{
Reldep *rd2 = GETRELDEP(pool, rd->evr);
if (rd2->flags == REL_ELSE)
{
r1 = solver_dep_fulfilled_alreadyinstalled(solv, rd2->name);
if (r1)
{
r2 = solver_dep_fulfilled_alreadyinstalled(solv, rd2->evr);
return r2 && r1 == 2 ? 2 : r2;
}
return solver_dep_fulfilled_alreadyinstalled(solv, rd->name);
}
}
/* A AND NOT(B) */
r1 = solver_dep_fulfilled_alreadyinstalled(solv, rd->name);
r2 = !solver_dep_fulfilled_alreadyinstalled(solv, rd->evr);
if (!r1 || !r2)
return 0;
return r1 == 2 ? 2 : 1;
}
if (rd->flags == REL_AND)
{
int r2, r1 = solver_dep_fulfilled_alreadyinstalled(solv, rd->name);
if (!r1)
return 0;
r2 = solver_dep_fulfilled_alreadyinstalled(solv, rd->evr);
if (!r2)
return 0;
return r1 == 2 || r2 == 2 ? 2 : 1;
}
if (rd->flags == REL_OR)
{
int r2, r1 = solver_dep_fulfilled_alreadyinstalled(solv, rd->name);
r2 = solver_dep_fulfilled_alreadyinstalled(solv, rd->evr);
if (!r1 && !r2)
return 0;
return r1 == 2 || r2 == 2 ? 2 : 1;
}
if (rd->flags == REL_COND || rd->flags == REL_UNLESS || rd->flags == REL_AND || rd->flags == REL_OR)
return solver_dep_fulfilled_complex_func(solv, rd, solver_dep_fulfilled_alreadyinstalled);
if (rd->flags == REL_NAMESPACE && rd->name == NAMESPACE_SPLITPROVIDES)
return solver_splitprovides(solv, rd->evr, 0) ? 2 : 0;
if (rd->flags == REL_NAMESPACE && solv->installsuppdepq)
@@ -282,14 +289,42 @@ solver_dep_fulfilled_alreadyinstalled(Solver *solv, Id dep)
return r;
}
static int
solver_dep_fulfilled_namespace(Solver *solv, Id dep)
{
Pool *pool = solv->pool;
Id p, pp;
int r = 1;
if (ISRELDEP(dep))
{
Reldep *rd = GETRELDEP(pool, dep);
if (rd->flags == REL_COND || rd->flags == REL_UNLESS || rd->flags == REL_AND || rd->flags == REL_OR)
return solver_dep_fulfilled_complex_func(solv, rd, solver_dep_fulfilled_namespace);
if (rd->flags == REL_NAMESPACE && rd->name == NAMESPACE_SPLITPROVIDES)
return solver_splitprovides(solv, rd->evr, 0) ? 2 : 0;
if (rd->flags == REL_NAMESPACE)
r = 2;
}
FOR_PROVIDES(p, pp, dep)
if (solv->decisionmap[p] > 0)
return r;
return 0;
}
int
solver_is_supplementing_alreadyinstalled(Solver *solv, Solvable *s)
{
Id sup, *supp;
supp = s->repo->idarraydata + s->supplements;
while ((sup = *supp++) != 0)
if (solver_dep_fulfilled_alreadyinstalled(solv, sup) == 2)
{
if (!solv->addalreadyrecommended && solver_dep_fulfilled_alreadyinstalled(solv, sup) != 2)
continue;
if (solv->only_namespace_recommended && solver_dep_fulfilled_namespace(solv, sup) != 2)
continue;
return 1;
}
return 0;
}
/*

View File

@@ -11,6 +11,13 @@ repo test 0 testtags <inline>
#>=Prv: locale(C:de)
#>=Pkg: C-en 1 1 noarch
#>=Prv: locale(C:en)
#>=Pkg: D 1 1 noarch
#>=Sup: C
#>=Pkg: E 1 1 noarch
#>=Prv: locale(F:de)
#>=Pkg: F 1 1 noarch
#>=Pkg: G 1 1 noarch
#>=Sup: F
system i686 rpm system
# first test an empty job
@@ -24,6 +31,7 @@ solverflags addalreadyrecommended
result transaction,problems <inline>
#>install A-1-1.noarch@test
#>install C-de-1-1.noarch@test
#>install D-1-1.noarch@test
nextjob
namespace namespace:language(de) @SYSTEM
@@ -59,3 +67,19 @@ result transaction,problems <inline>
#>erase B-1-1.noarch@system
#>install A-1-1.noarch@test
#>install C-de-1-1.noarch@test
nextjob
namespace namespace:language(de) @SYSTEM
solverflags addalreadyrecommended onlynamespacerecommended
result transaction,problems <inline>
#>install A-1-1.noarch@test
#>install C-de-1-1.noarch@test
nextjob
namespace namespace:language(de) @SYSTEM
solverflags onlynamespacerecommended
job install name F
result transaction,problems <inline>
#>install E-1-1.noarch@test
#>install F-1-1.noarch@test