Parse zypp.conf multiversion option and make the setting available in pool and resolver.
authorMichael Andres <ma@suse.de>
Fri, 20 Nov 2009 12:29:37 +0000 (13:29 +0100)
committerMichael Andres <ma@suse.de>
Fri, 20 Nov 2009 12:29:37 +0000 (13:29 +0100)
- Let  return the plain config file values (name or provides:...).
- Add 'bool multiversionInstall()' method in Solvable, ResObject and Selectable.
- Add sat::Pool::multiversionBegin to iterate over all multiversion installable packages.
- Pass the multiversion settings to the solver.

14 files changed:
zypp.conf
zypp/Resolvable.h
zypp/ZConfig.cc
zypp/ZConfig.h
zypp/sat/Pool.cc
zypp/sat/Pool.h
zypp/sat/Solvable.cc
zypp/sat/Solvable.h
zypp/sat/detail/PoolImpl.cc
zypp/sat/detail/PoolImpl.h
zypp/solver/detail/SATResolver.cc
zypp/ui/Selectable.cc
zypp/ui/Selectable.h
zypp/ui/SelectableImpl.h

index c62d21d..b57ca59 100644 (file)
--- a/zypp.conf
+++ b/zypp.conf
 # solver.upgradeRemoveDroppedPackages = true
 
 ##
-## Packages which are parallel installable with
-## diffent versions
+## Packages which can be installed in different versions at the same time.
 ##
-# multiversion = kernel-default,kernel-smp
+## Packages are selected either by name, or by provides. In the later case
+## the string must start with "provides:" immediately followed by the capability.
+##
+## Example:
+##     kernel                          - just packages whith name 'kernel'
+##     provides:multiversion(kernel)   - all packages providing 'multiversion(kernel)'
+##                                       (kenel and kmp packages should do this)
+## Valid values:
+##     Comma separated list of packages.
+##
+## Default value:
+##     empty
+##
+# multiversion = provides:multiversion(kernel)
 
 ##
 ## Path to locks file. If not exist then is create.
index 40c9a92..c7735a2 100644 (file)
@@ -79,12 +79,15 @@ namespace zypp
     Arch arch() const
     { return sat::Solvable::arch(); }
 
-    /**
-     * Flag in the metadata indicating this should be
-     * installed unsing '-i' (not -U).
+    /** Whether different versions of this package can be installed at the same time.
+     * Per default \c false. \see also \ref ZConfig::multiversion.
      */
+    bool multiversionInstall() const
+    { return sat::Solvable::multiversionInstall(); }
+
+    /** \deprecated Use \ref multiversionInstall. */
     bool installOnly() const
-    { return sat::Solvable::installOnly(); }
+    { return sat::Solvable::multiversionInstall(); }
 
     /** \name Dependencies. */
     //@{
