Imported Upstream version 0.7.27
[platform/upstream/libsolv.git] / src / policy.c
index 823a008..02548ea 100644 (file)
@@ -232,13 +232,13 @@ check_complex_dep(Solver *solv, Id dep, Map *m, Queue **cqp)
 {
   Pool *pool = solv->pool;
   Queue q;
-  queue_init(&q);
   Id p;
   int i, qcnt;
 
 #if 0
   printf("check_complex_dep %s\n", pool_dep2str(pool, dep));
 #endif
+  queue_init(&q);
   i = pool_normalize_complex_dep(pool, dep, &q, CPLXDEPS_EXPAND);
   if (i == 0 || i == 1)
     {
@@ -833,11 +833,22 @@ move_installed_to_front(Pool *pool, Queue *plist)
     }
 }
 
+#ifdef ENABLE_CONDA
+static int
+pool_featurecountcmp(Pool *pool, Solvable *s1, Solvable *s2)
+{
+  unsigned int cnt1, cnt2;
+  cnt1 = solvable_lookup_count(s1, SOLVABLE_TRACK_FEATURES);
+  cnt2 = solvable_lookup_count(s2, SOLVABLE_TRACK_FEATURES);
+  return cnt1 == cnt2 ? 0 : cnt1 > cnt2 ? -1 : 1;
+}
+
 static int
 pool_buildversioncmp(Pool *pool, Solvable *s1, Solvable *s2)
 {
-  const char *bv1 = solvable_lookup_str(s1, SOLVABLE_BUILDVERSION);
-  const char *bv2 = solvable_lookup_str(s2, SOLVABLE_BUILDVERSION);
+  const char *bv1, *bv2;
+  bv1 = solvable_lookup_str(s1, SOLVABLE_BUILDVERSION);
+  bv2 = solvable_lookup_str(s2, SOLVABLE_BUILDVERSION);
   if (!bv1 && !bv2)
     return 0;
   return pool_evrcmp_str(pool, bv1 ? bv1 : "" , bv2 ? bv2 : "", EVRCMP_COMPARE);
@@ -852,6 +863,7 @@ pool_buildflavorcmp(Pool *pool, Solvable *s1, Solvable *s2)
     return 0;
   return pool_evrcmp_str(pool, f1 ? f1 : "" , f2 ? f2 : "", EVRCMP_COMPARE);
 }
+#endif
 
 /*
  * prune_to_best_version
@@ -895,15 +907,29 @@ prune_to_best_version(Pool *pool, Queue *plist)
           best = s;            /* take current as new best */
           continue;
         }
-      r = best->evr != s->evr ? pool_evrcmp(pool, best->evr, s->evr, EVRCMP_COMPARE) : 0;
+     
+      r = 0; 
+#ifdef ENABLE_CONDA
+      if (pool->disttype == DISTTYPE_CONDA)
+        r = pool_featurecountcmp(pool, best, s);
+#endif
+      if (r == 0)
+        r = best->evr != s->evr ? pool_evrcmp(pool, best->evr, s->evr, EVRCMP_COMPARE) : 0;
 #ifdef ENABLE_LINKED_PKGS
       if (r == 0 && has_package_link(pool, s))
         r = pool_link_evrcmp(pool, best, s);
 #endif
-      if (r == 0 && pool->disttype == DISTTYPE_CONDA)
-       r = pool_buildversioncmp(pool, best, s);
-      if (r == 0 && pool->disttype == DISTTYPE_CONDA)
-       r = pool_buildflavorcmp(pool, best, s);
+#ifdef ENABLE_CONDA
+      if (pool->disttype == DISTTYPE_CONDA)
+       {
+         if (r == 0)
+           r = (best->repo ? best->repo->subpriority : 0) - (s->repo ? s->repo->subpriority : 0);
+         if (r == 0)
+           r = pool_buildversioncmp(pool, best, s);
+         if (r == 0)
+           r = pool_buildflavorcmp(pool, best, s);
+       }
+#endif
       if (r < 0)
        best = s;
     }
