]> git.ipfire.org Git - thirdparty/libsolv.git/commitdiff
Add experimental SOLVER_FLAG_ONLY_NAMESPACE_RECOMMENDED flag
authorMichael Schroeder <mls@suse.de>
Thu, 22 Nov 2018 15:18:56 +0000 (16:18 +0100)
committerMichael Schroeder <mls@suse.de>
Thu, 22 Nov 2018 15:22:12 +0000 (16:22 +0100)
This limits the recommends/supplements to namespace dependencies.

ext/testcase.c
src/solver.c
src/solver.h
src/solver_util.c
test/testcases/namespace/namespaceprovides.t

index 469218d3b7938664190b1e3ee9275e1a6af1eb29..6a512a0075df2c34fe47746b9ceb95fa8566ee1c 100644 (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 }
 };
 
index a4e0c4b666496dc88c6437d0469736ecdba08316..a6d00cb457f29b28f67187448c2925b11f1ed7b8 100644 (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)
index 4c85b4d5058235b0cb387af88934a485c0139e62..6fc2e9f009b0878a20edab173f14cad90c15ba27 100644 (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 */
index bd5d4b4d1796a34db0fb045f93484be808ce51d5..a910e115f649f2141cb1c56bd658666e765ceddd 100644 (file)
@@ -181,84 +181,91 @@ solver_dep_fulfilled_cplx(Solver *solv, Reldep *rd)
   return 0;
 }
 
-
-/* mirrors solver_dep_fulfilled, but returns 2 if a new package
- * was involved */
 static int
-solver_dep_fulfilled_alreadyinstalled(Solver *solv, Id dep)
+solver_dep_fulfilled_complex_func(Solver *solv, Reldep *rd, int (*dep_fullfilled)(Solver *, Id))
 {
   Pool *pool = solv->pool;
-  Id p, pp;
-  int r;
-
-  if (ISRELDEP(dep))
+  int r1, r2;
+  if (rd->flags == REL_COND)
     {
-      Reldep *rd = GETRELDEP(pool, dep);
-      if (rd->flags == REL_COND)
+      if (ISRELDEP(rd->evr))
        {
-         int r1, r2;
-         if (ISRELDEP(rd->evr))
+         Reldep *rd2 = GETRELDEP(pool, rd->evr);
+         if (rd2->flags == REL_ELSE)
            {
-             Reldep *rd2 = GETRELDEP(pool, rd->evr);
-             if (rd2->flags == REL_ELSE)
+             r1 = dep_fullfilled(solv, rd2->name);
+             if (r1)
                {
-                 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);
+                 r2 = dep_fullfilled(solv, rd->name);
+                 return r2 && r1 == 2 ? 2 : r2;
                }
+             return dep_fullfilled(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)
+      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))
        {
-         int r1, r2;
-         if (ISRELDEP(rd->evr))
+         Reldep *rd2 = GETRELDEP(pool, rd->evr);
+         if (rd2->flags == REL_ELSE)
            {
-             Reldep *rd2 = GETRELDEP(pool, rd->evr);
-             if (rd2->flags == REL_ELSE)
+             r1 = dep_fullfilled(solv, rd2->name);
+             if (r1)
                {
-                 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);
+                 r2 = dep_fullfilled(solv, rd2->evr);
+                 return r2 && r1 == 2 ? 2 : r2;
                }
+             return dep_fullfilled(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;
        }
+      /* 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 */
+static int
+solver_dep_fulfilled_alreadyinstalled(Solver *solv, Id dep)
+{
+  Pool *pool = solv->pool;
+  Id p, pp;
+  int r;
+
+  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_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;
 }
 /*
index 62ca98288437f0c2a59d2acf34ea2434473c0627..609b58a67fb0c60d0a29d984da1ff96adbfa2c8e 100644 (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
+