On 12/13/2017 5:31 PM, Ken Brown wrote:
On 12/13/2017 1:05 PM, Achim Gratz wrote:
Ken Brown writes:
1. Uninstall A.
2. Don't uninstall B.

On the surface, it would seem that libsolv chose 2 by default, because
it returned an empty transaction list.  This was reflected in the log
and was also clear when I selected 'Back'.

I don't think there is a default in this case.  I also see in zypper
that the order of the proposed solutions (there can be way more than two
if the dependencies are more complicated) is not always the same, so
there is no preference implied by the order as well.

Maybe we have to deal with this situation ourselves.  Whenever a
problem involves a missing dependency, we could choose as default
solution the one that installs/keeps the dependent package, as is
currently done.

That solution unfortunately isn't always the one that causes the least
amount of transactions or even the least amount of breakage.

That may be true, but I still think it's a reasonable default.  The user doesn't have to accept it.  Also, it's consistent with what setup currently does, so it won't surprise anyone.

The attached patch attempts to implement my suggestion.

Ken


0001-Implement-a-default-solution-for-SOLVER_RULE_PKG_REQ.patch

+      if (type == SOLVER_RULE_PKG_REQUIRES)
+       {
+         packagemeta *pkg = 
db.findBinary(PackageSpecification(pool_dep2str(pool.pool, dep)));
+         if (!pkg->desired && pkg->installed < pkg->default_version)
+           // User chose to uninstall or skip a required package.
+           trans.push_back(SolverTransaction(pkg->default_version,
+                                             SolverTransaction::transInstall));

This isn't quite right. We also need a transErase if the package is installed. Revised patch attached.

Ken
From 1930460c9f5c8a4c1aea0837778d76d8322642fa Mon Sep 17 00:00:00 2001
From: Ken Brown <kbr...@cornell.edu>
Date: Wed, 13 Dec 2017 17:20:26 -0500
Subject: [PATCH setup libsolv v2] Implement a default solution for
 SOLVER_RULE_PKG_REQUIRES

If libsolv reports a SOLVER_RULE_PKG_REQUIRES problem, it means that
the user chose to uninstall or skip a required package.  Add
appropriate transactions, if necessary, to override this choice.  The
user will have to uncheck the "Accept default problem solutions" box
to insist on the original choice.
---
 libsolv.cc | 26 +++++++++++++++++++++++---
 libsolv.h  |  2 +-
 2 files changed, 24 insertions(+), 4 deletions(-)

diff --git a/libsolv.cc b/libsolv.cc
index 0fb39c7..48c24c4 100644
--- a/libsolv.cc
+++ b/libsolv.cc
@@ -868,7 +868,7 @@ SolverSolution::transactions() const
 
 // Construct a string reporting the problems and solutions
 std::string
-SolverSolution::report() const
+SolverSolution::report()
 {
   packagedb db;
   std::string r = "";
@@ -881,8 +881,28 @@ SolverSolution::report() const
       Id probr = solver_findproblemrule(solv, problem);
       Id dep, source, target;
       SolverRuleinfo type = solver_ruleinfo(solv, probr, &source, &target, 
&dep);
-      if (source == db.basepkg.id)
-       r += "package " + std::string(pool_dep2str(pool.pool, dep)) + " is a 
Base package and is therefore required";
+      if (type == SOLVER_RULE_PKG_REQUIRES)
+       {
+         // The user chose to uninstall or skip a required package.
+         // libsolv will not create an erase transaction, but we
+         // might need to create our own transactions to implement a
+         // default solution to the problem.
+         packagemeta *pkg = 
db.findBinary(PackageSpecification(pool_dep2str(pool.pool, dep)));
+         if (!pkg->desired && pkg->installed < pkg->default_version)
+           {
+             trans.push_back(SolverTransaction(pkg->default_version,
+                                               
SolverTransaction::transInstall));
+             if (pkg->installed)
+               trans.push_back(SolverTransaction(pkg->installed,
+                                                 
SolverTransaction::transErase));
+           }
+         if (source == db.basepkg.id)
+           r += "package " + std::string(pool_dep2str(pool.pool, dep))
+             + " is a Base package and is therefore required";
+         else
+           r += "package " + std::string(pool_dep2str(pool.pool, dep)) +
+             " is  required by " + std::string(pool_solvid2str(pool.pool, 
source));
+       }
       else
        r += solver_problemruleinfo2str(solv, type, source, target, dep);
       r += "\n";
diff --git a/libsolv.h b/libsolv.h
index cddf76f..391a96d 100644
--- a/libsolv.h
+++ b/libsolv.h
@@ -253,7 +253,7 @@ class SolverSolution
     updateForce, // distupdate: downgrade if necessary to best version in repo
   };
   bool update(SolverTasks &tasks, updateMode update, bool use_test_packages, 
bool include_source);
-  std::string report() const;
+  std::string report();
 
   const SolverTransactionList &transactions() const;
 
-- 
2.15.1

Reply via email to