@@ -1485,7 +1511,7 @@ policy_create_obsolete_index(Solver *solv)
        {
          FOR_PROVIDES(p, pp, obs)
            {
-             Solvable *ps = pool->solvables + p;;
+             Solvable *ps = pool->solvables + p;
              if (ps->repo != installed)
                continue;
              if (ps->name == s->name)
@@ -1519,7 +1545,7 @@ policy_create_obsolete_index(Solver *solv)
        {
          FOR_PROVIDES(p, pp, obs)
            {
-             Solvable *ps = pool->solvables + p;;
+             Solvable *ps = pool->solvables + p;
              if (ps->repo != installed)
                continue;
              if (ps->name == s->name)
@@ -1536,6 +1562,29 @@ policy_create_obsolete_index(Solver *solv)
 }
 
 
+/* return true if solvable s obsoletes solvable with id pi */
+static inline int
+is_obsoleting(Pool *pool, Solvable *s, Id pi)
+{
+  Id p, pp, obs, *obsp;
+  Solvable *si = pool->solvables + pi;
+  if (pool->obsoleteusescolors && !pool_colormatch(pool, si, s))
+    return 0;
+  obsp = s->repo->idarraydata + s->obsoletes;
+  while ((obs = *obsp++) != 0) /* for all obsoletes */
+    {
+      FOR_PROVIDES(p, pp, obs)   /* and all matching providers of the obsoletes */
+       {
+         if (p != pi)
+           continue;
+         if (!pool->obsoleteusesprovides && !pool_match_nevr(pool, si, obs))
+           continue;
+         return 1;
+       }
+    }
+  return 0;
+}
+
 /*
  * find update candidates
  *
@@ -1550,8 +1599,7 @@ policy_findupdatepackages(Solver *solv, Solvable *s, Queue *qs, int allow_all)
 {
   /* installed packages get a special upgrade allowed rule */
   Pool *pool = solv->pool;
-  Id p, pp, n, p2, pp2;
-  Id obs, *obsp;
+  Id p, pp, n;
   Solvable *ps;
   int haveprovobs = 0;
   int allowdowngrade = allow_all ? 1 : solv->allowdowngrade;
@@ -1579,6 +1627,8 @@ policy_findupdatepackages(Solver *solv, Solvable *s, Queue *qs, int allow_all)
        continue;
 
       ps = pool->solvables + p;
+      if (pool->considered && pool->whatprovideswithdisabled && ps->repo != pool->installed && pool_disabled_solvable(pool, ps)) 
+       continue;
       if (s->name == ps->name) /* name match */
        {
          if (pool->implicitobsoleteusescolors && !pool_colormatch(pool, s, ps))
@@ -1590,31 +1640,14 @@ policy_findupdatepackages(Solver *solv, Solvable *s, Queue *qs, int allow_all)
        continue;
       else if ((!solv->noupdateprovide || solv->needupdateprovide) && ps->obsoletes)   /* provides/obsoletes combination ? */
        {
-         /* check if package ps obsoletes installed package s */
+         /* check if package ps that provides s->name obsoletes installed package s */
          /* implicitobsoleteusescolors is somewhat wrong here, but we nevertheless
           * use it to limit our update candidates */
-         if ((pool->obsoleteusescolors || pool->implicitobsoleteusescolors) && !pool_colormatch(pool, s, ps))
+         if (pool->implicitobsoleteusescolors && !pool_colormatch(pool, s, ps))
            continue;
-         obsp = ps->repo->idarraydata + ps->obsoletes;
-         while ((obs = *obsp++) != 0)  /* for all obsoletes */
-           {
-             FOR_PROVIDES(p2, pp2, obs)   /* and all matching providers of the obsoletes */
-               {
-                 Solvable *ps2 = pool->solvables + p2;
-                 if (!pool->obsoleteusesprovides && !pool_match_nevr(pool, ps2, obs))
-                   continue;
-                 if (p2 == n)          /* match ! */
-                   break;
-               }
-             if (p2)                   /* match! */
-               break;
-           }
-         if (!obs)                     /* continue if no match */
+         if (!is_obsoleting(pool, ps, n))
            continue;
-         /* here we have 'p' with a matching provides/obsoletes combination
-          * thus flagging p as a valid update candidate for s
-          */
-         haveprovobs = 1;
+         haveprovobs = 1;              /* have matching provides/obsoletes combination */
        }
       else
         continue;
@@ -1636,14 +1669,14 @@ policy_findupdatepackages(Solver *solv, Solvable *s, Queue *qs, int allow_all)
       for (opp = solv->obsoletes_data + solv->obsoletes[n - solv->installed->start]; (p = *opp++) != 0;)
        {
          ps = pool->solvables + p;
-         if (!allowarchchange && s->arch != ps->arch && policy_illegal_archchange(solv, s, ps))
-           continue;
-         if (!allowvendorchange && s->vendor != ps->vendor && policy_illegal_vendorchange(solv, s, ps))
-           continue;
          /* implicitobsoleteusescolors is somewhat wrong here, but we nevertheless
           * use it to limit our update candidates */
          if (pool->implicitobsoleteusescolors && !pool_colormatch(pool, s, ps))
            continue;
+         if (!allowarchchange && s->arch != ps->arch && policy_illegal_archchange(solv, s, ps))
+           continue;
+         if (!allowvendorchange && s->vendor != ps->vendor && policy_illegal_vendorchange(solv, s, ps))
+           continue;
          queue_push(qs, p);
        }
     }