Now we have the flexibilty to record a package as explicitly required to
be installed, rather than merely installed because the desired version
is different to the installed version, we can record packages selected
for installation on the command line as distinct from choosing a
specific version of that package via the picker.

Use this to allow the solver to make a better choice of what provides a
package name specified on the command line.

(Note that we need to use SOLVER_SOLVABLE_PROVIDES rather than
SOLVER_SOLVABLE_NAME to allow the solver to take packages which provide
and obsolete the named package into account.)

Only turn this behaviour on when --upgrade-also is specified.

e.g. setup -q -g -P python3-lxml currently gets you an (empty)
python3-lxml package, which is replaced by python36-lxml (which
obsoletes it) on the next setup run.  After this change, python36-lxml
is installed instead.

See also the dicusssion at
https://cygwin.com/ml/cygwin-apps/2017-10/msg00092.html et seq.
---
 choose.cc  | 2 +-
 libsolv.cc | 8 +++++++-
 libsolv.h  | 1 +
 3 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/choose.cc b/choose.cc
index 7f6e332..be08627 100644
--- a/choose.cc
+++ b/choose.cc
@@ -299,7 +299,7 @@ ChooserPage::applyCommandLinePackageSelection()
       bool uninstall = (!(wanted  || base) && (deleted || PruneInstallOption))
                     || (orphaned && CleanOrphansOption);
       if (install)
-       pkg.set_action (packagemeta::Install_action, pkg.curr);
+       pkg.set_action (packagemeta::Install_action, UpgradeAlsoOption ? 
packageversion () : pkg.curr);
       else if (reinstall)
        pkg.set_action (packagemeta::Reinstall_action, pkg.curr);
       else if (uninstall)
diff --git a/libsolv.cc b/libsolv.cc
index cbc651b..d7a9d01 100644
--- a/libsolv.cc
+++ b/libsolv.cc
@@ -653,7 +653,10 @@ SolverTasks::setTasks()
           break;
 
         case packagemeta::Install_action:
-          add(pkg->desired, taskInstall); // install/upgrade
+          if (pkg->desired)
+            add(pkg->desired, taskInstall); // install/upgrade
+          else
+            add(pkg->curr, taskInstallAny); // install
           break;
 
         case packagemeta::Uninstall_action:
@@ -829,6 +832,9 @@ SolverSolution::tasksToJobs(SolverTasks &tasks, updateMode 
update, Queue &job)
         case SolverTasks::taskInstall:
           queue_push2(&job, SOLVER_INSTALL | SOLVER_SOLVABLE, sv.id);
           break;
+        case SolverTasks::taskInstallAny:
+          queue_push2(&job, SOLVER_INSTALL | SOLVER_SOLVABLE_PROVIDES, 
sv.name_id());
+          break;
         case SolverTasks::taskUninstall:
           queue_push2(&job, SOLVER_ERASE | SOLVER_SOLVABLE, sv.id);
           break;
diff --git a/libsolv.h b/libsolv.h
index 4fd6d61..43f7269 100644
--- a/libsolv.h
+++ b/libsolv.h
@@ -197,6 +197,7 @@ class SolverTasks
     taskKeep,
     taskSkip,
     taskForceDistUpgrade,
+    taskInstallAny,
   };
   void add(const SolvableVersion &v, task t)
   {
-- 
2.21.0

Reply via email to