]> git.ipfire.org Git - thirdparty/libsolv.git/commitdiff
Add mechanisms to ignore pkgs for weak dependencies 454/head
authorJaroslav Mracek <jmracek@redhat.com>
Tue, 22 Jun 2021 14:30:45 +0000 (16:30 +0200)
committerJaroslav Mracek <jmracek@redhat.com>
Mon, 9 Aug 2021 14:14:22 +0000 (16:14 +0200)
It adds mechanism to avoid installation of certain packages
to satisfy recommends and supplemented.

bindings/solv.i
doc/libsolv-bindings.txt
ext/testcase.c
src/solver.c
src/solver.h
test/testcases/excludefromweak/excludefromweak-obsoletes.t [new file with mode: 0644]
test/testcases/excludefromweak/excludefromweak.t [new file with mode: 0644]

index abfb5e15a4ff3d80128e96847e3270cf50effeee..61c6fc825d3f6249fc1fbef5e789ae01adc41e31 100644 (file)
@@ -1283,6 +1283,7 @@ typedef struct {
   static const Id SOLVER_ALLOWUNINSTALL = SOLVER_ALLOWUNINSTALL;
   static const Id SOLVER_FAVOR = SOLVER_FAVOR;
   static const Id SOLVER_DISFAVOR = SOLVER_DISFAVOR;
+  static const Id SOLVER_EXCLUDEFROMWEAK = SOLVER_EXCLUDEFROMWEAK;
   static const Id SOLVER_JOBMASK = SOLVER_JOBMASK;
   static const Id SOLVER_WEAK = SOLVER_WEAK;
   static const Id SOLVER_ESSENTIAL = SOLVER_ESSENTIAL;
index ac112cfd760953f74799e3440bbd136b6c7d4a0e..0fa313bfb0c1d99cf66a426209981db01eb8260c 100644 (file)
@@ -2076,6 +2076,10 @@ Avoid the specified packages if the solver encounters an alternative. This
 can also be used to block recommended or supplemented packages from being
 installed.
 
+*SOLVER_EXCLUDEFROMWEAK*::
+Avoid the specified packages to satisfy recommended or supplemented dependencies.
+Unlike SOLVER_DISFAVOR, it does not interfere with other rules.
+
 *SOLVER_JOBMASK*::
 A mask containing all the above action bits.
 
index 20b0c48faa3d0bc950c2caf34dcce629c2836693..055452f8355afb99f86ac1c89a1b002af4d6b3fd 100644 (file)
@@ -60,6 +60,7 @@ static struct job2str {
   { SOLVER_FAVOR,          "favor" },
   { SOLVER_DISFAVOR,       "disfavor" },
   { SOLVER_BLACKLIST,      "blacklist" },
+  { SOLVER_EXCLUDEFROMWEAK,   "excludefromweak" },
   { 0, 0 }
 };
 
index 89a2ed10f85cf10c14ca9fa2053a8fccafd259dd..1dc2c783f0c25f88273b9b4510dbbe477db131ea 100644 (file)
@@ -1398,6 +1398,8 @@ solver_free(Solver *solv)
   map_free(&solv->droporphanedmap);
   map_free(&solv->cleandepsmap);
   map_free(&solv->allowuninstallmap);
+  map_free(&solv->excludefromweakmap);
+
 
   solv_free(solv->favormap);
   solv_free(solv->decisionmap);
@@ -2202,6 +2204,20 @@ prune_disfavored(Solver *solv, Queue *plist)
     queue_truncate(plist, j);
 }
 
+static void
+prune_exclude_from_weak(Solver *solv, Queue *plist)
+{
+  int i, j;
+  for (i = j = 0; i < plist->count; i++)
+    {
+      Id p = plist->elements[i];
+      if (!MAPTST(&solv->excludefromweakmap, p))
+        plist->elements[j++] = p;
+    }
+  if (i != j)
+    queue_truncate(plist, j);
+}
+
 static int
 resolve_weak(Solver *solv, int level, int disablerules, Queue *dq, Queue *dqs, int *rerunp)
 {
@@ -2275,6 +2291,8 @@ resolve_weak(Solver *solv, int level, int disablerules, Queue *dq, Queue *dqs, i
            continue;
          if (solv->havedisfavored && solv->favormap[i] < 0)
            continue;   /* disfavored supplements, do not install */
+         if (solv->excludefromweakmap.size && MAPTST(&solv->excludefromweakmap, i))
+           continue;   /* excluded for weak deps, do not install */
          queue_push(dqs, i);
        }
     }
