trivial_installable: check vendor of affected package to see if a patch should be...
authorMichael Schroeder <mls@suse.de>
Mon, 14 Jan 2013 14:59:55 +0000 (15:59 +0100)
committerMichael Schroeder <mls@suse.de>
Mon, 14 Jan 2013 14:59:55 +0000 (15:59 +0100)
src/pool.h
src/solvable.c
src/solver.c

index 97224e08acfbc7214a885c69303a9440b47bdea5..e785cd8c24fff27b6d9d080d4d5e897763742549 100644 (file)
@@ -265,6 +265,8 @@ Id pool_id2langid(Pool *pool, Id id, const char *lang, int create);
 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);
+struct _Solver; /* argh, needed for vendorchange callback FIXME */
+int solvable_is_irrelevant_patch(Solvable *s, Map *installedmap, struct _Solver *solv);
 
 void pool_create_state_maps(Pool *pool, Queue *installed, Map *installedmap, Map *conflictsmap);
 
index 536c1b0681617104b9edf530a2fbf14f9c96e47c..45945443211ad8fa26380eaabd5e5cd4ed899646 100644 (file)
@@ -20,6 +20,8 @@
 #include "pool.h"
 #include "repo.h"
 #include "util.h"
+#include "policy.h"
+#include "poolvendor.h"
 #include "chksum.h"
 
 const char *
@@ -459,7 +461,11 @@ solvable_trivial_installable_map(Solvable *s, Map *installedmap, Map *conflictsm
       while ((con = *conp++) != 0)
        {
          if (providedbyinstalled(pool, installedmap, con, ispatch, noobsoletesmap))
-           return 0;
+           {
+             if (ispatch && solvable_is_irrelevant_patch(s, installedmap, 0))
+               return -1;
+             return 0;
+           }
          if (!interesting && ISRELDEP(con))
            {
               con = dep2name(pool, con);
@@ -467,6 +473,8 @@ solvable_trivial_installable_map(Solvable *s, Map *installedmap, Map *conflictsm
                interesting = 1;
            }
        }
+      if (ispatch && interesting && solvable_is_irrelevant_patch(s, installedmap, 0))
+       interesting = 0;
     }
 #if 0
   if (s->repo)
@@ -568,6 +576,76 @@ solvable_trivial_installable_repo(Solvable *s, Repo *installed, Map *noobsoletes
 }
 
 
+/* check if this patch is relevant according to the vendor. To bad that patches
+ * don't have a vendor, so we need to do some careful repo testing. */
+int
+solvable_is_irrelevant_patch(Solvable *s, Map *installedmap, Solver *solv)
+{
+  Pool *pool = s->repo->pool;
+  Id con, *conp;
+  int hadpatchpackage = 0;
+
+  if (!s->conflicts)
+    return 0;
+  conp = s->repo->idarraydata + s->conflicts;
+  while ((con = *conp++) != 0)
+    {
+      Reldep *rd;
+      Id p, pp, p2, pp2;
+      if (!ISRELDEP(con))
+       continue;
+      rd = GETRELDEP(pool, con);
+      if (rd->flags != REL_LT)
+       continue;
+      FOR_PROVIDES(p, pp, con)
+       {
+         Solvable *si;
+         if (!MAPTST(installedmap, p))
+           continue;
+         si = pool->solvables + p;
+         if (!pool_match_nevr(pool, si, con))
+           continue;
+         FOR_PROVIDES(p2, pp2, rd->name)
+           {
+             Solvable *s2 = pool->solvables + p2;
+             if (!pool_match_nevr(pool, s2, rd->name))
+               continue;
+             if (pool_match_nevr(pool, s2, con))
+               continue;       /* does not fulfill patch */
+             if (s2->repo == s->repo)
+               {
+                 hadpatchpackage = 1;
+                 /* ok, we have a package from the patch repo that solves the conflict. check vendor */
+                 if (si->vendor == s2->vendor)
+                   return 0;
+                 /* FIXME: solv is only needed for the vendorchange callback */
+                 if (solv)
+                   {
+                     if (!policy_illegal_vendorchange(solv, si, s2))
+                       return 0;
+                   }
+                 else
+                   {
+                     Id v1 = si->vendor ? si->vendor : ID_EMPTY;
+                     Id v2 = s2->vendor ? s2->vendor : ID_EMPTY;
+                     if (v1 == v2)
+                       return 0;
+                     v1 = pool_vendor2mask(pool, v1);
+                     v2 = pool_vendor2mask(pool, v2);
+                     if ((v1 & v2) != 0)
+                       return 0;
+                   }
+                 /* vendor change was illegal, ignore conflict */
+               }
+           }
+       }
+    }
+  /* if we didn't find a patchpackage don't claim that the patch is irrelevant */
+  if (!hadpatchpackage)
+    return 0;
+  return 1;
+}
+
 /*****************************************************************************/
 
 /*
index 2f248398897b936900cbc06e5dcab6b97997c9ee..43668d549f1be67154f9480121c5edcf7973f587 100644 (file)
@@ -3745,9 +3745,18 @@ solver_create_state_maps(Solver *solv, Map *installedmap, Map *conflictsmap)
 void
 solver_trivial_installable(Solver *solv, Queue *pkgs, Queue *res)
 {
+  Pool *pool = solv->pool;
   Map installedmap;
-  pool_create_state_maps(solv->pool,  &solv->decisionq, &installedmap, 0);
-  pool_trivial_installable_noobsoletesmap(solv->pool, &installedmap, pkgs, res, solv->noobsoletes.size ? &solv->noobsoletes : 0);
+  int i;
+  pool_create_state_maps(pool,  &solv->decisionq, &installedmap, 0);
+  pool_trivial_installable_noobsoletesmap(pool, &installedmap, pkgs, res, solv->noobsoletes.size ? &solv->noobsoletes : 0);
+  for (i = 0; i < res->count; i++)
+    if (res->elements[i] != -1)
+      {
+       Solvable *s = pool->solvables + pkgs->elements[i];
+       if (!strncmp("patch:", pool_id2str(pool, s->name), 6) && solvable_is_irrelevant_patch(s, &installedmap, solv))
+         res->elements[i] = -1;
+      }
   map_free(&installedmap);
 }