solutions for locks added
authorStefan Schubert <schubi@suse.de>
Sat, 25 Feb 2006 16:51:55 +0000 (16:51 +0000)
committerStefan Schubert <schubi@suse.de>
Sat, 25 Feb 2006 16:51:55 +0000 (16:51 +0000)
16 files changed:
zypp/solver/detail/ProblemSolutionIgnore.cc
zypp/solver/detail/ProblemSolutionIgnore.h
zypp/solver/detail/ProblemSolutionKeep.cc
zypp/solver/detail/QueueItemConflict.cc
zypp/solver/detail/QueueItemInstall.cc
zypp/solver/detail/QueueItemUninstall.cc
zypp/solver/detail/QueueItemUninstall.h
zypp/solver/detail/Resolver.cc
zypp/solver/detail/Resolver.h
zypp/solver/detail/ResolverContext.cc
zypp/solver/detail/ResolverContext.h
zypp/solver/detail/ResolverInfoMisc.cc
zypp/solver/detail/ResolverInfoMisc.h
zypp/solver/detail/Resolver_problems.cc
zypp/solver/detail/SolutionAction.cc
zypp/solver/detail/SolutionAction.h

index 526459b..71a2972 100644 (file)
@@ -79,11 +79,25 @@ ProblemSolutionIgnoreConflicts::ProblemSolutionIgnoreConflicts( ResolverProblem_
        addAction (new InjectSolutionAction (item, capability, CONFLICTS, otherItem));  
 }
 
+ProblemSolutionIgnoreObsoletes::ProblemSolutionIgnoreObsoletes( ResolverProblem_Ptr parent,
+                                                               PoolItem_Ref item,
+                                                               const Capability & capability,
+                                                               PoolItem_Ref otherItem)
+    : ProblemSolution (parent, "", "")
+{
+       // TranslatorExplanation %s = name of package, patch, selection ...
+       _description = str::form (_("Ignore the obsolete %s in %s"),
+                                 ResolverInfo::toString (capability).c_str(),
+                                 otherItem->name().c_str());
+       addAction (new InjectSolutionAction (item, capability, OBSOLETES, otherItem));  
+}
+
+
 ProblemSolutionIgnoreArch::ProblemSolutionIgnoreArch( ResolverProblem_Ptr parent,
                                                      PoolItem_Ref item )
     : ProblemSolution (parent, "", "")
 {
-    _description = _("Ignore architecture");
+    _description = _("ignore architecture");
     addAction ( new InjectSolutionAction (item, Capability(), ARCHITECTURE));
 }
 
index 0276928..d710c6c 100644 (file)
@@ -68,6 +68,19 @@ namespace zypp
                                           const Capability & capability);
        };
 
