nscallback(Pool *pool, void *data, Id name, Id evr)
{
if (name == NAMESPACE_PRODUCTBUDDY)
- {
+ {
/* SUSE specific hack: each product has an associated rpm */
- Solvable *s = pool->solvables + evr;
- Id p, pp, cap;
-
+ Solvable *s = pool->solvables + evr;
+ Id p, pp, cap;
+ Id bestp = 0;
+
cap = pool_str2id(pool, pool_tmpjoin(pool, "product(", pool_id2str(pool, s->name) + 8, ")"), 0);
if (!cap)
return 0;
cap = pool_rel2id(pool, cap, s->evr, REL_EQ, 0);
if (!cap)
return 0;
- FOR_PROVIDES(p, pp, cap)
+ FOR_PROVIDES(p, pp, cap)
{
- Solvable *ps = pool->solvables + p;
+ Solvable *ps = pool->solvables + p;
if (ps->repo == s->repo && ps->arch == s->arch)
- break;
+ if (!bestp || pool_evrcmp(pool, pool->solvables[bestp].evr, ps->evr, EVRCMP_COMPARE) < 0)
+ bestp = p;
}
- return p;
+ return bestp;
}
return 0;
}
{
Id p, pp;
int pruneyou = 0;
- Map installedmap;
+ Map installedmap, noobsmap;
Solvable *s;
+ map_init(&noobsmap, 0);
map_init(&installedmap, pool->nsolvables);
+ solver_calculate_noobsmap(pool, job, &noobsmap);
if (pool->installed)
FOR_REPO_SOLVABLES(pool->installed, p, s)
MAPSET(&installedmap, p);
type = solvable_lookup_str(s, SOLVABLE_PATCHCATEGORY);
if (type && !strcmp(type, "optional"))
continue;
- r = solvable_trivial_installable_map(s, &installedmap, 0);
+ r = solvable_trivial_installable_map(s, &installedmap, 0, &noobsmap);
if (r == -1)
continue;
if (solvable_lookup_bool(s, UPDATE_RESTART) && r == 0)
queue_push2(job, SOLVER_SOLVABLE, p);
}
map_free(&installedmap);
+ map_free(&noobsmap);
}
#define MODE_LIST 0
dataiterator_free(&di);
solv_free(matchname);
}
-
+
if (newpkgsfps[i])
{
putchar('d');
void pool_set_languages(Pool *pool, const char **languages, int nlanguages);
Id pool_id2langid(Pool *pool, Id id, const char *lang, int create);
-int solvable_trivial_installable_map(Solvable *s, Map *installedmap, Map *conflictsmap);
-int solvable_trivial_installable_repo(Solvable *s, struct _Repo *installed);
-int solvable_trivial_installable_queue(Solvable *s, Queue *installed);
+int solvable_trivial_installable_map(Solvable *s, Map *installedmap, Map *conflictsmap, Map *noobsoletesmap);
+int solvable_trivial_installable_repo(Solvable *s, struct _Repo *installed, Map *noobsoletesmap);
+int solvable_trivial_installable_queue(Solvable *s, Queue *installed, Map *noobsoletesmap);
void pool_create_state_maps(Pool *pool, Queue *installed, Map *installedmap, Map *conflictsmap);
return dep;
}
-static inline int providedbyinstalled(Pool *pool, Map *installed, Id dep)
+static int providedbyinstalled_multiversion(Pool *pool, Map *installed, Id n, Id con)
+{
+ Id p, pp;
+ Solvable *sn = pool->solvables + n;
+
+ FOR_PROVIDES(p, pp, sn->name)
+ {
+ Solvable *s = pool->solvables + p;
+ if (s->name != sn->name || s->arch != sn->arch)
+ continue;
+ if (!MAPTST(installed, p))
+ continue;
+ if (pool_match_nevr(pool, pool->solvables + p, con))
+ continue;
+ return 1; /* found installed package that doesn't conflict */
+ }
+ return 0;
+}
+
+static inline int providedbyinstalled(Pool *pool, Map *installed, Id dep, int ispatch, Map *noobsoletesmap)
{
Id p, pp;
FOR_PROVIDES(p, pp, dep)
{
if (p == SYSTEMSOLVABLE)
return -1;
+ if (ispatch && !pool_match_nevr(pool, pool->solvables + p, dep))
+ continue;
+ if (ispatch && noobsoletesmap && noobsoletesmap->size && MAPTST(noobsoletesmap, p) && ISRELDEP(dep))
+ if (providedbyinstalled_multiversion(pool, installed, p, dep))
+ continue;
if (MAPTST(installed, p))
return 1;
}
* -1: solvable is installable, but doesn't constrain any installed packages
*/
int
-solvable_trivial_installable_map(Solvable *s, Map *installedmap, Map *conflictsmap)
+solvable_trivial_installable_map(Solvable *s, Map *installedmap, Map *conflictsmap, Map *noobsoletesmap)
{
Pool *pool = s->repo->pool;
Solvable *s2;
- Id p, pp, *dp;
+ Id p, *dp;
Id *reqp, req;
Id *conp, con;
- Id *obsp, obs;
int r, interesting = 0;
if (conflictsmap && MAPTST(conflictsmap, s - pool->solvables))
{
if (req == SOLVABLE_PREREQMARKER)
continue;
- r = providedbyinstalled(pool, installedmap, req);
+ r = providedbyinstalled(pool, installedmap, req, 0, 0);
if (!r)
return 0;
if (r > 0)
}
if (s->conflicts)
{
+ int ispatch = 0;
+
+ if (!strncmp("patch:", pool_id2str(pool, s->name), 6))
+ ispatch = 1;
conp = s->repo->idarraydata + s->conflicts;
while ((con = *conp++) != 0)
{
- if (providedbyinstalled(pool, installedmap, con))
+ if (providedbyinstalled(pool, installedmap, con, ispatch, noobsoletesmap))
return 0;
if (!interesting && ISRELDEP(con))
{
con = dep2name(pool, con);
- if (providedbyinstalled(pool, installedmap, con))
+ if (providedbyinstalled(pool, installedmap, con, ispatch, noobsoletesmap))
interesting = 1;
}
}
}
+#if 0
if (s->repo)
{
+ Id *obsp, obs;
Repo *installed = 0;
if (s->obsoletes && s->repo != installed)
{
obsp = s->repo->idarraydata + s->obsoletes;
while ((obs = *obsp++) != 0)
{
- if (providedbyinstalled(pool, installedmap, obs))
+ if (providedbyinstalled(pool, installedmap, obs, 0, 0))
return 0;
}
}
if (s->repo != installed)
{
+ Id pp;
FOR_PROVIDES(p, pp, s->name)
{
s2 = pool->solvables + p;
}
}
}
+#endif
if (!conflictsmap)
{
int i;
* by a queue.
*/
int
-solvable_trivial_installable_queue(Solvable *s, Queue *installed)
+solvable_trivial_installable_queue(Solvable *s, Queue *installed, Map *noobsoletesmap)
{
Pool *pool = s->repo->pool;
int i;
if (p > 0) /* makes it work with decisionq */
MAPSET(&installedmap, p);
}
- r = solvable_trivial_installable_map(s, &installedmap, 0);
+ r = solvable_trivial_installable_map(s, &installedmap, 0, noobsoletesmap);
map_free(&installedmap);
return r;
}
* by a repo containing the installed solvables.
*/
int
-solvable_trivial_installable_repo(Solvable *s, Repo *installed)
+solvable_trivial_installable_repo(Solvable *s, Repo *installed, Map *noobsoletesmap)
{
Pool *pool = s->repo->pool;
Id p;
map_init(&installedmap, pool->nsolvables);
FOR_REPO_SOLVABLES(installed, p, s2)
MAPSET(&installedmap, p);
- r = solvable_trivial_installable_map(s, &installedmap, 0);
+ r = solvable_trivial_installable_map(s, &installedmap, 0, noobsoletesmap);
map_free(&installedmap);
return r;
}