summaryrefslogtreecommitdiff
path: root/apt-pkg/depcache.cc
diff options
context:
space:
mode:
authorDavid Kalnischkies <kalnischkies@gmail.com>2010-03-01 21:59:03 +0100
committerDavid Kalnischkies <kalnischkies@gmail.com>2010-03-01 21:59:03 +0100
commit1ec1653cd4849423e0d5f769ecbfab2d6f16c4ad (patch)
treec812736ee9b1e36c28123aad2e6d4697e364c6ad /apt-pkg/depcache.cc
parent70ae240915df3ef89715d71d5fe7a6910cbf057e (diff)
We need to kill also pseudo packages which have no dependency, no
installed reverse dependency and which also doesn't provide something. They cause problems if this pseudo packages get new dependencies. As a consequence we also need to recheck the dependencies of a killed pseudo package (and especially the providers of these dependencies) to really kill all non required packages.
Diffstat (limited to 'apt-pkg/depcache.cc')
-rw-r--r--apt-pkg/depcache.cc77
1 files changed, 65 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;
}