BuildRequires: libudev-devel
BuildRequires: boost-devel dejagnu doxygen gcc-c++ gettext-devel graphviz libxml2-devel
-BuildRequires: libsatsolver-devel >= 0.14.13
+BuildRequires: libsatsolver-devel >= 0.14.17
%if 0%{?suse_version}
%requires_eq satsolver-tools
%else
# solver.allowVendorChange = false
##
+## Cleanup when deleting packages. Whether the solver should per default
+## try to remove packages exclusively required by the ones he's asked to delete.
+##
+## Valid values: boolean
+## Default value: false
+##
+# solver.cleandepsOnRemove = false
+
+##
## This file contains requirements/conflicts which fulfill the
## needs of a running system.
## For example the system would be broken if not glibc or kernel is
// METHOD TYPE : Ctor
//
Resolver::Resolver( const ResPool & pool )
- {
- _pimpl = new solver::detail::Resolver(pool);
- }
+ : _pimpl( new Impl(pool) )
+ {}
///////////////////////////////////////////////////////////////////
//
{ _pimpl->doUpdate(); }
void Resolver::setForceResolve( bool yesno_r ) { _pimpl->setForceResolve( yesno_r ); }
- bool Resolver::forceResolve() { return _pimpl->forceResolve(); }
+ bool Resolver::forceResolve() const { return _pimpl->forceResolve(); }
void Resolver::setIgnoreAlreadyRecommended( bool yesno_r) { _pimpl->setIgnoreAlreadyRecommended( yesno_r ); }
- bool Resolver::ignoreAlreadyRecommended() { return _pimpl->ignoreAlreadyRecommended(); }
+ bool Resolver::ignoreAlreadyRecommended() const { return _pimpl->ignoreAlreadyRecommended(); }
void Resolver::setOnlyRequires( bool yesno_r ) { _pimpl->setOnlyRequires( yesno_r ); }
void Resolver::resetOnlyRequires() { _pimpl->setOnlyRequires( indeterminate ); }
- bool Resolver::onlyRequires() { return _pimpl->onlyRequires(); }
+ bool Resolver::onlyRequires() const { return _pimpl->onlyRequires(); }
bool Resolver::upgradeMode() const { return _pimpl->isUpgradeMode(); }
void Resolver::setDefaultSolveSrcPackages() { _pimpl->setSolveSrcPackages( indeterminate ); }
bool Resolver::solveSrcPackages() const { return _pimpl->solveSrcPackages(); }
+ void Resolver::setCleandepsOnRemove( bool yesno_r ) { _pimpl->setCleandepsOnRemove( yesno_r ); }
+ void Resolver::setDefaultCleandepsOnRemove() { _pimpl->setCleandepsOnRemove( indeterminate ); }
+ bool Resolver::cleandepsOnRemove() const { return _pimpl->cleandepsOnRemove(); }
+
void Resolver::addUpgradeRepo( Repository repo_r ) { _pimpl->addUpgradeRepo( repo_r ); }
bool Resolver::upgradingRepo( Repository repo_r ) const { return _pimpl->upgradingRepo( repo_r ); }
void Resolver::removeUpgradeRepo( Repository repo_r ) { _pimpl->removeUpgradeRepo( repo_r ); }
void Resolver::removeRequire( const Capability & capability ) { _pimpl->removeExtraRequire( capability ); }
void Resolver::removeConflict( const Capability & capability ){ _pimpl->removeExtraConflict( capability ); }
- CapabilitySet Resolver::getRequire() { return _pimpl->extraRequires(); }
- CapabilitySet Resolver::getConflict() { return _pimpl->extraConflicts(); }
+ CapabilitySet Resolver::getRequire() const { return _pimpl->extraRequires(); }
+ CapabilitySet Resolver::getConflict() const { return _pimpl->extraConflicts(); }
std::list<PoolItem> Resolver::problematicUpdateItems() const
{ return _pimpl->problematicUpdateItems(); }
void Resolver::reset()
{ _pimpl->reset( false ); /* Do not keep extra requires/conflicts */ }
-
+ std::ostream & operator<<( std::ostream & str, const Resolver & obj )
+ { return str << *obj._pimpl; }
/////////////////////////////////////////////////////////////////
} // namespace zypp
* This behaviour is favourited by ZMD.
**/
void setForceResolve( bool force );
- bool forceResolve();
+ bool forceResolve() const;
/**
* Ignore recommended packages that were already recommended by
* the installed packages
**/
void setIgnoreAlreadyRecommended( bool yesno_r );
- bool ignoreAlreadyRecommended();
+ bool ignoreAlreadyRecommended() const;
/**
* Setting whether required packages are installed ONLY
**/
void setOnlyRequires( bool yesno_r );
void resetOnlyRequires(); // set back to default (described in zypp.conf)
- bool onlyRequires();
+ bool onlyRequires() const;
/**
* Whether the \ref Resolver is in upgrade mode.
void setDefaultSolveSrcPackages();
bool solveSrcPackages() const;
+ /**
+ * Cleanup when deleting packages. Whether the solver should per default
+ * try to remove packages exclusively required by the ones he's asked to delete.
+ */
+ void setCleandepsOnRemove( bool yesno_r );
+ void setDefaultCleandepsOnRemove(); // set back to default (in zypp.conf)
+ bool cleandepsOnRemove() const;
+
/** \name Upgrade to content of a specific repository.
* \note This is an ordinary solver request. You should simply
* \ref resolvePool to execute, and not \ref doUpgrade.
* Get all the additional requirements set by \ref addRequire(Capability).
*
*/
- CapabilitySet getRequire();
+ CapabilitySet getRequire() const;
/**
* Get all the additional conflicts set by \ref addConflict(Capability).
*
*/
- CapabilitySet getConflict();
+ CapabilitySet getConflict() const;
/**
* Generates a solver Testcase of the current state
solver::detail::ItemCapKindList installedSatisfied( const PoolItem & item );
-
private:
- solver::detail::Resolver_Ptr _pimpl;
+ friend std::ostream & operator<<( std::ostream & str, const Resolver & obj );
+
+ typedef solver::detail::Resolver Impl;
+ zypp::RW_pointer<Impl,rw_pointer::Intrusive<Impl> > _pimpl;
};
///////////////////////////////////////////////////////////////////
+ /** \relates Resolver Stream output */
+ std::ostream & operator<<( std::ostream & str, const Resolver & obj );
+
/////////////////////////////////////////////////////////////////
} // namespace zypp
///////////////////////////////////////////////////////////////////
, commit_downloadMode ( DownloadDefault )
, solver_onlyRequires ( false )
, solver_allowVendorChange ( false )
+ , solver_cleandepsOnRemove ( false )
, solver_upgradeTestcasesToKeep ( 2 )
, solverUpgradeRemoveDroppedPackages( true )
, apply_locks_file ( true )
{
solver_allowVendorChange.set( str::strToBool( value, solver_allowVendorChange ) );
}
+ else if ( entry == "solver.cleandepsOnRemove" )
+ {
+ solver_cleandepsOnRemove.set( str::strToBool( value, solver_cleandepsOnRemove ) );
+ }
else if ( entry == "solver.upgradeTestcasesToKeep" )
{
solver_upgradeTestcasesToKeep.set( str::strtonum<unsigned>( value ) );
Option<bool> solver_onlyRequires;
Option<bool> solver_allowVendorChange;
+ Option<bool> solver_cleandepsOnRemove;
Option<unsigned> solver_upgradeTestcasesToKeep;
DefaultOption<bool> solverUpgradeRemoveDroppedPackages;
bool ZConfig::solver_allowVendorChange() const
{ return _pimpl->solver_allowVendorChange; }
+ bool ZConfig::solver_cleandepsOnRemove() const
+ { return _pimpl->solver_cleandepsOnRemove; }
+
Pathname ZConfig::solver_checkSystemFile() const
{ return ( _pimpl->solver_checkSystemFile.empty()
? (configPath()/"systemCheck") : _pimpl->solver_checkSystemFile ); }
bool solver_allowVendorChange() const;
/**
+ * Whether removing a package should also remove no longer needed requirements.
+ */
+ bool solver_cleandepsOnRemove() const;
+
+ /**
* When committing a dist upgrade (e.g. <tt>zypper dup</tt>)
* a solver testcase is written. It is needed in bugreports,
* in case something went wrong. This returns the number of
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/>";
}
, _onlyRequires ( ZConfig::instance().solver_onlyRequires() )
, _allowVendorChange ( ZConfig::instance().solver_allowVendorChange() )
, _solveSrcPackages ( false )
- , _ignoreAlreadyRecommended (false)
+ , _cleandepsOnRemove ( ZConfig::instance().solver_cleandepsOnRemove() )
+ , _ignoreAlreadyRecommended (true)
{
sat::Pool satPool( sat::Pool::instance() );
_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
_satResolver->setNoupdateprovide (false);
_satResolver->setDosplitprovides (false);
_satResolver->setSolveSrcPackages ( solveSrcPackages() );
+ _satResolver->setCleandepsOnRemove ( cleandepsOnRemove() );
if (_upgradeMode) {
// may overwrite some settings
// packages, hardware packages (modalias)
bool _allowVendorChange; // whether the solver should allow or disallow vendor changes.
bool _solveSrcPackages; // whether to generate solver jobs for selected source packges.
+ bool _cleandepsOnRemove; // whether removing a package should also remove no longer needed requirements
bool _ignoreAlreadyRecommended; //ignore recommended packages that have already been recommended by the installed packages
//@}
void removeQueueItem( SolverQueueItem_Ptr item );
void addQueueItem( SolverQueueItem_Ptr item );
- CapabilitySet extraRequires() { return _extra_requires; }
- CapabilitySet extraConflicts() { return _extra_conflicts; }
+ CapabilitySet extraRequires() const { return _extra_requires; }
+ CapabilitySet extraConflicts() const { return _extra_conflicts; }
void addWeak( const PoolItem & item );
bool solveSrcPackages() const { return _solveSrcPackages; }
void setSolveSrcPackages( TriBool state_r ) { _solveSrcPackages = indeterminate(state_r) ? false : bool(state_r); }
+
+ bool cleandepsOnRemove() const { return _cleandepsOnRemove; }
+ void setCleandepsOnRemove( TriBool state_r );
//@}
ResolverProblemList problems() const;
IMPL_PTR_TYPE(SATResolver);
+#define MAYBE_CLEANDEPS (cleandepsOnRemove()?SOLVER_CLEANDEPS:0)
+
//---------------------------------------------------------------------------
// Callbacks for SAT policies
//---------------------------------------------------------------------------
os << " distupgrade = " << _distupgrade << endl;
os << " distupgrade_removeunsupported = " << _distupgrade_removeunsupported << endl;
os << " solveSrcPackages = " << _solveSrcPackages << endl;
+ os << " cleandepsOnRemove = " << _cleandepsOnRemove << endl;
} else {
os << "<NULL>";
}
, _fixsystem(false)
, _allowdowngrade(false)
, _allowarchchange(false)
- , _allowvendorchange(false)
+ , _allowvendorchange(ZConfig::instance().solver_allowVendorChange())
, _allowuninstall(false)
, _updatesystem(false)
, _noupdateprovide(false)
, _dosplitprovides(false)
, _onlyRequires(ZConfig::instance().solver_onlyRequires())
- , _ignorealreadyrecommended(false)
+ , _ignorealreadyrecommended(true)
, _distupgrade(false)
, _distupgrade_removeunsupported(false)
-
+ , _solveSrcPackages(false)
+ , _cleandepsOnRemove(ZConfig::instance().solver_cleandepsOnRemove())
{
}
ERR << "Delete: " << *iter << " not found" << endl;
} else {
MIL << "Delete " << *iter << endl;
- queue_push( &(_jobQueue), SOLVER_ERASE_SOLVABLE );
+ queue_push( &(_jobQueue), SOLVER_ERASE_SOLVABLE | MAYBE_CLEANDEPS );
queue_push( &(_jobQueue), id);
}
}
}
for (CapabilitySet::const_iterator iter = conflict_caps.begin(); iter != conflict_caps.end(); iter++) {
- queue_push( &(_jobQueue), SOLVER_ERASE_SOLVABLE_PROVIDES);
+ queue_push( &(_jobQueue), SOLVER_ERASE_SOLVABLE_PROVIDES | MAYBE_CLEANDEPS );
queue_push( &(_jobQueue), iter->id() );
MIL << "Conflicts " << *iter << endl;
}
for (PoolItemList::const_iterator iter = _items_to_remove.begin(); iter != _items_to_remove.end(); iter++) {
sat::detail::IdType ident( (*iter)->satSolvable().ident().id() );
MIL << "Delete " << *iter << ident << endl;
- queue_push( &(_jobQueue), SOLVER_ERASE_SOLVABLE_NAME );
+ queue_push( &(_jobQueue), SOLVER_ERASE_SOLVABLE_NAME | MAYBE_CLEANDEPS );
queue_push( &(_jobQueue), ident);
}
queue_push( &(_jobQueue), ident );
} else {
MIL << "Lock NOT installed item " << *iter << endl;
- queue_push( &(_jobQueue), SOLVER_ERASE_SOLVABLE );
+ queue_push( &(_jobQueue), SOLVER_ERASE_SOLVABLE | MAYBE_CLEANDEPS );
queue_push( &(_jobQueue), ident );
}
}
queue_push( &(_jobQueue), ident );
} else {
MIL << "Keep NOT installed item " << *iter << ident << endl;
- queue_push( &(_jobQueue), SOLVER_ERASE_SOLVABLE | SOLVER_WEAK);
+ queue_push( &(_jobQueue), SOLVER_ERASE_SOLVABLE | SOLVER_WEAK | MAYBE_CLEANDEPS );
queue_push( &(_jobQueue), ident );
}
}
}
for (CapabilitySet::const_iterator iter = system_conflicts.begin(); iter != system_conflicts.end(); iter++) {
- queue_push( &(_jobQueue), SOLVER_ERASE_SOLVABLE_PROVIDES);
+ queue_push( &(_jobQueue), SOLVER_ERASE_SOLVABLE_PROVIDES | MAYBE_CLEANDEPS );
queue_push( &(_jobQueue), iter->id() );
MIL << "SYSTEM Conflicts " << *iter << endl;
}
bool _distupgrade;
bool _distupgrade_removeunsupported;
bool _solveSrcPackages; // false: generate no job rule for source packages selected in the pool
+ bool _cleandepsOnRemove; // whether removing a package should also remove no longer needed requirements
// ---------------------------------- methods
std::string SATprobleminfoString (Id problem, std::string &detail, Id &ignoreId);
bool solveSrcPackages() const { return _solveSrcPackages; }
void setSolveSrcPackages( bool state_r ) { _solveSrcPackages = state_r; }
+ bool cleandepsOnRemove() const { return _cleandepsOnRemove; }
+ void setCleandepsOnRemove( bool state_r ) { _cleandepsOnRemove = state_r; }
+
PoolItemList problematicUpdateItems( void ) const { return _problem_items; }
PoolItemList resultItemsToInstall () { return _result_items_to_install; }
#include "zypp/base/Logger.h"
#include "zypp/IdString.h"
+#include "zypp/Resolver.h"
#include "zypp/solver/detail/SolverQueueItemDelete.h"
/////////////////////////////////////////////////////////////////////////
bool SolverQueueItemDelete::addRule (_Queue & q)
{
+#define MAYBE_CLEANDEPS (pool().resolver().cleandepsOnRemove()?SOLVER_CLEANDEPS:0)
+
::Id id = IdString(_name).id();
if (_soft) {
- queue_push( &(q), SOLVER_ERASE_SOLVABLE_NAME | SOLVER_WEAK);
+ queue_push( &(q), SOLVER_ERASE_SOLVABLE_NAME | SOLVER_WEAK | MAYBE_CLEANDEPS );
} else {
- queue_push( &(q), SOLVER_ERASE_SOLVABLE_NAME );
+ queue_push( &(q), SOLVER_ERASE_SOLVABLE_NAME | MAYBE_CLEANDEPS );
}
queue_push( &(q), id);