summaryrefslogtreecommitdiff
path: root/apt-pkg
diff options
context:
space:
mode:
Diffstat (limited to 'apt-pkg')
-rw-r--r--apt-pkg/depcache.cc77
-rw-r--r--apt-pkg/depcache.h1
2 files changed, 66 insertions, 12 deletions
diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc
index 45c614c6f..893164ea1 100644
--- a/apt-pkg/depcache.cc
+++ b/apt-pkg/depcache.cc
@@ -630,11 +630,46 @@ bool pkgDepCache::RemovePseudoInstalledPkg(PkgIterator &Pkg, std::set<unsigned l
if (V->MultiArch != Version::All)
return false;
- unsigned char const DepState = VersionState(V.DependsList(),DepInstall,DepInstMin,DepInstPolicy);
- if ((DepState & DepInstMin) == DepInstMin)
+ // Never ever kill an "all" package - they have no dependency so they can't be broken
+ if (strcmp(Pkg.Arch(),"all") == 0)
return false;
- // Dependencies for this arch all are not statisfied
+// std::cout << "CHECK " << Pkg << std::endl;
+
+ unsigned char const DepState = VersionState(V.DependsList(),DepInstall,DepInstMin,DepInstPolicy);
+ if ((DepState & DepInstMin) == DepInstMin) {
+ // okay, the package isn't broken, but is the package also required?
+ // If it has no real dependencies, no installed rdepends and doesn't
+ // provide something of value, we will kill it as not required.
+ // These pseudopackages have otherwise interesting effects if they get
+ // a new dependency in a newer version…
+ for (pkgCache::DepIterator D = V.DependsList();
+ D.end() != true; ++D)
+ if ((D->Type == pkgCache::Dep::Depends ||
+ D->Type == pkgCache::Dep::PreDepends) &&
+ D.ParentPkg()->Group != Pkg->Group)
+ return false;
+ for (DepIterator D = Pkg.RevDependsList(); D.end() != true; ++D)
+ {
+ if (D->Type != pkgCache::Dep::Depends &&
+ D->Type != pkgCache::Dep::PreDepends)
+ continue;
+ PkgIterator const P = D.ParentPkg();
+ if (P->CurrentVer != 0)
+ return false;
+ }
+ for (PrvIterator Prv = V.ProvidesList(); Prv.end() != true; Prv++)
+ for (DepIterator d = Prv.ParentPkg().RevDependsList();
+ d.end() != true; ++d)
+ {
+ PkgIterator const P = d.ParentPkg();
+ if (P->CurrentVer != 0 &&
+ P->Group != Pkg->Group)
+ return false;
+ }
+ }
+
+ // Dependencies for this arch all package are not statisfied
// so we installed it only for our convenience: get right of it now.
RemoveSizes(Pkg);
RemoveStates(Pkg);
@@ -655,15 +690,33 @@ bool pkgDepCache::RemovePseudoInstalledPkg(PkgIterator &Pkg, std::set<unsigned l
recheck.insert(P.Index());
}
- if (V.end() != true)
- for (PrvIterator Prv = V.ProvidesList(); Prv.end() != true; Prv++)
- for (DepIterator d = Prv.ParentPkg().RevDependsList();
- d.end() != true; ++d)
- {
- PkgIterator const P = d.ParentPkg();
- if (P->CurrentVer != 0)
- recheck.insert(P.Index());
- }
+ for (DepIterator d = V.DependsList(); d.end() != true; ++d)
+ {
+ PkgIterator const P = d.TargetPkg();
+ for (PrvIterator Prv = P.ProvidesList(); Prv.end() != true; ++Prv)
+ {
+ PkgIterator const O = Prv.OwnerPkg();
+ if (O->CurrentVer != 0)
+ recheck.insert(O.Index());
+ }
+
+ if (P->CurrentVer != 0)
+ recheck.insert(P.Index());
+ }
+
+ for (PrvIterator Prv = V.ProvidesList(); Prv.end() != true; Prv++)
+ {
+ for (DepIterator d = Prv.ParentPkg().RevDependsList();
+ d.end() != true; ++d)
+ {
+ PkgIterator const P = d.ParentPkg();
+ if (P->CurrentVer == 0)
+ continue;
+
+ recheck.insert(P.Index());
+ }
+ }
+
return true;
}
diff --git a/apt-pkg/depcache.h b/apt-pkg/depcache.h
index 23b29cc13..ea605f199 100644
--- a/apt-pkg/depcache.h
+++ b/apt-pkg/depcache.h
@@ -332,6 +332,7 @@ class pkgDepCache : protected pkgCache::Namespace
inline operator pkgCache &() {return *Cache;};
inline Header &Head() {return *Cache->HeaderP;};
inline PkgIterator PkgBegin() {return Cache->PkgBegin();};
+ inline GrpIterator FindGrp(string const &Name) {return Cache->FindGrp(Name);};
inline PkgIterator FindPkg(string const &Name) {return Cache->FindPkg(Name);};
inline PkgIterator FindPkg(string const &Name, string const &Arch) {return Cache->FindPkg(Name, Arch);};