added new API calls: setAdditionalProvide,setAdditionalConflict,setAdditionalRequire
authorStefan Schubert <schubi@suse.de>
Mon, 14 Aug 2006 14:56:25 +0000 (14:56 +0000)
committerStefan Schubert <schubi@suse.de>
Mon, 14 Aug 2006 14:56:25 +0000 (14:56 +0000)
package/libzypp.changes
zypp/ResPool.cc
zypp/ResPool.h
zypp/pool/PoolImpl.h
zypp/pool/PoolTraits.h
zypp/solver/detail/QueueItemRequire.cc
zypp/solver/detail/Resolver.cc
zypp/solver/detail/Resolver_problems.cc

index 6baa827..130d09f 100644 (file)
@@ -1,4 +1,12 @@
 -------------------------------------------------------------------
+Mon Aug 14 16:50:53 CEST 2006 - schubi@suse.de
+
+- Added new API calls:
+  setAdditionalProvide 
+  setAdditionalConflict
+  setAdditionalRequire 
+
+-------------------------------------------------------------------
 Mon Aug 14 11:26:20 CEST 2006 - dmacvicar@suse.de
 
 - don't link examples to testsuite library. 
index ca8cd0e..ae88a55 100644 (file)
@@ -87,6 +87,22 @@ namespace zypp
   ResPool::byCapabilityIndex_iterator ResPool::byCapabilityIndexEnd( const std::string & index_r, Dep depType_r ) const
   { return _pimpl->_caphash.end( index_r, depType_r ); }
 
+  void ResPool::setAdditionalRequire( const AdditionalCapSet & capset ) const
+  { _pimpl->setAdditionalRequire( capset ); }
+  ResPool::AdditionalCapSet & ResPool::additionalRequire() const
+  { return _pimpl->additionalRequire(); }
+    
+  void ResPool::setAdditionalConflict( const AdditionalCapSet & capset ) const
+  { _pimpl->setAdditionalConflict( capset ); }
+  ResPool::AdditionalCapSet & ResPool::additionaConflict() const
+  { return _pimpl->additionaConflict(); }
+    
+  void ResPool::setAdditionalProvide( const AdditionalCapSet & capset ) const
+  { _pimpl->setAdditionalProvide( capset ); }
+  ResPool::AdditionalCapSet & ResPool::additionaProvide() const
+  { return _pimpl->additionaProvide(); }
+    
+
   /******************************************************************
   **
   **   FUNCTION NAME : operator<<
index 68bfdef..2498c5f 100644 (file)
@@ -45,6 +45,7 @@ namespace zypp
     typedef pool::PoolTraits::const_iterator            const_iterator;
     typedef pool::PoolTraits::byName_iterator            byName_iterator;
     typedef pool::PoolTraits::byCapabilityIndex_iterator byCapabilityIndex_iterator;
+    typedef pool::PoolTraits::AdditionalCapSet          AdditionalCapSet;
 
   public:
     /** Default ctor: empty pool */
@@ -108,6 +109,63 @@ namespace zypp
    byCapabilityIndex_iterator byCapabilityIndexEnd( const std::string & index_r, Dep depType_r ) const;
    //@}
 
+ public:
+   /** \name Handling addition capabilities in the pool in order for solving it in
+    *  a solver run. This is used for tasks like needing a package with the name "foo".
+    *  The solver has to evaluate a proper package by his own.
+    *
+    *  CAUTION: This has another semantic in the solver. The required resolvable has
+    *  been set for installation (in the pool) only AFTER a solver run.
+   */
+
+   /**
+    *  Handling additional requirement. E.G. need package "foo" and package 
+    *  "foo1" which has a greater version than 1.0:
+    *
+    *  CapSet capset;
+    *  capset.insert (CapFactory().parse( ResTraits<Package>::kind, "foo"));    
+    *  capset.insert (CapFactory().parse( ResTraits<Package>::kind, "foo1 > 1.0"));
+    *
+    *  // The user is setting this capablility
+    *  ResPool::AdditionalCapSet aCapSet;
+    *  aCapSet[ResStatus::USER] = capset;
+    *
+    *  setAdditionalRequire( aCapSet );
+    */
+   void setAdditionalRequire( const AdditionalCapSet & capset ) const;
+   AdditionalCapSet & additionalRequire() const;
+
+   /**
+    *  Handling additional conflicts. E.G. do not install anything which provides "foo":
+    *
+    *  CapSet capset;    
+    *  capset.insert (CapFactory().parse( ResTraits<Package>::kind, "foo"));
+    *
+    *  // The user is setting this capablility
+    *  ResPool::AdditionalCapSet aCapSet;
+    *  aCapSet[ResStatus::USER] = capset;
+    *
+    *  setAdditionalConflict( aCapSet );    
+    */      
+   void setAdditionalConflict( const AdditionalCapSet & capset ) const;
+   AdditionalCapSet & additionaConflict() const;
+      
+   /**
+    *  Handling additional provides. This is used for ignoring a requirement.
+    *  e.G. Do ignore the requirement "foo":
+    *
+    *  CapSet capset;    
+    *  capset.insert (CapFactory().parse( ResTraits<Package>::kind, "foo"));
+    *
+    *  // The user is setting this capablility
+    *  ResPool::AdditionalCapSet aCapSet;
+    *  aCapSet[ResStatus::USER] = capset;
+    *
+    *  setAdditionalProvide( aCapSet );    
+    */      
+   void setAdditionalProvide( const AdditionalCapSet & capset ) const;
+   AdditionalCapSet & additionaProvide() const;                  
+
   private:
     /** */
     friend class ResPoolManager;
