support cleandeps in targeted up/dup cases, add tests
authorMichael Schroeder <mls@suse.de>
Tue, 4 Dec 2012 13:00:34 +0000 (14:00 +0100)
committerMichael Schroeder <mls@suse.de>
Tue, 4 Dec 2012 13:00:34 +0000 (14:00 +0100)
bindings/solv.i
examples/pysolv
src/rules.c
src/solver.c
test/testcases/cleandeps/cleandeps_dup.t [new file with mode: 0644]
test/testcases/cleandeps/cleandeps_in.t [new file with mode: 0644]
test/testcases/cleandeps/cleandeps_up.t [new file with mode: 0644]
test/testcases/cleandeps/mistake-packages.repo [deleted file]
test/testcases/cleandeps/mistake-system.repo [deleted file]
test/testcases/cleandeps/mistake.t

index 8bd8ee4..d83df92 100644 (file)
@@ -777,11 +777,14 @@ typedef struct {
   static const Id SOLVER_WEAK = SOLVER_WEAK;
   static const Id SOLVER_ESSENTIAL = SOLVER_ESSENTIAL;
   static const Id SOLVER_CLEANDEPS = SOLVER_CLEANDEPS;
+  static const Id SOLVER_FORCEBEST = SOLVER_FORCEBEST;
+  static const Id SOLVER_TARGETED = SOLVER_TARGETED;
   static const Id SOLVER_SETEV = SOLVER_SETEV;
   static const Id SOLVER_SETEVR = SOLVER_SETEVR;
   static const Id SOLVER_SETARCH = SOLVER_SETARCH;
   static const Id SOLVER_SETVENDOR = SOLVER_SETVENDOR;
   static const Id SOLVER_SETREPO = SOLVER_SETREPO;
+  static const Id SOLVER_SETNAME = SOLVER_SETNAME;
   static const Id SOLVER_NOAUTOSET = SOLVER_NOAUTOSET;
   static const Id SOLVER_SETMASK = SOLVER_SETMASK;
 
@@ -2372,7 +2375,7 @@ typedef struct {
     Id extraflags = solver_solutionelement_extrajobflags($self->solv, $self->problemid, $self->solutionid);
     if ($self->type == SOLVER_SOLUTION_JOB)
       return new_Job($self->solv->pool, SOLVER_NOOP, 0);
-    if ($self->type == SOLVER_SOLUTION_INFARCH || $self->type == SOLVER_SOLUTION_DISTUPGRADE)
+    if ($self->type == SOLVER_SOLUTION_INFARCH || $self->type == SOLVER_SOLUTION_DISTUPGRADE || $self->type == SOLVER_SOLUTION_BEST)
       return new_Job($self->solv->pool, SOLVER_INSTALL|SOLVER_SOLVABLE|extraflags, $self->p);
     if ($self->type == SOLVER_SOLUTION_REPLACE || $self->type == SOLVER_SOLUTION_REPLACE_DOWNGRADE || $self->type == SOLVER_SOLUTION_REPLACE_ARCHCHANGE || $self->type == SOLVER_SOLUTION_REPLACE_VENDORCHANGE)
       return new_Job($self->solv->pool, SOLVER_INSTALL|SOLVER_SOLVABLE|extraflags, $self->rp);
@@ -2406,6 +2409,7 @@ typedef struct {
   static const int SOLVER_SOLUTION_JOB = SOLVER_SOLUTION_JOB;
   static const int SOLVER_SOLUTION_INFARCH = SOLVER_SOLUTION_INFARCH;
   static const int SOLVER_SOLUTION_DISTUPGRADE = SOLVER_SOLUTION_DISTUPGRADE;
+  static const int SOLVER_SOLUTION_BEST = SOLVER_SOLUTION_BEST;
   static const int SOLVER_SOLUTION_ERASE = SOLVER_SOLUTION_ERASE;
   static const int SOLVER_SOLUTION_REPLACE = SOLVER_SOLUTION_REPLACE;
   static const int SOLVER_SOLUTION_REPLACE_DOWNGRADE = SOLVER_SOLUTION_REPLACE_DOWNGRADE;
index 23cdd98..7e2eda5 100755 (executable)
@@ -568,7 +568,9 @@ def load_stub(repodata):
 
 
 parser = OptionParser(usage="usage: solv.py [options] COMMAND")
-parser.add_option('-r', '--repo', action="append", type="string", dest="repos")
+parser.add_option('-r', '--repo', action="append", type="string", dest="repos", help="limit to specified repositories")
+parser.add_option('--best', action="store_true", dest="best", help="force installation/update to best packages")
+parser.add_option('--clean', action="store_true", dest="clean", help="delete no longer needed packages")
 (options, args) = parser.parse_args()
 if not args:
     parser.print_help(sys.stderr)
@@ -744,6 +746,10 @@ if cmd == 'list' or cmd == 'info':
 for job in jobs:
     if cmd == 'up' and job.isemptyupdate():
         job.how ^= Job.SOLVER_UPDATE ^ Job.SOLVER_INSTALL
+    if options.best:
+        job.how |= Job.SOLVER_FORCEBEST
+    if options.clean:
+        job.how |= Job.SOLVER_CLEANDEPS
 
 #pool.set_debuglevel(2)
 solver = None
index 5f8cfbc..4a9459d 100644 (file)
@@ -1181,6 +1181,17 @@ reenableinfarchrule(Solver *solv, Id name)
  ***
  ***/
 
+static inline void 
+add_cleandeps_package(Solver *solv, Id p)
+{
+  if (!solv->cleandeps_updatepkgs)
+    {    
+      solv->cleandeps_updatepkgs = solv_calloc(1, sizeof(Queue));
+      queue_init(solv->cleandeps_updatepkgs);
+    }    
+  queue_pushunique(solv->cleandeps_updatepkgs, p); 
+}
+
 static inline void
 solver_addtodupmaps(Solver *solv, Id p, Id how, int targeted)
 {
@@ -1211,6 +1222,8 @@ solver_addtodupmaps(Solver *solv, Id p, Id how, int targeted)
            map_grow(&solv->bestupdatemap, installed->end - installed->start);
          MAPSET(&solv->bestupdatemap, pi - installed->start);
        }
+      if (ps->repo == installed && (how & SOLVER_CLEANDEPS) != 0)
+       add_cleandeps_package(solv, pi);
       if (!targeted && ps->repo != installed)
        MAPSET(&solv->dupmap, pi);
     }
@@ -1254,6 +1267,8 @@ solver_addtodupmaps(Solver *solv, Id p, Id how, int targeted)
                    map_grow(&solv->bestupdatemap, installed->end - installed->start);
                  MAPSET(&solv->bestupdatemap, pi - installed->start);
                }
+             if (ps->repo == installed && (how & SOLVER_CLEANDEPS) != 0)
+               add_cleandeps_package(solv, pi);
            }
        }
     }
