]> git.ipfire.org Git - thirdparty/libsolv.git/commitdiff
Support SOLVER_ALLOWUNINSTALL jobs
authorMichael Schroeder <mls@suse.de>
Mon, 21 Sep 2015 11:47:02 +0000 (13:47 +0200)
committerMichael Schroeder <mls@suse.de>
Mon, 21 Sep 2015 11:47:02 +0000 (13:47 +0200)
This works like the SOLVER_FLAG_ALLOW_UNINSTALL flag, but limited
to a specific set of packages.

bindings/solv.i
doc/libsolv-bindings.3
doc/libsolv-bindings.txt
ext/testcase.c
src/solver.c
src/solver.h

index 0c37f6c6316c74da2051705b557d6c3bab8f75e3..823dedac73817342753e86325c4177fa3109d0bc 100644 (file)
@@ -1171,6 +1171,7 @@ typedef struct {
   static const Id SOLVER_VERIFY = SOLVER_VERIFY;
   static const Id SOLVER_DROP_ORPHANED = SOLVER_DROP_ORPHANED;
   static const Id SOLVER_USERINSTALLED = SOLVER_USERINSTALLED;
+  static const Id SOLVER_ALLOWUNINSTALL = SOLVER_ALLOWUNINSTALL;
   static const Id SOLVER_JOBMASK = SOLVER_JOBMASK;
   static const Id SOLVER_WEAK = SOLVER_WEAK;
   static const Id SOLVER_ESSENTIAL = SOLVER_ESSENTIAL;
index 9fe26c13319d305fee24c7120baa71d245e3d86d..dc86e1f997447d3bf7f6423c7af6269ad03ccc5f 100644 (file)
@@ -2,12 +2,12 @@
 .\"     Title: Libsolv-Bindings
 .\"    Author: [see the "Author" section]
 .\" Generator: DocBook XSL Stylesheets v1.78.0 <http://docbook.sf.net/>
-.\"      Date: 08/28/2015
+.\"      Date: 09/21/2015
 .\"    Manual: LIBSOLV
 .\"    Source: libsolv
 .\"  Language: English
 .\"
-.TH "LIBSOLV\-BINDINGS" "3" "08/28/2015" "libsolv" "LIBSOLV"
+.TH "LIBSOLV\-BINDINGS" "3" "09/21/2015" "libsolv" "LIBSOLV"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
@@ -3251,6 +3251,11 @@ Fix dependency problems of matching installed packages\&. The default is to igno
 The matching installed packages are considered to be installed by a user, thus not installed to fulfill some dependency\&. This is needed input for the calculation of unneeded packages for jobs that have the SOLVER_CLEANDEPS flag set\&.
 .RE
 .PP
+\fBSOLVER_ALLOWUNINSTALL\fR
+.RS 4
+Allow the solver to deinstall the matching installed packages if they get into the way of resolving a dependency\&. This is like the SOLVER_FLAG_ALLOW_UNINSTALL flag, but limited to a specific set of packages\&.
+.RE
+.PP
 \fBSOLVER_JOBMASK\fR
 .RS 4
 A mask containing all the above action bits\&.
index 175d922e2567e254fa419a0b737c349cfbd5aadb..13d73bd319dadddcfee001db5cc1b06f0a99e872 100644 (file)
@@ -1873,6 +1873,11 @@ thus not installed to fulfill some dependency. This is needed input for
 the calculation of unneeded packages for jobs that have the
 SOLVER_CLEANDEPS flag set.
 
+*SOLVER_ALLOWUNINSTALL*::
+Allow the solver to deinstall the matching installed packages if they get
+into the way of resolving a dependency. This is like the
+SOLVER_FLAG_ALLOW_UNINSTALL flag, but limited to a specific set of packages.
+
 *SOLVER_JOBMASK*::
 A mask containing all the above action bits.
 
index e4346fe76d7f5ab88424db663a2bece5279a3742..3c404515dc28d30b7431dc23fa6131bf801cbf70 100644 (file)
@@ -33,18 +33,19 @@ static struct job2str {
   Id job;
   const char *str;
 } job2str[] = {
-  { SOLVER_NOOP,          "noop" },
-  { SOLVER_INSTALL,       "install" },
-  { SOLVER_ERASE,         "erase" },
-  { SOLVER_UPDATE,        "update" },
-  { SOLVER_WEAKENDEPS,    "weakendeps" },
-  { SOLVER_MULTIVERSION,  "multiversion" },
-  { SOLVER_MULTIVERSION,  "noobsoletes" },     /* old name */
-  { SOLVER_LOCK,          "lock" },
-  { SOLVER_DISTUPGRADE,   "distupgrade" },
-  { SOLVER_VERIFY,        "verify" },
-  { SOLVER_DROP_ORPHANED, "droporphaned" },
-  { SOLVER_USERINSTALLED, "userinstalled" },
+  { SOLVER_NOOP,           "noop" },
+  { SOLVER_INSTALL,        "install" },
+  { SOLVER_ERASE,          "erase" },
+  { SOLVER_UPDATE,         "update" },
+  { SOLVER_WEAKENDEPS,     "weakendeps" },
+  { SOLVER_MULTIVERSION,   "multiversion" },
+  { SOLVER_MULTIVERSION,   "noobsoletes" },    /* old name */
+  { SOLVER_LOCK,           "lock" },
+  { SOLVER_DISTUPGRADE,    "distupgrade" },
+  { SOLVER_VERIFY,         "verify" },
+  { SOLVER_DROP_ORPHANED,  "droporphaned" },
+  { SOLVER_USERINSTALLED,  "userinstalled" },
+  { SOLVER_ALLOWUNINSTALL, "allowuninstall" },
   { 0, 0 }
 };
 
index b89e0d17ed863a560c5d3c946586bda4816d8b3e..3358b6b07f55063b74cb4180e4b80b2da0cea80b 100644 (file)
@@ -200,15 +200,25 @@ autouninstall(Solver *solv, Id *problem)
   int lastfeature = 0, lastupdate = 0;
   Id v;
   Id extraflags = -1;
+  Map *m = 0;
 
+  if (!solv->allowuninstall && !solv->allowuninstall_all)
+    {
+      if (!solv->allowuninstallmap.size)
+       return 0;               /* why did we get called? */
+      m = &solv->allowuninstallmap;
+    }
   for (i = 0; (v = problem[i]) != 0; i++)
     {
       if (v < 0)
        extraflags &= solv->job.elements[-v - 1];
       if (v >= solv->updaterules && v < solv->updaterules_end)
        {
+         Rule *r;
+         if (m && !MAPTST(m, v - solv->updaterules))
+           continue;
          /* check if identical to feature rule, we don't like that */
-         Rule *r = solv->rules + solv->featurerules + (v - solv->updaterules);
+         r = solv->rules + solv->featurerules + (v - solv->updaterules);
          if (!r->p)
            {
              /* update rule == feature rule */
@@ -427,8 +437,16 @@ makeruledecisions(Solver *solv)
                v = ri;
              queue_push(&solv->problems, v);
              queue_push(&solv->problems, 0);
-             if (solv->allowuninstall && v >= solv->featurerules && v < solv->updaterules_end)
-               solv->problems.count = oldproblemcount;
+             if (v >= solv->featurerules && v < solv->updaterules_end)
+               {
+                 if (solv->allowuninstall || solv->allowuninstall_all || solv->allowuninstallmap.size)
+                   if (autouninstall(solv, solv->problems.elements + oldproblemcount + 1) != 0)
+                     {
+                       solv->problems.count = oldproblemcount;
+                       havedisabled = 1;
+                       break;  /* start over */
+                     }
+               }
              solver_disableproblem(solv, v);
              havedisabled = 1;
              break;    /* start over */
@@ -458,8 +476,16 @@ makeruledecisions(Solver *solv)
                v = ri;
              queue_push(&solv->problems, v);
              queue_push(&solv->problems, 0);
-             if (solv->allowuninstall && v >= solv->featurerules && v < solv->updaterules_end)
-               solv->problems.count = oldproblemcount;
+             if (v >= solv->featurerules && v < solv->updaterules_end)
+               {
+                 if (solv->allowuninstall || solv->allowuninstall_all || solv->allowuninstallmap.size)
+                   if (autouninstall(solv, solv->problems.elements + oldproblemcount + 1) != 0)
+                     {
+                       solv->problems.count = oldproblemcount;
+                       havedisabled = 1;
+                       break;  /* start over */
+                     }
+               }
              solver_disableproblem(solv, v);
              havedisabled = 1;
              break;    /* start over */
@@ -507,8 +533,13 @@ makeruledecisions(Solver *solv)
            }
          queue_push(&solv->problems, 0);
 
-         if (solv->allowuninstall && (v = autouninstall(solv, solv->problems.elements + oldproblemcount + 1)) != 0)
-           solv->problems.count = oldproblemcount;
+         if (solv->allowuninstall || solv->allowuninstall_all || solv->allowuninstallmap.size)
+           if (autouninstall(solv, solv->problems.elements + oldproblemcount + 1) != 0)
+             {
+               solv->problems.count = oldproblemcount;
+               havedisabled = 1;
+               break;  /* start over */
+             }
 
          for (i = oldproblemcount + 1; i < solv->problems.count - 1; i++)
            solver_disableproblem(solv, solv->problems.elements[i]);
@@ -1245,13 +1276,14 @@ analyze_unsolvable(Solver *solv, Rule *cr, int disablerules)
       return 0;
     }
 
-  if (solv->allowuninstall && (v = autouninstall(solv, solv->problems.elements + oldproblemcount + 1)) != 0)
-    {
-      solv->problems.count = oldproblemcount;
-      solv->learnt_pool.count = oldlearntpoolcount;
-      solver_reset(solv);
-      return 0;
-    }
+  if (solv->allowuninstall || solv->allowuninstall_all || solv->allowuninstallmap.size)
+    if (autouninstall(solv, solv->problems.elements + oldproblemcount + 1) != 0)
+      {
+       solv->problems.count = oldproblemcount;
+       solv->learnt_pool.count = oldlearntpoolcount;
+       solver_reset(solv);
+       return 0;
+      }
 
   /* finish proof */
   if (record_proof)
@@ -1672,6 +1704,7 @@ solver_free(Solver *solv)
   map_free(&solv->dupinvolvedmap);
   map_free(&solv->droporphanedmap);
   map_free(&solv->cleandepsmap);
+  map_free(&solv->allowuninstallmap);
 
   solv_free(solv->decisionmap);
   solv_free(solv->rules);
@@ -3359,6 +3392,8 @@ solver_solve(Solver *solv, Queue *job)
   map_zerosize(&solv->dupinvolvedmap);
   solv->droporphanedmap_all = 0;
   map_zerosize(&solv->droporphanedmap);
+  solv->allowuninstall_all = 0;
+  map_zerosize(&solv->allowuninstallmap);
   map_zerosize(&solv->cleandepsmap);
   map_zerosize(&solv->weakrulemap);
   queue_empty(&solv->weakruleq);
@@ -3873,6 +3908,20 @@ solver_solve(Solver *solv, Queue *job)
        case SOLVER_USERINSTALLED:
          POOL_DEBUG(SOLV_DEBUG_JOB, "job: user installed %s\n", solver_select2str(pool, select, what));
          break;
+       case SOLVER_ALLOWUNINSTALL:
+         POOL_DEBUG(SOLV_DEBUG_JOB, "job: allowuninstall %s\n", solver_select2str(pool, select, what));
+         if (select == SOLVER_SOLVABLE_ALL || (select == SOLVER_SOLVABLE_REPO && installed && what == installed->repoid))
+           solv->allowuninstall_all = 1;
+         FOR_JOB_SELECT(p, pp, select, what)
+           {
+             s = pool->solvables + p;
+             if (s->repo != installed)
+               continue;
+             if (!solv->allowuninstallmap.size)
+               map_grow(&solv->allowuninstallmap, installed->end - installed->start);
+             MAPSET(&solv->allowuninstallmap, p - installed->start);
+           }
+         break;
        default:
          POOL_DEBUG(SOLV_DEBUG_JOB, "job: unknown job\n");
          break;
@@ -5082,6 +5131,9 @@ pool_job2str(Pool *pool, Id how, Id what, Id flagmask)
     case SOLVER_USERINSTALLED:
       strstart = "regard ", strend = " as userinstalled";
       break;
+    case SOLVER_ALLOWUNINSTALL:
+      strstart = "allow deinstallation of ";
+      break;
     default:
       strstart = "unknown job ";
       break;
index 1a47ae018e1bc1cdaca6a68353b8343dcc1b201f..2ae9c8d569ccff6953d72e4ac1dac1105bb29591 100644 (file)
@@ -195,6 +195,10 @@ struct _Solver {
   int keep_orphans;                    /* how to treat orphans */
   int break_orphans;                   /* how to treat orphans */
   Queue *brokenorphanrules;            /* broken rules of orphaned packages */
+
+  Map allowuninstallmap;               /* ok to uninstall those */
+  int allowuninstall_all;
+
 #endif /* LIBSOLV_INTERNAL */
 };
 
@@ -223,7 +227,8 @@ typedef struct _Solver Solver;
 #define SOLVER_DISTUPGRADE             0x0700
 #define SOLVER_VERIFY                  0x0800
 #define SOLVER_DROP_ORPHANED           0x0900
-#define SOLVER_USERINSTALLED            0x0a00
+#define SOLVER_USERINSTALLED           0x0a00
+#define SOLVER_ALLOWUNINSTALL          0x0b00
 
 #define SOLVER_JOBMASK                 0xff00