From d8276801a1c84582a85ed9ea1f2eb4e66e052e6b Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Tue, 15 Jun 2010 20:46:09 +0200 Subject: * cmdline/cacheset.cc: - doesn't include it in the library for now as it is too volatile --- cmdline/cacheset.cc | 330 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 330 insertions(+) create mode 100644 cmdline/cacheset.cc (limited to 'cmdline/cacheset.cc') diff --git a/cmdline/cacheset.cc b/cmdline/cacheset.cc new file mode 100644 index 000000000..fde52168a --- /dev/null +++ b/cmdline/cacheset.cc @@ -0,0 +1,330 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +/* ###################################################################### + + Simple wrapper around a std::set to provide a similar interface to + a set of cache structures as to the complete set of all structures + in the pkgCache. Currently only Package is supported. + + ##################################################################### */ + /*}}}*/ +// Include Files /*{{{*/ +#include +#include +#include +#include +#include + +#include + +#include + +#include + /*}}}*/ +namespace APT { +// FromRegEx - Return all packages in the cache matching a pattern /*{{{*/ +PackageSet PackageSet::FromRegEx(pkgCacheFile &Cache, std::string pattern, std::ostream &out) { + PackageSet pkgset; + std::string arch = "native"; + static const char * const isregex = ".?+*|[^$"; + + if (pattern.find_first_of(isregex) == std::string::npos) + return pkgset; + + size_t archfound = pattern.find_last_of(':'); + if (archfound != std::string::npos) { + arch = pattern.substr(archfound+1); + if (arch.find_first_of(isregex) == std::string::npos) + pattern.erase(archfound); + else + arch = "native"; + } + + regex_t Pattern; + int Res; + if ((Res = regcomp(&Pattern, pattern.c_str() , REG_EXTENDED | REG_ICASE | REG_NOSUB)) != 0) { + char Error[300]; + regerror(Res, &Pattern, Error, sizeof(Error)); + _error->Error(_("Regex compilation error - %s"), Error); + return pkgset; + } + + for (pkgCache::GrpIterator Grp = Cache.GetPkgCache()->GrpBegin(); Grp.end() == false; ++Grp) + { + if (regexec(&Pattern, Grp.Name(), 0, 0, 0) != 0) + continue; + pkgCache::PkgIterator Pkg = Grp.FindPkg(arch); + if (Pkg.end() == true) { + if (archfound == std::string::npos) { + std::vector archs = APT::Configuration::getArchitectures(); + for (std::vector::const_iterator a = archs.begin(); + a != archs.end() && Pkg.end() != true; ++a) + Pkg = Grp.FindPkg(*a); + } + if (Pkg.end() == true) + continue; + } + + ioprintf(out, _("Note, selecting %s for regex '%s'\n"), + Pkg.FullName(true).c_str(), pattern.c_str()); + + pkgset.insert(Pkg); + } + + regfree(&Pattern); + + return pkgset; +} + /*}}}*/ +// GroupedFromCommandLine - Return all versions specified on commandline/*{{{*/ +std::map PackageSet::GroupedFromCommandLine( + pkgCacheFile &Cache, const char **cmdline, + std::list const &mods, + unsigned short const &fallback, std::ostream &out) { + std::map pkgsets; + for (const char **I = cmdline; *I != 0; ++I) { + unsigned short modID = fallback; + std::string str = *I; + for (std::list::const_iterator mod = mods.begin(); + mod != mods.end(); ++mod) { + size_t const alength = strlen(mod->Alias); + switch(mod->Pos) { + case PackageSet::Modifier::POSTFIX: + if (str.compare(str.length() - alength, alength, + mod->Alias, 0, alength) != 0) + continue; + str.erase(str.length() - alength); + modID = mod->ID; + break; + case PackageSet::Modifier::PREFIX: + continue; + case PackageSet::Modifier::NONE: + continue; + } + break; + } + PackageSet pset = PackageSet::FromString(Cache, str, out); + pkgsets[modID].insert(pset.begin(), pset.end()); + } + return pkgsets; +} + /*}}}*/ +// FromCommandLine - Return all packages specified on commandline /*{{{*/ +PackageSet PackageSet::FromCommandLine(pkgCacheFile &Cache, const char **cmdline, std::ostream &out) { + PackageSet pkgset; + for (const char **I = cmdline; *I != 0; ++I) { + PackageSet pset = FromString(Cache, *I, out); + pkgset.insert(pset.begin(), pset.end()); + } + return pkgset; +} + /*}}}*/ +// FromString - Return all packages matching a specific string /*{{{*/ +PackageSet PackageSet::FromString(pkgCacheFile &Cache, std::string const &str, std::ostream &out) { + std::string pkg = str; + size_t archfound = pkg.find_last_of(':'); + std::string arch; + if (archfound != std::string::npos) { + arch = pkg.substr(archfound+1); + pkg.erase(archfound); + } + + pkgCache::PkgIterator Pkg; + if (arch.empty() == true) { + pkgCache::GrpIterator Grp = Cache.GetPkgCache()->FindGrp(pkg); + if (Grp.end() == false) + Pkg = Grp.FindPreferredPkg(); + } else + Pkg = Cache.GetPkgCache()->FindPkg(pkg, arch); + + if (Pkg.end() == false) { + PackageSet pkgset; + pkgset.insert(Pkg); + return pkgset; + } + PackageSet regex = FromRegEx(Cache, str, out); + if (regex.empty() == true) + _error->Warning(_("Unable to locate package %s"), str.c_str()); + return regex; +} + /*}}}*/ +// GroupedFromCommandLine - Return all versions specified on commandline/*{{{*/ +std::map VersionSet::GroupedFromCommandLine( + pkgCacheFile &Cache, const char **cmdline, + std::list const &mods, + unsigned short const &fallback, std::ostream &out) { + std::map versets; + for (const char **I = cmdline; *I != 0; ++I) { + unsigned short modID = fallback; + VersionSet::Version select = VersionSet::NEWEST; + std::string str = *I; + for (std::list::const_iterator mod = mods.begin(); + mod != mods.end(); ++mod) { + if (modID == fallback && mod->ID == fallback) + select = mod->SelectVersion; + size_t const alength = strlen(mod->Alias); + switch(mod->Pos) { + case VersionSet::Modifier::POSTFIX: + if (str.compare(str.length() - alength, alength, + mod->Alias, 0, alength) != 0) + continue; + str.erase(str.length() - alength); + modID = mod->ID; + select = mod->SelectVersion; + break; + case VersionSet::Modifier::PREFIX: + continue; + case VersionSet::Modifier::NONE: + continue; + } + break; + } + VersionSet vset = VersionSet::FromString(Cache, str, select , out); + versets[modID].insert(vset.begin(), vset.end()); + } + return versets; +} + /*}}}*/ +// FromCommandLine - Return all versions specified on commandline /*{{{*/ +APT::VersionSet VersionSet::FromCommandLine(pkgCacheFile &Cache, const char **cmdline, + APT::VersionSet::Version const &fallback, std::ostream &out) { + VersionSet verset; + for (const char **I = cmdline; *I != 0; ++I) { + VersionSet vset = VersionSet::FromString(Cache, *I, fallback, out); + verset.insert(vset.begin(), vset.end()); + } + return verset; +} + /*}}}*/ +// FromString - Returns all versions spedcified by a string /*{{{*/ +APT::VersionSet VersionSet::FromString(pkgCacheFile &Cache, std::string pkg, + APT::VersionSet::Version const &fallback, std::ostream &out) { + std::string ver; + bool verIsRel = false; + size_t const vertag = pkg.find_last_of("/="); + if (vertag != string::npos) { + ver = pkg.substr(vertag+1); + verIsRel = (pkg[vertag] == '/'); + pkg.erase(vertag); + } + PackageSet pkgset = PackageSet::FromString(Cache, pkg.c_str(), out); + VersionSet verset; + for (PackageSet::const_iterator P = pkgset.begin(); + P != pkgset.end(); ++P) { + if (vertag == string::npos) { + AddSelectedVersion(Cache, verset, P, fallback); + continue; + } + pkgCache::VerIterator V; + if (ver == "installed") + V = getInstalledVer(Cache, P); + else if (ver == "candidate") + V = getCandidateVer(Cache, P); + else { + pkgVersionMatch Match(ver, (verIsRel == true ? pkgVersionMatch::Release : + pkgVersionMatch::Version)); + V = Match.Find(P); + if (V.end() == true) { + if (verIsRel == true) + _error->Error(_("Release '%s' for '%s' was not found"), + ver.c_str(), P.FullName(true).c_str()); + else + _error->Error(_("Version '%s' for '%s' was not found"), + ver.c_str(), P.FullName(true).c_str()); + continue; + } + } + if (V.end() == true) + continue; + if (ver == V.VerStr()) + ioprintf(out, _("Selected version '%s' (%s) for '%s'\n"), + V.VerStr(), V.RelStr().c_str(), P.FullName(true).c_str()); + verset.insert(V); + } + return verset; +} + /*}}}*/ +// AddSelectedVersion - add version from package based on fallback /*{{{*/ +bool VersionSet::AddSelectedVersion(pkgCacheFile &Cache, VersionSet &verset, + pkgCache::PkgIterator const &P, VersionSet::Version const &fallback, + bool const &AllowError) { + pkgCache::VerIterator V; + switch(fallback) { + case VersionSet::ALL: + if (P->VersionList != 0) + for (V = P.VersionList(); V.end() != true; ++V) + verset.insert(V); + else if (AllowError == false) + return _error->Error(_("Can't select versions from package '%s' as it purely virtual"), P.FullName(true).c_str()); + else + return false; + break; + case VersionSet::CANDANDINST: + verset.insert(getInstalledVer(Cache, P, AllowError)); + verset.insert(getCandidateVer(Cache, P, AllowError)); + break; + case VersionSet::CANDIDATE: + verset.insert(getCandidateVer(Cache, P, AllowError)); + break; + case VersionSet::INSTALLED: + verset.insert(getInstalledVer(Cache, P, AllowError)); + break; + case VersionSet::CANDINST: + V = getCandidateVer(Cache, P, true); + if (V.end() == true) + V = getInstalledVer(Cache, P, true); + if (V.end() == false) + verset.insert(V); + else if (AllowError == false) + return _error->Error(_("Can't select installed nor candidate version from package '%s' as it has neither of them"), P.FullName(true).c_str()); + else + return false; + break; + case VersionSet::INSTCAND: + V = getInstalledVer(Cache, P, true); + if (V.end() == true) + V = getCandidateVer(Cache, P, true); + if (V.end() == false) + verset.insert(V); + else if (AllowError == false) + return _error->Error(_("Can't select installed nor candidate version from package '%s' as it has neither of them"), P.FullName(true).c_str()); + else + return false; + break; + case VersionSet::NEWEST: + if (P->VersionList != 0) + verset.insert(P.VersionList()); + else if (AllowError == false) + return _error->Error(_("Can't select newest version from package '%s' as it is purely virtual"), P.FullName(true).c_str()); + else + return false; + break; + } + return true; +} + /*}}}*/ +// getCandidateVer - Returns the candidate version of the given package /*{{{*/ +pkgCache::VerIterator VersionSet::getCandidateVer(pkgCacheFile &Cache, + pkgCache::PkgIterator const &Pkg, bool const &AllowError) { + pkgCache::VerIterator Cand; + if (Cache.IsDepCacheBuilt() == true) + Cand = Cache[Pkg].CandidateVerIter(Cache); + else { + if (unlikely(Cache.BuildPolicy() == false)) + return pkgCache::VerIterator(*Cache); + Cand = Cache.GetPolicy()->GetCandidateVer(Pkg); + } + if (AllowError == false && Cand.end() == true) + _error->Error(_("Can't select candidate version from package %s as it has no candidate"), Pkg.FullName(true).c_str()); + return Cand; +} + /*}}}*/ +// getInstalledVer - Returns the installed version of the given package /*{{{*/ +pkgCache::VerIterator VersionSet::getInstalledVer(pkgCacheFile &Cache, + pkgCache::PkgIterator const &Pkg, bool const &AllowError) { + if (AllowError == false && Pkg->CurrentVer == 0) + _error->Error(_("Can't select installed version from package %s as it is not installed"), Pkg.FullName(true).c_str()); + return Pkg.CurrentVer(); +} + /*}}}*/ +} -- cgit v1.2.3-70-g09d2 From dc0f01f7cbe2ed8ae6a1d2dbc0e00c19bb04679d Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sat, 19 Jun 2010 11:49:38 +0200 Subject: get packages by task^ with FromTask() --- cmdline/cacheset.cc | 76 ++++++++++++++++++++++++++++++++++++++++++++++++----- cmdline/cacheset.h | 20 ++++++++++++-- debian/changelog | 1 + 3 files changed, 88 insertions(+), 9 deletions(-) (limited to 'cmdline/cacheset.cc') diff --git a/cmdline/cacheset.cc b/cmdline/cacheset.cc index fde52168a..55ab26780 100644 --- a/cmdline/cacheset.cc +++ b/cmdline/cacheset.cc @@ -11,27 +11,83 @@ // Include Files /*{{{*/ #include #include -#include #include #include #include +#include "cacheset.h" + #include #include /*}}}*/ namespace APT { +// FromTask - Return all packages in the cache from a specific task /*{{{*/ +PackageSet PackageSet::FromTask(pkgCacheFile &Cache, std::string pattern, std::ostream &out) { + PackageSet pkgset; + if (Cache.BuildCaches() == false || Cache.BuildDepCache() == false) + return pkgset; + + size_t archfound = pattern.find_last_of(':'); + std::string arch = "native"; + if (archfound != std::string::npos) { + arch = pattern.substr(archfound+1); + pattern.erase(archfound); + } + + if (pattern[pattern.length() -1] != '^') + return pkgset; + pattern.erase(pattern.length()-1); + + // get the records + pkgRecords Recs(Cache); + + // build regexp for the task + regex_t Pattern; + char S[300]; + snprintf(S, sizeof(S), "^Task:.*[, ]%s([, ]|$)", pattern.c_str()); + if(regcomp(&Pattern,S, REG_EXTENDED | REG_NOSUB | REG_NEWLINE) != 0) { + _error->Error("Failed to compile task regexp"); + return pkgset; + } + + for (pkgCache::GrpIterator Grp = Cache->GrpBegin(); Grp.end() == false; ++Grp) { + pkgCache::PkgIterator Pkg = Grp.FindPkg(arch); + if (Pkg.end() == true) + continue; + pkgCache::VerIterator ver = Cache[Pkg].CandidateVerIter(Cache); + if(ver.end() == true) + continue; + + pkgRecords::Parser &parser = Recs.Lookup(ver.FileList()); + const char *start, *end; + parser.GetRec(start,end); + unsigned int const length = end - start; + char buf[length]; + strncpy(buf, start, length); + buf[length-1] = '\0'; + if (regexec(&Pattern, buf, 0, 0, 0) == 0) + pkgset.insert(Pkg); + } + + if (pkgset.empty() == true) + _error->Error(_("Couldn't find task %s"), pattern.c_str()); + + regfree(&Pattern); + return pkgset; +} + /*}}}*/ // FromRegEx - Return all packages in the cache matching a pattern /*{{{*/ PackageSet PackageSet::FromRegEx(pkgCacheFile &Cache, std::string pattern, std::ostream &out) { PackageSet pkgset; - std::string arch = "native"; static const char * const isregex = ".?+*|[^$"; if (pattern.find_first_of(isregex) == std::string::npos) return pkgset; size_t archfound = pattern.find_last_of(':'); + std::string arch = "native"; if (archfound != std::string::npos) { arch = pattern.substr(archfound+1); if (arch.find_first_of(isregex) == std::string::npos) @@ -142,10 +198,16 @@ PackageSet PackageSet::FromString(pkgCacheFile &Cache, std::string const &str, s pkgset.insert(Pkg); return pkgset; } - PackageSet regex = FromRegEx(Cache, str, out); - if (regex.empty() == true) - _error->Warning(_("Unable to locate package %s"), str.c_str()); - return regex; + PackageSet pset = FromTask(Cache, str, out); + if (pset.empty() == false) + return pset; + + pset = FromRegEx(Cache, str, out); + if (pset.empty() == false) + return pset; + + _error->Warning(_("Unable to locate package %s"), str.c_str()); + return pset; } /*}}}*/ // GroupedFromCommandLine - Return all versions specified on commandline/*{{{*/ @@ -236,7 +298,7 @@ APT::VersionSet VersionSet::FromString(pkgCacheFile &Cache, std::string pkg, } if (V.end() == true) continue; - if (ver == V.VerStr()) + if (ver != V.VerStr()) ioprintf(out, _("Selected version '%s' (%s) for '%s'\n"), V.VerStr(), V.RelStr().c_str(), P.FullName(true).c_str()); verset.insert(V); diff --git a/cmdline/cacheset.h b/cmdline/cacheset.h index 2bc268380..64a72e758 100644 --- a/cmdline/cacheset.h +++ b/cmdline/cacheset.h @@ -28,7 +28,7 @@ class PackageSet : public std::set { /*{{{*/ pkgCache. */ public: /*{{{*/ /** \brief smell like a pkgCache::PkgIterator */ - class const_iterator : public std::set::const_iterator { + class const_iterator : public std::set::const_iterator {/*{{{*/ public: const_iterator(std::set::const_iterator x) : std::set::const_iterator(x) {} @@ -62,10 +62,25 @@ public: /*{{{*/ }; // 103. set::iterator is required to be modifiable, but this allows modification of keys typedef APT::PackageSet::const_iterator iterator; + /*}}}*/ using std::set::insert; inline void insert(pkgCache::PkgIterator const &P) { if (P.end() == false) std::set::insert(P); }; + /** \brief returns all packages in the cache who belong to the given task + + A simple helper responsible for search for all members of a task + in the cache. Optional it prints a a notice about the + packages chosen cause of the given task. + \param Cache the packages are in + \param pattern name of the task + \param out stream to print the notice to */ + static APT::PackageSet FromTask(pkgCacheFile &Cache, std::string pattern, std::ostream &out); + static APT::PackageSet FromTask(pkgCacheFile &Cache, std::string const &pattern) { + std::ostream out (std::ofstream("/dev/null").rdbuf()); + return APT::PackageSet::FromTask(Cache, pattern, out); + } + /** \brief returns all packages in the cache whose name matchs a given pattern A simple helper responsible for executing a regular expression on all @@ -134,7 +149,7 @@ class VersionSet : public std::set { /*{{{*/ pkgCache. */ public: /*{{{*/ /** \brief smell like a pkgCache::VerIterator */ - class const_iterator : public std::set::const_iterator { + class const_iterator : public std::set::const_iterator {/*{{{*/ public: const_iterator(std::set::const_iterator x) : std::set::const_iterator(x) {} @@ -168,6 +183,7 @@ public: /*{{{*/ inline bool Pseudo() const { return (**this).Pseudo(); }; inline pkgCache::VerFileIterator NewestFile() const { return (**this).NewestFile(); }; }; + /*}}}*/ // 103. set::iterator is required to be modifiable, but this allows modification of keys typedef APT::VersionSet::const_iterator iterator; diff --git a/debian/changelog b/debian/changelog index 4de21d343..f6645c0fe 100644 --- a/debian/changelog +++ b/debian/changelog @@ -4,6 +4,7 @@ apt (0.7.26~exp8) UNRELEASED; urgency=low - doesn't include it in the library for now as it is too volatile - get the candidate either from an already built depcache or use the policy which is a bit faster than depcache generation + - get packages by task^ with FromTask() * apt-pkg/orderlist.cc: - untouched packages are never missing * apt-pkg/packagemanager.cc: -- cgit v1.2.3-70-g09d2 From 70e706adf75ed319d931a220ce27db2b981093f5 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Tue, 22 Jun 2010 18:01:11 +0200 Subject: Use an abstract helper for error handling and output instead of doing this directly in the CacheSets. With this method an application like apt-get can change the behavior of the CacheSets to his liking. It can for example easily keep track of how packages were added to the set: by names or with regex's… MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cmdline/apt-get.cc | 79 ++++++++++++++++------- cmdline/cacheset.cc | 179 ++++++++++++++++++++++++++++++++++------------------ cmdline/cacheset.h | 104 ++++++++++++++++++++---------- 3 files changed, 244 insertions(+), 118 deletions(-) (limited to 'cmdline/cacheset.cc') diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc index c081ca130..6a7d7a448 100644 --- a/cmdline/apt-get.cc +++ b/cmdline/apt-get.cc @@ -1079,7 +1079,7 @@ bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask = true, name matching it was split out.. */ bool TryToInstall(pkgCache::PkgIterator Pkg,pkgDepCache &Cache, pkgProblemResolver &Fix,bool Remove,bool BrokenFix, - unsigned int &ExpectedInst,bool AllowFail = true) + bool AllowFail = true) { /* This is a pure virtual package and there is a single available candidate providing it. */ @@ -1244,9 +1244,7 @@ bool TryToInstall(pkgCache::PkgIterator Pkg,pkgDepCache &Cache, Pkg.FullName(true).c_str()); } } - else - ExpectedInst++; - + // Install it with autoinstalling enabled (if we not respect the minial // required deps or the policy) if ((State.InstBroken() == true || State.InstPolicyBroken() == true) && BrokenFix == false) @@ -1589,6 +1587,41 @@ bool DoUpgrade(CommandLine &CmdL) return InstallPackages(Cache,true); } /*}}}*/ +// CacheSetHelperAPTGet - responsible for message telling from the CacheSets/*{{{*/ +class CacheSetHelperAPTGet : public APT::CacheSetHelper { + /** \brief stream message should be printed to */ + std::ostream &out; + /** \brief were things like Task or RegEx used to select packages? */ + bool explicitlyNamed; + +public: + CacheSetHelperAPTGet(std::ostream &out) : APT::CacheSetHelper(true), out(out) { + explicitlyNamed = true; + } + + 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"), + 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"), + Pkg.FullName(true).c_str(), pattern.c_str()); + explicitlyNamed = false; + } + virtual void showSelectedVersion(pkgCache::PkgIterator const &Pkg, pkgCache::VerIterator const Ver, + string const &ver, bool const &verIsRel) { + if (ver != Ver.VerStr()) + ioprintf(out, _("Selected version '%s' (%s) for '%s'\n"), + Ver.VerStr(), Ver.RelStr().c_str(), Pkg.FullName(true).c_str()); + } + + inline bool allPkgNamedExplicitly() const { return explicitlyNamed; } + +}; + /*}}}*/ // DoInstall - Install packages from the command line /*{{{*/ // --------------------------------------------------------------------- /* Install named packages */ @@ -1605,7 +1638,6 @@ bool DoInstall(CommandLine &CmdL) BrokenFix = true; unsigned int AutoMarkChanged = 0; - unsigned int ExpectedInst = 0; pkgProblemResolver Fix(Cache); unsigned short fallback = 0; @@ -1621,28 +1653,29 @@ bool DoInstall(CommandLine &CmdL) _config->Set("APT::Get::AutomaticRemove", "true"); fallback = 1; } - // new scope for the ActionGroup - { - // TODO: Howto get an ExpectedInst count ? - pkgDepCache::ActionGroup group(Cache); - std::list mods; - mods.push_back(APT::VersionSet::Modifier(0, "+", + + std::list mods; + mods.push_back(APT::VersionSet::Modifier(0, "+", APT::VersionSet::Modifier::POSTFIX, APT::VersionSet::CANDINST)); - mods.push_back(APT::VersionSet::Modifier(1, "-", + mods.push_back(APT::VersionSet::Modifier(1, "-", APT::VersionSet::Modifier::POSTFIX, APT::VersionSet::INSTCAND)); - std::map verset = APT::VersionSet::GroupedFromCommandLine(Cache, - CmdL.FileList + 1, mods, fallback, c0out); + CacheSetHelperAPTGet helper(c0out); + std::map verset = APT::VersionSet::GroupedFromCommandLine(Cache, + CmdL.FileList + 1, mods, fallback, helper); - if (_error->PendingError() == true) - return false; + if (_error->PendingError() == true) + return false; + // new scope for the ActionGroup + { + pkgDepCache::ActionGroup group(Cache); for (APT::VersionSet::const_iterator Ver = verset[0].begin(); Ver != verset[0].end(); ++Ver) { pkgCache::PkgIterator Pkg = Ver.ParentPkg(); Cache->SetCandidateVersion(Ver); - if (TryToInstall(Pkg, Cache, Fix, false, BrokenFix, ExpectedInst) == false) + if (TryToInstall(Pkg, Cache, Fix, false, BrokenFix) == false) return false; // see if we need to fix the auto-mark flag @@ -1666,7 +1699,7 @@ bool DoInstall(CommandLine &CmdL) { pkgCache::PkgIterator Pkg = Ver.ParentPkg(); - if (TryToInstall(Pkg, Cache, Fix, true, BrokenFix, ExpectedInst) == false) + if (TryToInstall(Pkg, Cache, Fix, true, BrokenFix) == false) return false; } @@ -1719,7 +1752,7 @@ bool DoInstall(CommandLine &CmdL) /* Print out a list of packages that are going to be installed extra to what the user asked */ - if (Cache->InstCount() != ExpectedInst) + if (Cache->InstCount() != verset[0].size()) { string List; string VersionsList; @@ -1845,7 +1878,8 @@ bool DoInstall(CommandLine &CmdL) Cache->writeStateFile(NULL); // See if we need to prompt - if (Cache->InstCount() == ExpectedInst && Cache->DelCount() == 0) + // FIXME: check if really the packages in the set are going to be installed + if (Cache->InstCount() == verset[0].size() && Cache->DelCount() == 0) return InstallPackages(Cache,false,false); return InstallPackages(Cache,false); @@ -2429,7 +2463,6 @@ bool DoBuildDep(CommandLine &CmdL) } // Install the requested packages - unsigned int ExpectedInst = 0; vector ::iterator D; pkgProblemResolver Fix(Cache); bool skipAlternatives = false; // skip remaining alternatives in an or group @@ -2460,7 +2493,7 @@ bool DoBuildDep(CommandLine &CmdL) */ if (IV.end() == false && Cache->VS().CheckDep(IV.VerStr(),(*D).Op,(*D).Version.c_str()) == true) - TryToInstall(Pkg,Cache,Fix,true,false,ExpectedInst); + TryToInstall(Pkg,Cache,Fix,true,false); } else // BuildDep || BuildDepIndep { @@ -2576,7 +2609,7 @@ bool DoBuildDep(CommandLine &CmdL) if (_config->FindB("Debug::BuildDeps",false) == true) cout << " Trying to install " << (*D).Package << endl; - if (TryToInstall(Pkg,Cache,Fix,false,false,ExpectedInst) == true) + if (TryToInstall(Pkg,Cache,Fix,false,false) == true) { // We successfully installed something; skip remaining alternatives skipAlternatives = hasAlternatives; diff --git a/cmdline/cacheset.cc b/cmdline/cacheset.cc index 55ab26780..88a98fdbe 100644 --- a/cmdline/cacheset.cc +++ b/cmdline/cacheset.cc @@ -24,7 +24,7 @@ /*}}}*/ namespace APT { // FromTask - Return all packages in the cache from a specific task /*{{{*/ -PackageSet PackageSet::FromTask(pkgCacheFile &Cache, std::string pattern, std::ostream &out) { +PackageSet PackageSet::FromTask(pkgCacheFile &Cache, std::string pattern, CacheSetHelper &helper) { PackageSet pkgset; if (Cache.BuildCaches() == false || Cache.BuildDepCache() == false) return pkgset; @@ -67,19 +67,22 @@ PackageSet PackageSet::FromTask(pkgCacheFile &Cache, std::string pattern, std::o char buf[length]; strncpy(buf, start, length); buf[length-1] = '\0'; - if (regexec(&Pattern, buf, 0, 0, 0) == 0) - pkgset.insert(Pkg); + if (regexec(&Pattern, buf, 0, 0, 0) != 0) + continue; + + pkgset.insert(Pkg); } + regfree(&Pattern); if (pkgset.empty() == true) - _error->Error(_("Couldn't find task %s"), pattern.c_str()); + return helper.canNotFindTask(Cache, pattern); - regfree(&Pattern); + helper.showTaskSelection(pkgset, pattern); return pkgset; } /*}}}*/ // FromRegEx - Return all packages in the cache matching a pattern /*{{{*/ -PackageSet PackageSet::FromRegEx(pkgCacheFile &Cache, std::string pattern, std::ostream &out) { +PackageSet PackageSet::FromRegEx(pkgCacheFile &Cache, std::string pattern, CacheSetHelper &helper) { PackageSet pkgset; static const char * const isregex = ".?+*|[^$"; @@ -121,14 +124,14 @@ PackageSet PackageSet::FromRegEx(pkgCacheFile &Cache, std::string pattern, std:: continue; } - ioprintf(out, _("Note, selecting %s for regex '%s'\n"), - Pkg.FullName(true).c_str(), pattern.c_str()); - pkgset.insert(Pkg); } - regfree(&Pattern); + if (pkgset.empty() == true) + return helper.canNotFindRegEx(Cache, pattern); + + helper.showRegExSelection(pkgset, pattern); return pkgset; } /*}}}*/ @@ -136,7 +139,7 @@ PackageSet PackageSet::FromRegEx(pkgCacheFile &Cache, std::string pattern, std:: std::map PackageSet::GroupedFromCommandLine( pkgCacheFile &Cache, const char **cmdline, std::list const &mods, - unsigned short const &fallback, std::ostream &out) { + unsigned short const &fallback, CacheSetHelper &helper) { std::map pkgsets; for (const char **I = cmdline; *I != 0; ++I) { unsigned short modID = fallback; @@ -159,24 +162,23 @@ std::map PackageSet::GroupedFromCommandLine( } break; } - PackageSet pset = PackageSet::FromString(Cache, str, out); - pkgsets[modID].insert(pset.begin(), pset.end()); + pkgsets[modID].insert(PackageSet::FromString(Cache, str, helper)); } return pkgsets; } /*}}}*/ // FromCommandLine - Return all packages specified on commandline /*{{{*/ -PackageSet PackageSet::FromCommandLine(pkgCacheFile &Cache, const char **cmdline, std::ostream &out) { +PackageSet PackageSet::FromCommandLine(pkgCacheFile &Cache, const char **cmdline, CacheSetHelper &helper) { PackageSet pkgset; for (const char **I = cmdline; *I != 0; ++I) { - PackageSet pset = FromString(Cache, *I, out); + PackageSet pset = FromString(Cache, *I, helper); pkgset.insert(pset.begin(), pset.end()); } return pkgset; } /*}}}*/ // FromString - Return all packages matching a specific string /*{{{*/ -PackageSet PackageSet::FromString(pkgCacheFile &Cache, std::string const &str, std::ostream &out) { +PackageSet PackageSet::FromString(pkgCacheFile &Cache, std::string const &str, CacheSetHelper &helper) { std::string pkg = str; size_t archfound = pkg.find_last_of(':'); std::string arch; @@ -198,23 +200,22 @@ PackageSet PackageSet::FromString(pkgCacheFile &Cache, std::string const &str, s pkgset.insert(Pkg); return pkgset; } - PackageSet pset = FromTask(Cache, str, out); + PackageSet pset = FromTask(Cache, str, helper); if (pset.empty() == false) return pset; - pset = FromRegEx(Cache, str, out); + pset = FromRegEx(Cache, str, helper); if (pset.empty() == false) return pset; - _error->Warning(_("Unable to locate package %s"), str.c_str()); - return pset; + return helper.canNotFindPackage(Cache, str); } /*}}}*/ // GroupedFromCommandLine - Return all versions specified on commandline/*{{{*/ std::map VersionSet::GroupedFromCommandLine( pkgCacheFile &Cache, const char **cmdline, std::list const &mods, - unsigned short const &fallback, std::ostream &out) { + unsigned short const &fallback, CacheSetHelper &helper) { std::map versets; for (const char **I = cmdline; *I != 0; ++I) { unsigned short modID = fallback; @@ -241,18 +242,17 @@ std::map VersionSet::GroupedFromCommandLine( } break; } - VersionSet vset = VersionSet::FromString(Cache, str, select , out); - versets[modID].insert(vset.begin(), vset.end()); + versets[modID].insert(VersionSet::FromString(Cache, str, select , helper)); } return versets; } /*}}}*/ // FromCommandLine - Return all versions specified on commandline /*{{{*/ APT::VersionSet VersionSet::FromCommandLine(pkgCacheFile &Cache, const char **cmdline, - APT::VersionSet::Version const &fallback, std::ostream &out) { + APT::VersionSet::Version const &fallback, CacheSetHelper &helper) { VersionSet verset; for (const char **I = cmdline; *I != 0; ++I) { - VersionSet vset = VersionSet::FromString(Cache, *I, fallback, out); + VersionSet vset = VersionSet::FromString(Cache, *I, fallback, helper); verset.insert(vset.begin(), vset.end()); } return verset; @@ -260,7 +260,7 @@ APT::VersionSet VersionSet::FromCommandLine(pkgCacheFile &Cache, const char **cm /*}}}*/ // FromString - Returns all versions spedcified by a string /*{{{*/ APT::VersionSet VersionSet::FromString(pkgCacheFile &Cache, std::string pkg, - APT::VersionSet::Version const &fallback, std::ostream &out) { + APT::VersionSet::Version const &fallback, CacheSetHelper &helper) { std::string ver; bool verIsRel = false; size_t const vertag = pkg.find_last_of("/="); @@ -269,19 +269,19 @@ APT::VersionSet VersionSet::FromString(pkgCacheFile &Cache, std::string pkg, verIsRel = (pkg[vertag] == '/'); pkg.erase(vertag); } - PackageSet pkgset = PackageSet::FromString(Cache, pkg.c_str(), out); + PackageSet pkgset = PackageSet::FromString(Cache, pkg.c_str(), helper); VersionSet verset; for (PackageSet::const_iterator P = pkgset.begin(); P != pkgset.end(); ++P) { if (vertag == string::npos) { - AddSelectedVersion(Cache, verset, P, fallback); + AddSelectedVersion(Cache, verset, P, fallback, helper); continue; } pkgCache::VerIterator V; if (ver == "installed") - V = getInstalledVer(Cache, P); + V = getInstalledVer(Cache, P, helper); else if (ver == "candidate") - V = getCandidateVer(Cache, P); + V = getCandidateVer(Cache, P, helper); else { pkgVersionMatch Match(ver, (verIsRel == true ? pkgVersionMatch::Release : pkgVersionMatch::Version)); @@ -298,76 +298,70 @@ APT::VersionSet VersionSet::FromString(pkgCacheFile &Cache, std::string pkg, } if (V.end() == true) continue; - if (ver != V.VerStr()) - ioprintf(out, _("Selected version '%s' (%s) for '%s'\n"), - V.VerStr(), V.RelStr().c_str(), P.FullName(true).c_str()); + helper.showSelectedVersion(P, V, ver, verIsRel); verset.insert(V); } return verset; } /*}}}*/ // AddSelectedVersion - add version from package based on fallback /*{{{*/ -bool VersionSet::AddSelectedVersion(pkgCacheFile &Cache, VersionSet &verset, +void VersionSet::AddSelectedVersion(pkgCacheFile &Cache, VersionSet &verset, pkgCache::PkgIterator const &P, VersionSet::Version const &fallback, - bool const &AllowError) { + CacheSetHelper &helper) { pkgCache::VerIterator V; + bool showErrors; switch(fallback) { case VersionSet::ALL: if (P->VersionList != 0) for (V = P.VersionList(); V.end() != true; ++V) verset.insert(V); - else if (AllowError == false) - return _error->Error(_("Can't select versions from package '%s' as it purely virtual"), P.FullName(true).c_str()); else - return false; + verset.insert(helper.canNotFindAllVer(Cache, P)); break; case VersionSet::CANDANDINST: - verset.insert(getInstalledVer(Cache, P, AllowError)); - verset.insert(getCandidateVer(Cache, P, AllowError)); + verset.insert(getInstalledVer(Cache, P, helper)); + verset.insert(getCandidateVer(Cache, P, helper)); break; case VersionSet::CANDIDATE: - verset.insert(getCandidateVer(Cache, P, AllowError)); + verset.insert(getCandidateVer(Cache, P, helper)); break; case VersionSet::INSTALLED: - verset.insert(getInstalledVer(Cache, P, AllowError)); + verset.insert(getInstalledVer(Cache, P, helper)); break; case VersionSet::CANDINST: - V = getCandidateVer(Cache, P, true); + showErrors = helper.showErrors(false); + V = getCandidateVer(Cache, P, helper); if (V.end() == true) - V = getInstalledVer(Cache, P, true); + V = getInstalledVer(Cache, P, helper); + helper.showErrors(showErrors); if (V.end() == false) verset.insert(V); - else if (AllowError == false) - return _error->Error(_("Can't select installed nor candidate version from package '%s' as it has neither of them"), P.FullName(true).c_str()); else - return false; + verset.insert(helper.canNotFindInstCandVer(Cache, P)); break; case VersionSet::INSTCAND: - V = getInstalledVer(Cache, P, true); + showErrors = helper.showErrors(false); + V = getInstalledVer(Cache, P, helper); if (V.end() == true) - V = getCandidateVer(Cache, P, true); + V = getCandidateVer(Cache, P, helper); + helper.showErrors(showErrors); if (V.end() == false) verset.insert(V); - else if (AllowError == false) - return _error->Error(_("Can't select installed nor candidate version from package '%s' as it has neither of them"), P.FullName(true).c_str()); else - return false; + verset.insert(helper.canNotFindInstCandVer(Cache, P)); break; case VersionSet::NEWEST: if (P->VersionList != 0) verset.insert(P.VersionList()); - else if (AllowError == false) - return _error->Error(_("Can't select newest version from package '%s' as it is purely virtual"), P.FullName(true).c_str()); else - return false; + verset.insert(helper.canNotFindNewestVer(Cache, P)); break; } - return true; } /*}}}*/ // getCandidateVer - Returns the candidate version of the given package /*{{{*/ pkgCache::VerIterator VersionSet::getCandidateVer(pkgCacheFile &Cache, - pkgCache::PkgIterator const &Pkg, bool const &AllowError) { + pkgCache::PkgIterator const &Pkg, CacheSetHelper &helper) { pkgCache::VerIterator Cand; if (Cache.IsDepCacheBuilt() == true) Cand = Cache[Pkg].CandidateVerIter(Cache); @@ -376,17 +370,78 @@ pkgCache::VerIterator VersionSet::getCandidateVer(pkgCacheFile &Cache, return pkgCache::VerIterator(*Cache); Cand = Cache.GetPolicy()->GetCandidateVer(Pkg); } - if (AllowError == false && Cand.end() == true) - _error->Error(_("Can't select candidate version from package %s as it has no candidate"), Pkg.FullName(true).c_str()); + if (Cand.end() == true) + return helper.canNotFindCandidateVer(Cache, Pkg); return Cand; } /*}}}*/ // getInstalledVer - Returns the installed version of the given package /*{{{*/ pkgCache::VerIterator VersionSet::getInstalledVer(pkgCacheFile &Cache, - pkgCache::PkgIterator const &Pkg, bool const &AllowError) { - if (AllowError == false && Pkg->CurrentVer == 0) - _error->Error(_("Can't select installed version from package %s as it is not installed"), Pkg.FullName(true).c_str()); + pkgCache::PkgIterator const &Pkg, CacheSetHelper &helper) { + if (Pkg->CurrentVer == 0) + return helper.canNotFindInstalledVer(Cache, Pkg); return Pkg.CurrentVer(); } /*}}}*/ +// canNotFindTask - handle the case no package is found for a task /*{{{*/ +PackageSet CacheSetHelper::canNotFindTask(pkgCacheFile &Cache, std::string pattern) { + if (ShowError == true) + _error->Error(_("Couldn't find task '%s'"), pattern.c_str()); + return PackageSet(); +} + /*}}}*/ +// canNotFindRegEx - handle the case no package is found by a regex /*{{{*/ +PackageSet CacheSetHelper::canNotFindRegEx(pkgCacheFile &Cache, std::string pattern) { + if (ShowError == true) + _error->Error(_("Couldn't find any package by regex '%s'"), pattern.c_str()); + return PackageSet(); +} + /*}}}*/ +// canNotFindPackage - handle the case no package is found from a string/*{{{*/ +PackageSet CacheSetHelper::canNotFindPackage(pkgCacheFile &Cache, std::string const &str) { + if (ShowError == true) + _error->Error(_("Unable to locate package %s"), str.c_str()); + return PackageSet(); +} + /*}}}*/ +// canNotFindAllVer /*{{{*/ +VersionSet CacheSetHelper::canNotFindAllVer(pkgCacheFile &Cache, + pkgCache::PkgIterator const &Pkg) { + if (ShowError == true) + _error->Error(_("Can't select versions from package '%s' as it purely virtual"), Pkg.FullName(true).c_str()); + return VersionSet(); +} + /*}}}*/ +// canNotFindInstCandVer /*{{{*/ +VersionSet CacheSetHelper::canNotFindInstCandVer(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) { + if (ShowError == true) + _error->Error(_("Can't select newest version from package '%s' as it is purely virtual"), Pkg.FullName(true).c_str()); + return pkgCache::VerIterator(*Cache); +} + /*}}}*/ +// canNotFindCandidateVer /*{{{*/ +pkgCache::VerIterator CacheSetHelper::canNotFindCandidateVer(pkgCacheFile &Cache, + pkgCache::PkgIterator const &Pkg) { + if (ShowError == true) + _error->Error(_("Can't select candidate version from package %s as it has no candidate"), Pkg.FullName(true).c_str()); + return pkgCache::VerIterator(*Cache); +} + /*}}}*/ +// canNotFindInstalledVer /*{{{*/ +pkgCache::VerIterator CacheSetHelper::canNotFindInstalledVer(pkgCacheFile &Cache, + pkgCache::PkgIterator const &Pkg) { + if (ShowError == true) + _error->Error(_("Can't select installed version from package %s as it is not installed"), Pkg.FullName(true).c_str()); + return pkgCache::VerIterator(*Cache); +} + /*}}}*/ } diff --git a/cmdline/cacheset.h b/cmdline/cacheset.h index 64a72e758..9c9491020 100644 --- a/cmdline/cacheset.h +++ b/cmdline/cacheset.h @@ -20,6 +20,45 @@ #include /*}}}*/ namespace APT { +class PackageSet; +class VersionSet; +class CacheSetHelper { /*{{{*/ +/** \class APT::CacheSetHelper + Simple base class with a lot of virtual methods which can be overridden + to alter the behavior or the output of the CacheSets. + + This helper is passed around by the static methods in the CacheSets and + used every time they hit an error condition or something could be + printed out. +*/ +public: /*{{{*/ + CacheSetHelper(bool const &ShowError = true) : ShowError(ShowError) {}; + virtual ~CacheSetHelper() {}; + + virtual void showTaskSelection(PackageSet const &pkgset, string const &pattern) {}; + virtual void showRegExSelection(PackageSet const &pkgset, string const &pattern) {}; + virtual void showSelectedVersion(pkgCache::PkgIterator const &Pkg, pkgCache::VerIterator const Ver, + string const &ver, bool const &verIsRel) {}; + + virtual PackageSet canNotFindTask(pkgCacheFile &Cache, std::string pattern); + virtual PackageSet canNotFindRegEx(pkgCacheFile &Cache, std::string pattern); + virtual PackageSet canNotFindPackage(pkgCacheFile &Cache, std::string const &str); + virtual VersionSet canNotFindAllVer(pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg); + virtual VersionSet canNotFindInstCandVer(pkgCacheFile &Cache, + pkgCache::PkgIterator const &Pkg); + virtual pkgCache::VerIterator canNotFindNewestVer(pkgCacheFile &Cache, + pkgCache::PkgIterator const &Pkg); + virtual pkgCache::VerIterator canNotFindCandidateVer(pkgCacheFile &Cache, + pkgCache::PkgIterator const &Pkg); + virtual pkgCache::VerIterator canNotFindInstalledVer(pkgCacheFile &Cache, + pkgCache::PkgIterator const &Pkg); + + bool showErrors() const { return ShowError; }; + bool showErrors(bool const &newValue) { if (ShowError == newValue) return ShowError; else return ((ShowError = newValue) == false); }; + /*}}}*/ +protected: + bool ShowError; +}; /*}}}*/ class PackageSet : public std::set { /*{{{*/ /** \class APT::PackageSet @@ -66,6 +105,7 @@ public: /*{{{*/ using std::set::insert; inline void insert(pkgCache::PkgIterator const &P) { if (P.end() == false) std::set::insert(P); }; + inline void insert(PackageSet const &pkgset) { insert(pkgset.begin(), pkgset.end()); }; /** \brief returns all packages in the cache who belong to the given task @@ -75,10 +115,10 @@ public: /*{{{*/ \param Cache the packages are in \param pattern name of the task \param out stream to print the notice to */ - static APT::PackageSet FromTask(pkgCacheFile &Cache, std::string pattern, std::ostream &out); + static APT::PackageSet FromTask(pkgCacheFile &Cache, std::string pattern, CacheSetHelper &helper); static APT::PackageSet FromTask(pkgCacheFile &Cache, std::string const &pattern) { - std::ostream out (std::ofstream("/dev/null").rdbuf()); - return APT::PackageSet::FromTask(Cache, pattern, out); + CacheSetHelper helper; + return APT::PackageSet::FromTask(Cache, pattern, helper); } /** \brief returns all packages in the cache whose name matchs a given pattern @@ -89,10 +129,10 @@ public: /*{{{*/ \param Cache the packages are in \param pattern regular expression for package names \param out stream to print the notice to */ - static APT::PackageSet FromRegEx(pkgCacheFile &Cache, std::string pattern, std::ostream &out); + static APT::PackageSet FromRegEx(pkgCacheFile &Cache, std::string pattern, CacheSetHelper &helper); static APT::PackageSet FromRegEx(pkgCacheFile &Cache, std::string const &pattern) { - std::ostream out (std::ofstream("/dev/null").rdbuf()); - return APT::PackageSet::FromRegEx(Cache, pattern, out); + CacheSetHelper helper; + return APT::PackageSet::FromRegEx(Cache, pattern, helper); } /** \brief returns all packages specified by a string @@ -100,10 +140,10 @@ public: /*{{{*/ \param Cache the packages are in \param string String the package name(s) should be extracted from \param out stream to print various notices to */ - static APT::PackageSet FromString(pkgCacheFile &Cache, std::string const &string, std::ostream &out); + static APT::PackageSet FromString(pkgCacheFile &Cache, std::string const &string, CacheSetHelper &helper); static APT::PackageSet FromString(pkgCacheFile &Cache, std::string const &string) { - std::ostream out (std::ofstream("/dev/null").rdbuf()); - return APT::PackageSet::FromString(Cache, string, out); + CacheSetHelper helper; + return APT::PackageSet::FromString(Cache, string, helper); } /** \brief returns all packages specified on the commandline @@ -113,10 +153,10 @@ public: /*{{{*/ \param Cache the packages are in \param cmdline Command line the package names should be extracted from \param out stream to print various notices to */ - static APT::PackageSet FromCommandLine(pkgCacheFile &Cache, const char **cmdline, std::ostream &out); + static APT::PackageSet FromCommandLine(pkgCacheFile &Cache, const char **cmdline, CacheSetHelper &helper); static APT::PackageSet FromCommandLine(pkgCacheFile &Cache, const char **cmdline) { - std::ostream out (std::ofstream("/dev/null").rdbuf()); - return APT::PackageSet::FromCommandLine(Cache, cmdline, out); + CacheSetHelper helper; + return APT::PackageSet::FromCommandLine(Cache, cmdline, helper); } struct Modifier { @@ -130,14 +170,14 @@ public: /*{{{*/ static std::map GroupedFromCommandLine( pkgCacheFile &Cache, const char **cmdline, std::list const &mods, - unsigned short const &fallback, std::ostream &out); + unsigned short const &fallback, CacheSetHelper &helper); static std::map GroupedFromCommandLine( pkgCacheFile &Cache, const char **cmdline, std::list const &mods, unsigned short const &fallback) { - std::ostream out (std::ofstream("/dev/null").rdbuf()); + CacheSetHelper helper; return APT::PackageSet::GroupedFromCommandLine(Cache, cmdline, - mods, fallback, out); + mods, fallback, helper); } /*}}}*/ }; /*}}}*/ @@ -189,6 +229,7 @@ public: /*{{{*/ using std::set::insert; inline void insert(pkgCache::VerIterator const &V) { if (V.end() == false) std::set::insert(V); }; + inline void insert(VersionSet const &verset) { insert(verset.begin(), verset.end()); }; /** \brief specifies which version(s) will be returned if non is given */ enum Version { @@ -216,22 +257,22 @@ public: /*{{{*/ \param cmdline Command line the versions should be extracted from \param out stream to print various notices to */ static APT::VersionSet FromCommandLine(pkgCacheFile &Cache, const char **cmdline, - APT::VersionSet::Version const &fallback, std::ostream &out); + APT::VersionSet::Version const &fallback, CacheSetHelper &helper); static APT::VersionSet FromCommandLine(pkgCacheFile &Cache, const char **cmdline, APT::VersionSet::Version const &fallback) { - std::ostream out (std::ofstream("/dev/null").rdbuf()); - return APT::VersionSet::FromCommandLine(Cache, cmdline, fallback, out); + CacheSetHelper helper; + return APT::VersionSet::FromCommandLine(Cache, cmdline, fallback, helper); } static APT::VersionSet FromCommandLine(pkgCacheFile &Cache, const char **cmdline) { return APT::VersionSet::FromCommandLine(Cache, cmdline, CANDINST); } static APT::VersionSet FromString(pkgCacheFile &Cache, std::string pkg, - APT::VersionSet::Version const &fallback, std::ostream &out); + APT::VersionSet::Version const &fallback, CacheSetHelper &helper); static APT::VersionSet FromString(pkgCacheFile &Cache, std::string pkg, APT::VersionSet::Version const &fallback) { - std::ostream out (std::ofstream("/dev/null").rdbuf()); - return APT::VersionSet::FromString(Cache, pkg, fallback, out); + CacheSetHelper helper; + return APT::VersionSet::FromString(Cache, pkg, fallback, helper); } static APT::VersionSet FromString(pkgCacheFile &Cache, std::string pkg) { return APT::VersionSet::FromString(Cache, pkg, CANDINST); @@ -251,14 +292,14 @@ public: /*{{{*/ static std::map GroupedFromCommandLine( pkgCacheFile &Cache, const char **cmdline, std::list const &mods, - unsigned short const &fallback, std::ostream &out); + unsigned short const &fallback, CacheSetHelper &helper); static std::map GroupedFromCommandLine( pkgCacheFile &Cache, const char **cmdline, std::list const &mods, unsigned short const &fallback) { - std::ostream out (std::ofstream("/dev/null").rdbuf()); + CacheSetHelper helper; return APT::VersionSet::GroupedFromCommandLine(Cache, cmdline, - mods, fallback, out); + mods, fallback, helper); } /*}}}*/ protected: /*{{{*/ @@ -266,23 +307,20 @@ protected: /*{{{*/ /** \brief returns the candidate version of the package \param Cache to be used to query for information - \param Pkg we want the candidate version from this package - \param AllowError add an error to the stack if not */ + \param Pkg we want the candidate version from this package */ static pkgCache::VerIterator getCandidateVer(pkgCacheFile &Cache, - pkgCache::PkgIterator const &Pkg, bool const &AllowError = false); + pkgCache::PkgIterator const &Pkg, CacheSetHelper &helper); /** \brief returns the installed version of the package \param Cache to be used to query for information - \param Pkg we want the installed version from this package - \param AllowError add an error to the stack if not */ + \param Pkg we want the installed version from this package */ static pkgCache::VerIterator getInstalledVer(pkgCacheFile &Cache, - pkgCache::PkgIterator const &Pkg, bool const &AllowError = false); - + pkgCache::PkgIterator const &Pkg, CacheSetHelper &helper); - static bool AddSelectedVersion(pkgCacheFile &Cache, VersionSet &verset, + static void AddSelectedVersion(pkgCacheFile &Cache, VersionSet &verset, pkgCache::PkgIterator const &P, VersionSet::Version const &fallback, - bool const &AllowError = false); + CacheSetHelper &helper); /*}}}*/ }; /*}}}*/ -- cgit v1.2.3-70-g09d2 From 48c39e3246b72802a6f723eef1ce0c30e06be33d Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sat, 26 Jun 2010 21:17:34 +0200 Subject: - only print errors if all tries to get a package by string failed * --- cmdline/cacheset.cc | 18 ++++++++++++------ debian/changelog | 4 +++- 2 files changed, 15 insertions(+), 7 deletions(-) (limited to 'cmdline/cacheset.cc') diff --git a/cmdline/cacheset.cc b/cmdline/cacheset.cc index 88a98fdbe..2b00187d8 100644 --- a/cmdline/cacheset.cc +++ b/cmdline/cacheset.cc @@ -200,15 +200,21 @@ PackageSet PackageSet::FromString(pkgCacheFile &Cache, std::string const &str, C pkgset.insert(Pkg); return pkgset; } + + _error->PushToStack(); + PackageSet pset = FromTask(Cache, str, helper); - if (pset.empty() == false) - return pset; + if (pset.empty() == true) { + pset = FromRegEx(Cache, str, helper); + if (pset.empty() == true) + pset = helper.canNotFindPackage(Cache, str); + } - pset = FromRegEx(Cache, str, helper); if (pset.empty() == false) - return pset; - - return helper.canNotFindPackage(Cache, str); + _error->RevertToStack(); + else + _error->MergeWithStack(); + return pset; } /*}}}*/ // GroupedFromCommandLine - Return all versions specified on commandline/*{{{*/ diff --git a/debian/changelog b/debian/changelog index fbe814d84..32a18cf59 100644 --- a/debian/changelog +++ b/debian/changelog @@ -5,6 +5,7 @@ apt (0.7.26~exp8) UNRELEASED; urgency=low - get the candidate either from an already built depcache or use the policy which is a bit faster than depcache generation - get packages by task^ with FromTask() + - only print errors if all tries to get a package by string failed * cmdline/apt-get.cc: - use the cachsets in the install commands * apt-pkg/orderlist.cc: @@ -29,8 +30,9 @@ apt (0.7.26~exp8) UNRELEASED; urgency=low * apt-pkg/contrib/fileutl.cc: - show notice about ignored file instead of being always silent - add a Dir::Ignore-Files-Silently list option to control the notice + * - -- David Kalnischkies Sat, 26 Jun 2010 20:43:09 +0200 + -- David Kalnischkies Sat, 26 Jun 2010 21:17:08 +0200 apt (0.7.26~exp7) experimental; urgency=low -- cgit v1.2.3-70-g09d2 From bd631595620ca5b3c53ede4ef46c89399c26c5f3 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Mon, 28 Jun 2010 22:13:17 +0200 Subject: - factor out code to get a single package FromName() - check in Grouped* first without modifier interpretation --- cmdline/cacheset.cc | 151 ++++++++++++++++++++++++++++++++++------------------ cmdline/cacheset.h | 15 +++++- debian/changelog | 4 +- 3 files changed, 116 insertions(+), 54 deletions(-) (limited to 'cmdline/cacheset.cc') diff --git a/cmdline/cacheset.cc b/cmdline/cacheset.cc index 2b00187d8..42bc79693 100644 --- a/cmdline/cacheset.cc +++ b/cmdline/cacheset.cc @@ -25,11 +25,7 @@ namespace APT { // FromTask - Return all packages in the cache from a specific task /*{{{*/ PackageSet PackageSet::FromTask(pkgCacheFile &Cache, std::string pattern, CacheSetHelper &helper) { - PackageSet pkgset; - if (Cache.BuildCaches() == false || Cache.BuildDepCache() == false) - return pkgset; - - size_t archfound = pattern.find_last_of(':'); + size_t const archfound = pattern.find_last_of(':'); std::string arch = "native"; if (archfound != std::string::npos) { arch = pattern.substr(archfound+1); @@ -37,9 +33,13 @@ PackageSet PackageSet::FromTask(pkgCacheFile &Cache, std::string pattern, CacheS } if (pattern[pattern.length() -1] != '^') - return pkgset; + return APT::PackageSet(); pattern.erase(pattern.length()-1); + if (unlikely(Cache.GetPkgCache() == 0 || Cache.GetDepCache() == 0)) + return APT::PackageSet(); + + PackageSet pkgset; // get the records pkgRecords Recs(Cache); @@ -83,11 +83,9 @@ PackageSet PackageSet::FromTask(pkgCacheFile &Cache, std::string pattern, CacheS /*}}}*/ // FromRegEx - Return all packages in the cache matching a pattern /*{{{*/ PackageSet PackageSet::FromRegEx(pkgCacheFile &Cache, std::string pattern, CacheSetHelper &helper) { - PackageSet pkgset; static const char * const isregex = ".?+*|[^$"; - if (pattern.find_first_of(isregex) == std::string::npos) - return pkgset; + return PackageSet(); size_t archfound = pattern.find_last_of(':'); std::string arch = "native"; @@ -105,9 +103,13 @@ PackageSet PackageSet::FromRegEx(pkgCacheFile &Cache, std::string pattern, Cache char Error[300]; regerror(Res, &Pattern, Error, sizeof(Error)); _error->Error(_("Regex compilation error - %s"), Error); - return pkgset; + return PackageSet(); } + if (unlikely(Cache.GetPkgCache() == 0)) + return PackageSet(); + + PackageSet pkgset; for (pkgCache::GrpIterator Grp = Cache.GetPkgCache()->GrpBegin(); Grp.end() == false; ++Grp) { if (regexec(&Pattern, Grp.Name(), 0, 0, 0) != 0) @@ -135,6 +137,33 @@ PackageSet PackageSet::FromRegEx(pkgCacheFile &Cache, std::string pattern, Cache return pkgset; } /*}}}*/ +// FromName - Returns the package defined by this string /*{{{*/ +pkgCache::PkgIterator PackageSet::FromName(pkgCacheFile &Cache, + std::string const &str, CacheSetHelper &helper) { + std::string pkg = str; + size_t archfound = pkg.find_last_of(':'); + std::string arch; + if (archfound != std::string::npos) { + arch = pkg.substr(archfound+1); + pkg.erase(archfound); + } + + if (Cache.GetPkgCache() == 0) + return pkgCache::PkgIterator(Cache, 0); + + pkgCache::PkgIterator Pkg(Cache, 0); + if (arch.empty() == true) { + pkgCache::GrpIterator Grp = Cache.GetPkgCache()->FindGrp(pkg); + if (Grp.end() == false) + Pkg = Grp.FindPreferredPkg(); + } else + Pkg = Cache.GetPkgCache()->FindPkg(pkg, arch); + + if (Pkg.end() == true) + return helper.canNotFindPkgName(Cache, str); + return Pkg; +} + /*}}}*/ // GroupedFromCommandLine - Return all versions specified on commandline/*{{{*/ std::map PackageSet::GroupedFromCommandLine( pkgCacheFile &Cache, const char **cmdline, @@ -144,6 +173,7 @@ std::map PackageSet::GroupedFromCommandLine( for (const char **I = cmdline; *I != 0; ++I) { unsigned short modID = fallback; std::string str = *I; + bool modifierPresent = false; for (std::list::const_iterator mod = mods.begin(); mod != mods.end(); ++mod) { size_t const alength = strlen(mod->Alias); @@ -160,8 +190,18 @@ std::map PackageSet::GroupedFromCommandLine( case PackageSet::Modifier::NONE: continue; } + modifierPresent = true; break; } + if (modifierPresent == true) { + bool const errors = helper.showErrors(false); + pkgCache::PkgIterator Pkg = FromName(Cache, *I, helper); + helper.showErrors(errors); + if (Pkg.end() == false) { + pkgsets[fallback].insert(Pkg); + continue; + } + } pkgsets[modID].insert(PackageSet::FromString(Cache, str, helper)); } return pkgsets; @@ -179,42 +219,26 @@ PackageSet PackageSet::FromCommandLine(pkgCacheFile &Cache, const char **cmdline /*}}}*/ // FromString - Return all packages matching a specific string /*{{{*/ PackageSet PackageSet::FromString(pkgCacheFile &Cache, std::string const &str, CacheSetHelper &helper) { - std::string pkg = str; - size_t archfound = pkg.find_last_of(':'); - std::string arch; - if (archfound != std::string::npos) { - arch = pkg.substr(archfound+1); - pkg.erase(archfound); - } - - pkgCache::PkgIterator Pkg; - if (arch.empty() == true) { - pkgCache::GrpIterator Grp = Cache.GetPkgCache()->FindGrp(pkg); - if (Grp.end() == false) - Pkg = Grp.FindPreferredPkg(); - } else - Pkg = Cache.GetPkgCache()->FindPkg(pkg, arch); - - if (Pkg.end() == false) { - PackageSet pkgset; - pkgset.insert(Pkg); - return pkgset; - } - _error->PushToStack(); - PackageSet pset = FromTask(Cache, str, helper); - if (pset.empty() == true) { - pset = FromRegEx(Cache, str, helper); - if (pset.empty() == true) - pset = helper.canNotFindPackage(Cache, str); + PackageSet pkgset; + pkgCache::PkgIterator Pkg = FromName(Cache, str, helper); + if (Pkg.end() == false) + pkgset.insert(Pkg); + else { + pkgset = FromTask(Cache, str, helper); + if (pkgset.empty() == true) { + pkgset = FromRegEx(Cache, str, helper); + if (pkgset.empty() == true) + pkgset = helper.canNotFindPackage(Cache, str); + } } - if (pset.empty() == false) + if (pkgset.empty() == false) _error->RevertToStack(); else _error->MergeWithStack(); - return pset; + return pkgset; } /*}}}*/ // GroupedFromCommandLine - Return all versions specified on commandline/*{{{*/ @@ -227,6 +251,7 @@ std::map VersionSet::GroupedFromCommandLine( unsigned short modID = fallback; VersionSet::Version select = VersionSet::NEWEST; std::string str = *I; + bool modifierPresent = false; for (std::list::const_iterator mod = mods.begin(); mod != mods.end(); ++mod) { if (modID == fallback && mod->ID == fallback) @@ -246,8 +271,19 @@ std::map VersionSet::GroupedFromCommandLine( case VersionSet::Modifier::NONE: continue; } + modifierPresent = true; break; } + + if (modifierPresent == true) { + bool const errors = helper.showErrors(false); + VersionSet const vset = VersionSet::FromString(Cache, std::string(*I), select, helper, true); + helper.showErrors(errors); + if (vset.empty() == false) { + versets[fallback].insert(vset); + continue; + } + } versets[modID].insert(VersionSet::FromString(Cache, str, select , helper)); } return versets; @@ -257,16 +293,15 @@ std::map VersionSet::GroupedFromCommandLine( APT::VersionSet VersionSet::FromCommandLine(pkgCacheFile &Cache, const char **cmdline, APT::VersionSet::Version const &fallback, CacheSetHelper &helper) { VersionSet verset; - for (const char **I = cmdline; *I != 0; ++I) { - VersionSet vset = VersionSet::FromString(Cache, *I, fallback, helper); - verset.insert(vset.begin(), vset.end()); - } + for (const char **I = cmdline; *I != 0; ++I) + verset.insert(VersionSet::FromString(Cache, *I, fallback, helper)); return verset; } /*}}}*/ // FromString - Returns all versions spedcified by a string /*{{{*/ APT::VersionSet VersionSet::FromString(pkgCacheFile &Cache, std::string pkg, - APT::VersionSet::Version const &fallback, CacheSetHelper &helper) { + APT::VersionSet::Version const &fallback, CacheSetHelper &helper, + bool const &onlyFromName) { std::string ver; bool verIsRel = false; size_t const vertag = pkg.find_last_of("/="); @@ -275,7 +310,13 @@ APT::VersionSet VersionSet::FromString(pkgCacheFile &Cache, std::string pkg, verIsRel = (pkg[vertag] == '/'); pkg.erase(vertag); } - PackageSet pkgset = PackageSet::FromString(Cache, pkg.c_str(), helper); + PackageSet pkgset; + if (onlyFromName == false) + pkgset = PackageSet::FromString(Cache, pkg, helper); + else { + pkgset.insert(PackageSet::FromName(Cache, pkg, helper)); + } + VersionSet verset; for (PackageSet::const_iterator P = pkgset.begin(); P != pkgset.end(); ++P) { @@ -372,8 +413,8 @@ pkgCache::VerIterator VersionSet::getCandidateVer(pkgCacheFile &Cache, if (Cache.IsDepCacheBuilt() == true) Cand = Cache[Pkg].CandidateVerIter(Cache); else { - if (unlikely(Cache.BuildPolicy() == false)) - return pkgCache::VerIterator(*Cache); + if (unlikely(Cache.GetPolicy() == 0)) + return pkgCache::VerIterator(Cache); Cand = Cache.GetPolicy()->GetCandidateVer(Pkg); } if (Cand.end() == true) @@ -389,6 +430,14 @@ pkgCache::VerIterator VersionSet::getInstalledVer(pkgCacheFile &Cache, return Pkg.CurrentVer(); } /*}}}*/ +// canNotFindPkgName - handle the case no package has this name /*{{{*/ +pkgCache::PkgIterator CacheSetHelper::canNotFindPkgName(pkgCacheFile &Cache, + std::string const &str) { + if (ShowError == true) + _error->Error(_("Unable to locate package %s"), str.c_str()); + return pkgCache::PkgIterator(Cache, 0); +} + /*}}}*/ // canNotFindTask - handle the case no package is found for a task /*{{{*/ PackageSet CacheSetHelper::canNotFindTask(pkgCacheFile &Cache, std::string pattern) { if (ShowError == true) @@ -405,8 +454,6 @@ PackageSet CacheSetHelper::canNotFindRegEx(pkgCacheFile &Cache, std::string patt /*}}}*/ // canNotFindPackage - handle the case no package is found from a string/*{{{*/ PackageSet CacheSetHelper::canNotFindPackage(pkgCacheFile &Cache, std::string const &str) { - if (ShowError == true) - _error->Error(_("Unable to locate package %s"), str.c_str()); return PackageSet(); } /*}}}*/ @@ -431,7 +478,7 @@ pkgCache::VerIterator CacheSetHelper::canNotFindNewestVer(pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg) { if (ShowError == true) _error->Error(_("Can't select newest version from package '%s' as it is purely virtual"), Pkg.FullName(true).c_str()); - return pkgCache::VerIterator(*Cache); + return pkgCache::VerIterator(Cache); } /*}}}*/ // canNotFindCandidateVer /*{{{*/ @@ -439,7 +486,7 @@ pkgCache::VerIterator CacheSetHelper::canNotFindCandidateVer(pkgCacheFile &Cache pkgCache::PkgIterator const &Pkg) { if (ShowError == true) _error->Error(_("Can't select candidate version from package %s as it has no candidate"), Pkg.FullName(true).c_str()); - return pkgCache::VerIterator(*Cache); + return pkgCache::VerIterator(Cache); } /*}}}*/ // canNotFindInstalledVer /*{{{*/ @@ -447,7 +494,7 @@ pkgCache::VerIterator CacheSetHelper::canNotFindInstalledVer(pkgCacheFile &Cache pkgCache::PkgIterator const &Pkg) { if (ShowError == true) _error->Error(_("Can't select installed version from package %s as it is not installed"), Pkg.FullName(true).c_str()); - return pkgCache::VerIterator(*Cache); + return pkgCache::VerIterator(Cache); } /*}}}*/ } diff --git a/cmdline/cacheset.h b/cmdline/cacheset.h index 9c9491020..21c42c511 100644 --- a/cmdline/cacheset.h +++ b/cmdline/cacheset.h @@ -40,6 +40,7 @@ public: /*{{{*/ virtual void showSelectedVersion(pkgCache::PkgIterator const &Pkg, pkgCache::VerIterator const Ver, string const &ver, bool const &verIsRel) {}; + virtual pkgCache::PkgIterator canNotFindPkgName(pkgCacheFile &Cache, std::string const &str); virtual PackageSet canNotFindTask(pkgCacheFile &Cache, std::string pattern); virtual PackageSet canNotFindRegEx(pkgCacheFile &Cache, std::string pattern); virtual PackageSet canNotFindPackage(pkgCacheFile &Cache, std::string const &str); @@ -146,6 +147,17 @@ public: /*{{{*/ return APT::PackageSet::FromString(Cache, string, helper); } + /** \brief returns a package specified by a string + + \param Cache the package is in + \param string String the package name should be extracted from + \param out stream to print various notices to */ + static pkgCache::PkgIterator FromName(pkgCacheFile &Cache, std::string const &string, CacheSetHelper &helper); + static pkgCache::PkgIterator FromName(pkgCacheFile &Cache, std::string const &string) { + CacheSetHelper helper; + return APT::PackageSet::FromName(Cache, string, helper); + } + /** \brief returns all packages specified on the commandline Get all package names from the commandline and executes regex's if needed. @@ -268,7 +280,8 @@ public: /*{{{*/ } static APT::VersionSet FromString(pkgCacheFile &Cache, std::string pkg, - APT::VersionSet::Version const &fallback, CacheSetHelper &helper); + APT::VersionSet::Version const &fallback, CacheSetHelper &helper, + bool const &onlyFromName = false); static APT::VersionSet FromString(pkgCacheFile &Cache, std::string pkg, APT::VersionSet::Version const &fallback) { CacheSetHelper helper; diff --git a/debian/changelog b/debian/changelog index 32a18cf59..d7c6b8d0c 100644 --- a/debian/changelog +++ b/debian/changelog @@ -6,6 +6,8 @@ apt (0.7.26~exp8) UNRELEASED; urgency=low or use the policy which is a bit faster than depcache generation - get packages by task^ with FromTask() - only print errors if all tries to get a package by string failed + - factor out code to get a single package FromName() + - check in Grouped* first without modifier interpretation * cmdline/apt-get.cc: - use the cachsets in the install commands * apt-pkg/orderlist.cc: @@ -32,7 +34,7 @@ apt (0.7.26~exp8) UNRELEASED; urgency=low - add a Dir::Ignore-Files-Silently list option to control the notice * - -- David Kalnischkies Sat, 26 Jun 2010 21:17:08 +0200 + -- David Kalnischkies Mon, 28 Jun 2010 22:12:24 +0200 apt (0.7.26~exp7) experimental; urgency=low -- cgit v1.2.3-70-g09d2 From fb83c1d078b9f5e2e28a828c325dc62dcf060f2b Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Tue, 29 Jun 2010 19:10:47 +0200 Subject: rename AddSelectedVersion() to a better public FromPackage() --- cmdline/cacheset.cc | 11 ++++++----- cmdline/cacheset.h | 14 +++++++++----- 2 files changed, 15 insertions(+), 10 deletions(-) (limited to 'cmdline/cacheset.cc') diff --git a/cmdline/cacheset.cc b/cmdline/cacheset.cc index 42bc79693..35ef74f9a 100644 --- a/cmdline/cacheset.cc +++ b/cmdline/cacheset.cc @@ -321,7 +321,7 @@ APT::VersionSet VersionSet::FromString(pkgCacheFile &Cache, std::string pkg, for (PackageSet::const_iterator P = pkgset.begin(); P != pkgset.end(); ++P) { if (vertag == string::npos) { - AddSelectedVersion(Cache, verset, P, fallback, helper); + verset.insert(VersionSet::FromPackage(Cache, P, fallback, helper)); continue; } pkgCache::VerIterator V; @@ -351,10 +351,10 @@ APT::VersionSet VersionSet::FromString(pkgCacheFile &Cache, std::string pkg, return verset; } /*}}}*/ -// AddSelectedVersion - add version from package based on fallback /*{{{*/ -void VersionSet::AddSelectedVersion(pkgCacheFile &Cache, VersionSet &verset, - pkgCache::PkgIterator const &P, VersionSet::Version const &fallback, - CacheSetHelper &helper) { +// FromPackage - versions from package based on fallback /*{{{*/ +VersionSet VersionSet::FromPackage(pkgCacheFile &Cache, pkgCache::PkgIterator const &P, + VersionSet::Version const &fallback, CacheSetHelper &helper) { + VersionSet verset; pkgCache::VerIterator V; bool showErrors; switch(fallback) { @@ -404,6 +404,7 @@ void VersionSet::AddSelectedVersion(pkgCacheFile &Cache, VersionSet &verset, verset.insert(helper.canNotFindNewestVer(Cache, P)); break; } + return verset; } /*}}}*/ // getCandidateVer - Returns the candidate version of the given package /*{{{*/ diff --git a/cmdline/cacheset.h b/cmdline/cacheset.h index 21c42c511..bf863fb39 100644 --- a/cmdline/cacheset.h +++ b/cmdline/cacheset.h @@ -291,6 +291,15 @@ public: /*{{{*/ return APT::VersionSet::FromString(Cache, pkg, CANDINST); } + /** \brief returns all versions specified for the package + + \param Cache the package and versions are in + \param P the package in question + \param fallback the version(s) you want to get + \param helper the helper used for display and error handling */ + static VersionSet FromPackage(pkgCacheFile &Cache, pkgCache::PkgIterator const &P, + VersionSet::Version const &fallback, CacheSetHelper &helper); + struct Modifier { enum Position { NONE, PREFIX, POSTFIX }; unsigned short ID; @@ -330,11 +339,6 @@ protected: /*{{{*/ \param Pkg we want the installed version from this package */ static pkgCache::VerIterator getInstalledVer(pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg, CacheSetHelper &helper); - - static void AddSelectedVersion(pkgCacheFile &Cache, VersionSet &verset, - pkgCache::PkgIterator const &P, VersionSet::Version const &fallback, - CacheSetHelper &helper); - /*}}}*/ }; /*}}}*/ } -- cgit v1.2.3-70-g09d2 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(-) (limited to 'cmdline/cacheset.cc') 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-70-g09d2 From c8db3fff877f102dc6fb62c4e4c7f700160b68f5 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Fri, 2 Jul 2010 07:06:53 +0200 Subject: add a ConstructedBy member to the PackageSet which can be used by the e.g. FromString to tell the caller if the string was an exact match or found by regex or task. The two later ones can match packages for which we want to ignore failures in the VersionSet --- cmdline/cacheset.cc | 26 ++++++++++++++++---------- cmdline/cacheset.h | 42 +++++++++++++++++++++++++++++++++++------- 2 files changed, 51 insertions(+), 17 deletions(-) (limited to 'cmdline/cacheset.cc') diff --git a/cmdline/cacheset.cc b/cmdline/cacheset.cc index cc2860a22..4d6d6a87c 100644 --- a/cmdline/cacheset.cc +++ b/cmdline/cacheset.cc @@ -33,13 +33,13 @@ PackageSet PackageSet::FromTask(pkgCacheFile &Cache, std::string pattern, CacheS } if (pattern[pattern.length() -1] != '^') - return APT::PackageSet(); + return APT::PackageSet(TASK); pattern.erase(pattern.length()-1); if (unlikely(Cache.GetPkgCache() == 0 || Cache.GetDepCache() == 0)) - return APT::PackageSet(); + return APT::PackageSet(TASK); - PackageSet pkgset; + PackageSet pkgset(TASK); // get the records pkgRecords Recs(Cache); @@ -85,7 +85,7 @@ PackageSet PackageSet::FromTask(pkgCacheFile &Cache, std::string pattern, CacheS PackageSet PackageSet::FromRegEx(pkgCacheFile &Cache, std::string pattern, CacheSetHelper &helper) { static const char * const isregex = ".?+*|[^$"; if (pattern.find_first_of(isregex) == std::string::npos) - return PackageSet(); + return PackageSet(REGEX); size_t archfound = pattern.find_last_of(':'); std::string arch = "native"; @@ -103,13 +103,13 @@ PackageSet PackageSet::FromRegEx(pkgCacheFile &Cache, std::string pattern, Cache char Error[300]; regerror(Res, &Pattern, Error, sizeof(Error)); _error->Error(_("Regex compilation error - %s"), Error); - return PackageSet(); + return PackageSet(REGEX); } if (unlikely(Cache.GetPkgCache() == 0)) - return PackageSet(); + return PackageSet(REGEX); - PackageSet pkgset; + PackageSet pkgset(REGEX); for (pkgCache::GrpIterator Grp = Cache.GetPkgCache()->GrpBegin(); Grp.end() == false; ++Grp) { if (regexec(&Pattern, Grp.Name(), 0, 0, 0) != 0) @@ -318,8 +318,12 @@ APT::VersionSet VersionSet::FromString(pkgCacheFile &Cache, std::string pkg, } VersionSet verset; + bool errors = true; + if (pkgset.getConstructor() != PackageSet::UNKNOWN) + errors = helper.showErrors(false); for (PackageSet::const_iterator P = pkgset.begin(); P != pkgset.end(); ++P) { + helper.canNotFindCandidateVer(Cache, P); if (vertag == string::npos) { verset.insert(VersionSet::FromPackage(Cache, P, fallback, helper)); continue; @@ -348,6 +352,8 @@ APT::VersionSet VersionSet::FromString(pkgCacheFile &Cache, std::string pkg, helper.showSelectedVersion(P, V, ver, verIsRel); verset.insert(V); } + if (pkgset.getConstructor() != PackageSet::UNKNOWN) + helper.showErrors(errors); return verset; } /*}}}*/ @@ -487,7 +493,7 @@ pkgCache::VerIterator CacheSetHelper::canNotFindNewestVer(pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg) { if (ShowError == true) _error->Error(_("Can't select newest version from package '%s' as it is purely virtual"), Pkg.FullName(true).c_str()); - return pkgCache::VerIterator(Cache); + return pkgCache::VerIterator(Cache, 0); } /*}}}*/ // canNotFindCandidateVer /*{{{*/ @@ -495,7 +501,7 @@ pkgCache::VerIterator CacheSetHelper::canNotFindCandidateVer(pkgCacheFile &Cache pkgCache::PkgIterator const &Pkg) { if (ShowError == true) _error->Error(_("Can't select candidate version from package %s as it has no candidate"), Pkg.FullName(true).c_str()); - return pkgCache::VerIterator(Cache); + return pkgCache::VerIterator(Cache, 0); } /*}}}*/ // canNotFindInstalledVer /*{{{*/ @@ -503,7 +509,7 @@ pkgCache::VerIterator CacheSetHelper::canNotFindInstalledVer(pkgCacheFile &Cache pkgCache::PkgIterator const &Pkg) { if (ShowError == true) _error->Error(_("Can't select installed version from package %s as it is not installed"), Pkg.FullName(true).c_str()); - return pkgCache::VerIterator(Cache); + return pkgCache::VerIterator(Cache, 0); } /*}}}*/ } diff --git a/cmdline/cacheset.h b/cmdline/cacheset.h index 2ca794f28..c8c3dd096 100644 --- a/cmdline/cacheset.h +++ b/cmdline/cacheset.h @@ -117,7 +117,7 @@ public: /*{{{*/ packages chosen cause of the given task. \param Cache the packages are in \param pattern name of the task - \param out stream to print the notice to */ + \param helper responsible for error and message handling */ static APT::PackageSet FromTask(pkgCacheFile &Cache, std::string pattern, CacheSetHelper &helper); static APT::PackageSet FromTask(pkgCacheFile &Cache, std::string const &pattern) { CacheSetHelper helper; @@ -131,7 +131,7 @@ public: /*{{{*/ packages chosen cause of the given package. \param Cache the packages are in \param pattern regular expression for package names - \param out stream to print the notice to */ + \param helper responsible for error and message handling */ static APT::PackageSet FromRegEx(pkgCacheFile &Cache, std::string pattern, CacheSetHelper &helper); static APT::PackageSet FromRegEx(pkgCacheFile &Cache, std::string const &pattern) { CacheSetHelper helper; @@ -142,7 +142,7 @@ public: /*{{{*/ \param Cache the packages are in \param string String the package name(s) should be extracted from - \param out stream to print various notices to */ + \param helper responsible for error and message handling */ static APT::PackageSet FromString(pkgCacheFile &Cache, std::string const &string, CacheSetHelper &helper); static APT::PackageSet FromString(pkgCacheFile &Cache, std::string const &string) { CacheSetHelper helper; @@ -153,7 +153,7 @@ public: /*{{{*/ \param Cache the package is in \param string String the package name should be extracted from - \param out stream to print various notices to */ + \param helper responsible for error and message handling */ static pkgCache::PkgIterator FromName(pkgCacheFile &Cache, std::string const &string, CacheSetHelper &helper); static pkgCache::PkgIterator FromName(pkgCacheFile &Cache, std::string const &string) { CacheSetHelper helper; @@ -166,7 +166,7 @@ public: /*{{{*/ No special package command is supported, just plain names. \param Cache the packages are in \param cmdline Command line the package names should be extracted from - \param out stream to print various notices to */ + \param helper responsible for error and message handling */ static APT::PackageSet FromCommandLine(pkgCacheFile &Cache, const char **cmdline, CacheSetHelper &helper); static APT::PackageSet FromCommandLine(pkgCacheFile &Cache, const char **cmdline) { CacheSetHelper helper; @@ -181,6 +181,17 @@ public: /*{{{*/ Modifier (unsigned short const &id, const char * const alias, Position const &pos) : ID(id), Alias(alias), Pos(pos) {}; }; + /** \brief group packages by a action modifiers + + At some point it is needed to get from the same commandline + different package sets grouped by a modifier. Take + apt-get install apt awesome- + as an example. + \param Cache the packages are in + \param cmdline Command line the package names should be extracted from + \param mods list of modifiers the method should accept + \param fallback the default modifier group for a package + \param helper responsible for error and message handling */ static std::map GroupedFromCommandLine( pkgCacheFile &Cache, const char **cmdline, std::list const &mods, @@ -193,6 +204,15 @@ public: /*{{{*/ return APT::PackageSet::GroupedFromCommandLine(Cache, cmdline, mods, fallback, helper); } + + enum Constructor { UNKNOWN, REGEX, TASK }; + Constructor getConstructor() const { return ConstructedBy; }; + + PackageSet() : ConstructedBy(UNKNOWN) {}; + PackageSet(Constructor const &by) : ConstructedBy(by) {}; + /*}}}*/ +private: /*{{{*/ + Constructor ConstructedBy; /*}}}*/ }; /*}}}*/ class VersionSet : public std::set { /*{{{*/ @@ -269,7 +289,7 @@ public: /*{{{*/ non specifically requested and executes regex's if needed on names. \param Cache the packages and versions are in \param cmdline Command line the versions should be extracted from - \param out stream to print various notices to */ + \param helper responsible for error and message handling */ static APT::VersionSet FromCommandLine(pkgCacheFile &Cache, const char **cmdline, APT::VersionSet::Version const &fallback, CacheSetHelper &helper); static APT::VersionSet FromCommandLine(pkgCacheFile &Cache, const char **cmdline, @@ -299,8 +319,16 @@ public: /*{{{*/ \param P the package in question \param fallback the version(s) you want to get \param helper the helper used for display and error handling */ - static VersionSet FromPackage(pkgCacheFile &Cache, pkgCache::PkgIterator const &P, + static APT::VersionSet FromPackage(pkgCacheFile &Cache, pkgCache::PkgIterator const &P, VersionSet::Version const &fallback, CacheSetHelper &helper); + static APT::VersionSet FromPackage(pkgCacheFile &Cache, pkgCache::PkgIterator const &P, + APT::VersionSet::Version const &fallback) { + CacheSetHelper helper; + return APT::VersionSet::FromPackage(Cache, P, fallback, helper); + } + static APT::VersionSet FromPackage(pkgCacheFile &Cache, pkgCache::PkgIterator const &P) { + return APT::VersionSet::FromPackage(Cache, P, CANDINST); + } struct Modifier { enum Position { NONE, PREFIX, POSTFIX }; -- cgit v1.2.3-70-g09d2 From b8ad551295c70a882b629ee94668e8ea527d1a7d Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sat, 3 Jul 2010 20:09:17 +0200 Subject: Refactor TryToInstall to look a bit saner by splitting the Remove and the Virtual packages part out of the loop. The function still exists unchanged as TryToInstallBuildDep through for the BuildDep installation method --- cmdline/apt-get.cc | 229 ++++++++++++++++++++++++++++++++++++++++------------ cmdline/cacheset.cc | 1 - 2 files changed, 177 insertions(+), 53 deletions(-) (limited to 'cmdline/cacheset.cc') diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc index d3ddcbfe8..d17300943 100644 --- a/cmdline/apt-get.cc +++ b/cmdline/apt-get.cc @@ -1073,11 +1073,11 @@ bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask = true, return true; } /*}}}*/ -// TryToInstall - Try to install a single package /*{{{*/ +// TryToInstallBuildDep - Try to install a single package /*{{{*/ // --------------------------------------------------------------------- /* This used to be inlined in DoInstall, but with the advent of regex package name matching it was split out.. */ -bool TryToInstall(pkgCache::PkgIterator Pkg,pkgDepCache &Cache, +bool TryToInstallBuildDep(pkgCache::PkgIterator Pkg,pkgDepCache &Cache, pkgProblemResolver &Fix,bool Remove,bool BrokenFix, bool AllowFail = true) { @@ -1552,6 +1552,93 @@ bool DoUpgrade(CommandLine &CmdL) return InstallPackages(Cache,true); } /*}}}*/ +// TryToInstall - Mark a package for installation /*{{{*/ +struct TryToInstall { + pkgCacheFile* Cache; + pkgProblemResolver* Fix; + bool FixBroken; + unsigned long AutoMarkChanged; + + TryToInstall(pkgCacheFile &Cache, pkgProblemResolver &PM, bool const &FixBroken) : Cache(&Cache), Fix(&PM), + FixBroken(FixBroken), AutoMarkChanged(0) {}; + + void operator() (pkgCache::VerIterator const &Ver) { + pkgCache::PkgIterator Pkg = Ver.ParentPkg(); + Cache->GetDepCache()->SetCandidateVersion(Ver); + pkgDepCache::StateCache &State = (*Cache)[Pkg]; + + // Handle the no-upgrade case + if (_config->FindB("APT::Get::upgrade",true) == false && Pkg->CurrentVer != 0) + ioprintf(c1out,_("Skipping %s, it is already installed and upgrade is not set.\n"), + Pkg.FullName(true).c_str()); + // Ignore request for install if package would be new + else if (_config->FindB("APT::Get::Only-Upgrade", false) == true && Pkg->CurrentVer == 0) + ioprintf(c1out,_("Skipping %s, it is not installed and only upgrades are requested.\n"), + Pkg.FullName(true).c_str()); + else { + Fix->Clear(Pkg); + Fix->Protect(Pkg); + Cache->GetDepCache()->MarkInstall(Pkg,false); + + if (State.Install() == false) { + if (_config->FindB("APT::Get::ReInstall",false) == true) { + if (Pkg->CurrentVer == 0 || Pkg.CurrentVer().Downloadable() == false) + ioprintf(c1out,_("Reinstallation of %s is not possible, it cannot be downloaded.\n"), + Pkg.FullName(true).c_str()); + else + Cache->GetDepCache()->SetReInstall(Pkg, true); + } else + ioprintf(c1out,_("%s is already the newest version.\n"), + Pkg.FullName(true).c_str()); + } + + // Install it with autoinstalling enabled (if we not respect the minial + // required deps or the policy) + if ((State.InstBroken() == true || State.InstPolicyBroken() == true) && FixBroken == false) + Cache->GetDepCache()->MarkInstall(Pkg,true); + } + + // see if we need to fix the auto-mark flag + // e.g. apt-get install foo + // where foo is marked automatic + if (State.Install() == false && + (State.Flags & pkgCache::Flag::Auto) && + _config->FindB("APT::Get::ReInstall",false) == false && + _config->FindB("APT::Get::Only-Upgrade",false) == false && + _config->FindB("APT::Get::Download-Only",false) == false) + { + ioprintf(c1out,_("%s set to manually installed.\n"), + Pkg.FullName(true).c_str()); + Cache->GetDepCache()->MarkAuto(Pkg,false); + AutoMarkChanged++; + } + } +}; + /*}}}*/ +// TryToRemove - Mark a package for removal /*{{{*/ +struct TryToRemove { + pkgCacheFile* Cache; + pkgProblemResolver* Fix; + bool FixBroken; + unsigned long AutoMarkChanged; + + TryToRemove(pkgCacheFile &Cache, pkgProblemResolver &PM) : Cache(&Cache), Fix(&PM) {}; + + void operator() (pkgCache::VerIterator const &Ver) + { + pkgCache::PkgIterator Pkg = Ver.ParentPkg(); + + Fix->Clear(Pkg); + Fix->Protect(Pkg); + Fix->Remove(Pkg); + + if (Pkg->CurrentVer == 0) + ioprintf(c1out,_("Package %s is not installed, so not removed\n"),Pkg.FullName(true).c_str()); + else + Cache->GetDepCache()->MarkDelete(Pkg,_config->FindB("APT::Get::Purge",false)); + } +}; + /*}}}*/ // CacheSetHelperAPTGet - responsible for message telling from the CacheSets/*{{{*/ class CacheSetHelperAPTGet : public APT::CacheSetHelper { /** \brief stream message should be printed to */ @@ -1559,6 +1646,8 @@ class CacheSetHelperAPTGet : public APT::CacheSetHelper { /** \brief were things like Task or RegEx used to select packages? */ bool explicitlyNamed; + APT::PackageSet virtualPkgs; + public: CacheSetHelperAPTGet(std::ostream &out) : APT::CacheSetHelper(true), out(out) { explicitlyNamed = true; @@ -1583,23 +1672,85 @@ 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); + void showVirtualPackageErrors(pkgCacheFile &Cache) { + for (APT::PackageSet::const_iterator Pkg = virtualPkgs.begin(); + Pkg != virtualPkgs.end(); ++Pkg) { + if (Pkg->ProvidesList != 0) { + ioprintf(c1out,_("Package %s is a virtual package provided by:\n"), + Pkg.FullName(true).c_str()); + + pkgCache::PrvIterator I = Pkg.ProvidesList(); + unsigned short provider = 0; + for (; I.end() == false; ++I) { + pkgCache::PkgIterator Pkg = I.OwnerPkg(); + + if (Cache[Pkg].CandidateVerIter(Cache) == I.OwnerVer()) { + out << " " << Pkg.FullName(true) << " " << I.OwnerVer().VerStr(); + if (Cache[Pkg].Install() == true && Cache[Pkg].NewInstall() == false) + out << _(" [Installed]"); + out << endl; + ++provider; + } + } + // if we found no candidate which provide this package, show non-candidates + if (provider == 0) + for (I = Pkg.ProvidesList(); I.end() == false; I++) + out << " " << I.OwnerPkg().FullName(true) << " " << I.OwnerVer().VerStr() + << _(" [Not candidate version]") << endl; + else + out << _("You should explicitly select one to install.") << endl; + } else { + ioprintf(out, + _("Package %s is not available, but is referred to by another package.\n" + "This may mean that the package is missing, has been obsoleted, or\n" + "is only available from another source\n"),Pkg.FullName(true).c_str()); + + string List; + string VersionsList; + SPtrArray Seen = new bool[Cache.GetPkgCache()->Head().PackageCount]; + memset(Seen,0,Cache.GetPkgCache()->Head().PackageCount*sizeof(*Seen)); + for (pkgCache::DepIterator Dep = Pkg.RevDependsList(); + Dep.end() == false; Dep++) { + if (Dep->Type != pkgCache::Dep::Replaces) + continue; + if (Seen[Dep.ParentPkg()->ID] == true) + continue; + Seen[Dep.ParentPkg()->ID] = true; + List += Dep.ParentPkg().FullName(true) + " "; + //VersionsList += string(Dep.ParentPkg().CurVersion) + "\n"; ??? + } + ShowList(out,_("However the following packages replace it:"),List,VersionsList); + } + out << std::endl; + } } - virtual APT::VersionSet canNotFindInstCandVer(pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg) { - return tryVirtualPackage(Cache, Pkg, APT::VersionSet::INSTCAND); + virtual pkgCache::VerIterator canNotFindCandidateVer(pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg) { + APT::VersionSet const verset = tryVirtualPackage(Cache, Pkg, APT::VersionSet::CANDIDATE); + if (verset.empty() == false) + return *(verset.begin()); + if (ShowError == true) { + _error->Error(_("Package '%s' has no installation candidate"),Pkg.FullName(true).c_str()); + virtualPkgs.insert(Pkg); + } + return pkgCache::VerIterator(Cache, 0); + } + + virtual pkgCache::VerIterator canNotFindNewestVer(pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg) { + APT::VersionSet const verset = tryVirtualPackage(Cache, Pkg, APT::VersionSet::NEWEST); + if (verset.empty() == false) + return *(verset.begin()); + if (ShowError == true) + ioprintf(out, _("Virtual packages like '%s' can't be removed\n"), Pkg.FullName(true).c_str()); + return pkgCache::VerIterator(Cache, 0); } 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); - } + if (unlikely(Cache[Pkg].CandidateVer != 0) || Pkg->ProvidesList == 0) + return APT::VersionSet(); pkgCache::PkgIterator Prov; bool found_one = false; @@ -1625,9 +1776,7 @@ public: 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); + return APT::VersionSet(); } inline bool allPkgNamedExplicitly() const { return explicitlyNamed; } @@ -1649,7 +1798,6 @@ bool DoInstall(CommandLine &CmdL) if (Cache->BrokenCount() != 0) BrokenFix = true; - unsigned int AutoMarkChanged = 0; pkgProblemResolver Fix(Cache); static const unsigned short MOD_REMOVE = 1; @@ -1671,15 +1819,18 @@ bool DoInstall(CommandLine &CmdL) std::list mods; mods.push_back(APT::VersionSet::Modifier(MOD_INSTALL, "+", - APT::VersionSet::Modifier::POSTFIX, APT::VersionSet::CANDINST)); + APT::VersionSet::Modifier::POSTFIX, APT::VersionSet::CANDIDATE)); mods.push_back(APT::VersionSet::Modifier(MOD_REMOVE, "-", - APT::VersionSet::Modifier::POSTFIX, APT::VersionSet::INSTCAND)); + APT::VersionSet::Modifier::POSTFIX, APT::VersionSet::NEWEST)); CacheSetHelperAPTGet helper(c0out); std::map verset = APT::VersionSet::GroupedFromCommandLine(Cache, CmdL.FileList + 1, mods, fallback, helper); if (_error->PendingError() == true) + { + helper.showVirtualPackageErrors(Cache); return false; + } unsigned short order[] = { 0, 0, 0 }; if (fallback == MOD_INSTALL) { @@ -1690,45 +1841,19 @@ bool DoInstall(CommandLine &CmdL) order[1] = MOD_INSTALL; } + TryToInstall InstallAction(Cache, Fix, BrokenFix); + TryToRemove RemoveAction(Cache, Fix); + // new scope for the ActionGroup { pkgDepCache::ActionGroup group(Cache); + for (unsigned short i = 0; order[i] != 0; ++i) { if (order[i] == MOD_INSTALL) - for (APT::VersionSet::const_iterator Ver = verset[MOD_INSTALL].begin(); - Ver != verset[MOD_INSTALL].end(); ++Ver) - { - pkgCache::PkgIterator Pkg = Ver.ParentPkg(); - Cache->SetCandidateVersion(Ver); - - if (TryToInstall(Pkg, Cache, Fix, false, BrokenFix) == false) - return false; - - // see if we need to fix the auto-mark flag - // e.g. apt-get install foo - // where foo is marked automatic - if (Cache[Pkg].Install() == false && - (Cache[Pkg].Flags & pkgCache::Flag::Auto) && - _config->FindB("APT::Get::ReInstall",false) == false && - _config->FindB("APT::Get::Only-Upgrade",false) == false && - _config->FindB("APT::Get::Download-Only",false) == false) - { - ioprintf(c1out,_("%s set to manually installed.\n"), - Pkg.FullName(true).c_str()); - Cache->MarkAuto(Pkg,false); - AutoMarkChanged++; - } - } + InstallAction = std::for_each(verset[MOD_INSTALL].begin(), verset[MOD_INSTALL].end(), InstallAction); else if (order[i] == MOD_REMOVE) - for (APT::VersionSet::const_iterator Ver = verset[MOD_REMOVE].begin(); - Ver != verset[MOD_REMOVE].end(); ++Ver) - { - pkgCache::PkgIterator Pkg = Ver.ParentPkg(); - - if (TryToInstall(Pkg, Cache, Fix, true, BrokenFix) == false) - return false; - } + RemoveAction = std::for_each(verset[MOD_REMOVE].begin(), verset[MOD_REMOVE].end(), RemoveAction); } if (_error->PendingError() == true) @@ -1899,7 +2024,7 @@ bool DoInstall(CommandLine &CmdL) // if nothing changed in the cache, but only the automark information // we write the StateFile here, otherwise it will be written in // cache.commit() - if (AutoMarkChanged > 0 && + if (InstallAction.AutoMarkChanged > 0 && Cache->DelCount() == 0 && Cache->InstCount() == 0 && Cache->BadCount() == 0 && _config->FindB("APT::Get::Simulate",false) == false) @@ -2521,7 +2646,7 @@ bool DoBuildDep(CommandLine &CmdL) */ if (IV.end() == false && Cache->VS().CheckDep(IV.VerStr(),(*D).Op,(*D).Version.c_str()) == true) - TryToInstall(Pkg,Cache,Fix,true,false); + TryToInstallBuildDep(Pkg,Cache,Fix,true,false); } else // BuildDep || BuildDepIndep { @@ -2637,7 +2762,7 @@ bool DoBuildDep(CommandLine &CmdL) if (_config->FindB("Debug::BuildDeps",false) == true) cout << " Trying to install " << (*D).Package << endl; - if (TryToInstall(Pkg,Cache,Fix,false,false) == true) + if (TryToInstallBuildDep(Pkg,Cache,Fix,false,false) == true) { // We successfully installed something; skip remaining alternatives skipAlternatives = hasAlternatives; diff --git a/cmdline/cacheset.cc b/cmdline/cacheset.cc index 4d6d6a87c..b96b60450 100644 --- a/cmdline/cacheset.cc +++ b/cmdline/cacheset.cc @@ -323,7 +323,6 @@ APT::VersionSet VersionSet::FromString(pkgCacheFile &Cache, std::string pkg, errors = helper.showErrors(false); for (PackageSet::const_iterator P = pkgset.begin(); P != pkgset.end(); ++P) { - helper.canNotFindCandidateVer(Cache, P); if (vertag == string::npos) { verset.insert(VersionSet::FromPackage(Cache, P, fallback, helper)); continue; -- cgit v1.2.3-70-g09d2 From 2fbfb111312257fa5fc29b0c2ed386fb712f960e Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sun, 4 Jul 2010 00:32:52 +0200 Subject: prefer the Policy if it is built instead of the DepCache and if DepCache is not available as fallback built the Policy --- cmdline/apt-get.cc | 3 +++ cmdline/cacheset.cc | 7 ++++--- 2 files changed, 7 insertions(+), 3 deletions(-) (limited to 'cmdline/cacheset.cc') diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc index 38b93e7e5..9a6c12ee0 100644 --- a/cmdline/apt-get.cc +++ b/cmdline/apt-get.cc @@ -768,6 +768,9 @@ struct TryToInstall { void operator() (pkgCache::VerIterator const &Ver) { pkgCache::PkgIterator Pkg = Ver.ParentPkg(); + +std::clog << "INSTALL " << Pkg << " VER " << Ver.VerStr() << std::endl; + Cache->GetDepCache()->SetCandidateVersion(Ver); pkgDepCache::StateCache &State = (*Cache)[Pkg]; diff --git a/cmdline/cacheset.cc b/cmdline/cacheset.cc index b96b60450..78c9d3f6c 100644 --- a/cmdline/cacheset.cc +++ b/cmdline/cacheset.cc @@ -416,12 +416,13 @@ VersionSet VersionSet::FromPackage(pkgCacheFile &Cache, pkgCache::PkgIterator co pkgCache::VerIterator VersionSet::getCandidateVer(pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg, CacheSetHelper &helper) { pkgCache::VerIterator Cand; - if (Cache.IsDepCacheBuilt() == true) - Cand = Cache[Pkg].CandidateVerIter(Cache); - else { + if (Cache.IsPolicyBuilt() == true || Cache.IsDepCacheBuilt() == false) + { if (unlikely(Cache.GetPolicy() == 0)) return pkgCache::VerIterator(Cache); Cand = Cache.GetPolicy()->GetCandidateVer(Pkg); + } else { + Cand = Cache[Pkg].CandidateVerIter(Cache); } if (Cand.end() == true) return helper.canNotFindCandidateVer(Cache, Pkg); -- cgit v1.2.3-70-g09d2