@@ -2692,7 +2707,7 @@ solver_createcleandepsmap(Solver *solv, Map *cleandepsmap, int unneeded)
   Id p, pp, ip, jp;
   Id req, *reqp, sup, *supp;
   Solvable *s;
-  Queue iq;
+  Queue iq, iqcopy;
   int i;
 
   map_empty(cleandepsmap);
@@ -2787,9 +2802,9 @@ solver_createcleandepsmap(Solver *solv, Map *cleandepsmap, int unneeded)
   for (rid = solv->jobrules; rid < solv->jobrules_end; rid++)
     {
       r = solv->rules + rid;
-      if (r->d < 0)
+      if (r->d < 0)                            /* disabled? */
        continue;
-      if (r->d == 0 && r->p < 0 && r->w2 == 0)
+      if (r->d == 0 && r->p < 0 && r->w2 == 0) /* negative assertion (erase job)? */
        {
          p = -r->p;
          if (pool->solvables[p].repo != installed)
@@ -2802,7 +2817,7 @@ solver_createcleandepsmap(Solver *solv, Map *cleandepsmap, int unneeded)
          if ((how & (SOLVER_JOBMASK|SOLVER_CLEANDEPS)) == (SOLVER_ERASE|SOLVER_CLEANDEPS))
            queue_push(&iq, p);
        }
-      else if (r->p > 0)
+      else if (r->p > 0)                       /* install job */
        {
          if (unneeded)
            continue;
@@ -2859,6 +2874,7 @@ solver_createcleandepsmap(Solver *solv, Map *cleandepsmap, int unneeded)
            }
        }
     }
+  queue_init_clone(&iqcopy, &iq);
 
   if (!unneeded)
     {
@@ -3134,12 +3150,17 @@ solver_createcleandepsmap(Solver *solv, Map *cleandepsmap, int unneeded)
     }
     
   queue_free(&iq);
+  /* make sure the updatepkgs and mistakes are not in the cleandeps map */
   if (solv->cleandeps_updatepkgs)
     for (i = 0; i < solv->cleandeps_updatepkgs->count; i++)
       MAPSET(&im, solv->cleandeps_updatepkgs->elements[i]);
   if (solv->cleandeps_mistakes)
     for (i = 0; i < solv->cleandeps_mistakes->count; i++)
       MAPSET(&im, solv->cleandeps_mistakes->elements[i]);