+       class ProblemSolutionIgnoreObsoletes : public ProblemSolution
+       {
+       public:
+
+           /**
+            * Constructor.
+            **/
+           ProblemSolutionIgnoreObsoletes( ResolverProblem_Ptr parent,
+                                           PoolItem_Ref item,
+                                           const Capability & capability,
+                                           PoolItem_Ref otherItem);        
+       };
+
        class ProblemSolutionIgnoreArch : public ProblemSolution
        {
        public:
index 000ac49..323e46d 100644 (file)
@@ -64,7 +64,7 @@ ProblemSolutionKeep::ProblemSolutionKeep( ResolverProblem_Ptr parent,
                                          PoolItemList & itemList )
     : ProblemSolution (parent, "", "")
 {
-    _description = _("Keep missing resolvables");
+    _description = _("Keep resolvables");
 
     for (PoolItemList::iterator iter = itemList.begin();
         iter != itemList.end(); iter++) {
index 84ddff3..627deb0 100644 (file)
@@ -232,7 +232,7 @@ struct ConflictProcess
            uninstall->setCapability (conflict_capability);
 
            if (actually_an_obsolete) {
-               uninstall->setDueToObsolete ();
+               uninstall->setDueToObsolete (conflict_issuer);
                log_info = new ResolverInfoObsoletes (provider, conflict_issuer);
            } else {
                uninstall->setDueToConflict ();
index 3c32022..c1e76b9 100644 (file)
@@ -437,30 +437,40 @@ QueueItemInstall::process (ResolverContext_Ptr context, QueueItemList & qil)
 
        caps = _item->dep (Dep::CONFLICTS);
        for (CapSet::const_iterator iter = caps.begin(); iter != caps.end(); iter++) {
-
            const Capability cap = *iter;
            _XDEBUG("this conflicts with '" << cap << "'");
            QueueItemConflict_Ptr conflict_item = new QueueItemConflict (pool(), cap, _item, _soft);
            // Push the QueueItem at the END of the list in order to favourite conflicts caused
            // by obsolating this item.
            qil.push_back (conflict_item);
-
        }
 
        /* Construct conflict items for each of the item's obsoletes. */
 
        caps = _item->dep (Dep::OBSOLETES);
+       IgnoreMap ignoreMap = context->getIgnoreObsoletes();
+       
        for (CapSet::const_iterator iter = caps.begin(); iter != caps.end(); iter++) {
-
            const Capability cap = *iter;
-           _XDEBUG("this obsoletes " <<  cap);
-           QueueItemConflict_Ptr conflict_item = new QueueItemConflict (pool(), cap, _item, _soft);
-           conflict_item->setActuallyAnObsolete();
-           // Push the QueueItem at the BEGIN of the list in order to favourite this confict
-           // comparing to "normal" conflicts, cause this item will be deleted. So other
-           // conflicts will not be regarded in the future.
-           qil.push_front (conflict_item);
-
+           bool found = false;
+           for (IgnoreMap::iterator it = ignoreMap.begin();
+                it != ignoreMap.end(); it++) {
+               if (it->first == _item
+                   && it->second == cap) {
+                   _XDEBUG("Found ignoring obsoletes " << cap << " for " << _item);
+                   found = true;
+                   break;
+               }
+           }
+           if (!found) {           
+               _XDEBUG("this obsoletes " <<  cap);
+               QueueItemConflict_Ptr conflict_item = new QueueItemConflict (pool(), cap, _item, _soft);
+               conflict_item->setActuallyAnObsolete();
+               // Push the QueueItem at the BEGIN of the list in order to favourite this confict
+               // comparing to "normal" conflicts, cause this item will be deleted. So other
+               // conflicts will not be regarded in the future.
+               qil.push_front (conflict_item);
+           }
        }
 
        // Searching item that conflict with us and try to uninstall it if it is useful
index d9f5d20..4046655 100644 (file)
@@ -81,7 +81,8 @@ QueueItemUninstall::dumpOn( std::ostream & os ) const
     if (_explicitly_requested) os << ", Explicit";
     if (_remove_only) os << ", Remove Only";
     if (_due_to_conflict) os << ", Due To Conflict";
-    if (_due_to_obsolete) os << ", Due To Obsolete";
+    if (_due_to_obsolete)
+       os << ", Due To Obsolete:" << _obsoletes_item;
     if (_unlink) os << ", Unlink";
     os << "]";
     return os;
@@ -101,6 +102,7 @@ QueueItemUninstall::QueueItemUninstall (const ResPool & pool, PoolItem_Ref item,
     , _due_to_conflict (false)
     , _due_to_obsolete (false)
     , _unlink (false)
+    , _obsoletes_item (NULL)
 {
     _XDEBUG("QueueItemUninstall::QueueItemUninstall(" << item << ")");
 }
@@ -316,7 +318,18 @@ QueueItemUninstall::process (ResolverContext_Ptr context, QueueItemList & qil)
        if (! _explicitly_requested
            && _item.status().isLocked()) {
 
-           ResolverInfo_Ptr misc_info = new ResolverInfoMisc (RESOLVER_INFO_TYPE_UNINSTALL_LOCKED, _item, RESOLVER_INFO_PRIORITY_VERBOSE);
+           ResolverInfoMisc_Ptr misc_info = new ResolverInfoMisc (RESOLVER_INFO_TYPE_UNINSTALL_LOCKED,
+                                                                  _item, RESOLVER_INFO_PRIORITY_VERBOSE,
+                                                                  _cap_leading_to_uninstall);
+           if (_due_to_obsolete)
+           {
+               misc_info->setOtherPoolItem (_obsoletes_item);
+               misc_info->addTrigger (ResolverInfoMisc::OBSOLETE);
+           } else if (_due_to_conflict)
+           {
+               misc_info->addTrigger (ResolverInfoMisc::CONFLICT);             
+           }
+           
            context->addError (misc_info);
            goto finished;
        }
@@ -404,6 +417,7 @@ QueueItemUninstall::copy (void) const
     new_uninstall->_remove_only               = _remove_only;
     new_uninstall->_due_to_conflict           = _due_to_conflict;
     new_uninstall->_due_to_obsolete           = _due_to_obsolete;
+    new_uninstall->_obsoletes_item           = _obsoletes_item;
     new_uninstall->_unlink                    = _unlink;
 
     return new_uninstall;
index 23c8318..1c9e1c7 100644 (file)
@@ -69,6 +69,7 @@ class QueueItemUninstall : public QueueItem {
     bool _due_to_conflict;
     bool _due_to_obsolete;
     bool _unlink;
+    PoolItem_Ref _obsoletes_item;      // item which has caused (has the obsoletes) this request
 
   public:
 
@@ -90,7 +91,8 @@ class QueueItemUninstall : public QueueItem {
     void setRemoveOnly (void)                  { _remove_only = true; }
     void setUpgradedTo (PoolItem_Ref item)             { _upgraded_to = item; }
     void setDueToConflict (void)               { _due_to_conflict = true; }
-    void setDueToObsolete (void)               { _due_to_obsolete = true; }
+    void setDueToObsolete (const PoolItem_Ref item)
+       { _due_to_obsolete = true; _obsoletes_item = item; }
     void setUnlink (void);
 
     // ---------------------------------- methods
index 119e1fe..ce1d7f7 100644 (file)
@@ -261,6 +261,13 @@ Resolver::addIgnoreRequires (const PoolItem_Ref item,
 }
 
 void
+Resolver::addIgnoreObsoletes (const PoolItem_Ref item,
+                             const Capability & capability)
+{
+    _ignoreObsoletes.insert(make_pair(item, capability));
+}
+
+void
 Resolver::addIgnoreArchitecture (const PoolItem_Ref item)
 {
     _ignoreArchitecture.push_back (item);
@@ -389,6 +396,7 @@ Resolver::establishState (ResolverContext_Ptr context)
     context->setEstablishing (true);
     context->setIgnoreCababilities (_ignoreConflicts,
                                    _ignoreRequires,
+                                   _ignoreObsoletes,
                                    _ignoreArchitecture,
                                    _ignoreInstalledItem);
     context->setForceResolve (_forceResolve);
@@ -497,6 +505,7 @@ Resolver::resolveDependencies (const ResolverContext_Ptr context)
     // Initialize all ignoring dependencies
     initial_queue->context()->setIgnoreCababilities (_ignoreConflicts,
                                    _ignoreRequires,
+                                   _ignoreObsoletes,
                                    _ignoreArchitecture,
                                    _ignoreInstalledItem);
     initial_queue->context()->setForceResolve (_forceResolve);
index d4cacb6..bcd9903 100644 (file)
@@ -80,8 +80,10 @@ class Resolver : public base::ReferenceCounted, private base::NonCopyable {
 
     // These conflict should be ignored of the concering item
     IgnoreMap _ignoreConflicts;
-    // These conflict should be ignored of the concering item    
+    // These requires should be ignored of the concering item    
     IgnoreMap _ignoreRequires;
+    // These obsoletes should be ignored of the concering item    
+    IgnoreMap _ignoreObsoletes;    
     // Ignore architecture of the item
     PoolItemList _ignoreArchitecture;
     // Ignore the status "installed" of the item
@@ -165,6 +167,8 @@ class Resolver : public base::ReferenceCounted, private base::NonCopyable {
                            const Capability & capability);
     void addIgnoreRequires (const PoolItem_Ref item,
                            const Capability & capability);
+    void addIgnoreObsoletes (const PoolItem_Ref item,
+                            const Capability & capability);
     void addIgnoreArchitecture (const PoolItem_Ref item);
     void addIgnoreInstalledItem (const PoolItem_Ref item);
 
index 077d5cd..4ded5b8 100644 (file)
@@ -102,6 +102,7 @@ _XDEBUG( "ResolverContext[" << this << "]::ResolverContext(" << parent << ")" );
        _establishing        = parent->_establishing;
        _ignoreConflicts     = parent->_ignoreConflicts;
        _ignoreRequires      = parent->_ignoreRequires;
+       _ignoreObsoletes     = parent->_ignoreObsoletes;
        _ignoreArchitecture  = parent->_ignoreArchitecture;
        _ignoreInstalledItem = parent->_ignoreInstalledItem;
        _forceResolve        = parent->_forceResolve;
index c70bfdf..3d07654 100644 (file)
@@ -83,8 +83,10 @@ class ResolverContext : public base::ReferenceCounted, private base::NonCopyable
 
     // These conflict should be ignored of the concering item
     IgnoreMap _ignoreConflicts;
-    // These conflict should be ignored of the concering item    
+    // These requires should be ignored of the concering item    
     IgnoreMap _ignoreRequires;
+    // These obsoletes should be ignored of the concering item    
+    IgnoreMap _ignoreObsoletes;    
     // Ignore architecture of the item
     PoolItemList _ignoreArchitecture;
     // Ignore the status "installed" of the item
@@ -128,15 +130,18 @@ class ResolverContext : public base::ReferenceCounted, private base::NonCopyable
     // ---------------------------------- ignore capabilities
     void setIgnoreCababilities(const IgnoreMap ignoreConflicts,
                               const IgnoreMap ignoreRequires,
+                              const IgnoreMap ignoreObsoletes,
                               const PoolItemList ignoreArchitecture,
                               const PoolItemList ignoreInstalledItem)
        {_ignoreConflicts = ignoreConflicts;
        _ignoreRequires = ignoreRequires;
+       _ignoreObsoletes = ignoreObsoletes;
        _ignoreArchitecture = ignoreArchitecture;
        _ignoreInstalledItem = ignoreInstalledItem;}
 
     const IgnoreMap getIgnoreConflicts() const { return _ignoreConflicts; }
     const IgnoreMap getIgnoreRequires() const { return _ignoreRequires; }
+    const IgnoreMap getIgnoreObsoletes() const { return _ignoreObsoletes; }    
     const PoolItemList getIgnoreArchitecture() const { return _ignoreArchitecture; }
     const PoolItemList getIgnoreInstalledItem() const { return _ignoreInstalledItem; }
     
index d968116..0eb5453 100644 (file)
@@ -55,9 +55,14 @@ ResolverInfoMisc::dumpOn( std::ostream & os ) const
     if (!_action.empty()) {
        os << _(", Action: ") << _action << endl;
     }
-    if (!_trigger.empty()) {
-       os << _(", Trigger: ") << _trigger << endl;
+    os << _(", Trigger: ");
+    switch (_trigger) {
+       case ResolverInfoMisc::NONE:            os << "none"; break;
+       case ResolverInfoMisc::OBSOLETE:        os << "obsoletes"; break;
+       case ResolverInfoMisc::REQUIRE:         os << "requires"; break;            
+       case ResolverInfoMisc::CONFLICT:        os << "conflicts"; break;
     }
+    os << endl;
     return os;
 }
 
@@ -65,7 +70,8 @@ ResolverInfoMisc::dumpOn( std::ostream & os ) const
 
 ResolverInfoMisc::ResolverInfoMisc  (ResolverInfoType detailedtype, PoolItem_Ref affected, int priority, const Capability & capability)
     : ResolverInfoContainer (detailedtype, affected, priority)
-    , _capability (capability)
+      , _capability (capability)
+      , _trigger (NONE)
 {
 }
 
@@ -555,6 +561,9 @@ ResolverInfoMisc::copy (void) const
     ((ResolverInfoContainer_Ptr)cpy)->copy (this);
     cpy->_other_item = _other_item;
     cpy->_other_capability = _other_capability;
+    cpy->_action = _action;
+    cpy->_trigger = _trigger;
+    
     return cpy;
 }
 
@@ -568,9 +577,9 @@ ResolverInfoMisc::addAction (const std::string & action_msg)
 
 
 void
-ResolverInfoMisc::addTrigger (const std::string & trigger_msg)
+ResolverInfoMisc::addTrigger (const TriggerReason & trigger)
 {
-    _trigger = trigger_msg;
+    _trigger = trigger;
 }
 
 void
index 463215a..a067d34 100644 (file)
@@ -46,7 +46,16 @@ namespace zypp
 //     CLASS NAME : ResolverInfoMisc
 
 class ResolverInfoMisc : public ResolverInfoContainer {
-
+        public:
+        typedef enum {
+           NONE,
+           CONFLICT,   // conflicts [dep]
+           OBSOLETE,   // obsoletes [dep]
+           REQUIRE     // require [dep]
+       } TriggerReason;
+
+    
+    
        private:
 
          Capability _capability;                       // capability leading to this info
@@ -55,7 +64,7 @@ class ResolverInfoMisc : public ResolverInfoContainer {
          Capability _other_capability;
 
          std::string _action;
-         std::string _trigger;
+         TriggerReason _trigger;
 
        public:
 
@@ -72,7 +81,7 @@ class ResolverInfoMisc : public ResolverInfoContainer {
 
          virtual std::string message (void) const;
          std::string action (void) const { return _action; }
-         std::string trigger (void) const { return _trigger; }
+         TriggerReason trigger (void) const { return _trigger; }
 
          PoolItem_Ref other (void) const { return _other_item; }
          const Capability other_capability (void) const { return _other_capability; }
@@ -84,7 +93,7 @@ class ResolverInfoMisc : public ResolverInfoContainer {
          virtual ResolverInfo_Ptr copy (void) const;
 
          void addAction (const std::string & action_msg);
-         void addTrigger (const std::string & trigger_msg);
+         void addTrigger (const TriggerReason & trigger);
 
          void setOtherPoolItem (PoolItem_Ref other);
          void setOtherCapability (const Capability & capability);
index d125f3f..f536788 100644 (file)
@@ -404,10 +404,8 @@ Resolver::problems (void) const
            case RESOLVER_INFO_TYPE_UNINSTALL_PROVIDER: {               // p provides c but is scheduled to be uninstalled
                ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
                // TranslatorExplanation %s = name of package, patch, selection ...                             
-               ostringstream other_str;
-               other_str << misc_info->other();
                what =str::form (_("%s fulfil dependencies of %s but will be uninstalled"),
-                                other_str.str().c_str(),
+                                misc_info->other()->name().c_str(),
                                 who.c_str());
                details = misc_info->message();
                // It is only an info --> no solution is needed
@@ -487,10 +485,25 @@ Resolver::problems (void) const
            case RESOLVER_INFO_TYPE_UNINSTALL_LOCKED: {                 // cant uninstall, its locked
                ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
                what = misc_info->message();
+               
+               if (misc_info->trigger() == ResolverInfoMisc::OBSOLETE) {
+                   // TranslatorExplanation %s = name of package, patch, selection ...                                             
+                   details = str::form (_("%s obsoletes %s. But %s cannot be deleted because it is locked."),
+                                        misc_info->other()->name().c_str(),
+                                        who.c_str(), who.c_str());
+               }
+               
                ResolverProblem_Ptr problem = new ResolverProblem (what, details);
                problem->addSolution (new ProblemSolutionUnlock (problem, item)); // Unlocking resItem
-               // keep installed
-               problem->addSolution (new ProblemSolutionKeep (problem, item)); 
+               if (misc_info->trigger() == ResolverInfoMisc::OBSOLETE) {
+                   // Ignore obsoletes
+                   problem->addSolution (new ProblemSolutionIgnoreObsoletes (problem, item, misc_info->capability(),
+                                                                             misc_info->other())); 
+               } else {
+                   // This is an "default" soltution
+                   // keep installed
+                   problem->addSolution (new ProblemSolutionKeep (problem, item));
+               }
                problems.push_back (problem);
                problem_created = true;
            }
index 62148b1..168e440 100644 (file)
@@ -107,6 +107,7 @@ InjectSolutionAction::dumpOn( ostream& os ) const
     switch (_kind) {
        case REQUIRES:  os << "Requires"; break;
        case CONFLICTS: os << "Conflicts"; break;
+       case OBSOLETES: os << "Obsoletes"; break;
        case ARCHITECTURE: os << "Architecture"; break;
        case INSTALLED: os << "Installed"; break;
        default: os << "Wrong kind"; break;
@@ -149,7 +150,8 @@ TransactionSolutionAction::execute(Resolver & resolver) const
                _item.status().setToBeUninstalled (ResStatus::USER);
            break;
        case UNLOCK:
-           _item.status().setLock (false, ResStatus::USER);
+           ret = _item.status().setLock (false, ResStatus::USER);
+           if (!ret) ERR << "Cannot unlock " << _item << endl;
            break;
        default:
            ERR << "Wrong TransactionKind" << endl;
@@ -181,6 +183,10 @@ InjectSolutionAction::execute(Resolver & resolver) const
            // removing the requires dependency from the item
            resolver.addIgnoreRequires (_item, _capability);
            break;
+        case OBSOLETES:
+           // removing the obsoletes dependency from the item
+           resolver.addIgnoreObsoletes (_otherItem, _capability);
+           break;          
        case ARCHITECTURE:
            // ignoring architecture
            resolver.addIgnoreArchitecture (_item);
index bb62076..1c1dd0b 100644 (file)
@@ -107,6 +107,7 @@ namespace zypp
        {
            REQUIRES,
            CONFLICTS,
+           OBSOLETES,
            ARCHITECTURE,
            INSTALLED
        } InjectSolutionKind;