{
case SOLVER_INSTALL_SOLVABLE: /* install specific solvable */
s = pool->solvables + what;
+ if (solv->noobsoletes.size && MAPTST(&solv->noobsoletes, what))
+ break;
FOR_PROVIDES(p, pp, s->name)
{
if (pool->solvables[p].name != s->name)
*/
if (!installed || pool->solvables[n].repo != installed)
{ /* not installed */
- if (s->obsoletes)
+ int noobs = solv->noobsoletes.size && MAPTST(&solv->noobsoletes, n);
+ if (s->obsoletes && !noobs)
{
obsp = s->repo->idarraydata + s->obsoletes;
/* foreach obsoletes */
}
}
}
-/**
- * FIXME
- * This looks wrong, since its outside of the obsoletes loop so it probably prevents multiple installs of the same name
- *
- */
- /* foreach provider of s->name */
FOR_PROVIDES(p, pp, s->name)
{
- if (!solv->implicitobsoleteusesprovides /* implicit obsoletes due to same name are not matched against provides, just names */
- && s->name != pool->solvables[p].name)
+ Solvable *ps = pool->solvables + p;
+ /* we still obsolete packages with same nevra, like rpm does */
+ /* (actually, rpm mixes those packages. yuck...) */
+ if (noobs && (s->name != ps->name || s->evr != ps->evr || s->arch != ps->arch))
+ continue;
+ if (!solv->implicitobsoleteusesprovides && s->name != ps->name)
continue;
addrule(solv, -n, -p);
}
}
/* if nothing found, check for freshens
- * (patterns use this
+ * (patterns use this)
*/
if (!sup && s->freshens)
{
map_free(&solv->suggestsmap);
map_free(&solv->noupdate);
map_free(&solv->weakrulemap);
+ map_free(&solv->noobsoletes);
sat_free(solv->decisionmap);
sat_free(solv->rules);
/* if both packages have the same name and at least one of them
* is not installed, they conflict */
- if (s->name == s2->name && (!installed || (s->repo != installed || s2->repo != installed)))
+ if (s->name == s2->name && !(installed && s->repo == installed && s2->repo == installed))
{
- *depp = 0;
- *sourcep = -r->p;
- *targetp = -r->w2;
- return SOLVER_PROBLEM_SAME_NAME;
+ /* also check noobsoletes map */
+ if ((s->evr == s2->evr && s->arch == s2->arch) || !solv->noobsoletes.size
+ || ((!installed || s->repo != installed) && !MAPTST(&solv->noobsoletes, -r->p))
+ || ((!installed || s2->repo != installed) && !MAPTST(&solv->noobsoletes, -r->w2)))
+ {
+ *depp = 0;
+ *sourcep = -r->p;
+ *targetp = -r->w2;
+ return SOLVER_PROBLEM_SAME_NAME;
+ }
}
/* check conflicts in both directions */
}
}
/* check obsoletes in both directions */
- if ((!installed || s->repo != installed) && s->obsoletes)
+ if ((!installed || s->repo != installed) && s->obsoletes && !(solv->noobsoletes.size && MAPTST(&solv->noobsoletes, -r->p)))
{
obsp = s->repo->idarraydata + s->obsoletes;
while ((obs = *obsp++) != 0)
}
}
}
- if ((!installed || s2->repo != installed) && s2->obsoletes)
+ if ((!installed || s2->repo != installed) && s2->obsoletes && !(solv->noobsoletes.size && MAPTST(&solv->noobsoletes, -r->w2)))
{
obsp = s2->repo->idarraydata + s2->obsoletes;
while ((obs = *obsp++) != 0)
}
}
}
- if (solv->implicitobsoleteusesprovides && (!installed || s->repo != installed))
+ if (solv->implicitobsoleteusesprovides && (!installed || s->repo != installed) && !(solv->noobsoletes.size && MAPTST(&solv->noobsoletes, -r->p)))
{
FOR_PROVIDES(p, pp, s->name)
{
return SOLVER_PROBLEM_PACKAGE_OBSOLETES;
}
}
- if (solv->implicitobsoleteusesprovides && (!installed || s2->repo != installed))
+ if (solv->implicitobsoleteusesprovides && (!installed || s2->repo != installed) && !(solv->noobsoletes.size && MAPTST(&solv->noobsoletes, -r->w2)))
{
FOR_PROVIDES(p, pp, s2->name)
{
*
*/
+ /* create noobsolete map if needed */
+ for (i = 0; i < job->count; i += 2)
+ {
+ how = job->elements[i] & ~SOLVER_WEAK;
+ what = job->elements[i + 1];
+ switch(how)
+ {
+ case SOLVER_NOOBSOLETES_SOLVABLE:
+ case SOLVER_NOOBSOLETES_SOLVABLE_NAME:
+ case SOLVER_NOOBSOLETES_SOLVABLE_PROVIDES:
+ if (!solv->noobsoletes.size)
+ map_init(&solv->noobsoletes, pool->nsolvables);
+ if (how == SOLVER_NOOBSOLETES_SOLVABLE)
+ {
+ MAPSET(&solv->noobsoletes, what);
+ break;
+ }
+ FOR_PROVIDES(p, pp, what)
+ {
+ if (how == SOLVER_NOOBSOLETES_SOLVABLE_NAME && !pool_match_nevr(pool, pool->solvables + p, what))
+ continue;
+ MAPSET(&solv->noobsoletes, p);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
map_init(&addedmap, pool->nsolvables);
queue_init(&q);
}
}
- /* FIXME: Huh ? Impossile !, we only loop over installed here */
if (s->repo != installed)
{
addrule(solv, 0, 0); /* create dummy rule */
}
}
#endif
- /* FIXME: Huh ? Impossile !, we only loop over installed here */
if (s->repo != installed)
{
addrule(solv, 0, 0); /* create dummy rule */
POOL_DEBUG(SAT_DEBUG_JOB, "job: weaken deps %s\n", solvable2str(pool, s));
weaken_solvable_deps(solv, what);
break;
+ case SOLVER_NOOBSOLETES_SOLVABLE:
+ POOL_DEBUG(SAT_DEBUG_JOB, "job: no obsolete %s\n", solvable2str(pool, pool->solvables + what));
+ break;
+ case SOLVER_NOOBSOLETES_SOLVABLE_NAME:
+ POOL_DEBUG(SAT_DEBUG_JOB, "job: no obsolete name %s\n", dep2str(pool, what));
+ break;
+ case SOLVER_NOOBSOLETES_SOLVABLE_PROVIDES:
+ POOL_DEBUG(SAT_DEBUG_JOB, "job: no obsolete provides %s\n", dep2str(pool, what));
+ break;
}
/*
Id learntrules; /* learnt rules, (end == nrules) */
- Map noupdate; /* don't try to update these installed solvables */
- /* aka 'obsoletesmap' */
+ Map noupdate; /* don't try to update these
+ installed solvables */
+ Map noobsoletes; /* ignore obsoletes for these
+ (multiinstall) */
- Queue weakruleq; /* index into 'rules' for weak ones */
-
- Map weakrulemap; /* map rule# to '1' for weak rules, 1..learntrules */
+ Queue weakruleq; /* index into 'rules' for weak ones */
+ Map weakrulemap; /* map rule# to '1' for weak rules, 1..learntrules */
Id *watches; /* Array of rule offsets
* watches has nsolvables*2 entries and is addressed from the middle
SOLVER_INSTALL_SOLVABLE_UPDATE,
SOLVER_INSTALL_SOLVABLE_ONE_OF,
SOLVER_WEAKEN_SOLVABLE_DEPS,
+ SOLVER_NOOBSOLETES_SOLVABLE,
+ SOLVER_NOOBSOLETES_SOLVABLE_NAME,
+ SOLVER_NOOBSOLETES_SOLVABLE_PROVIDES,
+
+ /* flags */
SOLVER_WEAK = 0x100,
} SolverCmd;