]> git.ipfire.org Git - thirdparty/libsolv.git/commitdiff
add SOLVER_TARGETED and SOLVER_FLAG_NO_AUTOTARGET flags
authorMichael Schroeder <mls@suse.de>
Thu, 29 Nov 2012 11:48:12 +0000 (12:48 +0100)
committerMichael Schroeder <mls@suse.de>
Thu, 29 Nov 2012 11:48:12 +0000 (12:48 +0100)
src/rules.c
src/solver.c
src/solver.h

index d16c423113d2c072436b33d7f62ab6b85f10138e..a6940df012358603731c2a0a6add131bedac28d3 100644 (file)
@@ -1190,7 +1190,7 @@ solver_createdupmaps(Solver *solv)
   Repo *installed = solv->installed;
   Id select, how, what, p, pi, pp, pip, obs, *obsp;
   Solvable *s, *ps;
-  int i;
+  int i, targeted;
 
   map_init(&solv->dupmap, pool->nsolvables);
   map_init(&solv->dupinvolvedmap, pool->nsolvables);
@@ -1204,26 +1204,27 @@ solver_createdupmaps(Solver *solv)
        case SOLVER_DISTUPGRADE:
          if (select != SOLVER_SOLVABLE_REPO)
            {
-             int haveinstalled;
-             p = 0;
-             if (installed)
+             targeted = how & SOLVER_TARGETED ? 1 : 0;
+             if (installed && !targeted && !solv->noautotarget)
                {
                  FOR_JOB_SELECT(p, pp, select, what)
                    if (pool->solvables[p].repo == installed)
                      break;
+                 targeted = p == 0;
                }
-             haveinstalled = p != 0;
+             else if (!installed && !solv->noautotarget)
+               targeted = 1;
              FOR_JOB_SELECT(p, pp, select, what)
                {
                  Solvable *s = pool->solvables + p;
                  if (!s->repo)
                    continue;
-                 if (haveinstalled && s->repo != installed)
+                 if (!targeted && s->repo != installed)
                    continue;
                  if (s->repo != installed && !pool_installable(pool, s))
                    continue;
                  MAPSET(&solv->dupinvolvedmap, p);
-                 if (!haveinstalled)
+                 if (targeted)
                    MAPSET(&solv->dupmap, p);
                  FOR_PROVIDES(pi, pip, s->name)
                    {
@@ -1237,10 +1238,10 @@ solver_createdupmaps(Solver *solv)
                            map_grow(&solv->bestupdatemap, installed->end - installed->start);
                          MAPSET(&solv->bestupdatemap, pi - installed->start);
                        }
-                     if (haveinstalled && ps->repo != installed)
+                     if (!targeted && ps->repo != installed)
                        MAPSET(&solv->dupmap, pi);
                    }
-                 if (haveinstalled)
+                 if (!targeted)
                    {
                      if (solv->obsoletes && solv->obsoletes[p - installed->start])
                        {
@@ -1284,11 +1285,18 @@ solver_createdupmaps(Solver *solv)
          if (what <= 0 || what > pool->nrepos)
            break;
          repo = pool_id2repo(pool, what);
+         if (!repo)
+           break;
+         if (repo != installed && !(how & SOLVER_TARGETED) && solv->noautotarget)
+           break;
+         targeted = repo != installed || (how & SOLVER_TARGETED) != 0;
          FOR_REPO_SOLVABLES(repo, p, s)
            {
              if (repo != installed && !pool_installable(pool, s))
                continue;
-             MAPSET(&solv->dupmap, p);
+             MAPSET(&solv->dupinvolvedmap, p);
+             if (targeted)
+               MAPSET(&solv->dupmap, p);
              FOR_PROVIDES(pi, pip, s->name)
                {
                  ps = pool->solvables + pi;
@@ -1301,8 +1309,25 @@ solver_createdupmaps(Solver *solv)
                        map_grow(&solv->bestupdatemap, installed->end - installed->start);
                      MAPSET(&solv->bestupdatemap, pi - installed->start);
                    }
+                 if (!targeted && ps->repo != installed)
+                   MAPSET(&solv->dupmap, pi);
+               }
+             if (!targeted)
+               {
+                 if (repo == installed && solv->obsoletes && solv->obsoletes[p - installed->start])
+                   {
+                     Id *opp;
+                     for (opp = solv->obsoletes_data + solv->obsoletes[p - installed->start]; (pi = *opp++) != 0;)
+                       {
+                         ps = pool->solvables + pi;
+                         if (ps->repo == installed)
+                           continue;
+                         MAPSET(&solv->dupinvolvedmap, pi);
+                         MAPSET(&solv->dupmap, pi);
+                       }
+                   }
                }
-             if (s->obsoletes)
+             else if (s->obsoletes)
                {
                  /* XXX: check obsoletes/provides combination */
                  obsp = s->repo->idarraydata + s->obsoletes;
index ae0ddcf8bec231ed9f0ba46f9ac2ec63595a8189..bde00a3ca93b22e34d1f0f169d25b63a9782f349 100644 (file)
@@ -1485,6 +1485,8 @@ solver_get_flag(Solver *solv, int flag)
     return solv->keepexplicitobsoletes;
   case SOLVER_FLAG_BEST_OBEY_POLICY:
     return solv->bestobeypolicy;
+  case SOLVER_FLAG_NO_AUTOTARGET:
+    return solv->noautotarget;
   default:
     break;
   }
@@ -1533,6 +1535,9 @@ solver_set_flag(Solver *solv, int flag, int value)
   case SOLVER_FLAG_BEST_OBEY_POLICY:
     solv->bestobeypolicy = value;
     break;
+  case SOLVER_FLAG_NO_AUTOTARGET:
+    solv->noautotarget = value;
+    break;
   default:
     break;
   }
@@ -2606,6 +2611,11 @@ add_update_target(Solver *solv, Id p, Id how)
       solv->update_targets = solv_calloc(1, sizeof(Queue));
       queue_init(solv->update_targets);
     }
+  if (s->repo == installed)
+    {
+      queue_push2(solv->update_targets, p, p);
+      return;
+    }
   FOR_PROVIDES(pi, pip, s->name)
     {
       Solvable *si = pool->solvables + pi;
@@ -2794,45 +2804,56 @@ solver_solve(Solver *solv, Queue *job)
                }
              break;
            case SOLVER_UPDATE:
-             if (select == SOLVER_SOLVABLE_ALL || (select == SOLVER_SOLVABLE_REPO && installed && what == installed->repoid))
+             if (select == SOLVER_SOLVABLE_ALL)
                {
                  solv->updatemap_all = 1;
                  if (how & SOLVER_FORCEBEST)
                    solv->bestupdatemap_all = 1;
                }
-             else if (select == SOLVER_SOLVABLE_REPO && what != installed->repoid)
+             else if (select == SOLVER_SOLVABLE_REPO)
                {
                  Repo *repo = pool_id2repo(pool, what);
                  if (!repo)
                    break;
+                 if (repo == installed && !(how & SOLVER_TARGETED))
+                   {
+                     solv->updatemap_all = 1;
+                     if (how & SOLVER_FORCEBEST)
+                       solv->bestupdatemap_all = 1;
+                     break;
+                   }
+                 if (solv->noautotarget && !(how & SOLVER_TARGETED))
+                   break;
                  /* targeted update */
                  FOR_REPO_SOLVABLES(repo, p, s)
                    add_update_target(solv, p, how);
                }
              else
                {
-                 int targeted = 1;
-                 FOR_JOB_SELECT(p, pp, select, what)
+                 if (!(how & SOLVER_TARGETED))
                    {
-                     s = pool->solvables + p;
-                     if (s->repo != installed)
-                       continue;
-                     if (!solv->updatemap.size)
-                       map_grow(&solv->updatemap, installed->end - installed->start);
-                     MAPSET(&solv->updatemap, p - installed->start);
-                     if (how & SOLVER_FORCEBEST)
+                     int targeted = 1;
+                     FOR_JOB_SELECT(p, pp, select, what)
                        {
-                         if (!solv->bestupdatemap.size)
-                           map_grow(&solv->bestupdatemap, installed->end - installed->start);
-                         MAPSET(&solv->bestupdatemap, p - installed->start);
+                         s = pool->solvables + p;
+                         if (s->repo != installed)
+                           continue;
+                         if (!solv->updatemap.size)
+                           map_grow(&solv->updatemap, installed->end - installed->start);
+                         MAPSET(&solv->updatemap, p - installed->start);
+                         if (how & SOLVER_FORCEBEST)
+                           {
+                             if (!solv->bestupdatemap.size)
+                               map_grow(&solv->bestupdatemap, installed->end - installed->start);
+                             MAPSET(&solv->bestupdatemap, p - installed->start);
+                           }
+                         targeted = 0;
                        }
-                     targeted = 0;
-                   }
-                 if (targeted)
-                   {
-                     FOR_JOB_SELECT(p, pp, select, what)
-                       add_update_target(solv, p, how);
+                     if (!targeted || solv->noautotarget)
+                       break;
                    }
+                 FOR_JOB_SELECT(p, pp, select, what)
+                   add_update_target(solv, p, how);
                }
              break;
            default:
index 5e3a162214cad5b3194df48b7b6a80e5bc5887c6..fac1a17c7f9d83e6037631f4365f65ccfb53c168 100644 (file)
@@ -203,6 +203,7 @@ struct _Solver {
   int noinfarchcheck;                  /* true: do not forbid inferior architectures */
   int keepexplicitobsoletes;           /* true: honor obsoletes during multiinstall */
   int bestobeypolicy;                  /* true: stay in policy with the best rules */
+  int noautotarget;                    /* true: do not assume targeted for up/dup jobs that contain no installed solvable */
 
     
   Map dupmap;                          /* dup these packages*/
@@ -267,6 +268,12 @@ typedef struct _Solver Solver;
  * not installable. This can be used with INSTALL, UPDATE
  * and DISTUPGRADE */
 #define SOLVER_FORCEBEST               0x100000
+/* TARGETED is used in up/dup jobs to make the solver
+ * treat the specified selection as target packages.
+ * It is automatically assumed if the selection does not
+ * contain an "installed" package unless the
+ * NO_AUTOTARGET solver flag is set */
+#define SOLVER_TARGETED                        0x200000
 
 #define SOLVER_SETEV                   0x01000000
 #define SOLVER_SETEVR                  0x02000000
@@ -304,6 +311,7 @@ typedef struct _Solver Solver;
 #define SOLVER_FLAG_ALLOW_NAMECHANGE           10
 #define SOLVER_FLAG_KEEP_EXPLICIT_OBSOLETES    11
 #define SOLVER_FLAG_BEST_OBEY_POLICY           12
+#define SOLVER_FLAG_NO_AUTOTARGET              13
 
 extern Solver *solver_create(Pool *pool);
 extern void solver_free(Solver *solv);