index 442c27d..136a6c1 100644 (file)
@@ -367,12 +367,7 @@ namespace zypp
                 }
                 else if ( entry == "multiversion" )
                 {
-                 std::list<std::string> multi;
-                  str::split( value, back_inserter(multi), ", \t" );
-                 for ( std::list<string>::const_iterator it = multi.begin();
-                       it != multi.end(); it++) {
-                     multiversion.insert (IdString(*it));
-                 }
+                  str::split( value, inserter( multiversion, multiversion.end() ), ", \t" );
                 }
                 else if ( entry == "locksfile.path" )
                 {
@@ -485,7 +480,7 @@ namespace zypp
 
     Pathname solver_checkSystemFile;
 
-    std::set<IdString> multiversion;
+    std::set<std::string> multiversion;
 
     bool apply_locks_file;
 
@@ -706,14 +701,9 @@ namespace zypp
   void ZConfig::setSolverUpgradeRemoveDroppedPackages( bool val_r )    { _pimpl->solverUpgradeRemoveDroppedPackages.set( val_r ); }
   void ZConfig::resetSolverUpgradeRemoveDroppedPackages()              { _pimpl->solverUpgradeRemoveDroppedPackages.restoreToDefault(); }
 
-  std::set<IdString> ZConfig::multiversion() const
-  { return _pimpl->multiversion; }
-
-  void ZConfig::addMultiversion(std::string &name)
-  { _pimpl->multiversion.insert(IdString(name)); }
-
-  bool ZConfig::removeMultiversion(std::string &name)
-  { return _pimpl->multiversion.erase(IdString(name)); }
+  const std::set<std::string> & ZConfig::multiversionSpec() const      { return _pimpl->multiversion; }
+  void ZConfig::addMultiversionSpec( const std::string & name_r )      { _pimpl->multiversion.insert( name_r ); }
+  void ZConfig::removeMultiversionSpec( const std::string & name_r )   { _pimpl->multiversion.erase( name_r ); }
 
   bool ZConfig::apply_locks_file() const
   { return _pimpl->apply_locks_file; }
index badb1ec..a222594 100644 (file)
@@ -265,13 +265,16 @@ namespace zypp
       /** Reset \ref solverUpgradeRemoveDroppedPackages to the \c zypp.conf default. */
       void resetSolverUpgradeRemoveDroppedPackages();
 
-      /**
-       * Packages which can be installed parallel with different versions
-       * Returning a set of package names (IdString)
+      /** \name Packages which can be installed in different versions at the same time.
+       * This returns the config file values (\c names or \c provides:...). For the corresponding
+       * packages use e.g \ref sat::Pool::multiversionBegin, or \ref sat::Solbale::multiversionInstall
+       * (\ref ui::Selectable::multiversionInstall).
        */
-      std::set<IdString> multiversion() const;
-      void addMultiversion(std::string &name);
-      bool removeMultiversion(std::string &name);
+      //@{
+      const std::set<std::string> & multiversionSpec() const;
+      void addMultiversionSpec( const std::string & name_r );
+      void removeMultiversionSpec( const std::string & name_r );
+      //@}
 
       /**
        * Path where zypp can find or create lock file (configPath()/locks)
index ee5d607..b07df4e 100644 (file)
@@ -200,6 +200,12 @@ namespace zypp
     bool Pool::isAvailableLocale( const Locale & locale_r ) const
     { return myPool().isAvailableLocale( locale_r ); }
 
+    bool Pool::multiversionEmpty() const                       { return myPool().multiversionList().empty(); }
+    size_t Pool::multiversionSize() const                      { return myPool().multiversionList().size(); }
+    Pool::MultiversionIterator Pool::multiversionBegin() const { return myPool().multiversionList().begin(); }
+    Pool::MultiversionIterator Pool::multiversionEnd() const   { return myPool().multiversionList().end(); }
+    bool Pool::isMultiversion( IdString ident_r ) const                { return myPool().isMultiversion( ident_r ); }
+
    /******************************************************************
     **
     ** FUNCTION NAME : operator<<
index a1bd62a..bcd92e3 100644 (file)
@@ -202,6 +202,22 @@ namespace zypp
         //@}
 
       public:
+        /** \name Multiversion install.
+         * Ident list of all packages that can be installed in different version
+         * at the same time. (\see \ref ZConfig::multiversionSpec)
+         */
+        //@{
+        typedef std::tr1::unordered_set<IdString>::const_iterator MultiversionIterator;
+
+        bool multiversionEmpty() const;
+        size_t multiversionSize() const;
+        MultiversionIterator multiversionBegin() const;
+        MultiversionIterator multiversionEnd() const;
+
+        bool isMultiversion( IdString ident_r ) const;
+        //@}
+
+      public:
         /** Expert backdoor. */
         ::_Pool * get() const;
       private:
index 8802ac7..c15d169 100644 (file)
@@ -374,14 +374,13 @@ namespace zypp
       //return ArchId( _solvable->arch );
     }
 
-    bool Solvable::installOnly() const
+    bool Solvable::multiversionInstall() const
     {
-       std::set<IdString> multiversion = ZConfig::instance().multiversion();
-       if (multiversion.find(ident()) != multiversion.end())
-             return true;
-       return false;
+      return myPool().isMultiversion( ident() );
     }
 
