From a0f4e453f1ab342222765901df418e7babb8a57c Mon Sep 17 00:00:00 2001 From: Stefan Schubert Date: Sat, 25 Feb 2006 16:51:55 +0000 Subject: [PATCH] solutions for locks added --- zypp/solver/detail/ProblemSolutionIgnore.cc | 16 ++++++++++++++- zypp/solver/detail/ProblemSolutionIgnore.h | 13 ++++++++++++ zypp/solver/detail/ProblemSolutionKeep.cc | 2 +- zypp/solver/detail/QueueItemConflict.cc | 2 +- zypp/solver/detail/QueueItemInstall.cc | 32 +++++++++++++++++++---------- zypp/solver/detail/QueueItemUninstall.cc | 18 ++++++++++++++-- zypp/solver/detail/QueueItemUninstall.h | 4 +++- zypp/solver/detail/Resolver.cc | 9 ++++++++ zypp/solver/detail/Resolver.h | 6 +++++- zypp/solver/detail/ResolverContext.cc | 1 + zypp/solver/detail/ResolverContext.h | 7 ++++++- zypp/solver/detail/ResolverInfoMisc.cc | 19 ++++++++++++----- zypp/solver/detail/ResolverInfoMisc.h | 17 +++++++++++---- zypp/solver/detail/Resolver_problems.cc | 23 ++++++++++++++++----- zypp/solver/detail/SolutionAction.cc | 8 +++++++- zypp/solver/detail/SolutionAction.h | 1 + 16 files changed, 144 insertions(+), 34 deletions(-) diff --git a/zypp/solver/detail/ProblemSolutionIgnore.cc b/zypp/solver/detail/ProblemSolutionIgnore.cc index 526459b..71a2972 100644 --- a/zypp/solver/detail/ProblemSolutionIgnore.cc +++ b/zypp/solver/detail/ProblemSolutionIgnore.cc @@ -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)); } diff --git a/zypp/solver/detail/ProblemSolutionIgnore.h b/zypp/solver/detail/ProblemSolutionIgnore.h index 0276928..d710c6c 100644 --- a/zypp/solver/detail/ProblemSolutionIgnore.h +++ b/zypp/solver/detail/ProblemSolutionIgnore.h @@ -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: diff --git a/zypp/solver/detail/ProblemSolutionKeep.cc b/zypp/solver/detail/ProblemSolutionKeep.cc index 000ac49..323e46d 100644 --- a/zypp/solver/detail/ProblemSolutionKeep.cc +++ b/zypp/solver/detail/ProblemSolutionKeep.cc @@ -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++) { diff --git a/zypp/solver/detail/QueueItemConflict.cc b/zypp/solver/detail/QueueItemConflict.cc index 84ddff3..627deb0 100644 --- a/zypp/solver/detail/QueueItemConflict.cc +++ b/zypp/solver/detail/QueueItemConflict.cc @@ -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 (); diff --git a/zypp/solver/detail/QueueItemInstall.cc b/zypp/solver/detail/QueueItemInstall.cc index 3c32022..c1e76b9 100644 --- a/zypp/solver/detail/QueueItemInstall.cc +++ b/zypp/solver/detail/QueueItemInstall.cc @@ -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 diff --git a/zypp/solver/detail/QueueItemUninstall.cc b/zypp/solver/detail/QueueItemUninstall.cc index d9f5d20..4046655 100644 --- a/zypp/solver/detail/QueueItemUninstall.cc +++ b/zypp/solver/detail/QueueItemUninstall.cc @@ -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; diff --git a/zypp/solver/detail/QueueItemUninstall.h b/zypp/solver/detail/QueueItemUninstall.h index 23c8318..1c9e1c7 100644 --- a/zypp/solver/detail/QueueItemUninstall.h +++ b/zypp/solver/detail/QueueItemUninstall.h @@ -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 diff --git a/zypp/solver/detail/Resolver.cc b/zypp/solver/detail/Resolver.cc index 119e1fe..ce1d7f7 100644 --- a/zypp/solver/detail/Resolver.cc +++ b/zypp/solver/detail/Resolver.cc @@ -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); diff --git a/zypp/solver/detail/Resolver.h b/zypp/solver/detail/Resolver.h index d4cacb6..bcd9903 100644 --- a/zypp/solver/detail/Resolver.h +++ b/zypp/solver/detail/Resolver.h @@ -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); diff --git a/zypp/solver/detail/ResolverContext.cc b/zypp/solver/detail/ResolverContext.cc index 077d5cd..4ded5b8 100644 --- a/zypp/solver/detail/ResolverContext.cc +++ b/zypp/solver/detail/ResolverContext.cc @@ -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; diff --git a/zypp/solver/detail/ResolverContext.h b/zypp/solver/detail/ResolverContext.h index c70bfdf..3d07654 100644 --- a/zypp/solver/detail/ResolverContext.h +++ b/zypp/solver/detail/ResolverContext.h @@ -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; } diff --git a/zypp/solver/detail/ResolverInfoMisc.cc b/zypp/solver/detail/ResolverInfoMisc.cc index d968116..0eb5453 100644 --- a/zypp/solver/detail/ResolverInfoMisc.cc +++ b/zypp/solver/detail/ResolverInfoMisc.cc @@ -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 diff --git a/zypp/solver/detail/ResolverInfoMisc.h b/zypp/solver/detail/ResolverInfoMisc.h index 463215a..a067d34 100644 --- a/zypp/solver/detail/ResolverInfoMisc.h +++ b/zypp/solver/detail/ResolverInfoMisc.h @@ -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); diff --git a/zypp/solver/detail/Resolver_problems.cc b/zypp/solver/detail/Resolver_problems.cc index d125f3f..f536788 100644 --- a/zypp/solver/detail/Resolver_problems.cc +++ b/zypp/solver/detail/Resolver_problems.cc @@ -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(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(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; } diff --git a/zypp/solver/detail/SolutionAction.cc b/zypp/solver/detail/SolutionAction.cc index 62148b1..168e440 100644 --- a/zypp/solver/detail/SolutionAction.cc +++ b/zypp/solver/detail/SolutionAction.cc @@ -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); diff --git a/zypp/solver/detail/SolutionAction.h b/zypp/solver/detail/SolutionAction.h index bb62076..1c1dd0b 100644 --- a/zypp/solver/detail/SolutionAction.h +++ b/zypp/solver/detail/SolutionAction.h @@ -107,6 +107,7 @@ namespace zypp { REQUIRES, CONFLICTS, + OBSOLETES, ARCHITECTURE, INSTALLED } InjectSolutionKind; -- 2.7.4