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));
}
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:
PoolItemList & itemList )
: ProblemSolution (parent, "", "")
{
- _description = _("Keep missing resolvables");
+ _description = _("Keep resolvables");
for (PoolItemList::iterator iter = itemList.begin();
iter != itemList.end(); iter++) {
uninstall->setCapability (conflict_capability);
if (actually_an_obsolete) {
- uninstall->setDueToObsolete ();
+ uninstall->setDueToObsolete (conflict_issuer);
log_info = new ResolverInfoObsoletes (provider, conflict_issuer);
} else {
uninstall->setDueToConflict ();
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
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;
, _due_to_conflict (false)
, _due_to_obsolete (false)
, _unlink (false)
+ , _obsoletes_item (NULL)
{
_XDEBUG("QueueItemUninstall::QueueItemUninstall(" << item << ")");
}
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;
}
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;
bool _due_to_conflict;
bool _due_to_obsolete;
bool _unlink;
+ PoolItem_Ref _obsoletes_item; // item which has caused (has the obsoletes) this request
public:
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
}
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);
context->setEstablishing (true);
context->setIgnoreCababilities (_ignoreConflicts,
_ignoreRequires,
+ _ignoreObsoletes,
_ignoreArchitecture,
_ignoreInstalledItem);
context->setForceResolve (_forceResolve);
// Initialize all ignoring dependencies
initial_queue->context()->setIgnoreCababilities (_ignoreConflicts,
_ignoreRequires,
+ _ignoreObsoletes,
_ignoreArchitecture,
_ignoreInstalledItem);
initial_queue->context()->setForceResolve (_forceResolve);
// 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
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);
_establishing = parent->_establishing;
_ignoreConflicts = parent->_ignoreConflicts;
_ignoreRequires = parent->_ignoreRequires;
+ _ignoreObsoletes = parent->_ignoreObsoletes;
_ignoreArchitecture = parent->_ignoreArchitecture;
_ignoreInstalledItem = parent->_ignoreInstalledItem;
_forceResolve = parent->_forceResolve;
// 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
// ---------------------------------- 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; }
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;
}
ResolverInfoMisc::ResolverInfoMisc (ResolverInfoType detailedtype, PoolItem_Ref affected, int priority, const Capability & capability)
: ResolverInfoContainer (detailedtype, affected, priority)
- , _capability (capability)
+ , _capability (capability)
+ , _trigger (NONE)
{
}
((ResolverInfoContainer_Ptr)cpy)->copy (this);
cpy->_other_item = _other_item;
cpy->_other_capability = _other_capability;
+ cpy->_action = _action;
+ cpy->_trigger = _trigger;
+
return cpy;
}
void
-ResolverInfoMisc::addTrigger (const std::string & trigger_msg)
+ResolverInfoMisc::addTrigger (const TriggerReason & trigger)
{
- _trigger = trigger_msg;
+ _trigger = trigger;
}
void
// 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
Capability _other_capability;
std::string _action;
- std::string _trigger;
+ TriggerReason _trigger;
public:
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; }
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);
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
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;
}
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;
_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;
// 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);
{
REQUIRES,
CONFLICTS,
+ OBSOLETES,
ARCHITECTURE,
INSTALLED
} InjectSolutionKind;