*/
#include <boost/static_assert.hpp>
+#define ZYPP_USE_RESOLVER_INTERNALS
+
#include "zypp/solver/detail/Resolver.h"
-#include "zypp/solver/detail/Helper.h"
#include "zypp/solver/detail/Testcase.h"
#include "zypp/solver/detail/SATResolver.h"
+#include "zypp/solver/detail/ItemCapKind.h"
+#include "zypp/solver/detail/SolutionAction.h"
+#include "zypp/solver/detail/SolverQueueItem.h"
#include "zypp/Capabilities.h"
#include "zypp/ZConfig.h"
#include "zypp/ResFilters.h"
#include "zypp/sat/Pool.h"
#include "zypp/sat/Solvable.h"
+#include "zypp/sat/Transaction.h"
+#include "zypp/ResolverProblem.h"
#define MAXSOLVERRUNS 5
+using std::endl;
+using std::make_pair;
+
/////////////////////////////////////////////////////////////////////////
namespace zypp
{ ///////////////////////////////////////////////////////////////////////
namespace detail
{ ///////////////////////////////////////////////////////////////////
-using namespace std;
-
-IMPL_PTR_TYPE(Resolver);
-
+ //using namespace std;
//---------------------------------------------------------------------------
-std::ostream &
-Resolver::dumpOn( std::ostream & os ) const
+std::ostream & Resolver::dumpOn( std::ostream & os ) const
{
- return os << "<resolver/>";
+ os << "<resolver>" << endl;
+ #define OUTS(t) os << " " << #t << ":\t" << t << endl;
+ OUTS( _forceResolve );
+ OUTS( _upgradeMode );
+ OUTS( _updateMode );
+ OUTS( _verifying );
+ OUTS( _onlyRequires );
+ OUTS( _allowVendorChange );
+ OUTS( _solveSrcPackages );
+ OUTS( _cleandepsOnRemove );
+ OUTS( _ignoreAlreadyRecommended );
+ #undef OUT
+ return os << "<resolver/>";
}
: _pool(pool)
, _satResolver(NULL)
, _poolchanged(_pool.serial() )
- , _testing(false)
- , _forceResolve(false)
- , _upgradeMode(false)
- , _verifying(false)
- , _onlyRequires(indeterminate)
- , _ignorealreadyrecommended(false)
+ , _forceResolve (false)
+ , _upgradeMode (false)
+ , _updateMode (false)
+ , _verifying (false)
+ , _onlyRequires ( ZConfig::instance().solver_onlyRequires() )
+ , _allowVendorChange ( ZConfig::instance().solver_allowVendorChange() )
+ , _solveSrcPackages ( false )
+ , _cleandepsOnRemove ( ZConfig::instance().solver_cleandepsOnRemove() )
+ , _ignoreAlreadyRecommended ( true )
{
sat::Pool satPool( sat::Pool::instance() );
Resolver::~Resolver()
{
+ delete _satResolver;
}
//---------------------------------------------------------------------------
+// forward flags too SATResolver
+#define ZOLV_FLAG_TRIBOOL( ZSETTER, ZGETTER, ZVARNAME, ZVARDEFAULT ) \
+ void Resolver::ZSETTER( TriBool state_r ) \
+ { _satResolver->ZVARNAME = indeterminate(state_r) ? ZVARDEFAULT : bool(state_r); } \
+ bool Resolver::ZGETTER() const \
+ { return _satResolver->ZVARNAME; } \
+
+ZOLV_FLAG_TRIBOOL( dupSetAllowDowngrade, dupAllowDowngrade, _dup_allowdowngrade, ZConfig::instance().solver_dupAllowDowngrade() )
+ZOLV_FLAG_TRIBOOL( dupSetAllowNameChange, dupAllowNameChange, _dup_allownamechange, ZConfig::instance().solver_dupAllowNameChange() )
+ZOLV_FLAG_TRIBOOL( dupSetAllowArchChange, dupAllowArchChange, _dup_allowarchchange, ZConfig::instance().solver_dupAllowArchChange() )
+ZOLV_FLAG_TRIBOOL( dupSetAllowVendorChange, dupAllowVendorChange, _dup_allowvendorchange, ZConfig::instance().solver_dupAllowVendorChange() )
+
+#undef ZOLV_FLAG_TRIBOOL
+//---------------------------------------------------------------------------
-ResPool
-Resolver::pool (void) const
+void Resolver::setAllowVendorChange( TriBool state_r )
{
- return _pool;
+ _allowVendorChange = indeterminate(state_r) ? ZConfig::instance().solver_allowVendorChange() : bool(state_r);
}
-void
-Resolver::reset (bool keepExtras )
+void Resolver::setOnlyRequires( TriBool state_r )
{
- _verifying = false;
+ _onlyRequires = indeterminate(state_r) ? ZConfig::instance().solver_onlyRequires() : bool(state_r);
+}
+
+void Resolver::setCleandepsOnRemove( TriBool state_r )
+{
+ _cleandepsOnRemove = indeterminate(state_r) ? ZConfig::instance().solver_cleandepsOnRemove() : bool(state_r);
+}
+
+//---------------------------------------------------------------------------
+
+ResPool Resolver::pool() const
+{ return _pool; }
+
+void Resolver::reset( bool keepExtras )
+{
+ _verifying = false;
if (!keepExtras) {
_extra_requires.clear();
_isInstalledBy.clear();
_installs.clear();
- _satifiedByInstalled.clear();
+ _satifiedByInstalled.clear();
+ _installedSatisfied.clear();
}
-void
-Resolver::doUpdate()
+bool Resolver::doUpgrade()
{
- return _satResolver->doUpdate();
+ // Setting Resolver to upgrade mode. SAT solver will do the update
+ _upgradeMode = true;
+ return resolvePool();
}
-void
-Resolver::addExtraRequire (const Capability & capability)
+void Resolver::doUpdate()
{
- _extra_requires.insert (capability);
+ _updateMode = true;
+ return _satResolver->doUpdate();
}
-void
-Resolver::removeExtraRequire (const Capability & capability)
-{
- _extra_requires.erase (capability);
-}
+PoolItemList Resolver::problematicUpdateItems() const
+{ return _satResolver->problematicUpdateItems(); }
-void
-Resolver::addExtraConflict (const Capability & capability)
-{
- _extra_conflicts.insert (capability);
-}
+void Resolver::addExtraRequire( const Capability & capability )
+{ _extra_requires.insert (capability); }
-void
-Resolver::removeExtraConflict (const Capability & capability)
-{
- _extra_conflicts.erase (capability);
-}
+void Resolver::removeExtraRequire( const Capability & capability )
+{ _extra_requires.erase (capability); }
-void Resolver::removeQueueItem (const SolverQueueItem_Ptr item)
+void Resolver::addExtraConflict( const Capability & capability )
+{ _extra_conflicts.insert (capability); }
+
+void Resolver::removeExtraConflict( const Capability & capability )
+{ _extra_conflicts.erase (capability); }
+
+void Resolver::removeQueueItem( SolverQueueItem_Ptr item )
{
bool found = false;
for (SolverQueueItemList::const_iterator iter = _added_queue_items.begin();
_removed_queue_items.unique ();
}
}
-void Resolver::addQueueItem (const SolverQueueItem_Ptr item)
+
+void Resolver::addQueueItem( SolverQueueItem_Ptr item )
{
bool found = false;
for (SolverQueueItemList::const_iterator iter = _removed_queue_items.begin();
if (!found) {
_added_queue_items.push_back (item);
_added_queue_items.unique ();
- }
+ }
}
-void
-Resolver::addWeak (const PoolItem item)
-{
- _addWeak.push_back (item);
-}
+void Resolver::addWeak( const PoolItem & item )
+{ _addWeak.push_back( item ); }
//---------------------------------------------------------------------------
};
-bool
-Resolver::verifySystem ()
+bool Resolver::verifySystem()
{
UndoTransact resetting (ResStatus::APPL_HIGH);
- _DEBUG ("Resolver::verifySystem() ");
-
- _verifying = true;
+ DBG << "Resolver::verifySystem()" << endl;
+
+ _verifying = true;
invokeOnEach ( _pool.begin(), _pool.end(),
resfilter::ByTransact( ), // Resetting all transcations
//----------------------------------------------------------------------------
// undo
-
-void
-Resolver::undo(void)
+void Resolver::undo()
{
UndoTransact info(ResStatus::APPL_LOW);
MIL << "*** undo ***" << endl;
// Regard dependencies of the item weak onl
_addWeak.clear();
- // Ignore Obsoletes
- _noObsoletesCapability.clear();
- _noObsoletesItem.clear();
- _noObsoletesString.clear();
-
// Additional QueueItems which has to be regarded by the solver
_removed_queue_items.clear();
- _added_queue_items.clear();
+ _added_queue_items.clear();
return;
}
-void
-Resolver::solverInit()
+void Resolver::solverInit()
{
- // Solving with the satsolver
- static bool poolDumped = false;
- MIL << "-------------- Calling SAT Solver -------------------" << endl;
- if ( getenv("ZYPP_FULLLOG") ) {
- Testcase testcase("/var/log/YaST2/autoTestcase");
- if (!poolDumped) {
- testcase.createTestcase (*this, true, false); // dump pool
- poolDumped = true;
- } else {
- testcase.createTestcase (*this, false, false); // write control file only
- }
+ // Solving with libsolv
+ static bool poolDumped = false;
+ MIL << "-------------- Calling SAT Solver -------------------" << endl;
+ if ( getenv("ZYPP_FULLLOG") ) {
+ Testcase testcase("/var/log/YaST2/autoTestcase");
+ if (!poolDumped) {
+ testcase.createTestcase (*this, true, false); // dump pool
+ poolDumped = true;
+ } else {
+ testcase.createTestcase (*this, false, false); // write control file only
}
+ }
- _satResolver->setFixsystem(false);
- _satResolver->setIgnorealreadyrecommended(false);
- _satResolver->setAllowdowngrade(false);
- _satResolver->setAllowarchchange(false);
- _satResolver->setAllowvendorchange(false);
- _satResolver->setAllowuninstall(false);
- _satResolver->setUpdatesystem(false);
- _satResolver->setAllowvirtualconflicts(false);
- _satResolver->setNoupdateprovide(true);
- _satResolver->setDosplitprovides(false);
-
- if (_upgradeMode) {
- _satResolver->setAllowdowngrade(true);
- _satResolver->setUpdatesystem(false); // not needed cause packages has already been evaluteted by distupgrade
- _satResolver->setDosplitprovides(true);
- }
+ _satResolver->setFixsystem ( isVerifyingMode() );
+ _satResolver->setIgnorealreadyrecommended ( ignoreAlreadyRecommended() );
+ _satResolver->setOnlyRequires ( onlyRequires() );
+ _satResolver->setAllowdowngrade (false);
+ _satResolver->setAllowarchchange (false);
+ _satResolver->setAllowvendorchange ( allowVendorChange() );
+ _satResolver->setAllowuninstall ( forceResolve() );
+ _satResolver->setUpdatesystem (false);
+ _satResolver->setNoupdateprovide (false);
+ _satResolver->setDosplitprovides (true);
+ _satResolver->setSolveSrcPackages ( solveSrcPackages() );
+ _satResolver->setCleandepsOnRemove ( cleandepsOnRemove() );
+
+ _satResolver->setDistupgrade (_upgradeMode);
+ if (_upgradeMode) {
+ // may overwrite some settings
+ _satResolver->setDistupgrade_removeunsupported (false);
+ }
- if (_forceResolve)
- _satResolver->setAllowuninstall(true);
-
- if (_onlyRequires == indeterminate)
- _satResolver->setOnlyRequires(ZConfig::instance().solver_onlyRequires());
- else if (_onlyRequires)
- _satResolver->setOnlyRequires(true);
- else
- _satResolver->setOnlyRequires(false);
-
- if (_verifying)
- _satResolver->setFixsystem(true);
-
- if (_ignorealreadyrecommended)
- _satResolver->setIgnorealreadyrecommended(true);
-
- // Resetting additional solver information
- _isInstalledBy.clear();
- _installs.clear();
- _satifiedByInstalled.clear();
+ // Resetting additional solver information
+ _isInstalledBy.clear();
+ _installs.clear();
+ _satifiedByInstalled.clear();
+ _installedSatisfied.clear();
}
-bool
-Resolver::resolvePool()
+bool Resolver::resolvePool()
{
solverInit();
- return _satResolver->resolvePool(_extra_requires, _extra_conflicts, _addWeak,
- _noObsoletesCapability, _noObsoletesItem, _noObsoletesString
- );
+ return _satResolver->resolvePool(_extra_requires, _extra_conflicts, _addWeak, _upgradeRepos );
}
-bool
-Resolver::resolveQueue(solver::detail::SolverQueueItemList & queue)
+bool Resolver::resolveQueue( solver::detail::SolverQueueItemList & queue )
{
solverInit();
-
+
// add/remove additional SolverQueueItems
for (SolverQueueItemList::const_iterator iter = _removed_queue_items.begin();
iter != _removed_queue_items.end(); iter++) {
for (SolverQueueItemList::const_iterator iterQueue = queue.begin(); iterQueue != queue.end(); iterQueue++) {
- if ( (*iterQueue)->cmp(*iter) == 0) {
+ if ( (*iterQueue)->cmp(*iter) == 0) {
MIL << "remove from queue" << *iter;
queue.remove(*iterQueue);
break;
- }
+ }
}
}
if ( (*iterQueue)->cmp(*iter) == 0) {
found = true;
break;
- }
+ }
}
if (!found) {
- MIL << "add to queue" << *iter;
+ MIL << "add to queue" << *iter;
queue.push_back(*iter);
}
}
// give the user a chance for changing these decisions again.
_removed_queue_items.clear();
_added_queue_items.clear();
-
- return _satResolver->resolveQueue(queue, _addWeak,
- _noObsoletesCapability, _noObsoletesItem, _noObsoletesString);
+
+ return _satResolver->resolveQueue(queue, _addWeak);
}
+sat::Transaction Resolver::getTransaction()
+{
+ // FIXME: That's an ugly way of pushing autoInstalled into the transaction.
+ sat::Transaction ret( sat::Transaction::loadFromPool );
+ ret.autoInstalled( _satResolver->autoInstalled() );
+ return ret;
+}
-///////////////////////////////////////////////////////////////////
-//
-//
-// METHOD NAME : Resolver::checkUnmaintainedItems
-// METHOD TYPE :
-//
-// DESCRIPTION : Unmaintained packages which does not fit to
-// the updated system (broken dependencies) will be
-// deleted.
-// returns true if solving was successful
-//
-bool Resolver::checkUnmaintainedItems () {
- int solverRuns = 1;
- bool solverRet = resolvePool();
- MIL << "Checking unmaintained items....." << endl;
-
- while (!solverRet && solverRuns++ < MAXSOLVERRUNS) {
- ResolverProblemList problemList = problems();
- ProblemSolutionList solutionList;
- PoolItemList problemItemList;
-
- for (ResolverProblemList::iterator iter = problemList.begin(); iter != problemList.end(); ++iter) {
- ResolverProblem problem = **iter;
- DBG << "Problem:" << endl;
- DBG << problem.description() << endl;
- DBG << problem.details() << endl;
-
- ProblemSolutionList solutions = problem.solutions();
- for (ProblemSolutionList::const_iterator iterSolution = solutions.begin();
- iterSolution != solutions.end(); ++iterSolution) {
- ProblemSolution_Ptr solution = *iterSolution;
- DBG << " Solution:" << endl;
- DBG << " " << solution->description() << endl;
- DBG << " " << solution->details() << endl;
- solver::detail::CSolutionActionList actionList = solution->actions();
- bool fitUnmaintained = false;
- PoolItemList deletedItems;
- for (CSolutionActionList::const_iterator iterActions = actionList.begin();
- iterActions != actionList.end(); ++iterActions) {
- TransactionSolutionAction_constPtr transactionAction = dynamic_pointer_cast<const TransactionSolutionAction>(*iterActions);
- if (transactionAction &&
- transactionAction->action() == REMOVE
- && _unmaintained_items.find(transactionAction->item()) != _unmaintained_items.end()) {
- // The solution contains unmaintained items ONLY which will be deleted. So take this solution
- fitUnmaintained = true;
- deletedItems.push_back (transactionAction->item());
- } else {
- fitUnmaintained = false;
- }
- }
- if (fitUnmaintained) {
- MIL << "Problem:" << endl;
- MIL << problem.description() << endl;
- MIL << problem.details() << endl;
- MIL << "Will be solved by removing unmaintained package(s)............" << endl;
- MIL << " Solution:" << endl;
- MIL << " " << solution->description() << endl;
- MIL << " " << solution->details() << endl;
- solutionList.push_back (solution);
- problemItemList.insert (problemItemList.end(), deletedItems.begin(), deletedItems.end() );
- break; // not regarding the other solutions
- }
- }
- }
+//----------------------------------------------------------------------------
+// Getting more information about the solve results
- if (!solutionList.empty()) {
- applySolutions (solutionList);
- // list of problematic items after doUpgrade() which is show to the user
- _problem_items.insert (_problem_items.end(), problemItemList.begin(), problemItemList.end());
- _problem_items.unique();
- } else {
- // break cause there is no other solution available by the next run
- solverRuns = MAXSOLVERRUNS;
- }
- // next try
- solverRet = resolvePool();
- }
- return solverRet;
+ResolverProblemList Resolver::problems() const
+{
+ MIL << "Resolver::problems()" << endl;
+ return _satResolver->problems();
}
+void Resolver::applySolutions( const ProblemSolutionList & solutions )
+{
+ for ( ProblemSolution_Ptr solution : solutions )
+ {
+ if ( ! applySolution( *solution ) )
+ break;
+ }
+}
-//----------------------------------------------------------------------------
-// Getting more information about the solve results
+bool Resolver::applySolution( const ProblemSolution & solution )
+{
+ bool ret = true;
+ DBG << "apply solution " << solution << endl;
+ for ( SolutionAction_Ptr action : solution.actions() )
+ {
+ if ( ! action->execute( *this ) )
+ {
+ WAR << "apply solution action failed: " << action << endl;
+ ret = false;
+ break;
+ }
+ }
+ return ret;
+}
+//----------------------------------------------------------------------------
-void
-Resolver::collectResolverInfo(void)
+void Resolver::collectResolverInfo()
{
if ( _satResolver
&& _isInstalledBy.empty()
sat::WhatProvides possibleProviders(*capIt);
for_( iter, possibleProviders.begin(), possibleProviders.end() ) {
PoolItem provider = ResPool::instance().find( *iter );
-
+
// searching if this provider will already be installed
bool found = false;
bool alreadySetForInstallation = false;
&& !found) {
alreadySetForInstallation = true;
ItemCapKind capKind = pos->second;
- if (capKind.item == *instIter) found = true;
+ if (capKind.item() == *instIter) found = true;
pos++;
}
_isInstalledBy.insert (make_pair( provider, capKindisInstalledBy));
} else {
// no initial installation cause it has been set be e.g. user
- ItemCapKind capKindisInstalledBy( *instIter, *capIt, Dep::REQUIRES, false );
- _isInstalledBy.insert (make_pair( provider, capKindisInstalledBy));
+ ItemCapKind capKindisInstalledBy( *instIter, *capIt, Dep::REQUIRES, false );
+ _isInstalledBy.insert (make_pair( provider, capKindisInstalledBy));
}
ItemCapKind capKindisInstalledBy( provider, *capIt, Dep::REQUIRES, !alreadySetForInstallation );
- _installs.insert (make_pair( *instIter, capKindisInstalledBy));
+ _installs.insert (make_pair( *instIter, capKindisInstalledBy));
}
if (provider.status().staysInstalled()) { // Is already satisfied by an item which is installed
ItemCapKind capKindisInstalledBy( provider, *capIt, Dep::REQUIRES, false );
- _satifiedByInstalled.insert (make_pair( *instIter, capKindisInstalledBy));
+ _satifiedByInstalled.insert (make_pair( *instIter, capKindisInstalledBy));
+
+ ItemCapKind installedSatisfied( *instIter, *capIt, Dep::REQUIRES, false );
+ _installedSatisfied.insert (make_pair( provider, installedSatisfied));
}
}
}
-
- //Recommends
- for (Capabilities::const_iterator capIt = (*instIter)->dep (Dep::RECOMMENDS).begin(); capIt != (*instIter)->dep (Dep::RECOMMENDS).end(); ++capIt)
- {
- sat::WhatProvides possibleProviders(*capIt);
- for_( iter, possibleProviders.begin(), possibleProviders.end() ) {
- PoolItem provider = ResPool::instance().find( *iter );
-
- // searching if this provider will already be installed
- bool found = false;
- bool alreadySetForInstallation = false;
- ItemCapKindMap::const_iterator pos = _isInstalledBy.find(provider);
- while (pos != _isInstalledBy.end()
- && pos->first == provider
- && !found) {
- alreadySetForInstallation = true;
- ItemCapKind capKind = pos->second;
- if (capKind.item == *instIter) found = true;
- pos++;
- }
- if (!found
- && provider.status().isToBeInstalled()) {
- if (provider.status().isBySolver()) {
- ItemCapKind capKindisInstalledBy( *instIter, *capIt, Dep::RECOMMENDS, !alreadySetForInstallation );
- _isInstalledBy.insert (make_pair( provider, capKindisInstalledBy));
- } else {
- // no initial installation cause it has been set be e.g. user
- ItemCapKind capKindisInstalledBy( *instIter, *capIt, Dep::RECOMMENDS, false );
- _isInstalledBy.insert (make_pair( provider, capKindisInstalledBy));
+ if (!(_satResolver->onlyRequires())) {
+ //Recommends
+ for (Capabilities::const_iterator capIt = (*instIter)->dep (Dep::RECOMMENDS).begin(); capIt != (*instIter)->dep (Dep::RECOMMENDS).end(); ++capIt)
+ {
+ sat::WhatProvides possibleProviders(*capIt);
+ for_( iter, possibleProviders.begin(), possibleProviders.end() ) {
+ PoolItem provider = ResPool::instance().find( *iter );
+
+ // searching if this provider will already be installed
+ bool found = false;
+ bool alreadySetForInstallation = false;
+ ItemCapKindMap::const_iterator pos = _isInstalledBy.find(provider);
+ while (pos != _isInstalledBy.end()
+ && pos->first == provider
+ && !found) {
+ alreadySetForInstallation = true;
+ ItemCapKind capKind = pos->second;
+ if (capKind.item() == *instIter) found = true;
+ pos++;
}
- ItemCapKind capKindisInstalledBy( provider, *capIt, Dep::RECOMMENDS, !alreadySetForInstallation );
- _installs.insert (make_pair( *instIter, capKindisInstalledBy));
- }
- if (provider.status().staysInstalled()) { // Is already satisfied by an item which is installed
- ItemCapKind capKindisInstalledBy( provider, *capIt, Dep::RECOMMENDS, false );
- _satifiedByInstalled.insert (make_pair( *instIter, capKindisInstalledBy));
- }
- }
- }
+ if (!found
+ && provider.status().isToBeInstalled()) {
+ if (provider.status().isBySolver()) {
+ ItemCapKind capKindisInstalledBy( *instIter, *capIt, Dep::RECOMMENDS, !alreadySetForInstallation );
+ _isInstalledBy.insert (make_pair( provider, capKindisInstalledBy));
+ } else {
+ // no initial installation cause it has been set be e.g. user
+ ItemCapKind capKindisInstalledBy( *instIter, *capIt, Dep::RECOMMENDS, false );
+ _isInstalledBy.insert (make_pair( provider, capKindisInstalledBy));
+ }
+ ItemCapKind capKindisInstalledBy( provider, *capIt, Dep::RECOMMENDS, !alreadySetForInstallation );
+ _installs.insert (make_pair( *instIter, capKindisInstalledBy));
+ }
- //Supplements
- for (Capabilities::const_iterator capIt = (*instIter)->dep (Dep::SUPPLEMENTS).begin(); capIt != (*instIter)->dep (Dep::SUPPLEMENTS).end(); ++capIt)
- {
- sat::WhatProvides possibleProviders(*capIt);
- for_( iter, possibleProviders.begin(), possibleProviders.end() ) {
- PoolItem provider = ResPool::instance().find( *iter );
- // searching if this item will already be installed
- bool found = false;
- bool alreadySetForInstallation = false;
- ItemCapKindMap::const_iterator pos = _isInstalledBy.find(*instIter);
- while (pos != _isInstalledBy.end()
- && pos->first == *instIter
- && !found) {
- alreadySetForInstallation = true;
- ItemCapKind capKind = pos->second;
- if (capKind.item == provider) found = true;
- pos++;
- }
+ if (provider.status().staysInstalled()) { // Is already satisfied by an item which is installed
+ ItemCapKind capKindisInstalledBy( provider, *capIt, Dep::RECOMMENDS, false );
+ _satifiedByInstalled.insert (make_pair( *instIter, capKindisInstalledBy));
- if (!found
- && instIter->status().isToBeInstalled()) {
- if (instIter->status().isBySolver()) {
- ItemCapKind capKindisInstalledBy( provider, *capIt, Dep::SUPPLEMENTS, !alreadySetForInstallation );
- _isInstalledBy.insert (make_pair( *instIter, capKindisInstalledBy));
- } else {
- // no initial installation cause it has been set be e.g. user
- ItemCapKind capKindisInstalledBy( provider, *capIt, Dep::SUPPLEMENTS, false );
- _isInstalledBy.insert (make_pair( *instIter, capKindisInstalledBy));
+ ItemCapKind installedSatisfied( *instIter, *capIt, Dep::RECOMMENDS, false );
+ _installedSatisfied.insert (make_pair( provider, installedSatisfied));
}
- ItemCapKind capKindisInstalledBy( *instIter, *capIt, Dep::SUPPLEMENTS, !alreadySetForInstallation );
- _installs.insert (make_pair( provider, capKindisInstalledBy));
}
+ }
+
+ //Supplements
+ for (Capabilities::const_iterator capIt = (*instIter)->dep (Dep::SUPPLEMENTS).begin(); capIt != (*instIter)->dep (Dep::SUPPLEMENTS).end(); ++capIt)
+ {
+ sat::WhatProvides possibleProviders(*capIt);
+ for_( iter, possibleProviders.begin(), possibleProviders.end() ) {
+ PoolItem provider = ResPool::instance().find( *iter );
+ // searching if this item will already be installed
+ bool found = false;
+ bool alreadySetForInstallation = false;
+ ItemCapKindMap::const_iterator pos = _isInstalledBy.find(*instIter);
+ while (pos != _isInstalledBy.end()
+ && pos->first == *instIter
+ && !found) {
+ alreadySetForInstallation = true;
+ ItemCapKind capKind = pos->second;
+ if (capKind.item() == provider) found = true;
+ pos++;
+ }
+
+ if (!found
+ && instIter->status().isToBeInstalled()) {
+ if (instIter->status().isBySolver()) {
+ ItemCapKind capKindisInstalledBy( provider, *capIt, Dep::SUPPLEMENTS, !alreadySetForInstallation );
+ _isInstalledBy.insert (make_pair( *instIter, capKindisInstalledBy));
+ } else {
+ // no initial installation cause it has been set be e.g. user
+ ItemCapKind capKindisInstalledBy( provider, *capIt, Dep::SUPPLEMENTS, false );
+ _isInstalledBy.insert (make_pair( *instIter, capKindisInstalledBy));
+ }
+ ItemCapKind capKindisInstalledBy( *instIter, *capIt, Dep::SUPPLEMENTS, !alreadySetForInstallation );
+ _installs.insert (make_pair( provider, capKindisInstalledBy));
+ }
+
+ if (instIter->status().staysInstalled()) { // Is already satisfied by an item which is installed
+ ItemCapKind capKindisInstalledBy( *instIter, *capIt, Dep::SUPPLEMENTS, !alreadySetForInstallation );
+ _satifiedByInstalled.insert (make_pair( provider, capKindisInstalledBy));
- if (instIter->status().staysInstalled()) { // Is already satisfied by an item which is installed
- ItemCapKind capKindisInstalledBy( *instIter, *capIt, Dep::SUPPLEMENTS, !alreadySetForInstallation );
- _satifiedByInstalled.insert (make_pair( provider, capKindisInstalledBy));
+ ItemCapKind installedSatisfied( provider, *capIt, Dep::SUPPLEMENTS, false );
+ _installedSatisfied.insert (make_pair( *instIter, installedSatisfied));
+ }
}
}
- }
+ }
}
}
}
-const ItemCapKindList Resolver::isInstalledBy (const PoolItem item) {
+ItemCapKindList Resolver::isInstalledBy( const PoolItem & item )
+{
ItemCapKindList ret;
collectResolverInfo();
return ret;
}
-const ItemCapKindList Resolver::installs (const PoolItem item) {
+ItemCapKindList Resolver::installs( const PoolItem & item )
+{
ItemCapKindList ret;
collectResolverInfo();
return ret;
}
-const ItemCapKindList Resolver::satifiedByInstalled (const PoolItem item) {
+ItemCapKindList Resolver::satifiedByInstalled( const PoolItem & item )
+{
ItemCapKindList ret;
collectResolverInfo();
return ret;
}
+ItemCapKindList Resolver::installedSatisfied( const PoolItem & item )
+{
+ ItemCapKindList ret;
+ collectResolverInfo();
-
+ for (ItemCapKindMap::const_iterator iter = _installedSatisfied.find(item); iter != _installedSatisfied.end();) {
+ ItemCapKind info = iter->second;
+ PoolItem iterItem = iter->first;
+ if (iterItem == item) {
+ ret.push_back(info);
+ iter++;
+ } else {
+ // exit
+ iter = _installedSatisfied.end();
+ }
+ }
+ return ret;
+}
///////////////////////////////////////////////////////////////////