Imported Upstream version 15.18.0
[platform/upstream/libzypp.git] / zypp / solver / detail / SATResolver.cc
index f1e1753..77ba113 100644 (file)
@@ -29,7 +29,8 @@ extern "C"
 #include <solv/queue.h>
 }
 
-#include "zypp/solver/detail/Helper.h"
+#define ZYPP_USE_RESOLVER_INTERNALS
+
 #include "zypp/base/String.h"
 #include "zypp/Product.h"
 #include "zypp/Capability.h"
@@ -45,15 +46,22 @@ extern "C"
 #include "zypp/sat/Pool.h"
 #include "zypp/sat/WhatProvides.h"
 #include "zypp/sat/WhatObsoletes.h"
+#include "zypp/solver/detail/Resolver.h"
 #include "zypp/solver/detail/SATResolver.h"
 #include "zypp/solver/detail/ProblemSolutionCombi.h"
 #include "zypp/solver/detail/ProblemSolutionIgnore.h"
 #include "zypp/solver/detail/SolverQueueItemInstall.h"
 #include "zypp/solver/detail/SolverQueueItemDelete.h"
 #include "zypp/solver/detail/SystemCheck.h"
+#include "zypp/solver/detail/SolutionAction.h"
+#include "zypp/solver/detail/SolverQueueItem.h"
 #include "zypp/sat/Transaction.h"
 #include "zypp/sat/Queue.h"
 