+    bool Solvable::installOnly() const { return multiversionInstall(); }
+
     IdString Solvable::vendor() const
     {
       NO_SOLVABLE_RETURN( IdString() );
index ceb8417..4637d2f 100644 (file)
@@ -169,7 +169,13 @@ namespace zypp
 
         IdString     vendor()   const;
 
-       bool         installOnly() const;
+        /** Whether different versions of this package can be installed at the same time.
+         * Per default \c false. \see also \ref ZConfig::multiversion.
+         */
+        bool         multiversionInstall() const;
+
+        /** \deprecated Use \ref multiversionInstall. */
+       bool installOnly() const ZYPP_DEPRECATED;
 
         /** String representation <tt>"ident-edition.arch"</tt> or \c "noSolvable"
          * \code
index 951756f..68f9d33 100644 (file)
@@ -215,6 +215,7 @@ namespace zypp
         }
         _serial.setDirty();           // pool content change
         _availableLocalesPtr.reset(); // available locales may change
+        _multiversionListPtr.reset(); // re-evaluate ZConfig::multiversionSpec.
 
         // invaldate dependency/namespace related indices:
         depSetDirty();
@@ -478,6 +479,39 @@ namespace zypp
         return *_availableLocalesPtr;
       }
 
+      void PoolImpl::multiversionListInit() const
+      {
+        _multiversionListPtr.reset( new MultiversionList );
+        MultiversionList & multiversionList( *_multiversionListPtr );
+
+        const std::set<std::string> & multiversionSpec( ZConfig::instance().multiversionSpec() );
+        for_( it, multiversionSpec.begin(), multiversionSpec.end() )
+        {
+          static const std::string prefix( "provides:" );
+          if ( str::hasPrefix( *it, prefix ) )
+          {
+            WhatProvides provides( Capability( it->c_str() + prefix.size() ) );
+            if ( provides.empty() )
+            {
+              MIL << "Multiversion install not provided (" << *it << ")" << endl;
+            }
+            else
+            {
+              for_( pit, provides.begin(), provides.end() )
+              {
+                if ( multiversionList.insert( pit->ident() ).second )
+                  MIL << "Multiversion install " << pit->ident() << " (" << *it << ")" << endl;
+              }
+            }
+          }
+          else
+          {
+            MIL << "Multiversion install " << *it << endl;
+            multiversionList.insert( IdString( *it ) );
+          }
+        }
+      }
+
       /////////////////////////////////////////////////////////////////
     } // namespace detail
     ///////////////////////////////////////////////////////////////////
index ade5a97..b5f59cf 100644 (file)
@@ -222,6 +222,26 @@ namespace zypp
           }
           //@}
 
+        public:
+          /** \name Multiversion install. */
+          //@{
+          typedef std::tr1::unordered_set<IdString> MultiversionList;
+
+          const MultiversionList & multiversionList() const
+          {
+            if ( ! _multiversionListPtr )
+              multiversionListInit();
+            return *_multiversionListPtr;
+          }
+
+          bool isMultiversion( IdString ident_r ) const
+          {
+            const MultiversionList & l( multiversionList() );
+            return l.find( ident_r ) != l.end();
+          }
+
+          //@}
+
         private:
           /** sat-pool. */
           ::_Pool * _pool;
@@ -236,6 +256,10 @@ namespace zypp
           LocaleSet _requestedLocales;
           mutable scoped_ptr<LocaleSet> _availableLocalesPtr;
           mutable std::tr1::unordered_set<IdString> _locale2Solver;
+
+          /**  */
+          void multiversionListInit() const;
+          mutable scoped_ptr<MultiversionList> _multiversionListPtr;
       };
       ///////////////////////////////////////////////////////////////////
 
index 7826db2..909c2e4 100644 (file)
@@ -610,10 +610,10 @@ SATResolver::solverInit(const PoolItemList & weakItems)
     }
 
     // Add rules for parallel installable resolvables with different versions
-    std::set<IdString> parallel = ZConfig::instance().multiversion();
-    for (std::set<IdString>::const_iterator it = parallel.begin(); it != parallel.end(); ++it) {
-       queue_push( &(_jobQueue), SOLVER_NOOBSOLETES_SOLVABLE_NAME );
-       queue_push( &(_jobQueue), it->id() );
+    for_( it, sat::Pool::instance().multiversionBegin(), sat::Pool::instance().multiversionEnd() )
+    {
+      queue_push( &(_jobQueue), SOLVER_NOOBSOLETES_SOLVABLE_NAME );
+      queue_push( &(_jobQueue), it->id() );
     }
 
     if ( _distupgrade )
index 451c466..491e02b 100644 (file)
@@ -132,6 +132,9 @@ namespace zypp
     bool Selectable::isUnmaintained() const
     { return _pimpl->isUnmaintained(); }
 
+    bool Selectable::multiversionInstall() const
+    { return _pimpl->multiversionInstall(); }
+
     bool Selectable::isUndetermined() const
     { return _pimpl->isUndetermined(); }
 
index ac32377..7b0b3d0 100644 (file)
@@ -267,6 +267,11 @@ namespace zypp
        */
       bool isUnmaintained() const;
 
+      /** Whether different versions of this package can be installed at the same time.
+       * Per default \c false. \see also \ref ZConfig::multiversion.
+       */
+      bool multiversionInstall() const;
+
       /** \name Classification of available patches (pseudo installed items).
        * A patch is either \c not \c relevant, \c satisfied or \c broken.
        * The same applies to other pseudo installed kinds.
index 86f1ecc..b30d772 100644 (file)
@@ -228,6 +228,9 @@ namespace zypp
       bool isUnmaintained() const
       { return availableEmpty(); }
 
+      bool multiversionInstall() const
+      { return theObj().satSolvable().multiversionInstall(); }
+
       bool isUndetermined() const
       {
         PoolItem cand( candidateObj() );
@@ -346,7 +349,8 @@ namespace zypp
     /** \relates Selectable::Impl Stream output */
     inline std::ostream & dumpOn( std::ostream & str, const Selectable::Impl & obj )
     {
-      str << '[' << obj.kind() << ']' << obj.name() << ": " << obj.status() << endl;
+      str << '[' << obj.kind() << ']' << obj.name() << ": " << obj.status()
+          << ( obj.multiversionInstall() ? " (multiversion)" : "") << endl;
 
       if ( obj.installedEmpty() )
         str << "   (I 0) {}" << endl << "   ";