index 4191a22..01ae30f 100644 (file)
@@ -42,11 +42,11 @@ namespace zypp
 
       public:
 
-      typedef PoolTraits::ItemContainerT       ItemContainerT;
-      typedef PoolTraits::NameItemContainerT   ContainerT;
-      typedef PoolTraits::size_type            size_type;
-      typedef PoolTraits::iterator             iterator;
-      typedef PoolTraits::const_iterator       const_iterator;
+      typedef PoolTraits::ItemContainerT        ItemContainerT;
+      typedef PoolTraits::NameItemContainerT    ContainerT;
+      typedef PoolTraits::size_type             size_type;
+      typedef PoolTraits::iterator              iterator;
+      typedef PoolTraits::const_iterator        const_iterator;
 
       private:
        ItemContainerT & getItemContainer( const std::string & tag_r );
@@ -191,6 +191,7 @@ namespace zypp
     typedef PoolTraits::size_type              size_type;
     typedef PoolTraits::Inserter               Inserter;
     typedef PoolTraits::Deleter                        Deleter;
+    typedef PoolTraits::AdditionalCapSet       AdditionalCapSet;       
 
     public:
       /** Default ctor */
@@ -231,11 +232,57 @@ namespace zypp
       const_iterator end() const
       { return _store.end(); }
 
+      /**
+       *  Handling additional requirement. E.G. need package "foo" and package 
+       *  "foo1" which has a greater version than 1.0:
+       *
+       *  Capset capset;
+       *  capset.insert (CapFactory().parse( ResTraits<Package>::kind, "foo"));    
+       *  capset.insert (CapFactory().parse( ResTraits<Package>::kind, "foo1 > 1.0"));
+       *
+       *  setAdditionalRequire( capset );
+       */
+       void setAdditionalRequire( const AdditionalCapSet & capset ) const
+           { _additionalRequire = capset; }
+       AdditionalCapSet & additionalRequire() const
+           { return _additionalRequire; }
+
+       /**
+       *  Handling additional conflicts. E.G. do not install anything which provides "foo":
+       *
+       *  Capset capset;    
+       *  capset.insert (CapFactory().parse( ResTraits<Package>::kind, "foo"));
+       *
+       *  setAdditionalConflict( capset );    
+       */      
+       void setAdditionalConflict( const AdditionalCapSet & capset ) const
+           { _additionaConflict = capset; } 
+       AdditionalCapSet & additionaConflict() const
+           { return _additionaConflict; }
+      
+       /**
+        *  Handling additional provides. This is used for ignoring a requirement.
+        *  e.G. Do ignore the requirement "foo":
+        *
+        *  Capset capset;    
+        *  capset.insert (CapFactory().parse( ResTraits<Package>::kind, "foo"));
+        *
+        *  setAdditionalProvide( cap );    
+        */      
+       void setAdditionalProvide( const AdditionalCapSet & capset ) const
+           { _additionaProvide = capset; }
+       AdditionalCapSet & additionaProvide() const
+           { return _additionaProvide; }
+
       /** */
       void clear()
       { _store.clear();
        _caphash.clear();
        _namehash.clear();
+        _additionalRequire.clear();
+       _additionaConflict.clear();
+       _additionaProvide.clear();
+
        return;
       }
 
@@ -255,6 +302,9 @@ namespace zypp
       ContainerT _store;
       NameHash _namehash;
       CapHash _caphash;
+      mutable AdditionalCapSet _additionalRequire;
+      mutable AdditionalCapSet _additionaConflict;
+      mutable AdditionalCapSet _additionaProvide;
 
     public:
       ResPoolProxy proxy( ResPool self ) const
index a85b9aa..0eb7bf5 100644 (file)
@@ -19,6 +19,7 @@
 #include "zypp/Capability.h"
 #include "zypp/CapAndItem.h"
 #include "zypp/Dep.h"
+#include "zypp/ResStatus.h"
 
 ///////////////////////////////////////////////////////////////////
 namespace zypp
@@ -91,6 +92,10 @@ namespace zypp
       typedef shared_ptr<const PoolImpl> Impl_constPtr;
       typedef PoolImplInserter           Inserter;
       typedef PoolImplDeleter            Deleter;
+
+      /** Map of CapSet and "who" has set it*/
+      typedef std::map<ResStatus::TransactByValue,CapSet>              AdditionalCapSet;
+       
     };
     ///////////////////////////////////////////////////////////////////
 
