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 <y2pm/PkgName.h>
00029 #include <y2pm/PkgEdition.h>
00030 #include <y2pm/PkgRevRel.h>
00031 #include <y2pm/PkgSet.h>
00032 #include <y2pm/Alternatives.h>
00033
00037 class PkgDep {
00038
00039
00040
00041 public:
00042 enum alternative_kind {
00043 SIMPLE, REQUIRES_MORE, CONFLICT
00044 };
00045 enum alternatives_mode {
00046 ASK_ALWAYS, ASK_IF_NO_DEFAULT, AUTO_IF_NO_DEFAULT, AUTO_ALWAYS
00047 };
00048
00050 struct RelInfo {
00051
00052 enum Kind {
00053 REQUIREMENT = 0, CONFLICT, OBSOLETION
00054 };
00055
00059 PkgName name;
00064 PkgRelation rel;
00065
00070 Kind kind;
00071
00075 PMSolvablePtr solvable;
00076
00077 RelInfo( PMSolvablePtr s, PkgRelation r, Kind k = REQUIREMENT )
00078 : name(s->name()), rel(r),
00079 kind(k), solvable(s)
00080 {}
00081 RelInfo( PkgName n, PkgRelation r, Kind k = REQUIREMENT, PMSolvablePtr s = NULL )
00082 : name(n), rel(r), kind(k), solvable(s)
00083 {}
00084 RelInfo( PkgRevRelation r, Kind k = REQUIREMENT )
00085 : name(r.pkg()->name()), rel(r.relation()),
00086 kind(k), solvable(r.pkg())
00087 {}
00088 };
00089
00090 struct Alternative {
00091 PMSolvablePtr solvable;
00092 alternative_kind kind;
00093
00094 Alternative( PMSolvablePtr p, alternative_kind k )
00095 : solvable(p), kind(k) {}
00096 };
00097
00098 typedef Alternatives::AltDefaultList (*AlternativesCallback)( PkgName name );
00099
00111 struct NeededEditionRange {
00112 PkgEdition greater;
00113 PkgEdition less;
00114 bool less_incl : 1;
00115 bool greater_incl : 1;
00116
00117 NeededEditionRange()
00118 : greater(PkgEdition::UNSPEC), less(PkgEdition::UNSPEC),
00119 less_incl(false), greater_incl(false) {}
00120 bool allows_any() const {
00121 return greater.is_unspecified() && less.is_unspecified();
00122 }
00123 bool impossible() const {
00124 return( (less < greater) ||
00125 (less == greater && (!less_incl || !greater_incl)) );
00126 }
00127 void merge( const PkgRelation& rel );
00128 };
00129
00130 typedef std::list<PkgName> NameList;
00131 typedef NameList::iterator NameList_iterator;
00132 typedef NameList::const_iterator NameList_const_iterator;
00133
00134 typedef std::list<RelInfo> RelInfoList;
00135 typedef RelInfoList::iterator RelInfoList_iterator;
00136 typedef RelInfoList::const_iterator RelInfoList_const_iterator;
00137
00138 typedef std::list<PMSolvablePtr> SolvableList;
00139
00140 private:
00141 struct Notes;
00142
00143 public:
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 RelInfoList was_inconsistent;
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 ErrorResult(const PkgDep& pkgdep, const PkgName& name);
00306 ErrorResult(const Result& res);
00307
00308 void add_unresolvable( PMSolvablePtr s, const PkgRelation& rel );
00309 void add_conflict( const PkgRevRelation& rrel,
00310 const PkgDep& dep,
00311 PMSolvablePtr to_remove,
00312 PMSolvablePtr assume_instd,
00313 RelInfo::Kind kind = RelInfo::CONFLICT,
00314 const PkgSet* candidates = NULL);
00320 void add_conflict( PMSolvablePtr s, const PkgRelation& rel,
00321 const PkgDep& dep,
00322 PMSolvablePtr to_remove,
00323 PMSolvablePtr assume_instd,
00324 RelInfo::Kind kind = RelInfo::CONFLICT,
00325 const PkgSet* candidates = NULL);
00326 void add_alternative( PMSolvablePtr p, alternative_kind k );
00327 void add_notes( const Notes& notes );
00328
00333 bool state_change_not_possible;
00334
00341 bool _error;
00342 };
00343
00344 friend class Result;
00345 friend class ErrorResult;
00346 typedef std::list<Result> ResultList;
00347 typedef std::list<ErrorResult> ErrorResultList;
00348
00349 private:
00350
00351 class P;
00352 P* _dp;
00353 friend class P;
00354
00355
00356 PkgDep(const PkgDep&);
00357 PkgDep& operator=(const PkgDep&);
00358
00359 typedef std::list<PkgRevRelation> RevRelList;
00360 typedef RevRelList::iterator RevRelList_iterator;
00361 typedef RevRelList::const_iterator RevRelList_const_iterator;
00362
00363 enum search_result { NONE, ONE, MULTI };
00364
00365 struct IRelInfo {
00366 PMSolvablePtr pkg;
00367 PkgRelation rel;
00368
00369 IRelInfo( PMSolvablePtr p, PkgRelation r ) : pkg(p), rel(r) {}
00370 };
00371
00372 typedef std::list<IRelInfo> IRelInfoList;
00373 typedef IRelInfoList::iterator IRelInfoList_iterator;
00374 typedef IRelInfoList::const_iterator IRelInfoList_const_iterator;
00375
00377 struct Notes {
00378 bool from_input : 1;
00379 bool upgrade_to_solve_conflict : 1;
00380 bool install_to_avoid_break : 1;
00381 bool not_available : 1;
00382
00383
00384 bool inconsistent_notavailable : 1;
00385 RelInfoList was_inconsistent;
00386
00387 IRelInfoList referers;
00388 NeededEditionRange not_avail_range;
00389
00390 Notes() : from_input(false), upgrade_to_solve_conflict(false),
00391 install_to_avoid_break(false),
00392 not_available(false)
00393 {}
00394 };
00395
00396 typedef std::map<PkgName,Notes> Notes_type;
00397 typedef Notes_type::iterator Notes_iterator;
00398 typedef Notes_type::const_iterator Notes_const_iterator;
00399
00400 struct AltInfo {
00401 PMSolvablePtr pkg;
00402 PkgRelation req;
00403 RevRelList providers;
00404 ErrorResult result;
00405
00406 AltInfo( PMSolvablePtr p, const PkgRelation& r, const RevRelList& l,
00407 const ErrorResult& rs )
00408 : pkg(p), req(r), providers(l), result(rs) {}
00409 };
00410
00411 typedef std::deque<AltInfo> AltInfoList;
00412 typedef AltInfoList::iterator AltInfo_iterator;
00413 typedef AltInfoList::const_iterator AltInfo_const_iterator;
00414
00415
00416
00417
00418
00419 static alternatives_mode default_alternatives_mode;
00420 static unsigned default_max_remove;
00421
00422
00423 PkgSet installed;
00424 const PkgSet& available;
00425
00426 AlternativesCallback _alternatives_callback;
00427
00428
00429 PkgSet vinstalled;
00430 PkgSet *candidates;
00431 Notes_type notes;
00432 std::deque<PMSolvablePtr > to_check;
00433 ErrorResultList* i_obsoleted;
00434 ResultList *good;
00435 ErrorResultList *bad;
00436
00437 bool _install_installed;
00438
00439
00440
00441 void add_package( PMSolvablePtr cand );
00442 search_result search_for_provider( const PkgRelation& req,
00443 PMSolvablePtr referer,
00444 ErrorResult *res );
00445 bool check_for_broken_reqs( PMSolvablePtr oldpkg, PMSolvablePtr newpkg,
00446 ErrorResult &res );
00447 bool req_ok_after_upgrade( const PkgRelation& rel, PMSolvablePtr oldpkg,
00448 PMSolvablePtr newpkg );
00449
00450 void virtual_remove_package( PMSolvablePtr pkg, SolvableList& to_remove,
00451 PMSolvablePtr assume_instd = NULL, const PkgSet* candidates = NULL) const;
00452
00453 bool also_provided_by_installed( const PkgRelation& rel );
00454 PMSolvablePtr upgrade_solves_conflict( PMSolvablePtr pkg,
00455 const PkgRelation& confl );
00456 PMSolvablePtr try_upgrade_conflictor( PMSolvablePtr pkg,
00457 const PkgRelation& provides );
00458 PMSolvablePtr try_upgrade_conflicted( PMSolvablePtr pkg,
00459 const PkgRelation& confl );
00460 PMSolvablePtr try_upgrade_requirerer( PMSolvablePtr pkg,
00461 PMSolvablePtr oldpkg,
00462 PMSolvablePtr newpkg );
00463 PMSolvablePtr available_upgrade( PMSolvablePtr pkg );
00464 void do_upgrade_for_conflict( PMSolvablePtr upgrade );
00465 bool has_conflict_with( const PkgRelation& confl, PMSolvablePtr pkg );
00466 void add_referer( const PkgName& name, PMSolvablePtr referer,
00467 const PkgRelation& rel );
00468 void add_referer( PMSolvablePtr pkg, PMSolvablePtr referer,
00469 const PkgRelation& rel ) {
00470 add_referer( pkg->name(), referer, rel );
00471 }
00472 void add_not_available( PMSolvablePtr referer, const PkgRelation& rel );
00473
00474
00475 static Alternatives::AltDefaultList default_alternatives_callback( PkgName name )
00476 {
00477 return Alternatives::AltDefaultList();
00478 }
00479
00480 public:
00481 PkgDep( PkgSet& instd, const PkgSet& avail,
00482 AlternativesCallback alternatives_callback = default_alternatives_callback,
00483 alternatives_mode m = default_alternatives_mode );
00484 ~PkgDep();
00485
00486
00487
00488
00489
00490
00491
00495 bool install( PkgSet& candidates,
00496 ResultList& good,
00497 ErrorResultList& bad,
00498 ErrorResultList& out_obsoleted,
00499 bool commit_to_installed = true,
00500 bool check_inconsistent = false);
00504 void remove( SolvableList& pkgs );
00506 bool consistent( ErrorResultList& failures );
00520
00521
00522
00523
00524
00525
00526
00531 bool solvesystemnoauto(
00532 PkgSet &candidates,
00533 ResultList& out_good,
00534 ErrorResultList& out_bad,
00535 ErrorResultList& out_obsoleted);
00536
00537
00539 const PkgSet& current_installed() { return installed; }
00540
00542 const PkgSet& current_available() { return available; }
00543
00544
00545
00546
00547
00548
00549
00550 void set_alternatives_mode(alternatives_mode mode);
00551
00552 void set_alternatives_callback(Alternatives::AltDefaultList (*alternatives_callback)( PkgName name ))
00553 {
00554 _alternatives_callback = alternatives_callback;
00555 }
00556
00561 void install_installed(bool yes)
00562 { _install_installed = yes; }
00563
00564 static void set_default_alternatives_mode( alternatives_mode m ) {
00565 default_alternatives_mode = m;
00566 }
00567
00568 static void set_default_max_remove( unsigned mr ) {
00569 default_max_remove = mr;
00570 }
00571
00572 public:
00573
00580 static void remove_package( PkgSet *set, PMSolvablePtr pkg,
00581 SolvableList& to_remove, const PkgSet* candidates = NULL);
00582
00586 static unsigned count_providers_for( const PkgSet* set, const PkgRelation& req );
00587 };
00588
00589
00590 std::ostream& operator<<( std::ostream& os, const PkgDep::Result& res );
00591 std::ostream& operator<<( std::ostream& os, const PkgDep::ErrorResult& res );
00592 std::ostream& operator<<( std::ostream& os, const PkgDep::RelInfoList& rl );
00593 std::ostream& operator<<( std::ostream& os, const std::list<PkgDep::Alternative>& al );
00594 std::ostream& operator<<( std::ostream& os, const PkgDep::NameList& nl );
00595 std::ostream& operator<<( std::ostream& os, const PkgDep::NeededEditionRange& range );
00596
00597 #endif
00598
00599
00600
00601