@@ -2283,6 +2301,10 @@ resolve_weak(Solver *solv, int level, int disablerules, Queue *dq, Queue *dqs, i
   if (dq->count && solv->havedisfavored)
     prune_disfavored(solv, dq);
 
+  /* filter out weak_excluded recommended packages */
+  if (solv->excludefromweakmap.size)
+    prune_exclude_from_weak(solv, dq);
+
   /* filter out all packages obsoleted by installed packages */
   /* this is no longer needed if we have (and trust) reverse obsoletes */
   if ((dqs->count || dq->count) && solv->installed)
@@ -3319,6 +3341,37 @@ add_complex_jobrules(Solver *solv, Id dep, int flags, int jobidx, int weak)
 }
 #endif
 
+static void
+solver_add_exclude_from_weak(Solver *solv)
+{
+  Queue *job = &solv->job;
+  Pool *pool = solv->pool;
+  int i;
+  Id p, pp, how, what, select;
+for (i = 0; i < job->count; i += 2)
+  {
+    how = job->elements[i];
+    if ((how & SOLVER_JOBMASK) != SOLVER_EXCLUDEFROMWEAK)
+       continue;
+    if (!solv->excludefromweakmap.size)
+       map_grow(&solv->excludefromweakmap, pool->nsolvables);
+    what = job->elements[i + 1];
+    select = how & SOLVER_SELECTMASK;
+    if (select == SOLVER_SOLVABLE_REPO)
+      {
+       Repo *repo = pool_id2repo(pool, what);
+         if (repo)
+           {
+             Solvable *s;
+             FOR_REPO_SOLVABLES(repo, p, s)
+               MAPSET(&solv->excludefromweakmap, p);
+           }
+       }
+      FOR_JOB_SELECT(p, pp, select, what)
+       MAPSET(&solv->excludefromweakmap, p);
+    }
+}
+
 static void
 setup_favormap(Solver *solv)
 {
@@ -3385,6 +3438,7 @@ solver_solve(Solver *solv, Queue *job)
   int hasfavorjob = 0;
   int haslockjob = 0;
   int hasblacklistjob = 0;
+  int hasexcludefromweakjob = 0;
 
   solve_start = solv_timems(0);
 
@@ -3436,6 +3490,7 @@ solver_solve(Solver *solv, Queue *job)
   map_zerosize(&solv->droporphanedmap);
   solv->allowuninstall_all = 0;
   map_zerosize(&solv->allowuninstallmap);
+  map_zerosize(&solv->excludefromweakmap);
   map_zerosize(&solv->cleandepsmap);
   map_zerosize(&solv->weakrulemap);
   solv->favormap = solv_free(solv->favormap);
@@ -3999,6 +4054,10 @@ solver_solve(Solver *solv, Queue *job)
          POOL_DEBUG(SOLV_DEBUG_JOB, "job: blacklist %s\n", solver_select2str(pool, select, what));
          hasblacklistjob = 1;
          break;
+        case SOLVER_EXCLUDEFROMWEAK:
+         POOL_DEBUG(SOLV_DEBUG_JOB, "job: excludefromweak %s\n", solver_select2str(pool, select, what));
+         hasexcludefromweakjob = 1;
+         break;
        default:
          POOL_DEBUG(SOLV_DEBUG_JOB, "job: unknown job\n");
          break;
@@ -4057,6 +4116,9 @@ solver_solve(Solver *solv, Queue *job)
   else
     solv->blackrules = solv->blackrules_end = solv->nrules;
 
+  if (hasexcludefromweakjob)
+    solver_add_exclude_from_weak(solv);
+
   if (solv->havedisfavored && solv->strongrecommends && solv->recommendsruleq)
     solver_addrecommendsrules(solv);
   else
index 2dec2590a226b2f056b86190f261073dbefe8cf4..d30ae361548d4277ab32bf93ff23184955ef559e 100644 (file)
@@ -208,6 +208,8 @@ struct s_Solver {
   Map allowuninstallmap;               /* ok to uninstall those */
   int allowuninstall_all;
 
+  Map excludefromweakmap;              /* remove them from candidates for supplements and recommends */
+
   Id *favormap;                                /* favor job index, > 0: favored, < 0: disfavored */
   int havedisfavored;                  /* do we have disfavored packages? */
 
@@ -248,6 +250,7 @@ typedef struct s_Solver Solver;
 #define SOLVER_FAVOR                   0x0c00
 #define SOLVER_DISFAVOR                        0x0d00
 #define SOLVER_BLACKLIST               0x0e00
+#define SOLVER_EXCLUDEFROMWEAK         0x1000
 
 #define SOLVER_JOBMASK                 0xff00
 
diff --git a/test/testcases/excludefromweak/excludefromweak-obsoletes.t b/test/testcases/excludefromweak/excludefromweak-obsoletes.t
new file mode 100644 (file)
index 0000000..adc20d5
--- /dev/null
@@ -0,0 +1,35 @@
+repo @System 0 testtags <inline>
+#>=Pkg: pkg-A 1.0 1 noarch
+#>=Prv: pkg-A = 1.0-1
+#>=Rec: pkg-C
+#>=Pkg: pkg-B 1.0 1 noarch
+#>=Prv: pkg-B = 1.0-1
+
+repo available -99.-1000 testtags <inline>
+#>=Pkg: pkg-A 1.0 3 noarch
+#>=Prv: pkg-A = 1.0-3
+#>=Rec: pkg-B
+#>=Pkg: pkg-B 1.0 2 noarch
+#>=Prv: pkg-B = 1.0-2
+#>=Pkg: pkg-C 1.0 1 noarch
+#>=Prv: pkg-C = 1.0-1
+#>=Obs: pkg-B
+
+system x86_64 rpm @System
+poolflags implicitobsoleteusescolors
+solverflags allowvendorchange keepexplicitobsoletes bestobeypolicy keeporphans yumobsoletes
+
+job update all packages [forcebest]
+job excludefromweak name pkg-C
+result transaction,problems <inline>
+#>erase pkg-B-1.0-1.noarch@@System pkg-C-1.0-1.noarch@available
+#>install pkg-C-1.0-1.noarch@available
+#>upgrade pkg-A-1.0-1.noarch@@System pkg-A-1.0-3.noarch@available
+
+nextjob
+job update oneof pkg-A-1.0-1.noarch@@System pkg-B-1.0-1.noarch@@System pkg-A-1.0-3.noarch@available pkg-B-1.0-2.noarch@available pkg-C-1.0-1.noarch@available [forcebest,targeted,setevr,setarch]
+job excludefromweak name pkg-C
+result transaction,problems <inline>
+#>erase pkg-B-1.0-1.noarch@@System pkg-C-1.0-1.noarch@available
+#>install pkg-C-1.0-1.noarch@available
+#>upgrade pkg-A-1.0-1.noarch@@System pkg-A-1.0-3.noarch@available
diff --git a/test/testcases/excludefromweak/excludefromweak.t b/test/testcases/excludefromweak/excludefromweak.t
new file mode 100644 (file)
index 0000000..4d6d859
--- /dev/null
@@ -0,0 +1,24 @@
+repo @System 0 testtags <inline>
+
+repo available -99.-1000 testtags <inline>
+#>=Pkg: pkg-A 1 1 noarch
+#>=Prv: pkg-A = 1-1
+#>=Rec: pkg-B
+#>=Pkg: pkg-B 1 1 noarch
+#>=Prv: pkg-B = 1-1
+
+system x86_64 rpm @System
+poolflags implicitobsoleteusescolors
+solverflags allowvendorchange keepexplicitobsoletes bestobeypolicy keeporphans yumobsoletes
+
+job install oneof pkg-A-1-1.noarch@available [forcebest,targeted,setevr,setarch]
+job excludefromweak name pkg-B
+result transaction,problems <inline>
+#>install pkg-A-1-1.noarch@available
+
+nextjob
+job install oneof pkg-A-1-1.noarch@available [forcebest,targeted,setevr,setarch]
+job excludefromweak name pkg-A
+job excludefromweak name pkg-B
+result transaction,problems <inline>
+#>install pkg-A-1-1.noarch@available