index e4c9571..3ca178d 100644 (file)
@@ -418,8 +418,9 @@ QueueItemRequire::process (ResolverContext_Ptr context, QueueItemList & new_item
     IgnoreMap ignoreMap = context->getIgnoreRequires();
     for (IgnoreMap::iterator it = ignoreMap.begin();
         it != ignoreMap.end(); it++) {
-       if (it->first == _requiring_item
-           && it->second == _capability) {
+       if ( (!(it->first) // ignore ALL requirements on this capability
+             || it->first == _requiring_item)
+            && it->second == _capability) {
            _XDEBUG("Found ignoring requires " << _capability << " for " << _requiring_item);
            return true;
        } else {
index a69c79e..892b9c1 100644 (file)
@@ -651,9 +651,20 @@ Resolver::resolveDependencies (const ResolverContext_Ptr context)
 
     ResolverQueue_Ptr initial_queue = new ResolverQueue(_pool, _architecture, context);
 
+    // adding "external" provides, the the requirements will be ignored
+    IgnoreMap ignoreRequires = _ignoreRequires;
+    ResPool::AdditionalCapSet additionalCapSet = pool().additionaProvide();
+    for (ResPool::AdditionalCapSet::const_iterator it = additionalCapSet.begin();
+        it != additionalCapSet.end(); it++) {
+       CapSet cset = it->second;
+       for (CapSet::const_iterator cit = cset.begin(); cit != cset.end(); ++cit) {
+           ignoreRequires.insert(make_pair(PoolItem_Ref(), *cit));
+       }
+    }
+    
     // Initialize all ignoring dependencies
     initial_queue->context()->setIgnoreCababilities (_ignoreConflicts,
-                                   _ignoreRequires,
+                                   ignoreRequires,
                                    _ignoreObsoletes,
                                    _ignoreInstalledItem,
                                    _ignoreArchitectureItem);
@@ -709,11 +720,31 @@ Resolver::resolveDependencies (const ResolverContext_Ptr context)
     for (CapSet::const_iterator iter = _extra_caps.begin(); iter != _extra_caps.end(); iter++) {
        initial_queue->addExtraCapability (*iter);
     }
+    
+    // adding "external" requires
+    additionalCapSet = pool().additionalRequire();
+    for (ResPool::AdditionalCapSet::const_iterator it = additionalCapSet.begin();
+        it != additionalCapSet.end(); it++) {
+       CapSet cset = it->second;
+       for (CapSet::const_iterator cit = cset.begin(); cit != cset.end(); ++cit) {
+           initial_queue->addExtraCapability (*cit);       
+       }
+    }
 
     for (CapSet::const_iterator iter = _extra_conflicts.begin(); iter != _extra_conflicts.end(); iter++) {
        initial_queue->addExtraConflict (*iter);
     }
 
+    // adding "external" conflicts
+    additionalCapSet = pool().additionaConflict();
+    for (ResPool::AdditionalCapSet::const_iterator it = additionalCapSet.begin();
+        it != additionalCapSet.end(); it++) {
+       CapSet cset = it->second;
+       for (CapSet::const_iterator cit = cset.begin(); cit != cset.end(); ++cit) {
+           initial_queue->addExtraConflict (*cit);         
+       }
+    }
+
     // Adding System resolvable
     assertSystemResObjectInPool();
 
index 5b8bb32..5ff2d17 100644 (file)
@@ -657,22 +657,26 @@ Resolver::problems (void) const
        // from QueueItemConflict
            case RESOLVER_INFO_TYPE_CONFLICT_CANT_INSTALL: {            // to-be-installed p conflicts with q due to c
                ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
-               // TranslatorExplanation %s = name of package, patch, selection ...                             
-               what = str::form (_("Cannot install %s because it is conflicting with %s"),
-                                 who.c_str(),
-                                 misc_info->other()->name().c_str());                          
+               // TranslatorExplanation %s = name of package, patch, selection ...
+               if (misc_info->other())
+                   what = str::form (_("Cannot install %s because it is conflicting with %s"),
+                                     who.c_str(),
+                                     misc_info->other()->name().c_str());
+               else
+                   what = str::form (_("Cannot install %s because it is conflicting"),
+                                     who.c_str());
                details = misc_info->message();
                ResolverProblem_Ptr problem = new ResolverProblem (what, details);              
                // Uninstall p
                problem->addSolution (new ProblemSolutionUninstall (problem, item));
-               // Uninstall q
-               problem->addSolution (new ProblemSolutionUninstall (problem, misc_info->other()));
+               if (misc_info->other())
+                   // Uninstall q
+                   problem->addSolution (new ProblemSolutionUninstall (problem, misc_info->other()));
                // Remove conflict in the resolvable which has to be installed
                problem->addSolution (new ProblemSolutionIgnoreConflicts (problem, item, misc_info->other_capability(),
-                                                                         misc_info->other())); 
+                                                                         misc_info->other()));
                problems.push_back (problem);
                problem_created = true;
-               
            }
            break;
            case RESOLVER_INFO_TYPE_CONFLICT_UNINSTALLABLE: {           // uninstalled p is marked uninstallable it conflicts [with q] due to c