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 );
00319 void add_conflict( PMSolvablePtr s, const PkgRelation& rel,
00320 const PkgDep& dep,
00321 PMSolvablePtr to_remove,
00322 PMSolvablePtr assume_instd,
00323 RelInfo::Kind kind = RelInfo::CONFLICT );
00324 void add_alternative( PMSolvablePtr p, alternative_kind k );
00325 void add_notes( const Notes& notes );
00326
00331 bool state_change_not_possible;
00332
00339 bool _error;
00340 };
00341
00342 friend class Result;
00343 friend class ErrorResult;
00344 typedef std::list<Result> ResultList;
00345 typedef std::list<ErrorResult> ErrorResultList;
00346
00347 private:
00348
00349 class P;
00350 P* _dp;
00351 friend class P;
00352
00353
00354 PkgDep(const PkgDep&);
00355 PkgDep& operator=(const PkgDep&);
00356
00357 typedef std::list<PkgRevRelation> RevRelList;
00358 typedef RevRelList::iterator RevRelList_iterator;
00359 typedef RevRelList::const_iterator RevRelList_const_iterator;
00360
00361 enum search_result { NONE, ONE, MULTI };
00362
00363 struct IRelInfo {
00364 PMSolvablePtr pkg;
00365 PkgRelation rel;
00366
00367 IRelInfo( PMSolvablePtr p, PkgRelation r ) : pkg(p), rel(r) {}
00368 };
00369
00370 typedef std::list<IRelInfo> IRelInfoList;
00371 typedef IRelInfoList::iterator IRelInfoList_iterator;
00372 typedef IRelInfoList::const_iterator IRelInfoList_const_iterator;
00373
00375 struct Notes {
00376 bool from_input : 1;
00377 bool upgrade_to_solve_conflict : 1;
00378 bool install_to_avoid_break : 1;
00379 bool not_available : 1;
00380
00381
00382 bool inconsistent_notavailable : 1;
00383 RelInfoList was_inconsistent;
00384
00385 IRelInfoList referers;
00386 NeededEditionRange not_avail_range;
00387
00388 Notes() : from_input(false), upgrade_to_solve_conflict(false),
00389 install_to_avoid_break(false),
00390 not_available(false)
00391 {}
00392 };
00393
00394 typedef std::map<PkgName,Notes> Notes_type;
00395 typedef Notes_type::iterator Notes_iterator;
00396 typedef Notes_type::const_iterator Notes_const_iterator;
00397
00398 struct AltInfo {
00399 PMSolvablePtr pkg;
00400 PkgRelation req;
00401 RevRelList providers;
00402 ErrorResult result;
00403
00404 AltInfo( PMSolvablePtr p, const PkgRelation& r, const RevRelList& l,
00405 const ErrorResult& rs )
00406 : pkg(p), req(r), providers(l), result(rs) {}
00407 };
00408
00409 typedef std::deque<AltInfo> AltInfoList;
00410 typedef AltInfoList::iterator AltInfo_iterator;
00411 typedef AltInfoList::const_iterator AltInfo_const_iterator;
00412
00413
00414
00415
00416
00417 static alternatives_mode default_alternatives_mode;
00418 static unsigned default_max_remove;
00419
00420
00421 PkgSet installed;
00422 const PkgSet& available;
00423
00424 AlternativesCallback _alternatives_callback;
00425
00426
00427 PkgSet vinstalled;
00428 PkgSet *candidates;
00429 Notes_type notes;
00430 std::deque<PMSolvablePtr > to_check;
00431 ErrorResultList* i_obsoleted;
00432 ResultList *good;
00433 ErrorResultList *bad;
00434
00435 bool _install_installed;
00436
00437
00438
00439 void add_package( PMSolvablePtr cand );
00440 search_result search_for_provider( const PkgRelation& req,
00441 PMSolvablePtr referer,
00442 ErrorResult *res );
00443 bool check_for_broken_reqs( PMSolvablePtr oldpkg, PMSolvablePtr newpkg,
00444 ErrorResult &res );
00445 bool req_ok_after_upgrade( const PkgRelation& rel, PMSolvablePtr oldpkg,
00446 PMSolvablePtr newpkg );
00447
00448 void virtual_remove_package( PMSolvablePtr pkg, SolvableList& to_remove,
00449 PMSolvablePtr assume_instd = NULL ) const;
00450
00451 bool also_provided_by_installed( const PkgRelation& rel );
00452 PMSolvablePtr upgrade_solves_conflict( PMSolvablePtr pkg,
00453 const PkgRelation& confl );
00454 PMSolvablePtr try_upgrade_conflictor( PMSolvablePtr pkg,
00455 const PkgRelation& provides );
00456 PMSolvablePtr try_upgrade_conflicted( PMSolvablePtr pkg,
00457 const PkgRelation& confl );
00458 PMSolvablePtr try_upgrade_requirerer( PMSolvablePtr pkg,
00459 PMSolvablePtr oldpkg,
00460 PMSolvablePtr newpkg );
00461 PMSolvablePtr available_upgrade( PMSolvablePtr pkg );
00462 void do_upgrade_for_conflict( PMSolvablePtr upgrade );
00463 bool has_conflict_with( const PkgRelation& confl, PMSolvablePtr pkg );
00464 void add_referer( const PkgName& name, PMSolvablePtr referer,
00465 const PkgRelation& rel );
00466 void add_referer( PMSolvablePtr pkg, PMSolvablePtr referer,
00467 const PkgRelation& rel ) {
00468 add_referer( pkg->name(), referer, rel );
00469 }
00470 void add_not_available( PMSolvablePtr referer, const PkgRelation& rel );
00471
00472
00473 static Alternatives::AltDefaultList default_alternatives_callback( PkgName name )
00474 {
00475 return Alternatives::AltDefaultList();
00476 }
00477
00478 public:
00479 PkgDep( PkgSet& instd, const PkgSet& avail,
00480 AlternativesCallback alternatives_callback = default_alternatives_callback,
00481 alternatives_mode m = default_alternatives_mode );
00482 ~PkgDep();
00483
00484
00485
00486
00487
00488
00489
00493 bool install( PkgSet& candidates,
00494 ResultList& good,
00495 ErrorResultList& bad,
00496 ErrorResultList& out_obsoleted,
00497 bool commit_to_installed = true,
00498 bool check_inconsistent = false);
00502 void remove( SolvableList& pkgs );
00504 bool consistent( ErrorResultList& failures );
00518
00519
00520
00521
00522
00523
00524
00529 bool solvesystemnoauto(
00530 PkgSet &candidates,
00531 ResultList& out_good,
00532 ErrorResultList& out_bad,
00533 ErrorResultList& out_obsoleted);
00534
00535
00537 const PkgSet& current_installed() { return installed; }
00538
00540 const PkgSet& current_available() { return available; }
00541
00542
00543
00544
00545
00546
00547
00548 void set_alternatives_mode(alternatives_mode mode);
00549
00550 void set_alternatives_callback(Alternatives::AltDefaultList (*alternatives_callback)( PkgName name ))
00551 {
00552 _alternatives_callback = alternatives_callback;
00553 }
00554
00559 void install_installed(bool yes)
00560 { _install_installed = yes; }
00561
00562 static void set_default_alternatives_mode( alternatives_mode m ) {
00563 default_alternatives_mode = m;
00564 }
00565
00566 static void set_default_max_remove( unsigned mr ) {
00567 default_max_remove = mr;
00568 }
00569
00570 public:
00571
00574 static void remove_package( PkgSet *set, PMSolvablePtr pkg,
00575 SolvableList& to_remove);
00576
00580 static unsigned count_providers_for( const PkgSet* set, const PkgRelation& req );
00581 };
00582
00583
00584 std::ostream& operator<<( std::ostream& os, const PkgDep::Result& res );
00585 std::ostream& operator<<( std::ostream& os, const PkgDep::ErrorResult& res );
00586 std::ostream& operator<<( std::ostream& os, const PkgDep::RelInfoList& rl );
00587 std::ostream& operator<<( std::ostream& os, const std::list<PkgDep::Alternative>& al );
00588 std::ostream& operator<<( std::ostream& os, const PkgDep::NameList& nl );
00589 std::ostream& operator<<( std::ostream& os, const PkgDep::NeededEditionRange& range );
00590
00591 #endif
00592
00593
00594
00595