]> git.ipfire.org Git - thirdparty/libsolv.git/commitdiff
Further extend choicerule filtering check
authorMichael Schroeder <mls@suse.de>
Fri, 13 Nov 2020 14:58:51 +0000 (15:58 +0100)
committerMichael Schroeder <mls@suse.de>
Fri, 13 Nov 2020 14:58:51 +0000 (15:58 +0100)
Also add testcases. Fixes issue #406.

This is getting quite complicated...

src/rules.c
test/testcases/choicerules/choice3.t [new file with mode: 0644]
test/testcases/choicerules/choice4.t [new file with mode: 0644]

index 6c8e82ba81be697494c441bf8f880c147346bceb..b3609bb0ec9c3a7d0399f33e3f5787c70a9e6854 100644 (file)
@@ -3225,6 +3225,40 @@ solver_choicerulecheck2(Solver *solv, Id pi, Id pt, Queue *q)
   return 0;    /* not newest */
 }
 
+static int
+solver_choicerulecheck3(Solver *solv, Id pt, Queue *q)
+{
+  Pool *pool = solv->pool;
+  Id p, pp;
+  int i;
+
+  if (!q->count || q->elements[0] != pt)
+    {
+      Solvable *s = pool->solvables + pt;
+      if (q->count)
+        queue_empty(q);
+      /* no installed package, so check all with same name */
+      queue_push2(q, pt, 0);
+      FOR_PROVIDES(p, pp, s->name)
+        if (pool->solvables[p].name == s->name && p != pt)
+          queue_push(q, p);
+      queue_push(q, pt);
+    }
+  if (q->count <= 3)
+    return q->count == 3 && q->elements[2] == pt ? 1 : 0;
+  if (!q->elements[1])
+    {
+      queue_deleten(q, 0, 2);
+      policy_filter_unwanted(solv, q, POLICY_MODE_CHOOSE);
+      queue_unshift(q, 1);     /* filter mark */
+      queue_unshift(q, pt);
+    }
+  for (i = 2; i < q->count; i++)
+    if (q->elements[i] == pt)
+      return 1;
+  return 0;    /* not newest */
+}
+
 static inline void
 queue_removeelement(Queue *q, Id el)
 {
@@ -3381,6 +3415,11 @@ solver_addchoicerules(Solver *solv)
              isnewest = 0;
              break;
            }
+         if (!p2 && !solver_choicerulecheck3(solv, -p, &qcheck2))
+           {
+             isnewest = 0;
+             break;
+           }
        }
       /* do extra checking */
       for (i = j = 0; i < qi.count; i += 2)
diff --git a/test/testcases/choicerules/choice3.t b/test/testcases/choicerules/choice3.t
new file mode 100644 (file)
index 0000000..d5d41ac
--- /dev/null
@@ -0,0 +1,17 @@
+repo system 0 testtags <inline>
+#>=Pkg: A 1 1 noarch
+#>=Prv: libA
+#>=Pkg: B 1 1 noarch
+#>=Req: libA
+repo available 0 testtags <inline>
+#>=Pkg: B 1 1 noarch
+#>=Req: libA
+#>=Pkg: A 2 1 noarch
+#>=Pkg: Anew 2 1 noarch
+#>=Prv: libA
+system i686 rpm system
+
+job update all packages
+result transaction,problems <inline>
+#>install Anew-2-1.noarch@available
+#>upgrade A-1-1.noarch@system A-2-1.noarch@available
diff --git a/test/testcases/choicerules/choice4.t b/test/testcases/choicerules/choice4.t
new file mode 100644 (file)
index 0000000..1bf9f48
--- /dev/null
@@ -0,0 +1,31 @@
+repo system 0 testtags <inline>
+#>=Pkg: A 1 1 noarch
+#>=Prv: libA = 1-1
+repo available 0 testtags <inline>
+#>=Pkg: A 1 1 noarch
+#>=Prv: libA = 1-1
+#>=Pkg: Anew 1 1 noarch
+#>=Prv: libA = 1-1
+#>=Pkg: B 1 1 noarch
+#>=Req: libA = 1-1
+#>=Pkg: A 2 1 noarch
+#>=Prv: libA = 2-1
+#>=Pkg: Anew 2 1 noarch
+#>=Prv: libA = 2-1
+#>=Pkg: B 2 1 noarch
+#>=Req: libA = 2-1
+#>=Pkg: A 2 2 noarch
+#>=Prv: libA = 2-2
+#>=Pkg: Anew 2 2 noarch
+#>=Prv: libA = 2-2
+#>=Pkg: B 2 2 noarch
+#>=Req: libA = 2-2
+#>=Pkg: C 2 1 noarch
+#>=Req: B = 2
+system i686 rpm system
+
+job install name C
+result transaction,problems <inline>
+#>install B-2-2.noarch@available
+#>install C-2-1.noarch@available
+#>upgrade A-1-1.noarch@system A-2-2.noarch@available