- change splitprovides so that they only work on packages that are to be updated.
authorMichael Schroeder <mls@suse.de>
Tue, 10 Jan 2012 16:45:50 +0000 (17:45 +0100)
committerMichael Schroeder <mls@suse.de>
Tue, 10 Jan 2012 16:45:50 +0000 (17:45 +0100)
Thus, the splitprovides flag can always be set and splitprovides also work
with 'zypper dup --from'.

examples/p5solv
examples/pysolv
examples/rbsolv
examples/solv.c
src/solver.c

index bf3dd67..4de66cc 100755 (executable)
@@ -755,14 +755,12 @@ if ($cmd eq 'install' || $cmd eq 'erase' || $cmd eq 'up' || $cmd eq 'dup' || $cm
   while (1) {
     $solver = $pool->Solver();
     $solver->set_flag($solv::Solver::SOLVER_FLAG_IGNORE_ALREADY_RECOMMENDED, 1);
+    $solver->set_flag($solv::Solver::SOLVER_FLAG_SPLITPROVIDES, 1);
     $solver->set_flag($solv::Solver::SOLVER_FLAG_ALLOW_UNINSTALL, 1) if $cmd eq 'erase';
     if ($cmd eq 'dup' && @jobs == 1 $jobs[0]->{'how'} == ($solv::Job::SOLVER_DISTUPGRADE | $solv::Job::SOLVER_SOLVABLE_ALL)) {
       $solver->set_flag($solv::Solver::SOLVER_FLAG_ALLOW_DOWNGRADE, 1);
       $solver->set_flag($solv::Solver::SOLVER_FLAG_ALLOW_VENDERCHANGE, 1);
       $solver->set_flag($solv::Solver::SOLVER_FLAG_ALLOW_ARCHCHANGE, 1);
-      $solver->set_flag($solv::Solver::SOLVER_FLAG_SPLITPROVIDES, 1);
-    } elsif ($cmd eq 'up' && @jobs == 1 && $jobs[0]->{'how'} == ($solv::Job::SOLVER_UPDATE | $solv::Job::SOLVER_SOLVABLE_ALL)) {
-      $solver->set_flag($solv::Solver::SOLVER_FLAG_SPLITPROVIDES, 1);
     }
     my @problems = $solver->solve(\@jobs);
     last unless @problems;
index 1422027..a63c5e4 100755 (executable)
@@ -849,15 +849,13 @@ if cmd == 'install' or cmd == 'erase' or cmd == 'up' or cmd == 'dup' or cmd == '
     while True:
         solver = pool.Solver()
        solver.set_flag(Solver.SOLVER_FLAG_IGNORE_ALREADY_RECOMMENDED, 1);
+       solver.set_flag(Solver.SOLVER_FLAG_SPLITPROVIDES, 1);
         if cmd == 'erase':
            solver.set_flag(Solver.SOLVER_FLAG_ALLOW_UNINSTALL, 1);
         if cmd == 'dup' and len(jobs) == 1 and jobs[0].how == (Job.SOLVER_DISTUPGRADE | Job.SOLVER_SOLVABLE_ALL):
            solver.set_flag(Solver.SOLVER_FLAG_ALLOW_DOWNGRADE, 1);
            solver.set_flag(Solver.SOLVER_FLAG_ALLOW_VENDORCHANGE, 1);
            solver.set_flag(Solver.SOLVER_FLAG_ALLOW_ARCHCHANGE, 1);
-           solver.set_flag(Solver.SOLVER_FLAG_SPLITPROVIDES, 1);
-        if cmd == 'up' and len(jobs) == 1 and jobs[0].how == (Job.SOLVER_UPDATE | Job.SOLVER_SOLVABLE_ALL):
-           solver.set_flag(Solver.SOLVER_FLAG_SPLITPROVIDES, 1);
         problems = solver.solve(jobs)
         if not problems:
             break
index d12b8a1..ef6f021 100755 (executable)
@@ -757,14 +757,12 @@ if cmd == 'install' || cmd == 'erase' || cmd == 'up' || cmd == 'dup' || cmd == '
   while true
     solver = pool.Solver
     solver.set_flag(Solv::Solver::SOLVER_FLAG_IGNORE_ALREADY_RECOMMENDED, 1)
+    solver.set_flag(Solv::Solver::SOLVER_FLAG_SPLITPROVIDES, 1)
     solver.set_flag(Solv::Solver::SOLVER_FLAG_ALLOW_UNINSTALL, 1) if cmd == 'erase'
     if cmd == 'up' && jobs.length == 1 && jobs[0].how == (Solv::Job::SOLVER_DISTUPGRADE | Solv::Job::SOLVER_SOLVABLE_ALL)
       solver.set_flag(Solv::Solver::SOLVER_FLAG_ALLOW_DOWNGRADE, 1)
       solver.set_flag(Solv::Solver::SOLVER_FLAG_ALLOW_VENDORCHANGE, 1)
       solver.set_flag(Solv::Solver::SOLVER_FLAG_ALLOW_ARCHCHANGE, 1)
-      solver.set_flag(Solv::Solver::SOLVER_FLAG_SPLITPROVIDES, 1)
-    elsif cmd == 'up' && jobs.length == 1 && jobs[0].how == (Solv::Job::SOLVER_UPDATE | Solv::Job::SOLVER_SOLVABLE_ALL)
-      solver.set_flag(Solv::Solver::SOLVER_FLAG_SPLITPROVIDES, 1)
     end
     problems = solver.solve(jobs)
     break if problems.empty?
index bf6a622..004a85d 100644 (file)
@@ -2958,14 +2958,12 @@ rerunsolver:
 
       solv = solver_create(pool);
       solver_set_flag(solv, SOLVER_FLAG_IGNORE_ALREADY_RECOMMENDED, 1);
-      if (allpkgs && !repofilter && mainmode == MODE_UPDATE)
-       solver_set_flag(solv, SOLVER_FLAG_SPLITPROVIDES, 1);
+      solver_set_flag(solv, SOLVER_FLAG_SPLITPROVIDES, 1);
       if (mainmode == MODE_DISTUPGRADE && allpkgs && !repofilter)
        {
           solver_set_flag(solv, SOLVER_FLAG_ALLOW_DOWNGRADE, 1);
           solver_set_flag(solv, SOLVER_FLAG_ALLOW_ARCHCHANGE, 1);
           solver_set_flag(solv, SOLVER_FLAG_ALLOW_VENDORCHANGE, 1);
-         solver_set_flag(solv, SOLVER_FLAG_SPLITPROVIDES, 1);
        }
       if (mainmode == MODE_ERASE || mainmode == MODE_ERASECLEAN)
         solver_set_flag(solv, SOLVER_FLAG_ALLOW_UNINSTALL, 1); /* don't nag */
index 9e39643..d11e63b 100644 (file)
 
 /*-------------------------------------------------------------------
  * handle split provides
+ *
+ * a splitprovides dep looks like
+ *     namespace:splitprovides(pkg REL_WITH path)
+ * and is only true if pkg is installed and contains the specified path.
+ * we also make sure that pkg is selected for an update, otherwise the
+ * update would always be forced onto the user.
  */
-
 int
 solver_splitprovides(Solver *solv, Id dep)
 {
@@ -45,7 +50,7 @@ solver_splitprovides(Solver *solv, Id dep)
   Reldep *rd;
   Solvable *s;
 
-  if (!solv->dosplitprovides || !solv->installed)
+  if (!solv->dosplitprovides || !solv->installed || (!solv->updatemap_all && !solv->updatemap.size))
     return 0;
   if (!ISRELDEP(dep))
     return 0;
@@ -54,8 +59,11 @@ solver_splitprovides(Solver *solv, Id dep)
     return 0;
   FOR_PROVIDES(p, pp, dep)
     {
+      /* here we have packages that provide the correct name and contain the path,
+       * now do extra filtering */
       s = pool->solvables + p;
-      if (s->repo == solv->installed && s->name == rd->name)
+      if (s->repo == solv->installed && s->name == rd->name &&
+          (solv->updatemap_all || (solv->updatemap.size && MAPTST(&solv->updatemap, p - solv->installed->start))))
        return 1;
     }
   return 0;