+  /* also remove original iq packages */
+  for (i = 0; i < iqcopy.count; i++)
+    MAPSET(&im, iqcopy.elements[i]);
+  queue_free(&iqcopy);
   for (p = installed->start; p < installed->end; p++)
     {
       if (pool->solvables[p].repo != installed)
@@ -3150,6 +3171,12 @@ solver_createcleandepsmap(Solver *solv, Map *cleandepsmap, int unneeded)
   map_free(&im);
   map_free(&installedm);
   map_free(&userinstalled);
+#ifdef CLEANDEPSDEBUG
+  printf("=== final cleandeps map:\n");
+  for (p = installed->start; p < installed->end; p++)
+    if (MAPTST(cleandepsmap, p - installed->start))
+      printf("  - %s\n", pool_solvid2str(pool, p));
+#endif
 }
 
 
index 36af038..8b6140c 100644 (file)
@@ -2639,6 +2639,17 @@ solver_addjobrule(Solver *solv, Id p, Id d, Id job, int weak)
     queue_push(&solv->weakruleq, solv->nrules - 1);
 }
 
+static inline void
+add_cleandeps_package(Solver *solv, Id p)
+{
+  if (!solv->cleandeps_updatepkgs)
+    {
+      solv->cleandeps_updatepkgs = solv_calloc(1, sizeof(Queue));
+      queue_init(solv->cleandeps_updatepkgs);
+    }
+  queue_pushunique(solv->cleandeps_updatepkgs, p);
+}
+
 static void
 add_update_target(Solver *solv, Id p, Id how)
 {
@@ -2667,6 +2678,8 @@ add_update_target(Solver *solv, Id p, Id how)
            map_grow(&solv->bestupdatemap, installed->end - installed->start);
          MAPSET(&solv->bestupdatemap, pi - installed->start);
        }
+      if (how & SOLVER_CLEANDEPS)
+       add_cleandeps_package(solv, pi);
       queue_push2(solv->update_targets, pi, p);
       /* check if it's ok to keep the installed package */
       if (s->evr == si->evr && solvable_identical(s, si))
@@ -2694,6 +2707,8 @@ add_update_target(Solver *solv, Id p, Id how)
                    map_grow(&solv->bestupdatemap, installed->end - installed->start);
                  MAPSET(&solv->bestupdatemap, pi - installed->start);
                }
+             if (how & SOLVER_CLEANDEPS)
+               add_cleandeps_package(solv, pi);
              queue_push2(solv->update_targets, pi, p);
            }
        }
@@ -2795,11 +2810,18 @@ solver_solve(Solver *solv, Queue *job)
   queue_free(&solv->job);
   queue_init_clone(&solv->job, job);
 
+  /* free old stuff */
   if (solv->update_targets)
     {
       queue_free(solv->update_targets);
       solv->update_targets = solv_free(solv->update_targets);
     }
+  if (solv->cleandeps_updatepkgs)
+    {
+      queue_free(solv->cleandeps_updatepkgs);
+      solv->cleandeps_updatepkgs = solv_free(solv->cleandeps_updatepkgs);
+    }
+
   /*
    * create basic rule set of all involved packages
    * use addedmap bitmap to make sure we don't create rules twice
@@ -2849,6 +2871,11 @@ solver_solve(Solver *solv, Queue *job)
                  solv->updatemap_all = 1;
                  if (how & SOLVER_FORCEBEST)
                    solv->bestupdatemap_all = 1;
+                 if (how & SOLVER_CLEANDEPS)
+                   {
+                     FOR_REPO_SOLVABLES(installed, p, s)
+                       add_cleandeps_package(solv, p);
+                   }
                }
              else if (select == SOLVER_SOLVABLE_REPO)
                {
@@ -2860,6 +2887,11 @@ solver_solve(Solver *solv, Queue *job)
                      solv->updatemap_all = 1;
                      if (how & SOLVER_FORCEBEST)
                        solv->bestupdatemap_all = 1;
+                     if (how & SOLVER_CLEANDEPS)
+                       {
+                         FOR_REPO_SOLVABLES(installed, p, s)
+                           add_cleandeps_package(solv, p);
+                       }
                      break;
                    }
                  if (solv->noautotarget && !(how & SOLVER_TARGETED))
@@ -2887,6 +2919,8 @@ solver_solve(Solver *solv, Queue *job)
                                map_grow(&solv->bestupdatemap, installed->end - installed->start);
                              MAPSET(&solv->bestupdatemap, p - installed->start);
                            }
+                         if (how & SOLVER_CLEANDEPS)
+                           add_cleandeps_package(solv, p);
                          targeted = 0;
                        }
                      if (!targeted || solv->noautotarget)
@@ -3074,11 +3108,6 @@ solver_solve(Solver *solv, Queue *job)
    */
 
   solv->jobrules = solv->nrules;
