00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef _PkgDep_h
00022 #define _PkgDep_h
00023
00024 #include <iostream>
00025 #include <list>
00026 #include <deque>
00027
00028 #include <y2util/hash.h>
00029
00030 #include <y2pm/PkgName.h>
00031 #include <y2pm/PkgEdition.h>
00032 #include <y2pm/PkgRevRel.h>
00033 #include <y2pm/PkgSet.h>
00034 #include <y2pm/Alternatives.h>
00035
00039 class PkgDep {
00040
00041
00042
00043 public:
00044 enum alternative_kind {
00045 SIMPLE, REQUIRES_MORE, CONFLICT
00046 };
00047 enum alternatives_mode {
00048 ASK_ALWAYS, ASK_IF_NO_DEFAULT, AUTO_IF_NO_DEFAULT, AUTO_ALWAYS
00049 };
00050
00052 struct RelInfo {
00053
00054 enum Kind {
00055 REQUIREMENT = 0, CONFLICT, OBSOLETION
00056 };
00057
00061 PkgName name;
00066 PkgRelation rel;
00067
00072 Kind kind;
00073
00077 PMSolvablePtr solvable;
00078
00079 RelInfo( PMSolvablePtr s, PkgRelation r, Kind k = REQUIREMENT )
00080 : name(s->name()), rel(r),
00081 kind(k), solvable(s)
00082 {}
00083 RelInfo( PkgName n, PkgRelation r, Kind k = REQUIREMENT, PMSolvablePtr s = NULL )
00084 : name(n), rel(r), kind(k), solvable(s)
00085 {}
00086 RelInfo( PkgRevRelation r, Kind k = REQUIREMENT )
00087 : name(r.pkg()->name()), rel(r.relation()),
00088 kind(k), solvable(r.pkg())
00089 {}
00090 };
00091
00092 struct Alternative {
00093 PMSolvablePtr solvable;
00094 alternative_kind kind;
00095
00096 Alternative( PMSolvablePtr p, alternative_kind k )
00097 : solvable(p), kind(k) {}
00098 };
00099
00100 typedef Alternatives::AltDefaultList (*AlternativesCallback)( PkgName name );
00101
00113 struct NeededEditionRange {
00114 PkgEdition greater;
00115 PkgEdition less;
00116 bool less_incl : 1;
00117 bool greater_incl : 1;
00118
00119 NeededEditionRange()
00120 : greater(PkgEdition::UNSPEC), less(PkgEdition::UNSPEC),
00121 less_incl(false), greater_incl(false) {}
00122 bool allows_any() const {
00123 return greater.is_unspecified() && less.is_unspecified();
00124 }
00125 bool impossible() const {
00126 return( (less < greater) ||
00127 (less == greater && (!less_incl || !greater_incl)) );
00128 }
00129 void merge( const PkgRelation& rel );
00130 };
00131
00132 typedef std::list<PkgName> NameList;
00133 typedef NameList::iterator NameList_iterator;
00134 typedef NameList::const_iterator NameList_const_iterator;
00135
00136 typedef std::list<RelInfo> RelInfoList;
00137 typedef RelInfoList::iterator RelInfoList_iterator;
00138 typedef RelInfoList::const_iterator RelInfoList_const_iterator;
00139
00140 typedef std::list<PMSolvablePtr> SolvableList;
00141
00142 struct Notes;
00143
00148 struct Result
00149 {
00151 PkgName name;
00153 PkgEdition edition;
00154
00158 PMSolvablePtr solvable;
00159
00167 RelInfoList referers;
00174 PkgEdition is_upgrade_from;
00181 PkgEdition is_downgrade_from;
00186 bool from_input_list : 1;
00192 bool upgrade_to_remove_conflict : 1;
00197 bool install_to_avoid_break : 1;
00198
00203 bool was_inconsistent : 1;
00204
00209 Result(const PkgDep& pkgdep, PMSolvablePtr pkg);
00210
00212 Result(const PkgDep& pkgdep, const PkgName& name);
00213 void add_notes( const Notes& notes );
00214 };
00215
00221 struct ErrorResult : public Result {
00226 bool not_available;
00235 NeededEditionRange not_avail_range;
00243 RelInfoList unresolvable;
00253 std::list<Alternative> alternatives;
00254
00285 RelInfoList conflicts_with;
00295 SolvableList remove_to_solve_conflict;
00296
00302 SolvableList remove_referers;
00303
00304 ErrorResult(const PkgDep& pkgdep, PMSolvablePtr pkg)
00305 : Result(pkgdep,pkg), not_available(false), state_change_not_possible(false) {}
00306 ErrorResult(const PkgDep& pkgdep, const PkgName& name)
00307 : Result(pkgdep,name), not_available(false), state_change_not_possible(false) {}
00308 ErrorResult(const Result& res)
00309 : Result(res), not_available(false), state_change_not_possible(false) {}
00310
00311 void add_unresolvable( PMSolvablePtr s, const PkgRelation& rel );
00312 void add_conflict( const PkgRevRelation& rrel,
00313 const PkgDep& dep,
00314 PMSolvablePtr to_remove,
00315 PMSolvablePtr assume_instd,
00316 RelInfo::Kind kind = RelInfo::CONFLICT );
00322 void add_conflict( PMSolvablePtr s, const PkgRelation& rel,
00323 const PkgDep& dep,
00324 PMSolvablePtr to_remove,
00325 PMSolvablePtr assume_instd,
00326 RelInfo::Kind kind = RelInfo::CONFLICT );
00327 void add_alternative( PMSolvablePtr p, alternative_kind k );
00328 void add_notes( const Notes& notes );
00329
00334 bool state_change_not_possible;
00335 };
00336
00337 friend class Result;
00338 friend class ErrorResult;
00339 typedef std::list<Result> ResultList;
00340 typedef std::list<ErrorResult> ErrorResultList;
00341
00342 enum WhatToDoWithUnresolvable {
00343 UNRES_IGNORE = 0,
00344 UNRES_TAKETHIS,
00345 UNRES_FAIL
00346 };
00347
00359 typedef WhatToDoWithUnresolvable(*DealWithUnresolvable_callback)(
00360 PkgDep* solver, const PkgRelation& rel, PMSolvablePtr& ptr);
00361
00362
00363 DealWithUnresolvable_callback _unresolvable_callback;
00364
00365 private:
00366
00367 typedef std::list<PkgRevRelation> RevRelList;
00368 typedef RevRelList::iterator RevRelList_iterator;
00369 typedef RevRelList::const_iterator RevRelList_const_iterator;
00370
00371 enum search_result { NONE, ONE, MULTI };
00372
00373 struct IRelInfo {
00374 PMSolvablePtr pkg;
00375 PkgRelation rel;
00376
00377 IRelInfo( PMSolvablePtr p, PkgRelation r ) : pkg(p), rel(r) {}
00378 };
00379
00380 typedef std::list<IRelInfo> IRelInfoList;
00381 typedef IRelInfoList::iterator IRelInfoList_iterator;
00382 typedef IRelInfoList::const_iterator IRelInfoList_const_iterator;
00383
00385 struct Notes {
00386 bool from_input : 1;
00387 bool upgrade_to_solve_conflict : 1;
00388 bool install_to_avoid_break : 1;
00389 bool not_available : 1;
00390 bool was_inconsistent : 1;
00391 IRelInfoList referers;
00392 NeededEditionRange not_avail_range;
00393
00394 Notes() : from_input(false), upgrade_to_solve_conflict(false),
00395 install_to_avoid_break(false),
00396 not_available(false),
00397 was_inconsistent(false)
00398 {}
00399 };
00400
00401 typedef hash<PkgName,Notes> Notes_type;
00402 typedef Notes_type::iterator Notes_iterator;
00403 typedef Notes_type::const_iterator Notes_const_iterator;
00404
00405 struct AltInfo {
00406 PMSolvablePtr pkg;
00407 PkgRelation req;
00408 RevRelList providers;
00409 ErrorResult result;
00410
00411 AltInfo( PMSolvablePtr p, const PkgRelation& r, const RevRelList& l,
00412 const ErrorResult& rs )
00413 : pkg(p), req(r), providers(l), result(rs) {}
00414 };
00415
00416 typedef std::deque<AltInfo> AltInfoList;
00417 typedef AltInfoList::iterator AltInfo_iterator;
00418 typedef AltInfoList::const_iterator AltInfo_const_iterator;
00419
00420
00421
00422
00423
00424 static alternatives_mode default_alternatives_mode;
00425 static unsigned default_max_remove;
00426
00427
00428 alternatives_mode alt_mode;
00429 PkgSet installed;
00430 const PkgSet& available;
00431
00432 AlternativesCallback _alternatives_callback;
00433
00434
00435 PkgSet vinstalled;
00436 PkgSet *candidates;
00437 Notes_type notes;
00438 std::deque<PMSolvablePtr > to_check;
00439 AltInfoList alts_to_check;
00440 noval_hash<PkgName> alts_handled;
00441 ErrorResultList* i_obsoleted;
00442 ResultList *good;
00443 ErrorResultList *bad;
00444
00445 bool _install_installed;
00446
00447
00448
00449 void add_package( PMSolvablePtr cand );
00450 search_result search_for_provider( const PkgRelation& req,
00451 PMSolvablePtr referer,
00452 ErrorResult *res );
00453 bool check_for_broken_reqs( PMSolvablePtr oldpkg, PMSolvablePtr newpkg,
00454 ErrorResult &res );
00455 bool req_ok_after_upgrade( const PkgRelation& rel, PMSolvablePtr oldpkg,
00456 PMSolvablePtr newpkg );
00457
00458 void handle_alternative( const AltInfo& alt_info );
00459
00460 bool pkg_consistent( PMSolvablePtr pkg, ErrorResult *err );
00461
00462 void virtual_remove_package( PMSolvablePtr pkg, SolvableList& to_remove,
00463 PMSolvablePtr assume_instd = NULL ) const;
00464
00465 bool also_provided_by_installed( const PkgRelation& rel );
00466 PMSolvablePtr upgrade_solves_conflict( PMSolvablePtr pkg,
00467 const PkgRelation& confl );
00468 PMSolvablePtr try_upgrade_conflictor( PMSolvablePtr pkg,
00469 const PkgRelation& provides );
00470 PMSolvablePtr try_upgrade_conflicted( PMSolvablePtr pkg,
00471 const PkgRelation& confl );
00472 PMSolvablePtr try_upgrade_requirerer( PMSolvablePtr pkg,
00473 PMSolvablePtr oldpkg,
00474 PMSolvablePtr newpkg );
00475 PMSolvablePtr available_upgrade( PMSolvablePtr pkg );
00476 void do_upgrade_for_conflict( PMSolvablePtr upgrade );
00477 bool has_conflict_with( const PkgRelation& confl, PMSolvablePtr pkg );
00478 void add_referer( const PkgName& name, PMSolvablePtr referer,
00479 const PkgRelation& rel );
00480 void add_referer( PMSolvablePtr pkg, PMSolvablePtr referer,
00481 const PkgRelation& rel ) {
00482 add_referer( pkg->name(), referer, rel );
00483 }
00484 void add_not_available( PMSolvablePtr referer, const PkgRelation& rel );
00485
00486
00487 static Alternatives::AltDefaultList default_alternatives_callback( PkgName name )
00488 {
00489 return Alternatives::AltDefaultList();
00490 }
00491
00495 static WhatToDoWithUnresolvable default_unresolvable_callback(
00496 PkgDep* solver, const PkgRelation& rel, PMSolvablePtr& p);
00497
00498
00501 void inconsistent_to_candidates(PkgSet& candidates);
00502
00503 public:
00504 PkgDep( PkgSet& instd, const PkgSet& avail,
00505 AlternativesCallback alternatives_callback = default_alternatives_callback,
00506 alternatives_mode m = default_alternatives_mode );
00507
00508
00509
00510
00511
00512
00513
00517 bool install( PkgSet& candidates,
00518 ResultList& good,
00519 ErrorResultList& bad,
00520 ErrorResultList& out_obsoleted,
00521 bool commit_to_installed = true,
00522 bool check_inconsistent = false);
00526 void remove( SolvableList& pkgs );
00528 bool consistent( ErrorResultList& failures );
00542
00543
00544
00545
00546
00547
00548
00553 bool solvesystemnoauto(
00554 PkgSet &candidates,
00555 ResultList& out_good,
00556 ErrorResultList& out_bad,
00557 ErrorResultList& out_obsoleted);
00558
00559
00561 const PkgSet& current_installed() { return installed; }
00562
00564 const PkgSet& current_available() { return available; }
00565
00566
00567
00568
00569
00570
00571
00572 void set_alternatives_mode(alternatives_mode mode)
00573 {
00574 alt_mode = mode;
00575 }
00576
00577 void set_alternatives_callback(Alternatives::AltDefaultList (*alternatives_callback)( PkgName name ))
00578 {
00579 _alternatives_callback = alternatives_callback;
00580 }
00581
00587 void set_unresolvable_callback(DealWithUnresolvable_callback callback)
00588 {
00589 _unresolvable_callback = callback;
00590 }
00591
00596 void install_installed(bool yes)
00597 { _install_installed = yes; }
00598
00599 static void set_default_alternatives_mode( alternatives_mode m ) {
00600 default_alternatives_mode = m;
00601 }
00602
00603 static void set_default_max_remove( unsigned mr ) {
00604 default_max_remove = mr;
00605 }
00606
00607 public:
00608
00611 static void remove_package( PkgSet *set, PMSolvablePtr pkg,
00612 SolvableList& to_remove);
00613
00617 static unsigned count_providers_for( const PkgSet* set, const PkgRelation& req );
00618 };
00619
00620
00621 std::ostream& operator<<( std::ostream& os, const PkgDep::Result& res );
00622 std::ostream& operator<<( std::ostream& os, const PkgDep::ErrorResult& res );
00623 std::ostream& operator<<( std::ostream& os, const PkgDep::RelInfoList& rl );
00624 std::ostream& operator<<( std::ostream& os, const std::list<PkgDep::Alternative>& al );
00625 std::ostream& operator<<( std::ostream& os, const PkgDep::NameList& nl );
00626 std::ostream& operator<<( std::ostream& os, const PkgDep::NeededEditionRange& range );
00627
00628 #endif
00629
00630
00631
00632