From cf28bcadb301d00f6534fea97ccf1fde63041e7b Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Tue, 29 Jun 2010 19:21:35 +0200 Subject: if the package has no installed & candidate but is virtual see if only one package provides it - if it is only one use this package instead --- cmdline/apt-get.cc | 86 ++++++++++++++++++++++++++++++----------------------- cmdline/cacheset.cc | 8 +++++ cmdline/cacheset.h | 2 ++ 3 files changed, 59 insertions(+), 37 deletions(-) diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc index 7ba0e8e5c..d3ddcbfe8 100644 --- a/cmdline/apt-get.cc +++ b/cmdline/apt-get.cc @@ -1081,41 +1081,6 @@ bool TryToInstall(pkgCache::PkgIterator Pkg,pkgDepCache &Cache, pkgProblemResolver &Fix,bool Remove,bool BrokenFix, bool AllowFail = true) { - /* This is a pure virtual package and there is a single available - candidate providing it. */ - if (Cache[Pkg].CandidateVer == 0 && Pkg->ProvidesList != 0) - { - pkgCache::PkgIterator Prov; - bool found_one = false; - - for (pkgCache::PrvIterator P = Pkg.ProvidesList(); P; P++) - { - pkgCache::VerIterator const PVer = P.OwnerVer(); - pkgCache::PkgIterator const PPkg = PVer.ParentPkg(); - - /* Ignore versions that are not a candidate. */ - if (Cache[PPkg].CandidateVer != PVer) - continue; - - if (found_one == false) - { - Prov = PPkg; - found_one = true; - } - else if (PPkg != Prov) - { - found_one = false; // we found at least two - break; - } - } - - if (found_one == true) - { - ioprintf(c1out,_("Note, selecting %s instead of %s\n"), - Prov.FullName(true).c_str(),Pkg.FullName(true).c_str()); - Pkg = Prov; - } - } // Handle the no-upgrade case if (_config->FindB("APT::Get::upgrade",true) == false && @@ -1601,13 +1566,13 @@ public: virtual void showTaskSelection(APT::PackageSet const &pkgset, string const &pattern) { for (APT::PackageSet::const_iterator Pkg = pkgset.begin(); Pkg != pkgset.end(); ++Pkg) - ioprintf(out, _("Note, selecting %s for task '%s'\n"), + ioprintf(out, _("Note, selecting '%s' for task '%s'\n"), Pkg.FullName(true).c_str(), pattern.c_str()); explicitlyNamed = false; } virtual void showRegExSelection(APT::PackageSet const &pkgset, string const &pattern) { for (APT::PackageSet::const_iterator Pkg = pkgset.begin(); Pkg != pkgset.end(); ++Pkg) - ioprintf(out, _("Note, selecting %s for regex '%s'\n"), + ioprintf(out, _("Note, selecting '%s' for regex '%s'\n"), Pkg.FullName(true).c_str(), pattern.c_str()); explicitlyNamed = false; } @@ -1618,6 +1583,53 @@ public: Ver.VerStr(), Ver.RelStr().c_str(), Pkg.FullName(true).c_str()); } + virtual APT::VersionSet canNotFindCandInstVer(pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg) { + return tryVirtualPackage(Cache, Pkg, APT::VersionSet::CANDINST); + } + + virtual APT::VersionSet canNotFindInstCandVer(pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg) { + return tryVirtualPackage(Cache, Pkg, APT::VersionSet::INSTCAND); + } + + APT::VersionSet tryVirtualPackage(pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg, + APT::VersionSet::Version const &select) { + /* This is a pure virtual package and there is a single available + candidate providing it. */ + if (unlikely(Cache[Pkg].CandidateVer != 0) || Pkg->ProvidesList == 0) { + if (select == APT::VersionSet::CANDINST) + return APT::CacheSetHelper::canNotFindCandInstVer(Cache, Pkg); + return APT::CacheSetHelper::canNotFindInstCandVer(Cache, Pkg); + } + + pkgCache::PkgIterator Prov; + bool found_one = false; + for (pkgCache::PrvIterator P = Pkg.ProvidesList(); P; ++P) { + pkgCache::VerIterator const PVer = P.OwnerVer(); + pkgCache::PkgIterator const PPkg = PVer.ParentPkg(); + + /* Ignore versions that are not a candidate. */ + if (Cache[PPkg].CandidateVer != PVer) + continue; + + if (found_one == false) { + Prov = PPkg; + found_one = true; + } else if (PPkg != Prov) { + found_one = false; // we found at least two + break; + } + } + + if (found_one == true) { + ioprintf(out, _("Note, selecting '%s' instead of '%s'\n"), + Prov.FullName(true).c_str(), Pkg.FullName(true).c_str()); + return APT::VersionSet::FromPackage(Cache, Prov, select, *this); + } + if (select == APT::VersionSet::CANDINST) + return APT::CacheSetHelper::canNotFindCandInstVer(Cache, Pkg); + return APT::CacheSetHelper::canNotFindInstCandVer(Cache, Pkg); + } + inline bool allPkgNamedExplicitly() const { return explicitlyNamed; } }; diff --git a/cmdline/cacheset.cc b/cmdline/cacheset.cc index 35ef74f9a..cc2860a22 100644 --- a/cmdline/cacheset.cc +++ b/cmdline/cacheset.cc @@ -474,6 +474,14 @@ VersionSet CacheSetHelper::canNotFindInstCandVer(pkgCacheFile &Cache, return VersionSet(); } /*}}}*/ +// canNotFindInstCandVer /*{{{*/ +VersionSet CacheSetHelper::canNotFindCandInstVer(pkgCacheFile &Cache, + pkgCache::PkgIterator const &Pkg) { + if (ShowError == true) + _error->Error(_("Can't select installed nor candidate version from package '%s' as it has neither of them"), Pkg.FullName(true).c_str()); + return VersionSet(); +} + /*}}}*/ // canNotFindNewestVer /*{{{*/ pkgCache::VerIterator CacheSetHelper::canNotFindNewestVer(pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg) { diff --git a/cmdline/cacheset.h b/cmdline/cacheset.h index bf863fb39..2ca794f28 100644 --- a/cmdline/cacheset.h +++ b/cmdline/cacheset.h @@ -47,6 +47,8 @@ public: /*{{{*/ virtual VersionSet canNotFindAllVer(pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg); virtual VersionSet canNotFindInstCandVer(pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg); + virtual VersionSet canNotFindCandInstVer(pkgCacheFile &Cache, + pkgCache::PkgIterator const &Pkg); virtual pkgCache::VerIterator canNotFindNewestVer(pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg); virtual pkgCache::VerIterator canNotFindCandidateVer(pkgCacheFile &Cache, -- cgit v1.2.3