From 313678129b6f8ad37216db0b4e7679059ab37e56 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sat, 19 Jun 2010 14:16:40 +0200 Subject: * cmdline/apt-get.cc: - use the cachsets in the install commands --- cmdline/apt-get.cc | 249 ++++++++++------------------------------------------- 1 file changed, 47 insertions(+), 202 deletions(-) (limited to 'cmdline/apt-get.cc') diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc index 0ada46c73..c081ca130 100644 --- a/cmdline/apt-get.cc +++ b/cmdline/apt-get.cc @@ -40,12 +40,12 @@ #include #include #include -#include #include #include #include "acqprogress.h" +#include "cacheset.h" #include #include @@ -1252,41 +1252,6 @@ bool TryToInstall(pkgCache::PkgIterator Pkg,pkgDepCache &Cache, if ((State.InstBroken() == true || State.InstPolicyBroken() == true) && BrokenFix == false) Cache.MarkInstall(Pkg,true); - return true; -} - /*}}}*/ -// TryToChangeVer - Try to change a candidate version /*{{{*/ -// --------------------------------------------------------------------- -/* */ -bool TryToChangeVer(pkgCache::PkgIterator Pkg,pkgDepCache &Cache, - const char *VerTag,bool IsRel) -{ - pkgVersionMatch Match(VerTag,(IsRel == true?pkgVersionMatch::Release : - pkgVersionMatch::Version)); - - pkgCache::VerIterator Ver = Match.Find(Pkg); - - if (Ver.end() == true) - { - if (IsRel == true) - return _error->Error(_("Release '%s' for '%s' was not found"), - VerTag,Pkg.FullName(true).c_str()); - return _error->Error(_("Version '%s' for '%s' was not found"), - VerTag,Pkg.FullName(true).c_str()); - } - - if (strcmp(VerTag,Ver.VerStr()) != 0) - { - ioprintf(c1out,_("Selected version %s (%s) for %s\n"), - Ver.VerStr(),Ver.RelStr().c_str(),Pkg.FullName(true).c_str()); - } - - Cache.SetCandidateVersion(Ver); - - // Set the all package to the same candidate - if (Ver.Pseudo() == true) - Cache.SetCandidateVersion(Match.Find(Pkg.Group().FindPkg("all"))); - return true; } /*}}}*/ @@ -1624,61 +1589,6 @@ bool DoUpgrade(CommandLine &CmdL) return InstallPackages(Cache,true); } /*}}}*/ -// DoInstallTask - Install task from the command line /*{{{*/ -// --------------------------------------------------------------------- -/* Install named task */ -bool TryInstallTask(pkgDepCache &Cache, pkgProblemResolver &Fix, - bool BrokenFix, - unsigned int& ExpectedInst, - const char *taskname, - bool Remove) -{ - const char *start, *end; - pkgCache::PkgIterator Pkg; - char buf[64*1024]; - regex_t Pattern; - - // get the records - pkgRecords Recs(Cache); - - // build regexp for the task - char S[300]; - snprintf(S, sizeof(S), "^Task:.*[, ]%s([, ]|$)", taskname); - if(regcomp(&Pattern,S, REG_EXTENDED | REG_NOSUB | REG_NEWLINE) != 0) - return _error->Error("Failed to compile task regexp"); - - bool found = false; - bool res = true; - - // two runs, first ignore dependencies, second install any missing - for(int IgnoreBroken=1; IgnoreBroken >= 0; IgnoreBroken--) - { - for (Pkg = Cache.PkgBegin(); Pkg.end() == false; Pkg++) - { - pkgCache::VerIterator ver = Cache[Pkg].CandidateVerIter(Cache); - if(ver.end()) - continue; - pkgRecords::Parser &parser = Recs.Lookup(ver.FileList()); - parser.GetRec(start,end); - strncpy(buf, start, end-start); - buf[end-start] = 0x0; - if (regexec(&Pattern,buf,0,0,0) != 0) - continue; - res &= TryToInstall(Pkg,Cache,Fix,Remove,IgnoreBroken,ExpectedInst); - found = true; - } - } - - // now let the problem resolver deal with any issues - Fix.Resolve(true); - - if(!found) - _error->Error(_("Couldn't find task %s"),taskname); - - regfree(&Pattern); - return res; -} - /*}}}*/ // DoInstall - Install packages from the command line /*{{{*/ // --------------------------------------------------------------------- /* Install named packages */ @@ -1696,138 +1606,73 @@ bool DoInstall(CommandLine &CmdL) unsigned int AutoMarkChanged = 0; unsigned int ExpectedInst = 0; - unsigned int Packages = 0; pkgProblemResolver Fix(Cache); - - bool DefRemove = false; + + unsigned short fallback = 0; if (strcasecmp(CmdL.FileList[0],"remove") == 0) - DefRemove = true; + fallback = 1; else if (strcasecmp(CmdL.FileList[0], "purge") == 0) { _config->Set("APT::Get::Purge", true); - DefRemove = true; + fallback = 1; } else if (strcasecmp(CmdL.FileList[0], "autoremove") == 0) { _config->Set("APT::Get::AutomaticRemove", "true"); - DefRemove = true; + fallback = 1; } // new scope for the ActionGroup { + // TODO: Howto get an ExpectedInst count ? pkgDepCache::ActionGroup group(Cache); - for (const char **I = CmdL.FileList + 1; *I != 0; I++) - { - // Duplicate the string - unsigned int Length = strlen(*I); - char S[300]; - if (Length >= sizeof(S)) - continue; - strcpy(S,*I); - - // See if we are removing and special indicators.. - bool Remove = DefRemove; - char *VerTag = 0; - bool VerIsRel = false; + std::list mods; + mods.push_back(APT::VersionSet::Modifier(0, "+", + APT::VersionSet::Modifier::POSTFIX, APT::VersionSet::CANDINST)); + 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); - // this is a task! - if (Length >= 1 && S[Length - 1] == '^') - { - S[--Length] = 0; - // tasks must always be confirmed - ExpectedInst += 1000; - // see if we can install it - TryInstallTask(Cache, Fix, BrokenFix, ExpectedInst, S, Remove); - continue; - } + if (_error->PendingError() == true) + return false; - while (Cache->FindPkg(S).end() == true) + 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) + 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) { - // Handle an optional end tag indicating what to do - if (Length >= 1 && S[Length - 1] == '-') - { - Remove = true; - S[--Length] = 0; - continue; - } - - if (Length >= 1 && S[Length - 1] == '+') - { - Remove = false; - S[--Length] = 0; - continue; - } - - char *Slash = strchr(S,'='); - if (Slash != 0) - { - VerIsRel = false; - *Slash = 0; - VerTag = Slash + 1; - } - - Slash = strchr(S,'/'); - if (Slash != 0) - { - VerIsRel = true; - *Slash = 0; - VerTag = Slash + 1; - } - - break; + ioprintf(c1out,_("%s set to manually installed.\n"), + Pkg.FullName(true).c_str()); + Cache->MarkAuto(Pkg,false); + AutoMarkChanged++; } - - // Locate the package - pkgCache::PkgIterator Pkg = Cache->FindPkg(S); - Packages++; - if (Pkg.end() == true) - { - APT::PackageSet pkgset = APT::PackageSet::FromRegEx(Cache, S, c1out); - if (pkgset.empty() == true) - return _error->Error(_("Couldn't find package %s"),S); - - // Regexs must always be confirmed - ExpectedInst += 1000; - - bool Hit = false; - for (APT::PackageSet::const_iterator Pkg = pkgset.begin(); Pkg != pkgset.end(); ++Pkg) - { - if (VerTag != 0) - if (TryToChangeVer(Pkg,Cache,VerTag,VerIsRel) == false) - return false; + } - Hit |= TryToInstall(Pkg,Cache,Fix,Remove,BrokenFix, - ExpectedInst,false); - } + for (APT::VersionSet::const_iterator Ver = verset[1].begin(); + Ver != verset[1].end(); ++Ver) + { + pkgCache::PkgIterator Pkg = Ver.ParentPkg(); - if (Hit == false) - return _error->Error(_("Couldn't find package %s"),S); - } - else - { - if (VerTag != 0) - if (TryToChangeVer(Pkg,Cache,VerTag,VerIsRel) == false) - return false; - if (TryToInstall(Pkg,Cache,Fix,Remove,BrokenFix,ExpectedInst) == 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(!Remove && - 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++; - } - } + if (TryToInstall(Pkg, Cache, Fix, true, BrokenFix, ExpectedInst) == false) + return false; } + if (_error->PendingError() == true) + return false; + /* If we are in the Broken fixing mode we do not attempt to fix the problems. This is if the user invoked install without -f and gave packages */ -- 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/apt-get.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 65beb5720f82845bf175e0cd80f070da21838827 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Fri, 25 Jun 2010 20:11:11 +0200 Subject: print all messages if the application is in an interactive run --- cmdline/apt-cache.cc | 12 +++++------- cmdline/apt-cdrom.cc | 12 +++++------- cmdline/apt-get.cc | 12 +++++------- 3 files changed, 15 insertions(+), 21 deletions(-) (limited to 'cmdline/apt-get.cc') diff --git a/cmdline/apt-cache.cc b/cmdline/apt-cache.cc index 2332a0f13..a4ec63eed 100644 --- a/cmdline/apt-cache.cc +++ b/cmdline/apt-cache.cc @@ -1876,13 +1876,11 @@ int main(int argc,const char *argv[]) /*{{{*/ CmdL.DispatchArg(CmdsB); // Print any errors or warnings found during parsing - if (_error->empty() == false) - { - bool Errors = _error->PendingError(); + bool const Errors = _error->PendingError(); + if (_config->FindI("quiet",0) > 0) _error->DumpErrors(); - return Errors == true?100:0; - } - - return 0; + else + _error->DumpErrors(GlobalError::DEBUG); + return Errors == true ? 100 : 0; } /*}}}*/ diff --git a/cmdline/apt-cdrom.cc b/cmdline/apt-cdrom.cc index 8b9eacae6..da2ffa390 100644 --- a/cmdline/apt-cdrom.cc +++ b/cmdline/apt-cdrom.cc @@ -273,13 +273,11 @@ int main(int argc,const char *argv[]) /*{{{*/ CmdL.DispatchArg(Cmds); // Print any errors or warnings found during parsing - if (_error->empty() == false) - { - bool Errors = _error->PendingError(); + bool const Errors = _error->PendingError(); + if (_config->FindI("quiet",0) > 0) _error->DumpErrors(); - return Errors == true?100:0; - } - - return 0; + else + _error->DumpErrors(GlobalError::DEBUG); + return Errors == true ? 100 : 0; } /*}}}*/ diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc index 6a7d7a448..605eedb0f 100644 --- a/cmdline/apt-get.cc +++ b/cmdline/apt-get.cc @@ -2920,13 +2920,11 @@ int main(int argc,const char *argv[]) /*{{{*/ CmdL.DispatchArg(Cmds); // Print any errors or warnings found during parsing - if (_error->empty() == false) - { - bool Errors = _error->PendingError(); + bool const Errors = _error->PendingError(); + if (_config->FindI("quiet",0) > 0) _error->DumpErrors(); - return Errors == true?100:0; - } - - return 0; + else + _error->DumpErrors(GlobalError::DEBUG); + return Errors == true ? 100 : 0; } /*}}}*/ -- cgit v1.2.3-70-g09d2 From c340d1851242e691e7e0baad18a662d6c7a62bc8 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sat, 26 Jun 2010 19:04:20 +0200 Subject: do not override the user set quiet setting even if the target is not a tty --- cmdline/apt-cache.cc | 2 +- cmdline/apt-cdrom.cc | 2 +- cmdline/apt-get.cc | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'cmdline/apt-get.cc') diff --git a/cmdline/apt-cache.cc b/cmdline/apt-cache.cc index a4ec63eed..a5b3141d7 100644 --- a/cmdline/apt-cache.cc +++ b/cmdline/apt-cache.cc @@ -1868,7 +1868,7 @@ int main(int argc,const char *argv[]) /*{{{*/ } // Deal with stdout not being a tty - if (isatty(STDOUT_FILENO) && _config->FindI("quiet",0) < 1) + if (!isatty(STDOUT_FILENO) && _config->FindI("quiet", -1) == -1) _config->Set("quiet","1"); // if (_config->FindB("APT::Cache::Generate",true) == false) diff --git a/cmdline/apt-cdrom.cc b/cmdline/apt-cdrom.cc index da2ffa390..d1268edf9 100644 --- a/cmdline/apt-cdrom.cc +++ b/cmdline/apt-cdrom.cc @@ -266,7 +266,7 @@ int main(int argc,const char *argv[]) /*{{{*/ return ShowHelp(); // Deal with stdout not being a tty - if (isatty(STDOUT_FILENO) && _config->FindI("quiet",0) < 1) + if (isatty(STDOUT_FILENO) && _config->FindI("quiet", -1) == -1) _config->Set("quiet","1"); // Match the operation diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc index 605eedb0f..e3477b6db 100644 --- a/cmdline/apt-get.cc +++ b/cmdline/apt-get.cc @@ -2899,7 +2899,7 @@ int main(int argc,const char *argv[]) /*{{{*/ } // Deal with stdout not being a tty - if (!isatty(STDOUT_FILENO) && _config->FindI("quiet",0) < 1) + if (!isatty(STDOUT_FILENO) && _config->FindI("quiet", -1) == -1) _config->Set("quiet","1"); // Setup the output streams -- cgit v1.2.3-70-g09d2 From e67c08344dbb9ecd827658d74121fa9b66b28961 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Tue, 29 Jun 2010 17:14:45 +0200 Subject: for install, do all installs first and then the removes and vice versa --- cmdline/apt-get.cc | 92 ++++++++++++++++++++++++++++++++---------------------- 1 file changed, 54 insertions(+), 38 deletions(-) (limited to 'cmdline/apt-get.cc') diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc index e3477b6db..7ba0e8e5c 100644 --- a/cmdline/apt-get.cc +++ b/cmdline/apt-get.cc @@ -1640,24 +1640,27 @@ bool DoInstall(CommandLine &CmdL) unsigned int AutoMarkChanged = 0; pkgProblemResolver Fix(Cache); - unsigned short fallback = 0; + static const unsigned short MOD_REMOVE = 1; + static const unsigned short MOD_INSTALL = 2; + + unsigned short fallback = MOD_INSTALL; if (strcasecmp(CmdL.FileList[0],"remove") == 0) - fallback = 1; + fallback = MOD_REMOVE; else if (strcasecmp(CmdL.FileList[0], "purge") == 0) { _config->Set("APT::Get::Purge", true); - fallback = 1; + fallback = MOD_REMOVE; } else if (strcasecmp(CmdL.FileList[0], "autoremove") == 0) { _config->Set("APT::Get::AutomaticRemove", "true"); - fallback = 1; + fallback = MOD_REMOVE; } std::list mods; - mods.push_back(APT::VersionSet::Modifier(0, "+", + mods.push_back(APT::VersionSet::Modifier(MOD_INSTALL, "+", APT::VersionSet::Modifier::POSTFIX, APT::VersionSet::CANDINST)); - mods.push_back(APT::VersionSet::Modifier(1, "-", + mods.push_back(APT::VersionSet::Modifier(MOD_REMOVE, "-", APT::VersionSet::Modifier::POSTFIX, APT::VersionSet::INSTCAND)); CacheSetHelperAPTGet helper(c0out); std::map verset = APT::VersionSet::GroupedFromCommandLine(Cache, @@ -1666,41 +1669,54 @@ bool DoInstall(CommandLine &CmdL) if (_error->PendingError() == true) return false; + unsigned short order[] = { 0, 0, 0 }; + if (fallback == MOD_INSTALL) { + order[0] = MOD_INSTALL; + order[1] = MOD_REMOVE; + } else { + order[0] = MOD_REMOVE; + order[1] = MOD_INSTALL; + } + // 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) == 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++; - } - } - - for (APT::VersionSet::const_iterator Ver = verset[1].begin(); - Ver != verset[1].end(); ++Ver) + for (unsigned short i = 0; order[i] != 0; ++i) { - pkgCache::PkgIterator Pkg = Ver.ParentPkg(); + 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++; + } + } + 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; + if (TryToInstall(Pkg, Cache, Fix, true, BrokenFix) == false) + return false; + } } if (_error->PendingError() == true) @@ -1752,7 +1768,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() != verset[0].size()) + if (Cache->InstCount() != verset[MOD_INSTALL].size()) { string List; string VersionsList; @@ -1879,7 +1895,7 @@ bool DoInstall(CommandLine &CmdL) // See if we need to prompt // FIXME: check if really the packages in the set are going to be installed - if (Cache->InstCount() == verset[0].size() && Cache->DelCount() == 0) + if (Cache->InstCount() == verset[MOD_INSTALL].size() && Cache->DelCount() == 0) return InstallPackages(Cache,false,false); return InstallPackages(Cache,false); -- 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/apt-get.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 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/apt-get.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 21d4c9f192b5af9c8edb39356712aac853881348 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sat, 3 Jul 2010 23:55:12 +0200 Subject: reorder classes a bit and make TryToInstallBuildDep use them --- cmdline/apt-get.cc | 610 ++++++++++++++++++++++------------------------------- 1 file changed, 250 insertions(+), 360 deletions(-) (limited to 'cmdline/apt-get.cc') diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc index d17300943..38b93e7e5 100644 --- a/cmdline/apt-get.cc +++ b/cmdline/apt-get.cc @@ -609,6 +609,240 @@ void Stats(ostream &out,pkgDepCache &Dep) Dep.BadCount()); } /*}}}*/ +// 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; + + APT::PackageSet virtualPkgs; + +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()); + } + + bool showVirtualPackageErrors(pkgCacheFile &Cache) { + if (virtualPkgs.empty() == true) + return true; + 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; + } + return false; + } + + 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) + return APT::VersionSet(); + + 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); + } + return APT::VersionSet(); + } + + inline bool allPkgNamedExplicitly() const { return explicitlyNamed; } + +}; + /*}}}*/ +// 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)); + } +}; + /*}}}*/ // CacheFile::NameComp - QSort compare by name /*{{{*/ // --------------------------------------------------------------------- /* */ @@ -1077,143 +1311,30 @@ bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask = true, // --------------------------------------------------------------------- /* This used to be inlined in DoInstall, but with the advent of regex package name matching it was split out.. */ -bool TryToInstallBuildDep(pkgCache::PkgIterator Pkg,pkgDepCache &Cache, +bool TryToInstallBuildDep(pkgCache::PkgIterator Pkg,pkgCacheFile &Cache, pkgProblemResolver &Fix,bool Remove,bool BrokenFix, bool AllowFail = true) { - - // Handle the no-upgrade case - if (_config->FindB("APT::Get::upgrade",true) == false && - Pkg->CurrentVer != 0) - { - if (AllowFail == true) - ioprintf(c1out,_("Skipping %s, it is already installed and upgrade is not set.\n"), - Pkg.FullName(true).c_str()); - return true; - } - - // Ignore request for install if package would be new - if (_config->FindB("APT::Get::Only-Upgrade", false) == true && - Pkg->CurrentVer == 0) - { - if (AllowFail == true) - ioprintf(c1out,_("Skipping %s, it is not installed and only upgrades are requested.\n"), - Pkg.Name()); - return true; - } - - // Check if there is something at all to install - pkgDepCache::StateCache &State = Cache[Pkg]; - if (Remove == true && Pkg->CurrentVer == 0) - { - Fix.Clear(Pkg); - Fix.Protect(Pkg); - Fix.Remove(Pkg); - - /* We want to continue searching for regex hits, so we return false here - otherwise this is not really an error. */ - if (AllowFail == false) - return false; - - ioprintf(c1out,_("Package %s is not installed, so not removed\n"),Pkg.FullName(true).c_str()); - return true; - } - - if (State.CandidateVer == 0 && Remove == false) + if (Cache[Pkg].CandidateVer == 0 && Pkg->ProvidesList != 0) { - if (AllowFail == false) - return false; - - 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()) - { - c1out << " " << Pkg.FullName(true) << " " << I.OwnerVer().VerStr(); - if (Cache[Pkg].Install() == true && Cache[Pkg].NewInstall() == false) - c1out << _(" [Installed]"); - c1out << 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++) - c1out << " " << I.OwnerPkg().FullName(true) << " " << I.OwnerVer().VerStr() - << _(" [Not candidate version]") << endl; - else - c1out << _("You should explicitly select one to install.") << endl; - } - else - { - ioprintf(c1out, - _("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.Head().PackageCount]; - memset(Seen,0,Cache.Head().PackageCount*sizeof(*Seen)); - pkgCache::DepIterator Dep = Pkg.RevDependsList(); - for (; 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(c1out,_("However the following packages replace it:"),List,VersionsList); - } - - _error->Error(_("Package %s has no installation candidate"),Pkg.FullName(true).c_str()); - return false; + CacheSetHelperAPTGet helper(c1out); + helper.showErrors(AllowFail == false); + pkgCache::VerIterator Ver = helper.canNotFindNewestVer(Cache, Pkg); + if (Ver.end() == false) + Pkg = Ver.ParentPkg(); + else if (helper.showVirtualPackageErrors(Cache) == false) + return AllowFail; } - Fix.Clear(Pkg); - Fix.Protect(Pkg); if (Remove == true) { - Fix.Remove(Pkg); - Cache.MarkDelete(Pkg,_config->FindB("APT::Get::Purge",false)); - return true; - } - - // Install it - Cache.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.SetReInstall(Pkg,true); - } - else - { - if (AllowFail == true) - 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) && BrokenFix == false) - Cache.MarkInstall(Pkg,true); + TryToRemove RemoveAction(Cache, Fix); + RemoveAction(Pkg.VersionList()); + } else if (Cache[Pkg].CandidateVer != 0) { + TryToInstall InstallAction(Cache, Fix, BrokenFix); + InstallAction(Cache[Pkg].CandidateVerIter(Cache)); + } else + return AllowFail; return true; } @@ -1552,237 +1673,6 @@ 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 */ - std::ostream &out; - /** \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; - } - - 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()); - } - - 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 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) - return APT::VersionSet(); - - 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); - } - return APT::VersionSet(); - } - - inline bool allPkgNamedExplicitly() const { return explicitlyNamed; } - -}; - /*}}}*/ // DoInstall - Install packages from the command line /*{{{*/ // --------------------------------------------------------------------- /* Install named packages */ -- 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/apt-get.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 From 6806db8ac030ab7401b7b8b8324c62bb7b4a0275 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Mon, 5 Jul 2010 11:34:35 +0200 Subject: make the specify order of packages irrelevant (half-close #196021) --- cmdline/apt-get.cc | 23 ++++++++++++++++++----- debian/changelog | 1 + 2 files changed, 19 insertions(+), 5 deletions(-) (limited to 'cmdline/apt-get.cc') diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc index 9a6c12ee0..7cf760c27 100644 --- a/cmdline/apt-get.cc +++ b/cmdline/apt-get.cc @@ -762,6 +762,7 @@ struct TryToInstall { pkgProblemResolver* Fix; bool FixBroken; unsigned long AutoMarkChanged; + APT::PackageSet doAutoInstallLater; TryToInstall(pkgCacheFile &Cache, pkgProblemResolver &PM, bool const &FixBroken) : Cache(&Cache), Fix(&PM), FixBroken(FixBroken), AutoMarkChanged(0) {}; @@ -769,8 +770,6 @@ 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]; @@ -801,8 +800,8 @@ std::clog << "INSTALL " << Pkg << " VER " << Ver.VerStr() << std::endl; // 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); + if (FixBroken == false) + doAutoInstallLater.insert(Pkg); } // see if we need to fix the auto-mark flag @@ -820,6 +819,17 @@ std::clog << "INSTALL " << Pkg << " VER " << Ver.VerStr() << std::endl; AutoMarkChanged++; } } + + void doAutoInstall() { + for (APT::PackageSet::const_iterator P = doAutoInstallLater.begin(); + P != doAutoInstallLater.end(); ++P) { + pkgDepCache::StateCache &State = (*Cache)[P]; + if (State.InstBroken() == false && State.InstPolicyBroken() == false) + continue; + Cache->GetDepCache()->MarkInstall(P, true); + } + doAutoInstallLater.clear(); + } }; /*}}}*/ // TryToRemove - Mark a package for removal /*{{{*/ @@ -1336,6 +1346,7 @@ bool TryToInstallBuildDep(pkgCache::PkgIterator Pkg,pkgCacheFile &Cache, } else if (Cache[Pkg].CandidateVer != 0) { TryToInstall InstallAction(Cache, Fix, BrokenFix); InstallAction(Cache[Pkg].CandidateVerIter(Cache)); + InstallAction.doAutoInstall(); } else return AllowFail; @@ -1743,8 +1754,10 @@ bool DoInstall(CommandLine &CmdL) for (unsigned short i = 0; order[i] != 0; ++i) { - if (order[i] == MOD_INSTALL) + if (order[i] == MOD_INSTALL) { InstallAction = std::for_each(verset[MOD_INSTALL].begin(), verset[MOD_INSTALL].end(), InstallAction); + InstallAction.doAutoInstall(); + } else if (order[i] == MOD_REMOVE) RemoveAction = std::for_each(verset[MOD_REMOVE].begin(), verset[MOD_REMOVE].end(), RemoveAction); } diff --git a/debian/changelog b/debian/changelog index 0b1ca3cf1..a76bd0f0d 100644 --- a/debian/changelog +++ b/debian/changelog @@ -10,6 +10,7 @@ apt (0.7.26~exp8) UNRELEASED; urgency=low - check in Grouped* first without modifier interpretation * cmdline/apt-get.cc: - use the cachsets in the install commands + - make the specify order of packages irrelevant (half-close #196021) * apt-pkg/orderlist.cc: - untouched packages are never missing * apt-pkg/packagemanager.cc: -- cgit v1.2.3-70-g09d2