Support solver option cleandepsOnRemove: Cleanup when deleting packages
authorMichael Andres <ma@suse.de>
Thu, 29 Apr 2010 15:09:32 +0000 (17:09 +0200)
committerMichael Andres <ma@suse.de>
Thu, 29 Apr 2010 15:09:32 +0000 (17:09 +0200)
- zypp.conf option: solver.cleandepsOnRemove (default false)
- Resolver::setCleandepsOnRemove

libzypp.spec.cmake
zypp.conf
zypp/Resolver.cc
zypp/Resolver.h
zypp/ZConfig.cc
zypp/ZConfig.h
zypp/solver/detail/Resolver.cc
zypp/solver/detail/Resolver.h
zypp/solver/detail/SATResolver.cc
zypp/solver/detail/SATResolver.h
zypp/solver/detail/SolverQueueItemDelete.cc

index 0a50dd3..1aea545 100644 (file)
@@ -31,7 +31,7 @@ BuildRequires:  openssl-devel
 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
index 3bbb6e4..190f5c6 100644 (file)
--- a/zypp.conf
+++ b/zypp.conf
 # 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
index db9ff6c..ad1fe4a 100644 (file)
@@ -33,9 +33,8 @@ namespace zypp
   //   METHOD TYPE : Ctor
   //
   Resolver::Resolver( const ResPool & pool )
-  {
-    _pimpl = new solver::detail::Resolver(pool);
-  }
+  : _pimpl( new Impl(pool) )
+  {}
 
   ///////////////////////////////////////////////////////////////////
   //
@@ -75,14 +74,14 @@ namespace zypp
   { _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(); }
 
@@ -98,6 +97,10 @@ namespace zypp
   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 ); }
@@ -108,8 +111,8 @@ namespace zypp
   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(); }
@@ -135,7 +138,8 @@ namespace zypp
   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
index 74db641..4ad256b 100644 (file)
@@ -161,14 +161,14 @@ 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
@@ -177,7 +177,7 @@ namespace zypp
      **/
     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.
@@ -218,6 +218,14 @@ namespace zypp
     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.
@@ -275,13 +283,13 @@ namespace zypp
      * 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
@@ -357,12 +365,17 @@ namespace zypp
     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
 ///////////////////////////////////////////////////////////////////
index 16bf5ef..9ab5442 100644 (file)
@@ -229,6 +229,7 @@ namespace zypp
         , commit_downloadMode          ( DownloadDefault )
         , solver_onlyRequires          ( false )
         , solver_allowVendorChange     ( false )
+        , solver_cleandepsOnRemove     ( false )
         , solver_upgradeTestcasesToKeep        ( 2 )
         , solverUpgradeRemoveDroppedPackages( true )
         , apply_locks_file             ( true )
@@ -356,6 +357,10 @@ namespace zypp
                 {
                   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 ) );
@@ -479,6 +484,7 @@ namespace zypp
 
     Option<bool>       solver_onlyRequires;
     Option<bool>       solver_allowVendorChange;
+    Option<bool>       solver_cleandepsOnRemove;
     Option<unsigned>   solver_upgradeTestcasesToKeep;
     DefaultOption<bool> solverUpgradeRemoveDroppedPackages;
 
@@ -702,6 +708,9 @@ namespace zypp
   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 ); }
index b569a18..4af55bf 100644 (file)
@@ -254,6 +254,11 @@ namespace zypp
       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
index 2e38463..ed804aa 100644 (file)
@@ -58,7 +58,19 @@ IMPL_PTR_TYPE(Resolver);
 
 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/>";
 }
 
 
@@ -75,7 +87,8 @@ Resolver::Resolver (const ResPool & pool)
     , _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() );
@@ -100,6 +113,11 @@ void Resolver::setOnlyRequires( TriBool state_r )
   _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
@@ -272,6 +290,7 @@ void Resolver::solverInit()
     _satResolver->setNoupdateprovide           (false);
     _satResolver->setDosplitprovides           (false);
     _satResolver->setSolveSrcPackages          ( solveSrcPackages() );
+    _satResolver->setCleandepsOnRemove         ( cleandepsOnRemove() );
 
     if (_upgradeMode) {
       // may overwrite some settings
index ee4ee7b..77a0969 100644 (file)
@@ -113,6 +113,7 @@ class Resolver : public base::ReferenceCounted, private base::NonCopyable {
                                   // 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
     //@}
@@ -168,8 +169,8 @@ class Resolver : public base::ReferenceCounted, private base::NonCopyable {
     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 );
 
@@ -204,6 +205,9 @@ class Resolver : public base::ReferenceCounted, private base::NonCopyable {
 
     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;
index 77ee6b8..8ebef38 100644 (file)
@@ -66,6 +66,8 @@ using namespace std;
 
 IMPL_PTR_TYPE(SATResolver);
 
+#define MAYBE_CLEANDEPS (cleandepsOnRemove()?SOLVER_CLEANDEPS:0)
+
 //---------------------------------------------------------------------------
 // Callbacks for SAT policies
 //---------------------------------------------------------------------------
@@ -121,6 +123,7 @@ SATResolver::dumpOn( std::ostream & os ) const
        os << "  distupgrade = " << _distupgrade << endl;
         os << "  distupgrade_removeunsupported = " << _distupgrade_removeunsupported << endl;
        os << "  solveSrcPackages = " << _solveSrcPackages << endl;
+       os << "  cleandepsOnRemove = " << _cleandepsOnRemove << endl;
     } else {
        os << "<NULL>";
     }
@@ -136,16 +139,17 @@ SATResolver::SATResolver (const ResPool & pool, Pool *SATPool)
     , _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())
 {
 }
 
@@ -694,7 +698,7 @@ SATResolver::resolvePool(const CapabilitySet & requires_caps,
            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);
        }
     }
@@ -713,7 +717,7 @@ SATResolver::resolvePool(const CapabilitySet & requires_caps,
     }
 
     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;
     }
@@ -763,7 +767,7 @@ SATResolver::resolveQueue(const SolverQueueItemList &requestQueue,
     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);
     }
 
@@ -1379,7 +1383,7 @@ void SATResolver::setLocks()
            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 );
        }
     }
@@ -1392,7 +1396,7 @@ void SATResolver::setLocks()
            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 );
        }
     }
@@ -1410,7 +1414,7 @@ void SATResolver::setSystemRequirements()
     }
 
     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;
     }
index 5ac68b3..56140d0 100644 (file)
@@ -97,6 +97,7 @@ class SATResolver : public base::ReferenceCounted, private base::NonCopyable {
     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);
@@ -201,6 +202,9 @@ class SATResolver : public base::ReferenceCounted, private base::NonCopyable {
     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; }
index 70c2b28..91a75ec 100644 (file)
@@ -24,6 +24,7 @@ extern "C"
 
 #include "zypp/base/Logger.h"
 #include "zypp/IdString.h"
+#include "zypp/Resolver.h"
 #include "zypp/solver/detail/SolverQueueItemDelete.h"
 
 /////////////////////////////////////////////////////////////////////////
@@ -69,11 +70,13 @@ SolverQueueItemDelete::~SolverQueueItemDelete()
 
 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);