-  if (solv->cleandeps_updatepkgs)
-    {
-      queue_free(solv->cleandeps_updatepkgs);
-      solv->cleandeps_updatepkgs = solv_free(solv->cleandeps_updatepkgs);
-    }
   for (i = 0; i < job->count; i += 2)
     {
       oldnrules = solv->nrules;
@@ -3172,37 +3201,6 @@ solver_solve(Solver *solv, Queue *job)
          break;
 
        case SOLVER_UPDATE:
-          if ((how & SOLVER_CLEANDEPS) != 0 && installed)
-           {
-             if (how == SOLVER_SOLVABLE_ALL || (how == SOLVER_SOLVABLE_REPO && what == installed->repoid))
-               {
-                 FOR_REPO_SOLVABLES(installed, p, s)
-                   {
-                     if (!solv->cleandeps_updatepkgs)
-                       {
-                         solv->cleandeps_updatepkgs = solv_calloc(1, sizeof(Queue));
-                         queue_init(solv->cleandeps_updatepkgs);
-                       }
-                     queue_pushunique(solv->cleandeps_updatepkgs, p);
-                     if (!solv->cleandepsmap.size)
-                       map_grow(&solv->cleandepsmap, installed->end - installed->start);
-                   }
-               }
-             FOR_JOB_SELECT(p, pp, select, what)
-               {
-                 s = pool->solvables + p;
-                 if (s->repo != installed)
-                   continue;
-                 if (!solv->cleandeps_updatepkgs)
-                   {
-                     solv->cleandeps_updatepkgs = solv_calloc(1, sizeof(Queue));
-                     queue_init(solv->cleandeps_updatepkgs);
-                   }
-                 queue_pushunique(solv->cleandeps_updatepkgs, p);
-                 if (!solv->cleandepsmap.size)
-                   map_grow(&solv->cleandepsmap, installed->end - installed->start);
-               }
-           }
          POOL_DEBUG(SOLV_DEBUG_JOB, "job: %supdate %s\n", weak ? "weak " : "", solver_select2str(pool, select, what));
          break;
        case SOLVER_VERIFY:
@@ -3338,6 +3336,16 @@ solver_solve(Solver *solv, Queue *job)
       MAPSET(&solv->weakrulemap, p);
     }
 
+  /* enable cleandepsmap creation if we have updatepkgs */
+  if (solv->cleandeps_updatepkgs && !solv->cleandepsmap.size)
+    map_grow(&solv->cleandepsmap, installed->end - installed->start);
+  /* no mistakes */
+  if (solv->cleandeps_mistakes)
+    {    
+      queue_free(solv->cleandeps_mistakes);
+      solv->cleandeps_mistakes = solv_free(solv->cleandeps_mistakes);
+    }    
+
   /* all new rules are learnt after this point */
   solv->learntrules = solv->nrules;
 
@@ -3357,13 +3365,6 @@ solver_solve(Solver *solv, Queue *job)
   makeruledecisions(solv);
   POOL_DEBUG(SOLV_DEBUG_SOLVER, "problems so far: %d\n", solv->problems.count);
 