+#include "zypp/sat/detail/PoolImpl.h"
+
+#define _XDEBUG(x) do { if (base::logger::isExcessive()) XXX << x << std::endl;} while (0)
+
 /////////////////////////////////////////////////////////////////////////
 namespace zypp
 { ///////////////////////////////////////////////////////////////////////
@@ -178,11 +186,15 @@ SATResolver::SATResolver (const ResPool & pool, Pool *SATPool)
     , _allowuninstall(false)
     , _updatesystem(false)
     , _noupdateprovide(false)
-    , _dosplitprovides(false)
+    , _dosplitprovides(true)
     , _onlyRequires(ZConfig::instance().solver_onlyRequires())
     , _ignorealreadyrecommended(true)
     , _distupgrade(false)
     , _distupgrade_removeunsupported(false)
+    , _dup_allowdowngrade      ( ZConfig::instance().solver_dupAllowDowngrade() )
+    , _dup_allownamechange     ( ZConfig::instance().solver_dupAllowNameChange() )
+    , _dup_allowarchchange     ( ZConfig::instance().solver_dupAllowArchChange() )
+    , _dup_allowvendorchange   ( ZConfig::instance().solver_dupAllowVendorChange() )
     , _solveSrcPackages(false)
     , _cleandepsOnRemove(ZConfig::instance().solver_cleandepsOnRemove())
 {
@@ -406,22 +418,20 @@ class CheckIfUpdate : public resfilter::PoolItemFilterFunctor
 {
   public:
     bool is_updated;
-    bool multiversion;
     sat::Solvable _installed;
 
-    CheckIfUpdate( sat::Solvable installed_r )
-       : is_updated( false )
-        , multiversion( installed_r.multiversionInstall() )
-        , _installed( installed_r )
+    CheckIfUpdate( const sat::Solvable & installed_r )
+    : is_updated( false )
+    , _installed( installed_r )
     {}
 
     // check this item will be updated
 
-    bool operator()( PoolItem item )
+    bool operator()( const PoolItem & item )
     {
        if ( item.status().isToBeInstalled() )
         {
-          if ( ! multiversion || sameNVRA( _installed, item ) )
+          if ( ! item.multiversionInstall() || sameNVRA( _installed, item ) )
           {
             is_updated = true;
             return false;
@@ -480,14 +490,18 @@ SATResolver::solving(const CapabilitySet & requires_caps,
     solver_set_flag(_solv, SOLVER_FLAG_SPLITPROVIDES, _dosplitprovides);
     solver_set_flag(_solv, SOLVER_FLAG_NO_UPDATEPROVIDE, _noupdateprovide);
     solver_set_flag(_solv, SOLVER_FLAG_IGNORE_RECOMMENDED, _onlyRequires);
-
+    solver_set_flag(_solv, SOLVER_FLAG_DUP_ALLOW_DOWNGRADE,    _dup_allowdowngrade );
+    solver_set_flag(_solv, SOLVER_FLAG_DUP_ALLOW_NAMECHANGE,   _dup_allownamechange );
+    solver_set_flag(_solv, SOLVER_FLAG_DUP_ALLOW_ARCHCHANGE,   _dup_allowarchchange );
+    solver_set_flag(_solv, SOLVER_FLAG_DUP_ALLOW_VENDORCHANGE, _dup_allowvendorchange );
+#if 1
 #define HACKENV(X,D) solver_set_flag(_solv, X, env::HACKENV( #X, D ) );
-    HACKENV( SOLVER_FLAG_DUP_ALLOW_DOWNGRADE,  true );
-    HACKENV( SOLVER_FLAG_DUP_ALLOW_ARCHCHANGE, true );
-    HACKENV( SOLVER_FLAG_DUP_ALLOW_VENDORCHANGE,true );
-    HACKENV( SOLVER_FLAG_DUP_ALLOW_NAMECHANGE, true );
+    HACKENV( SOLVER_FLAG_DUP_ALLOW_DOWNGRADE,  _dup_allowdowngrade );
+    HACKENV( SOLVER_FLAG_DUP_ALLOW_NAMECHANGE, _dup_allownamechange );
+    HACKENV( SOLVER_FLAG_DUP_ALLOW_ARCHCHANGE, _dup_allowarchchange );
+    HACKENV( SOLVER_FLAG_DUP_ALLOW_VENDORCHANGE,_dup_allowvendorchange );
 #undef HACKENV
-
+#endif
     sat::Pool::instance().prepareForSolving();
 
     // Solve !
@@ -696,11 +710,25 @@ SATResolver::solverInit(const PoolItemList & weakItems)
         queue_push( &(_jobQueue), id );
     }
 
+    // Ad rules for changed requestedLocales
+    const auto & trackedLocaleIds( myPool().trackedLocaleIds() );
+    for ( const auto & locale : trackedLocaleIds.added() )
+    {
+      queue_push( &(_jobQueue), SOLVER_INSTALL | SOLVER_SOLVABLE_PROVIDES );
+      queue_push( &(_jobQueue), Capability( ResolverNamespace::language, IdString(locale) ).id() );
+    }
+
+    for ( const auto & locale : trackedLocaleIds.removed() )
+    {
+      queue_push( &(_jobQueue), SOLVER_ERASE | SOLVER_SOLVABLE_PROVIDES | SOLVER_CLEANDEPS );  // needs uncond. SOLVER_CLEANDEPS!
+      queue_push( &(_jobQueue), Capability( ResolverNamespace::language, IdString(locale) ).id() );
+    }
+
     // Add rules for parallel installable resolvables with different versions
-    for_( it, sat::Pool::instance().multiversionBegin(), sat::Pool::instance().multiversionEnd() )
+    for ( const sat::Solvable & solv : myPool().multiversionList() )
     {
-      queue_push( &(_jobQueue), SOLVER_NOOBSOLETES | SOLVER_SOLVABLE_NAME );
-      queue_push( &(_jobQueue), it->id() );
+      queue_push( &(_jobQueue), SOLVER_NOOBSOLETES | SOLVER_SOLVABLE );
+      queue_push( &(_jobQueue), solv.id() );
     }
 
     ::pool_add_userinstalled_jobs(_SATPool, sat::Pool::instance().autoInstalled(), &(_jobQueue), GET_USERINSTALLED_NAMES|GET_USERINSTALLED_INVERTED);
@@ -1115,7 +1143,7 @@ string SATResolver::SATprobleminfoString(Id problem, string &detail, Id &ignoreI
              bool found = false;
              for_( iter2, possibleProviders.begin(), possibleProviders.end() ) {
                  PoolItem provider2 = ResPool::instance().find( *iter2 );
-                 if (compareByNVR (provider1.resolvable(),provider2.resolvable()) == 0
+                 if (compareByNVR (provider1,provider2) == 0
                      && ( (provider1.status().isInstalled() && provider2.status().isUninstalled())
                          || (provider2.status().isInstalled() && provider1.status().isUninstalled()) ))  {
                      found = true;
@@ -1188,7 +1216,7 @@ SATResolver::problems ()
            solution = 0;
            while ((solution = solver_next_solution(_solv, problem, solution)) != 0) {
                element = 0;
-               ProblemSolutionCombi *problemSolution = new ProblemSolutionCombi(resolverProblem);
+               ProblemSolutionCombi *problemSolution = new ProblemSolutionCombi;
                while ((element = solver_next_solutionelement(_solv, problem, solution, element, &p, &rp)) != 0) {
                    if (p == SOLVER_SOLUTION_JOB) {
                        /* job, rp is index into job queue */
@@ -1201,7 +1229,7 @@ SATResolver::problems ()
                                if (poolItem) {
                                    if (pool->installed && s.get()->repo == pool->installed) {
                                        problemSolution->addSingleAction (poolItem, REMOVE);
-                                       string description = str::form (_("do not keep %s installed"),  s.asString().c_str() );
+                                       string description = str::form (_("remove lock to allow removal of %s"),  s.asString().c_str() );
                                        MIL << description << endl;
                                        problemSolution->addDescription (description);
                                    } else {
@@ -1226,7 +1254,7 @@ SATResolver::problems ()
                                        problemSolution->addDescription (description);
                                    } else {
                                        problemSolution->addSingleAction (poolItem, UNLOCK);
-                                       string description = str::form (_("do not forbid installation of %s"), itemToString( poolItem ).c_str());
+                                       string description = str::form (_("remove lock to allow installation of %s"), itemToString( poolItem ).c_str());
                                        MIL << description << endl;
                                        problemSolution->addDescription (description);
                                    }
@@ -1430,7 +1458,7 @@ SATResolver::problems ()
            if (ignoreId > 0) {
                // There is a possibility to ignore this error by setting weak dependencies
                PoolItem item = _pool.find (sat::Solvable(ignoreId));
-               ProblemSolutionIgnore *problemSolution = new ProblemSolutionIgnore(resolverProblem, item);
+               ProblemSolutionIgnore *problemSolution = new ProblemSolutionIgnore(item);
                resolverProblem->addSolution (problemSolution,
                                              false); // Solutions will be shown at the end
                MIL << "ignore some dependencies of " << item << endl;
@@ -1444,17 +1472,8 @@ SATResolver::problems ()
     return resolverProblems;
 }
 
-void
-SATResolver::applySolutions (const ProblemSolutionList & solutions)
-{
-    for (ProblemSolutionList::const_iterator iter = solutions.begin();
-        iter != solutions.end(); ++iter) {
-       ProblemSolution_Ptr solution = *iter;
-       Resolver dummyResolver(_pool);
-       if (!solution->apply (dummyResolver))
-           break;
-    }
-}
+void SATResolver::applySolutions( const ProblemSolutionList & solutions )
+{ Resolver( _pool ).applySolutions( solutions ); }
 
 void SATResolver::setLocks()
 {