summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Kalnischkies <kalnischkies@gmail.com>2010-03-14 14:45:00 +0100
committerDavid Kalnischkies <kalnischkies@gmail.com>2010-03-14 14:45:00 +0100
commit1f530ccb32c17b70b05dd5feee706dc1098a7251 (patch)
tree15520acabd229e76e172260783d1148af293421e
parent5e5d20643487fd1693af418bd1201be5802c232d (diff)
Ensure that for each all package at least one pseudopackage is installed
Removing pseudo packages is cool so far, the problem is that we will remove with the not required removing so many pseudo packages that we will have after the remove a few packages with NO installed pseudo package (e.g. metapackages are good candidates) - so we will walk over all these packages and try to find a pseudopackage for this package we can install without breaking something.
-rw-r--r--apt-pkg/depcache.cc77
1 files changed, 68 insertions, 9 deletions
diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc
index 893164ea1..ffa4fe71c 100644
--- a/apt-pkg/depcache.cc
+++ b/apt-pkg/depcache.cc
@@ -634,10 +634,8 @@ bool pkgDepCache::RemovePseudoInstalledPkg(PkgIterator &Pkg, std::set<unsigned l
if (strcmp(Pkg.Arch(),"all") == 0)
return false;
-// std::cout << "CHECK " << Pkg << std::endl;
-
- unsigned char const DepState = VersionState(V.DependsList(),DepInstall,DepInstMin,DepInstPolicy);
- if ((DepState & DepInstMin) == DepInstMin) {
+ unsigned char const CurDepState = VersionState(V.DependsList(),DepInstall,DepInstMin,DepInstPolicy);
+ if ((CurDepState & 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.
@@ -645,16 +643,15 @@ bool pkgDepCache::RemovePseudoInstalledPkg(PkgIterator &Pkg, std::set<unsigned l
// 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)
+ if (D.IsCritical() == true && 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)
+ if (D.IsCritical() == false)
continue;
PkgIterator const P = D.ParentPkg();
+ if (P->Group == Pkg->Group)
+ continue;
if (P->CurrentVer != 0)
return false;
}
@@ -800,6 +797,68 @@ void pkgDepCache::Update(OpProgress *Prog)
}
recheck.erase(p);
}
+
+ /* Okay, we have killed a great amount of pseudopackages -
+ we have killed so many that we have now arch "all" packages
+ without an installed pseudo package, but we NEED an installed
+ pseudo package, so we will search now for a pseudo package
+ we can install without breaking everything. */
+ for (GrpIterator G = Cache->GrpBegin(); G.end() != true; ++G)
+ {
+ PkgIterator P = G.FindPkg("all");
+ if (P.end() == true)
+ continue;
+ if (P->CurrentVer == 0)
+ continue;
+ bool installed = false;
+ for (P = G.FindPkg("any"); P.end() != true; P = G.NextPkg(P))
+ {
+ if (strcmp(P.Arch(), "all") == 0)
+ continue;
+ if (P->CurrentVer == 0)
+ continue;
+ installed = true;
+ break;
+ }
+ if (installed == false)
+ recheck.insert(G.Index());
+ }
+ std::vector<std::string> Archs = APT::Configuration::getArchitectures();
+ bool checkChanged = false;
+ do {
+ for(std::set<unsigned long>::const_iterator g = recheck.begin();
+ g != recheck.end(); ++g) {
+ GrpIterator G = GrpIterator(*Cache, Cache->GrpP + *g);
+ VerIterator allV = G.FindPkg("all").CurrentVer();
+ for (std::vector<std::string>::const_iterator a = Archs.begin();
+ a != Archs.end(); ++a)
+ {
+ PkgIterator P = G.FindPkg(*a);
+ if (P.end() == true) continue;
+ for (VerIterator V = P.VersionList(); V.end() != true; ++V)
+ {
+ // FIXME: String comparison isn't a save indicator!
+ if (strcmp(allV.VerStr(),V.VerStr()) != 0)
+ continue;
+ unsigned char const CurDepState = VersionState(V.DependsList(),DepInstall,DepInstMin,DepInstPolicy);
+ if ((CurDepState & DepInstMin) != DepInstMin)
+ break; // we found the correct version, but it is broken. Better try another arch or later again
+ P->CurrentVer = V.Index();
+ AddStates(P);
+ Update(P);
+ AddSizes(P);
+ checkChanged = true;
+ break;
+ }
+ }
+ recheck.erase(g);
+ }
+ } while (checkChanged == true && recheck.empty() == false);
+
+ if (_config->FindB("Debug::MultiArchKiller", false) == true)
+ for(std::set<unsigned long>::const_iterator g = recheck.begin();
+ g != recheck.end(); ++g)
+ std::cout << "No pseudo package for »" << GrpIterator(*Cache, Cache->GrpP + *g).Name() << "« installed" << std::endl;
}
if (Prog != 0)