-  /* no mistakes */
-  if (solv->cleandeps_mistakes)
-    {    
-      queue_free(solv->cleandeps_mistakes);
-      solv->cleandeps_mistakes = solv_free(solv->cleandeps_mistakes);
-    }    
-
   /*
    * ********************************************
    * solve!
diff --git a/test/testcases/cleandeps/cleandeps_dup.t b/test/testcases/cleandeps/cleandeps_dup.t
new file mode 100644 (file)
index 0000000..7002434
--- /dev/null
@@ -0,0 +1,33 @@
+repo system 0 testtags <inline>
+#>=Pkg: A 1 1 noarch
+#>=Req: B1
+#>=Pkg: B1 1 1 noarch
+repo test 0 testtags <inline>
+#>=Pkg: A 1 2 noarch
+#>=Req: B1
+#>=Pkg: A 2 1 noarch
+#>=Req: B2 = 1
+#>=Pkg: B1 1 1 noarch
+#>=Pkg: B2 1 1 noarch
+system i686 rpm system
+
+# check untargeted
+job distupgrade name A [cleandeps]
+result transaction,problems <inline>
+#>erase B1-1-1.noarch@system
+#>install B2-1-1.noarch@test
+#>upgrade A-1-1.noarch@system A-2-1.noarch@test
+
+# check targeted
+nextjob
+job distupgrade name A = 2 [cleandeps]
+result transaction,problems <inline>
+#>erase B1-1-1.noarch@system
+#>install B2-1-1.noarch@test
+#>upgrade A-1-1.noarch@system A-2-1.noarch@test
+
+# check targeted to 1-2
+nextjob
+job distupgrade name A = 1-2 [cleandeps]
+result transaction,problems <inline>
+#>upgrade A-1-1.noarch@system A-1-2.noarch@test
diff --git a/test/testcases/cleandeps/cleandeps_in.t b/test/testcases/cleandeps/cleandeps_in.t
new file mode 100644 (file)
index 0000000..3edacb5
--- /dev/null
@@ -0,0 +1,15 @@
+repo system 0 testtags <inline>
+#>=Pkg: A 1 1 noarch
+#>=Req: B1
+#>=Pkg: B1 1 1 noarch
+repo test 0 testtags <inline>
+#>=Pkg: A 2 1 noarch
+#>=Req: B2 = 1
+#>=Pkg: B1 1 1 noarch
+#>=Pkg: B2 1 1 noarch
+system i686 rpm system
+job install name A = 2 [cleandeps]
+result transaction,problems <inline>
+#>erase B1-1-1.noarch@system
+#>install B2-1-1.noarch@test
+#>upgrade A-1-1.noarch@system A-2-1.noarch@test
diff --git a/test/testcases/cleandeps/cleandeps_up.t b/test/testcases/cleandeps/cleandeps_up.t
new file mode 100644 (file)
index 0000000..9bb26d2
--- /dev/null
@@ -0,0 +1,33 @@
+repo system 0 testtags <inline>
+#>=Pkg: A 1 1 noarch
+#>=Req: B1
+#>=Pkg: B1 1 1 noarch
+repo test 0 testtags <inline>
+#>=Pkg: A 1 2 noarch
+#>=Req: B1
+#>=Pkg: A 2 1 noarch
+#>=Req: B2 = 1
+#>=Pkg: B1 1 1 noarch
+#>=Pkg: B2 1 1 noarch
+system i686 rpm system
+
+# check untargeted
+job update name A [cleandeps]
+result transaction,problems <inline>
+#>erase B1-1-1.noarch@system
+#>install B2-1-1.noarch@test
+#>upgrade A-1-1.noarch@system A-2-1.noarch@test
+
+# check targeted
+nextjob
+job update name A = 2 [cleandeps]
+result transaction,problems <inline>
+#>erase B1-1-1.noarch@system
+#>install B2-1-1.noarch@test
+#>upgrade A-1-1.noarch@system A-2-1.noarch@test
+
+# check targeted to 1-2
+nextjob
+job update name A = 1-2 [cleandeps]
+result transaction,problems <inline>
+#>upgrade A-1-1.noarch@system A-1-2.noarch@test
diff --git a/test/testcases/cleandeps/mistake-packages.repo b/test/testcases/cleandeps/mistake-packages.repo
deleted file mode 100644 (file)
index 7dcc351..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-=Pkg: A 2 1 noarch
-=Req: B = 1
-=Pkg: B 1 1 noarch
diff --git a/test/testcases/cleandeps/mistake-system.repo b/test/testcases/cleandeps/mistake-system.repo
deleted file mode 100644 (file)
index 4c2d012..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-=Pkg: A 1 1 noarch
-=Req: B
-=Pkg: B 2 1 noarch
index 44a29f0..b51ff69 100644 (file)
@@ -1,9 +1,14 @@
-repo system 0 testtags mistake-system.repo
-repo test 0 testtags mistake-packages.repo
+repo system 0 testtags <inline>
+#>=Pkg: A 1 1 noarch
+#>=Req: B
+#>=Pkg: B 2 1 noarch
+repo test 0 testtags <inline>
+#>=Pkg: A 2 1 noarch
+#>=Req: B = 1
+#>=Pkg: B 1 1 noarch
 system i686 rpm system
 job install name A = 2 [cleandeps]
 result transaction,problems <inline>
-#>erase A-1-1.noarch@system
 #>problem b5abcb9c info package A-2-1.noarch requires B = 1, but none of the providers can be installed
 #>problem b5abcb9c solution 37b448af deljob install name A = 2 [cleandeps]
 #>problem b5abcb9c solution 3c170283 replace B-2-1.noarch@system B-1-1.noarch@test