00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <map>
00023 #include <sstream>
00024
00025 #include "zypp/solver/detail/Resolver.h"
00026 #include "zypp/Resolver.h"
00027 #include "zypp/solver/detail/ResolverContext.h"
00028 #include "zypp/ResolverProblem.h"
00029 #include "zypp/solver/detail/ProblemSolutionIgnore.h"
00030 #include "zypp/solver/detail/ProblemSolutionInstall.h"
00031 #include "zypp/solver/detail/ProblemSolutionUninstall.h"
00032 #include "zypp/solver/detail/ProblemSolutionUnlock.h"
00033 #include "zypp/solver/detail/ProblemSolutionKeep.h"
00034
00035 #include "zypp/solver/detail/ResolverInfoChildOf.h"
00036 #include "zypp/solver/detail/ResolverInfoConflictsWith.h"
00037 #include "zypp/solver/detail/ResolverInfoContainer.h"
00038 #include "zypp/solver/detail/ResolverInfoDependsOn.h"
00039 #include "zypp/solver/detail/ResolverInfoMisc.h"
00040 #include "zypp/solver/detail/ResolverInfoMissingReq.h"
00041 #include "zypp/solver/detail/ResolverInfoNeededBy.h"
00042 #include "zypp/solver/detail/ResolverInfoObsoletes.h"
00043
00044 #include "zypp/base/String.h"
00045 #include "zypp/base/Logger.h"
00046 #include "zypp/base/Gettext.h"
00047
00048 #include "zypp/base/Algorithm.h"
00049 #include "zypp/ResPool.h"
00050 #include "zypp/ResFilters.h"
00051 #include "zypp/CapFilters.h"
00052
00053
00055 namespace zypp
00056 {
00057
00058 namespace solver
00059 {
00060
00061 namespace detail
00062 {
00063
00064 using namespace std;
00065
00066 typedef map<PoolItem_Ref, ResolverInfo_Ptr> ProblemMap;
00067 typedef multimap<PoolItem_Ref, Capability> ItemCapabilityMap;
00068 typedef multimap<PoolItem_Ref, PoolItem_Ref> ConflictMap;
00069
00070
00071 template <class K, class V>
00072 class cap_equals {
00073 private:
00074 V value;
00075 public:
00076 cap_equals (const V& v)
00077 : value(v) {
00078 }
00079
00080 bool operator() (pair<const K, V> elem) {
00081 return value.matches (elem.second) == CapMatch::yes;
00082 }
00083 };
00084
00085
00086 template <class K, class V>
00087 class conflict_equals {
00088 private:
00089 V value;
00090 public:
00091 conflict_equals (const V& v)
00092 : value(v) {
00093 }
00094
00095 bool operator() (pair<const K, V> elem) {
00096 return value = elem.second;
00097 }
00098 };
00099
00100
00101
00102 typedef struct {
00103 ProblemMap problems;
00104
00105
00106 ItemCapabilityMap provideAndDeleteMap;
00107
00108
00109 ItemCapabilityMap provideAndKeptMap;
00110
00111 ItemCapabilityMap provideAndLockMap;
00112
00113 ItemCapabilityMap provideAndOtherArchMap;
00114
00115 ConflictMap conflictMap;
00116 } ResItemCollector;
00117
00118
00119 static void
00120 collector_cb (ResolverInfo_Ptr info, void *data)
00121 {
00122 ResItemCollector *collector = (ResItemCollector *)data;
00123 PoolItem_Ref item = info->affected();
00124 if (item
00125 && info->error()) {
00126 collector->problems[item] = info;
00127 }
00128
00129
00130 if (info->type() == RESOLVER_INFO_TYPE_UNINSTALL_PROVIDER) {
00131 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00132
00133 ItemCapabilityMap::iterator pos = find_if (collector->provideAndDeleteMap.begin(),
00134 collector->provideAndDeleteMap.end(),
00135 cap_equals<PoolItem_Ref, Capability>(misc_info->capability()));
00136
00137 if (pos == collector->provideAndDeleteMap.end()) {
00138 _XDEBUG ("Inserting " << misc_info->capability() << "/" << misc_info->other()
00139 << " into provideAndDelete map");
00140 collector->provideAndDeleteMap.insert (make_pair( misc_info->other(), misc_info->capability()));
00141 }
00142 }
00143
00144
00145 if (info->type() == RESOLVER_INFO_TYPE_KEEP_PROVIDER) {
00146 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00147
00148 ItemCapabilityMap::iterator pos = find_if (collector->provideAndKeptMap.begin(),
00149 collector->provideAndKeptMap.end(),
00150 cap_equals<PoolItem_Ref, Capability>(misc_info->capability()));
00151
00152 if (pos == collector->provideAndKeptMap.end()) {
00153 _XDEBUG ("Inserting " << misc_info->capability() << "/" << misc_info->other()
00154 << " into provideAndKeptMap map");
00155 collector->provideAndKeptMap.insert (make_pair( misc_info->other(), misc_info->capability()));
00156 }
00157 }
00158
00159
00160 if (info->type() == RESOLVER_INFO_TYPE_LOCKED_PROVIDER) {
00161 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00162
00163 ItemCapabilityMap::iterator pos = find_if (collector->provideAndLockMap.begin(),
00164 collector->provideAndLockMap.end(),
00165 cap_equals<PoolItem_Ref, Capability>(misc_info->capability()));
00166
00167 if (pos == collector->provideAndLockMap.end()) {
00168 _XDEBUG ("Inserting " << misc_info->capability() << "/" << misc_info->other()
00169 << " into provideAndLockMap map");
00170 collector->provideAndLockMap.insert (make_pair( misc_info->other(), misc_info->capability()));
00171 }
00172 }
00173
00174
00175 if (info->type() == RESOLVER_INFO_TYPE_OTHER_ARCH_PROVIDER) {
00176 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00177
00178 ItemCapabilityMap::iterator pos = find_if (collector->provideAndOtherArchMap.begin(),
00179 collector->provideAndOtherArchMap.end(),
00180 cap_equals<PoolItem_Ref, Capability>(misc_info->capability()));
00181
00182 if (pos == collector->provideAndOtherArchMap.end()) {
00183 _XDEBUG ("Inserting " << misc_info->capability() << "/" << misc_info->other()
00184 << " into provideAndOtherArchMap map");
00185 collector->provideAndOtherArchMap.insert (make_pair( misc_info->other(), misc_info->capability()));
00186 }
00187 }
00188
00189
00190
00191 if (info->type() == RESOLVER_INFO_TYPE_CONFLICT_UNINSTALLABLE
00192 || info->type() == RESOLVER_INFO_TYPE_CONFLICT_CANT_INSTALL) {
00193 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00194
00195
00196 ConflictMap::iterator pos = find_if (collector->conflictMap.lower_bound(misc_info->other()),
00197 collector->conflictMap.upper_bound(misc_info->other()),
00198 conflict_equals<PoolItem_Ref, PoolItem_Ref>(misc_info->affected()));
00199 if (pos == collector->conflictMap.end()) {
00200 _XDEBUG ("Inserting " << misc_info->affected() << "/" << misc_info->other()
00201 << " into conflictMap map");
00202 collector->conflictMap.insert (make_pair(misc_info->affected(), misc_info->other()));
00203 collector->conflictMap.insert (make_pair(misc_info->other(), misc_info->affected()));
00204 }
00205 }
00206
00207 }
00208
00209 struct AllRequires
00210 {
00211 PoolItemList requirers;
00212
00213 bool operator()( const CapAndItem & cai )
00214 {
00215 DBG << cai.item << " requires " << cai.cap << endl;
00216 requirers.push_back( cai.item );
00217
00218 return true;
00219 }
00220 };
00221
00222
00223 ResolverProblemList
00224 Resolver::problems (const bool ignoreValidSolution) const
00225 {
00226 ResolverProblemList problems;
00227
00228 if (_best_context && !ignoreValidSolution) {
00229 MIL << "Valid solution found, no problems" << endl;
00230 return problems;
00231 }
00232
00233
00234
00235 ResolverQueueList invalid = invalidQueues();
00236 MIL << invalid.size() << " invalid queues" << endl;
00237
00238 if (invalid.empty()) {
00239 WAR << "No solver problems, but there is also no valid solution." << endl;
00240 return problems;
00241 }
00242
00243 ResolverContext_Ptr context = invalid.front()->context();
00244 ResItemCollector collector;
00245 context->foreachInfo (PoolItem(), RESOLVER_INFO_PRIORITY_VERBOSE, collector_cb, &collector);
00246
00247 for (ProblemMap::const_iterator iter = collector.problems.begin(); iter != collector.problems.end(); ++iter) {
00248 PoolItem_Ref item = iter->first;
00249 ResolverInfo_Ptr info = iter->second;
00250
00251 bool problem_created = false;
00252
00253 DBG << "Problem: " << *info;
00254 DBG << "; Evaluate solutions..." << endl;
00255
00256 string who = ResolverInfo::toString( item );
00257 string what;
00258 string details;
00259 switch (info->type()) {
00260 case RESOLVER_INFO_TYPE_INVALID: {
00261 what = _("Invalid information");
00262 }
00263 break;
00264 case RESOLVER_INFO_TYPE_NEEDED_BY: {
00265 ResolverInfoNeededBy_constPtr needed_by = dynamic_pointer_cast<const ResolverInfoNeededBy>(info);
00266 if (needed_by->items().size() >= 1)
00267
00268 what = str::form (_("%s is needed by other resolvables"), who.c_str());
00269 else
00270
00271 what = str::form (_("%s is needed by %s"), who.c_str(), needed_by->itemsToString(true).c_str());
00272 details = str::form (_("%s is needed by:\n%s"), who.c_str(), needed_by->itemsToString(false).c_str());
00273 }
00274 break;
00275 case RESOLVER_INFO_TYPE_CONFLICTS_WITH: {
00276 ResolverInfoConflictsWith_constPtr conflicts_with = dynamic_pointer_cast<const ResolverInfoConflictsWith>(info);
00277 if (conflicts_with->items().size() >= 1)
00278
00279 what = str::form (_("%s conflicts with other resolvables"), who.c_str() );
00280 else
00281
00282 what = str::form (_("%s conflicts with %s"), who.c_str(), conflicts_with->itemsToString(true).c_str());
00283 details = str::form (_("%s conflicts with:\n%s"), who.c_str(), conflicts_with->itemsToString(false).c_str());
00284 ResolverProblem_Ptr problem = new ResolverProblem (what, details);
00285
00286 problem->addSolution (new ProblemSolutionUninstall (problem, item));
00287 if (conflicts_with->items().size() == 1) {
00288
00289 problem->addSolution (new ProblemSolutionUninstall (problem, *(conflicts_with->items().begin())));
00290 } else {
00291
00292 PoolItemList conflict_items = conflicts_with->items();
00293 problem->addSolution (new ProblemSolutionUninstall (problem, conflict_items));
00294 }
00295
00296 problem->addSolution (new ProblemSolutionIgnoreConflicts (problem, item, conflicts_with->capability(),
00297 conflicts_with->items()));
00298 problems.push_back (problem);
00299 problem_created = true;
00300 }
00301 break;
00302 case RESOLVER_INFO_TYPE_OBSOLETES: {
00303 ResolverInfoObsoletes_constPtr obsoletes = dynamic_pointer_cast<const ResolverInfoObsoletes>(info);
00304 if (obsoletes->items().size() >= 1)
00305
00306 what = str::form (_("%s obsoletes other resolvables"), who.c_str());
00307 else
00308
00309 what = str::form (_("%s obsoletes %s"), who.c_str(), obsoletes->itemsToString(true).c_str());
00310
00311 details = str::form (_("%s obsoletes:%s"), who.c_str(), obsoletes->itemsToString(false).c_str());
00312 details += _("\nThese resolvables will be deleted from the system.");
00313 }
00314 break;
00315 case RESOLVER_INFO_TYPE_DEPENDS_ON: {
00316 ResolverInfoDependsOn_constPtr depends_on = dynamic_pointer_cast<const ResolverInfoDependsOn>(info);
00317 if (depends_on->items().size() >= 1)
00318
00319 what = str::form (_("%s depends on other resolvables"), who.c_str(),
00320 depends_on->itemsToString(true).c_str());
00321 else
00322
00323 what = str::form (_("%s depends on %s"), who.c_str(),
00324 depends_on->itemsToString(true).c_str());
00325
00326 details = str::form (_("%s depends on:%s"), who.c_str(), depends_on->itemsToString(false).c_str());
00327 }
00328 break;
00329 case RESOLVER_INFO_TYPE_CHILD_OF: {
00330 ResolverInfoChildOf_constPtr child_of = dynamic_pointer_cast<const ResolverInfoChildOf>(info);
00331
00332 what = _("Child of");
00333 }
00334 break;
00335 case RESOLVER_INFO_TYPE_MISSING_REQ: {
00336 ResolverInfoMissingReq_constPtr missing_req = dynamic_pointer_cast<const ResolverInfoMissingReq>(info);
00337
00338 what = str::form (_("Cannot install %s"), who.c_str());
00339
00340 details = str::form (_("None provides %s"), missing_req->capability().asString().c_str());
00341 details += _("\nThere is no resource available which support this requirement.");
00342 }
00343 break;
00344
00345
00346 case RESOLVER_INFO_TYPE_INVALID_SOLUTION: {
00347 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00348 what = misc_info->message();
00349 details = _("Due problems which are described above/below this resolution will not solve all dependencies");
00350
00351 }
00352 break;
00353 case RESOLVER_INFO_TYPE_UNINSTALLABLE: {
00354 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00355
00356
00357 for (ConflictMap::const_iterator it = collector.conflictMap.begin();
00358 it != collector.conflictMap.end(); ++it) {
00359 if (it->first == item) {
00360 what = str::form (_("Cannot install %s because it is conflicting with %s"),
00361 who.c_str(),
00362 it->second->name().c_str());
00363 details = "";
00364 ResolverProblem_Ptr problem = new ResolverProblem (what, details);
00365
00366 problem->addSolution (new ProblemSolutionUninstall (problem, item));
00367
00368 problem->addSolution (new ProblemSolutionUninstall (problem, it->second));
00369 problems.push_back (problem);
00370 problem_created = true;
00371 }
00372 }
00373 if (!problem_created) {
00374
00375 what = misc_info->message();
00376
00377 details = str::form (_("%s is not installed and has been marked as uninstallable"), who.c_str());
00378 ResolverProblem_Ptr problem = new ResolverProblem (what, details);
00379 problem->addSolution (new ProblemSolutionInstall (problem, item));
00380 problems.push_back (problem);
00381 problem_created = true;
00382 }
00383 }
00384 break;
00385 case RESOLVER_INFO_TYPE_REJECT_INSTALL: {
00386 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00387
00388 what = str::form (_("Cannot install %s due to dependency problems"), who.c_str());
00389 details = misc_info->message();
00390 ResolverProblem_Ptr problem = new ResolverProblem (what, details);
00391
00392 problem->addSolution (new ProblemSolutionUninstall (problem, item));
00393
00394 problems.push_back (problem);
00395 problem_created = true;
00396 }
00397 break;
00398 case RESOLVER_INFO_TYPE_INSTALL_TO_BE_UNINSTALLED: {
00399 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00400
00401 what = misc_info->message();
00402 ResolverProblem_Ptr problem = new ResolverProblem (what, details);
00403 problem->addSolution (new ProblemSolutionInstall (problem, item));
00404 problems.push_back (problem);
00405 problem_created = true;
00406 }
00407 break;
00408 case RESOLVER_INFO_TYPE_INSTALL_UNNEEDED: {
00409 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00410
00411 what = misc_info->message();
00412
00413 }
00414 break;
00415 case RESOLVER_INFO_TYPE_INSTALL_PARALLEL: {
00416 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00417
00418 what = str::form (_("Cannot install %s"), who.c_str());
00419 details = misc_info->message();
00420 ResolverProblem_Ptr problem = new ResolverProblem (what, details);
00421
00422 ResStatus status = item.status();
00423 string description = "";
00424 if (status.isInstalled())
00425
00426 description = str::form (_("delete %s"), ResolverInfo::toString (item).c_str());
00427 else
00428
00429 description = str::form (_("do not install %s"), ResolverInfo::toString (item).c_str());
00430 problem->addSolution (new ProblemSolutionUninstall (problem, item, description, ""));
00431
00432
00433 status = misc_info->other().status();
00434 if (status.isInstalled())
00435
00436 description = str::form (_("delete %s"), ResolverInfo::toString (misc_info->other()).c_str());
00437 else
00438
00439 description = str::form (_("do not install %s"), ResolverInfo::toString (misc_info->other()).c_str());
00440 problem->addSolution (new ProblemSolutionUninstall (problem, misc_info->other(), description, ""));
00441
00442
00443 problem->addSolution (new ProblemSolutionIgnoreInstalled (problem, item, misc_info->other()));
00444 problems.push_back (problem);
00445 problem_created = true;
00446 }
00447 break;
00448 case RESOLVER_INFO_TYPE_INCOMPLETES: {
00449 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00450 what = misc_info->message();
00451
00452 details = str::form (_("%s has unfulfilled requirements"), who.c_str());
00453 ResolverProblem_Ptr problem = new ResolverProblem (what, details);
00454
00455 problem->addSolution (new ProblemSolutionUninstall (problem, item));
00456 problems.push_back (problem);
00457 problem_created = true;
00458 }
00459 break;
00460
00461 case RESOLVER_INFO_TYPE_ESTABLISHING: {
00462 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00463 what = misc_info->message();
00464
00465 }
00466 break;
00467
00468 case RESOLVER_INFO_TYPE_INSTALLING: {
00469 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00470 what = misc_info->message();
00471
00472 }
00473 break;
00474 case RESOLVER_INFO_TYPE_UPDATING: {
00475 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00476 what = misc_info->message();
00477
00478 }
00479 break;
00480 case RESOLVER_INFO_TYPE_SKIPPING: {
00481 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00482 what = misc_info->message();
00483
00484 }
00485 break;
00486
00487 case RESOLVER_INFO_TYPE_NO_OTHER_PROVIDER: {
00488 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00489
00490 what = str::form (_("%s has missing dependencies"), who.c_str());
00491 details = misc_info->message();
00492 ResolverProblem_Ptr problem = new ResolverProblem (what, details);
00493
00494
00495 for (ItemCapabilityMap::const_iterator it = collector.provideAndDeleteMap.begin();
00496 it != collector.provideAndDeleteMap.end(); ++it) {
00497 if (it->second.matches (misc_info->capability()) == CapMatch::yes) {
00498
00499 problem->addSolution (new ProblemSolutionKeep (problem, it->first));
00500 }
00501 }
00502
00503
00504 for (ItemCapabilityMap::const_iterator it = collector.provideAndKeptMap.begin();
00505 it != collector.provideAndKeptMap.end(); ++it) {
00506 if (it->second.matches (misc_info->capability()) == CapMatch::yes) {
00507
00508 problem->addSolution (new ProblemSolutionInstall (problem, it->first));
00509 }
00510 }
00511
00512
00513 problem->addSolution (new ProblemSolutionUninstall (problem, item));
00514
00515
00516 problem->addSolution (new ProblemSolutionIgnoreRequires (problem, item, misc_info->capability()));
00517
00518
00519
00520 AllRequires info;
00521 Dep dep( Dep::REQUIRES );
00522
00523 invokeOnEach( _pool.byCapabilityIndexBegin( misc_info->capability().index(), dep ),
00524 _pool.byCapabilityIndexEnd( misc_info->capability().index(), dep ),
00525 resfilter::ByCapMatch( misc_info->capability() ),
00526 functor::functorRef<bool,CapAndItem>(info) );
00527 if (info.requirers.size() > 1)
00528 problem->addSolution (new ProblemSolutionIgnoreRequires (problem, info.requirers, misc_info->capability()));
00529
00530 problems.push_back (problem);
00531 problem_created = true;
00532 }
00533 break;
00534 case RESOLVER_INFO_TYPE_NO_PROVIDER: {
00535 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00536
00537 what = str::form (_("%s cannot be installed due to missing dependencies"), who.c_str());
00538 details = misc_info->message();
00539 ResolverProblem_Ptr problem = new ResolverProblem (what, details);
00540
00541
00542 for (ItemCapabilityMap::const_iterator it = collector.provideAndLockMap.begin();
00543 it != collector.provideAndLockMap.end(); ++it) {
00544 if (it->second.matches (misc_info->capability()) == CapMatch::yes) {
00545
00546 problem->addSolution (new ProblemSolutionUnlock (problem, it->first));
00547
00548 problem->addSolution (new ProblemSolutionUnlock (problem, pool()));
00549 }
00550 }
00551
00552 for (ItemCapabilityMap::const_iterator it = collector.provideAndOtherArchMap.begin();
00553 it != collector.provideAndOtherArchMap.end(); ++it) {
00554 if (it->second.matches (misc_info->capability()) == CapMatch::yes) {
00555
00556 problem->addSolution (new ProblemSolutionIgnoreArchitecture (problem, it->first));
00557 }
00558 }
00559
00560 for (ItemCapabilityMap::const_iterator it = collector.provideAndKeptMap.begin();
00561 it != collector.provideAndKeptMap.end(); ++it) {
00562 if (it->second.matches (misc_info->capability()) == CapMatch::yes) {
00563
00564 problem->addSolution (new ProblemSolutionInstall (problem, it->first));
00565 }
00566 }
00567
00568
00569 problem->addSolution (new ProblemSolutionUninstall (problem, item));
00570
00571 problem->addSolution (new ProblemSolutionIgnoreRequires (problem, item, misc_info->capability()));
00572 problems.push_back (problem);
00573 problem_created = true;
00574 }
00575 break;
00576 case RESOLVER_INFO_TYPE_NO_UPGRADE: {
00577 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00578 what = misc_info->message();
00579
00580 }
00581 break;
00582 case RESOLVER_INFO_TYPE_UNINSTALL_PROVIDER: {
00583 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00584
00585 what =str::form (_("%s fulfil dependencies of %s but will be uninstalled"),
00586 misc_info->other()->name().c_str(),
00587 who.c_str());
00588 details = misc_info->message();
00589
00590 }
00591 break;
00592 case RESOLVER_INFO_TYPE_KEEP_PROVIDER: {
00593 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00594
00595 what =str::form (_("%s fulfil dependencies of %s but will be kept on your system"),
00596 misc_info->other()->name().c_str(),
00597 who.c_str());
00598 details = misc_info->message();
00599
00600 }
00601 break;
00602 case RESOLVER_INFO_TYPE_PARALLEL_PROVIDER: {
00603 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00604
00605 what = str::form (_("No need to install %s"), misc_info->other()->name().c_str());
00606 details = misc_info->message();
00607
00608 }
00609 break;
00610 case RESOLVER_INFO_TYPE_NOT_INSTALLABLE_PROVIDER: {
00611 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00612
00613 what = str::form (_("Cannot install %s to fulfil the dependencies of %s"),
00614 misc_info->other()->name().c_str(),
00615 who.c_str());
00616 details = misc_info->message();
00617
00618 }
00619 case RESOLVER_INFO_TYPE_OTHER_ARCH_PROVIDER: {
00620 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00621 what = misc_info->message();
00622
00623 }
00624 break;
00625 case RESOLVER_INFO_TYPE_LOCKED_PROVIDER: {
00626 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00627
00628 what = str::form (_("Cannot be install %s to fulfil the dependencies of %s"),
00629 misc_info->other()->name().c_str(),
00630 who.c_str());
00631 what = misc_info->message();
00632
00633 }
00634 break;
00635 case RESOLVER_INFO_TYPE_CANT_SATISFY: {
00636 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00637 what = misc_info->message();
00638 ResolverProblem_Ptr problem = new ResolverProblem (what, details);
00639
00640 problem->addSolution (new ProblemSolutionUninstall (problem, item));
00641
00642
00643 problem->addSolution (new ProblemSolutionIgnoreRequires (problem, item, misc_info->capability()));
00644
00645
00646
00647 AllRequires info;
00648 Dep dep( Dep::REQUIRES );
00649
00650 invokeOnEach( _pool.byCapabilityIndexBegin( misc_info->capability().index(), dep ),
00651 _pool.byCapabilityIndexEnd( misc_info->capability().index(), dep ),
00652 resfilter::ByCapMatch( misc_info->capability() ),
00653 functor::functorRef<bool,CapAndItem>(info) );
00654 if (info.requirers.size() > 1)
00655 problem->addSolution (new ProblemSolutionIgnoreRequires (problem, info.requirers, misc_info->capability()));
00656
00657 problems.push_back (problem);
00658 problem_created = true;
00659 }
00660 break;
00661
00662 case RESOLVER_INFO_TYPE_UNINSTALL_TO_BE_INSTALLED: {
00663 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00664
00665 what = str::form (_("%s will not be uninstalled cause it is still required"), who.c_str());
00666 details = misc_info->message();
00667
00668 }
00669 break;
00670 case RESOLVER_INFO_TYPE_UNINSTALL_INSTALLED: {
00671 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00672
00673 what = str::form (_("%s will not be uninstalled cause it is still required"), who.c_str());
00674 details = misc_info->message();
00675
00676 }
00677 break;
00678 case RESOLVER_INFO_TYPE_UNINSTALL_LOCKED: {
00679 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00680 what = misc_info->message();
00681
00682 if (misc_info->trigger() == ResolverInfoMisc::OBSOLETE) {
00683
00684 details = str::form (_("%s obsoletes %s. But %s cannot be deleted because it is locked."),
00685 misc_info->other()->name().c_str(),
00686 who.c_str(), who.c_str());
00687 }
00688
00689 ResolverProblem_Ptr problem = new ResolverProblem (what, details);
00690 problem->addSolution (new ProblemSolutionUnlock (problem, item));
00691
00692 problem->addSolution (new ProblemSolutionUnlock (problem, pool()));
00693 if (misc_info->trigger() == ResolverInfoMisc::OBSOLETE) {
00694
00695 problem->addSolution (new ProblemSolutionIgnoreObsoletes (problem, item, misc_info->capability(),
00696 misc_info->other()));
00697 } else {
00698
00699
00700 problem->addSolution (new ProblemSolutionKeep (problem, item));
00701 }
00702 problems.push_back (problem);
00703 problem_created = true;
00704 }
00705 break;
00706
00707 case RESOLVER_INFO_TYPE_CONFLICT_CANT_INSTALL: {
00708 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00709
00710 if (misc_info->other())
00711 what = str::form (_("Cannot install %s because it is conflicting with %s"),
00712 who.c_str(),
00713 misc_info->other()->name().c_str());
00714 else
00715 what = str::form (_("Cannot install %s because it is conflicting"),
00716 who.c_str());
00717 details = misc_info->message();
00718 ResolverProblem_Ptr problem = new ResolverProblem (what, details);
00719
00720 problem->addSolution (new ProblemSolutionUninstall (problem, item));
00721 if (misc_info->other())
00722
00723 problem->addSolution (new ProblemSolutionUninstall (problem, misc_info->other()));
00724
00725 problem->addSolution (new ProblemSolutionIgnoreConflicts (problem, item, misc_info->other_capability(),
00726 misc_info->other()));
00727 problems.push_back (problem);
00728 problem_created = true;
00729 }
00730 break;
00731 case RESOLVER_INFO_TYPE_CONFLICT_UNINSTALLABLE: {
00732 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00733
00734 what = str::form (_("%s is uninstallable due to conflicts with %s"),
00735 who.c_str(),
00736 misc_info->other()->name().c_str());
00737 details = misc_info->message();
00738
00739 }
00740 break;
00741 }
00742 if (!problem_created) {
00743 ResolverProblem_Ptr problem = new ResolverProblem (what, details);
00744 problems.push_back (problem);
00745 }
00746 }
00747 if (problems.empty()) {
00748 context->spewInfo();
00749 }
00750 return problems;
00751 }
00752
00753 void
00754 Resolver::applySolutions (const ProblemSolutionList & solutions)
00755 {
00756 for (ProblemSolutionList::const_iterator iter = solutions.begin();
00757 iter != solutions.end(); ++iter) {
00758 ProblemSolution_Ptr solution = *iter;
00759 if (!solution->apply (*this))
00760 break;
00761 }
00762 }
00763
00765 };
00768 };
00771 };
00773