From 9112f77703c39d46e2e0471c48c8a5e1f93f4abf Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Mon, 13 Jul 2015 03:36:59 +0200 Subject: show or-groups in not-installed recommends and suggests lists Further abstracting our new ShowList allows to use it for containers of strings as well giving us the option to implement an or-groups display for the recommends and suggests lists which is a nice trick given that it also helps with migrating the last remaining other cases of old ShowList. --- apt-private/private-cachefile.h | 14 ++--- apt-private/private-download.cc | 13 ++-- apt-private/private-download.h | 3 +- apt-private/private-install.cc | 135 ++++++++++++++++++++-------------------- apt-private/private-output.cc | 60 ------------------ apt-private/private-output.h | 24 ++++--- 6 files changed, 95 insertions(+), 154 deletions(-) (limited to 'apt-private') diff --git a/apt-private/private-cachefile.h b/apt-private/private-cachefile.h index 4a68d9733..221852629 100644 --- a/apt-private/private-cachefile.h +++ b/apt-private/private-cachefile.h @@ -61,7 +61,7 @@ class APT_PUBLIC CacheFile : public pkgCacheFile }; /*}}}*/ -class APT_PUBLIC SortedPackageUniverse : public APT::PackageUniverse +class SortedPackageUniverse : public APT::PackageUniverse { std::vector &List; void LazyInit() const; @@ -85,12 +85,12 @@ public: }; typedef const_iterator iterator; - APT_PUBLIC const_iterator begin() const { LazyInit(); return const_iterator(data(), List.begin()); } - APT_PUBLIC const_iterator end() const { LazyInit(); return const_iterator(data(), List.end()); } - APT_PUBLIC const_iterator cbegin() const { LazyInit(); return const_iterator(data(), List.begin()); } - APT_PUBLIC const_iterator cend() const { LazyInit(); return const_iterator(data(), List.end()); } - APT_PUBLIC iterator begin() { LazyInit(); return iterator(data(), List.begin()); } - APT_PUBLIC iterator end() { LazyInit(); return iterator(data(), List.end()); } + const_iterator begin() const { LazyInit(); return const_iterator(data(), List.begin()); } + const_iterator end() const { LazyInit(); return const_iterator(data(), List.end()); } + const_iterator cbegin() const { LazyInit(); return const_iterator(data(), List.begin()); } + const_iterator cend() const { LazyInit(); return const_iterator(data(), List.end()); } + iterator begin() { LazyInit(); return iterator(data(), List.begin()); } + iterator end() { LazyInit(); return iterator(data(), List.end()); } }; #endif diff --git a/apt-private/private-download.cc b/apt-private/private-download.cc index 37fae18e9..099146187 100644 --- a/apt-private/private-download.cc +++ b/apt-private/private-download.cc @@ -78,20 +78,23 @@ bool CheckDropPrivsMustBeDisabled(pkgAcquire &Fetcher) /*{{{*/ // CheckAuth - check if each download comes form a trusted source /*{{{*/ bool CheckAuth(pkgAcquire& Fetcher, bool const PromptUser) { - std::string UntrustedList; + std::vector UntrustedList; for (pkgAcquire::ItemIterator I = Fetcher.ItemsBegin(); I < Fetcher.ItemsEnd(); ++I) if (!(*I)->IsTrusted()) - UntrustedList += std::string((*I)->ShortDesc()) + " "; + UntrustedList.push_back((*I)->ShortDesc()); - if (UntrustedList == "") + if (UntrustedList.empty()) return true; return AuthPrompt(UntrustedList, PromptUser); } -bool AuthPrompt(std::string const &UntrustedList, bool const PromptUser) +bool AuthPrompt(std::vector const &UntrustedList, bool const PromptUser) { - ShowList(c2out,_("WARNING: The following packages cannot be authenticated!"),UntrustedList,""); + ShowList(c2out,_("WARNING: The following packages cannot be authenticated!"), UntrustedList, + [](std::string const&) { return true; }, + [](std::string const&str) { return str; }, + [](std::string const&) { return ""; }); if (_config->FindB("APT::Get::AllowUnauthenticated",false) == true) { diff --git a/apt-private/private-download.h b/apt-private/private-download.h index 0a0ac6b95..0f3db5e7a 100644 --- a/apt-private/private-download.h +++ b/apt-private/private-download.h @@ -4,6 +4,7 @@ #include #include +#include class pkgAcquire; @@ -14,7 +15,7 @@ APT_PUBLIC bool CheckAuth(pkgAcquire& Fetcher, bool const PromptUser); // show a authentication warning prompt and return true if the system // should continue -APT_PUBLIC bool AuthPrompt(std::string const &UntrustedList, bool const PromptUser); +APT_PUBLIC bool AuthPrompt(std::vector const &UntrustedList, bool const PromptUser); APT_PUBLIC bool AcquireRun(pkgAcquire &Fetcher, int const PulseInterval, bool * const Failure, bool * const TransientNetworkFailure); diff --git a/apt-private/private-install.cc b/apt-private/private-install.cc index cdca45755..0b5e33ae5 100644 --- a/apt-private/private-install.cc +++ b/apt-private/private-install.cc @@ -330,19 +330,17 @@ bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask, bool Safety) } std::set const disappearedPkgs = PM->GetDisappearedPackages(); - if (disappearedPkgs.empty() == true) - return true; - - std::string disappear; - for (std::set::const_iterator d = disappearedPkgs.begin(); - d != disappearedPkgs.end(); ++d) - disappear.append(*d).append(" "); - - ShowList(c1out, P_("The following package disappeared from your system as\n" - "all files have been overwritten by other packages:", - "The following packages disappeared from your system as\n" - "all files have been overwritten by other packages:", disappearedPkgs.size()), disappear, ""); - c0out << _("Note: This is done automatically and on purpose by dpkg.") << std::endl; + if (disappearedPkgs.empty() == false) + { + ShowList(c1out, P_("The following package disappeared from your system as\n" + "all files have been overwritten by other packages:", + "The following packages disappeared from your system as\n" + "all files have been overwritten by other packages:", disappearedPkgs.size()), disappearedPkgs, + [](std::string const &Pkg) { return Pkg.empty() == false; }, + [](std::string const &Pkg) { return Pkg; }, + [](std::string const &) { return std::string(); }); + c0out << _("Note: This is done automatically and on purpose by dpkg.") << std::endl; + } return true; } @@ -699,8 +697,7 @@ bool DoInstall(CommandLine &CmdL) /* Print out a list of suggested and recommended packages */ { - std::string SuggestsList, RecommendsList; - std::string SuggestsVersions, RecommendsVersions; + std::list Recommends, Suggests, SingleRecommends, SingleSuggests; for (auto const &Pkg: Universe) { /* Just look at the ones we want to install */ @@ -714,77 +711,79 @@ bool DoInstall(CommandLine &CmdL) pkgCache::DepIterator Start; pkgCache::DepIterator End; D.GlobOr(Start,End); // advances D + if (Start->Type != pkgCache::Dep::Recommends && Start->Type != pkgCache::Dep::Suggests) + continue; - // FIXME: we really should display a or-group as a or-group to the user - // the problem is that ShowList is incapable of doing this - std::string RecommendsOrList,RecommendsOrVersions; - std::string SuggestsOrList,SuggestsOrVersions; - bool foundInstalledInOrGroup = false; - for(;;) { - /* Skip if package is installed already, or is about to be */ - pkgCache::PkgIterator const TarPkg = Start.TargetPkg(); - if (TarPkg->SelectedState == pkgCache::State::Install || - TarPkg->SelectedState == pkgCache::State::Hold || - Cache[Start.TargetPkg()].Install()) - { - foundInstalledInOrGroup=true; - break; - } - - /* Skip if we already saw it */ - std::string target = Start.TargetPkg().FullName(true) + " "; - if (int(SuggestsList.find(target)) != -1 || int(RecommendsList.find(target)) != -1) + // Skip if we already saw this + std::string target; + for (pkgCache::DepIterator I = Start; I != D; ++I) { - foundInstalledInOrGroup=true; - break; + if (target.empty() == false) + target.append(" | "); + target.append(I.TargetPkg().FullName(true)); } + std::list &Type = Start->Type == pkgCache::Dep::Recommends ? SingleRecommends : SingleSuggests; + if (std::find(Type.begin(), Type.end(), target) != Type.end()) + continue; + Type.push_back(target); + } - // this is a dep on a virtual pkg, check if any package that provides it - // should be installed - if(Start.TargetPkg().ProvidesList() != 0) + std::list OrList; + bool foundInstalledInOrGroup = false; + for (pkgCache::DepIterator I = Start; I != D; ++I) + { { - pkgCache::PrvIterator I = Start.TargetPkg().ProvidesList(); - for (; I.end() == false; ++I) + // satisfying package is installed and not marked for deletion + APT::VersionList installed = APT::VersionList::FromDependency(Cache, I, APT::CacheSetHelper::INSTALLED); + if (std::find_if(installed.begin(), installed.end(), + [&Cache](pkgCache::VerIterator const &Ver) { return Cache[Ver.ParentPkg()].Delete() == false; }) != installed.end()) { - pkgCache::PkgIterator Pkg = I.OwnerPkg(); - if (Cache[Pkg].CandidateVerIter(Cache) == I.OwnerVer() && - Pkg.CurrentVer() != 0) - foundInstalledInOrGroup=true; + foundInstalledInOrGroup = true; + break; } } - if (Start->Type == pkgCache::Dep::Suggests) - { - SuggestsOrList += target; - SuggestsOrVersions += std::string(Cache[Start.TargetPkg()].CandVersion) + "\n"; - } - - if (Start->Type == pkgCache::Dep::Recommends) { - RecommendsOrList += target; - RecommendsOrVersions += std::string(Cache[Start.TargetPkg()].CandVersion) + "\n"; + // satisfying package is upgraded to/new install + APT::VersionList upgrades = APT::VersionList::FromDependency(Cache, I, APT::CacheSetHelper::CANDIDATE); + if (std::find_if(upgrades.begin(), upgrades.end(), + [&Cache](pkgCache::VerIterator const &Ver) { return Cache[Ver.ParentPkg()].Upgrade(); }) != upgrades.end()) + { + foundInstalledInOrGroup = true; + break; + } } - if (Start >= End) - break; - ++Start; + if (OrList.empty()) + OrList.push_back(I.TargetPkg().FullName(true)); + else + OrList.push_back("| " + I.TargetPkg().FullName(true)); } - + if(foundInstalledInOrGroup == false) { - RecommendsList += RecommendsOrList; - RecommendsVersions += RecommendsOrVersions; - SuggestsList += SuggestsOrList; - SuggestsVersions += SuggestsOrVersions; + std::list &Type = Start->Type == pkgCache::Dep::Recommends ? Recommends : Suggests; + std::move(OrList.begin(), OrList.end(), std::back_inserter(Type)); } - } } - - ShowList(c1out,_("Suggested packages:"),SuggestsList,SuggestsVersions); - ShowList(c1out,_("Recommended packages:"),RecommendsList,RecommendsVersions); - + auto always_true = [](std::string const&) { return true; }; + auto string_ident = [](std::string const&str) { return str; }; + auto verbose_show_candidate = + [&Cache](std::string str) + { + if (APT::String::Startswith(str, "| ")) + str.erase(0, 2); + pkgCache::PkgIterator const Pkg = Cache->FindPkg(str); + if (Pkg.end() == true) + return ""; + return (*Cache)[Pkg].CandVersion; + }; + ShowList(c1out,_("Suggested packages:"), Suggests, + always_true, string_ident, verbose_show_candidate); + ShowList(c1out,_("Recommended packages:"), Recommends, + always_true, string_ident, verbose_show_candidate); } // See if we need to prompt @@ -792,7 +791,7 @@ bool DoInstall(CommandLine &CmdL) if (Cache->InstCount() == verset[MOD_INSTALL].size() && Cache->DelCount() == 0) return InstallPackages(Cache,false,false); - return InstallPackages(Cache,false); + return InstallPackages(Cache,false); } /*}}}*/ diff --git a/apt-private/private-output.cc b/apt-private/private-output.cc index b77efff86..b8e6dec02 100644 --- a/apt-private/private-output.cc +++ b/apt-private/private-output.cc @@ -300,66 +300,6 @@ void ListSingleVersion(pkgCacheFile &CacheFile, pkgRecords &records, /*{{{*/ out << output; } /*}}}*/ -// ShowList - Show a list /*{{{*/ -// --------------------------------------------------------------------- -/* This prints out a string of space separated words with a title and - a two space indent line wraped to the current screen width. */ -bool ShowList(ostream &out,string Title,string List,string VersionsList) -{ - if (List.empty() == true) - return true; - // trim trailing space - int NonSpace = List.find_last_not_of(' '); - if (NonSpace != -1) - { - List = List.erase(NonSpace + 1); - if (List.empty() == true) - return true; - } - - // Acount for the leading space - int ScreenWidth = ::ScreenWidth - 3; - - out << Title << endl; - string::size_type Start = 0; - string::size_type VersionsStart = 0; - while (Start < List.size()) - { - if(_config->FindB("APT::Get::Show-Versions",false) == true && - VersionsList.size() > 0) { - string::size_type End; - string::size_type VersionsEnd; - - End = List.find(' ',Start); - VersionsEnd = VersionsList.find('\n', VersionsStart); - - out << " " << string(List,Start,End - Start) << " (" << - string(VersionsList,VersionsStart,VersionsEnd - VersionsStart) << - ")" << endl; - - if (End == string::npos || End < Start) - End = Start + ScreenWidth; - - Start = End + 1; - VersionsStart = VersionsEnd + 1; - } else { - string::size_type End; - - if (Start + ScreenWidth >= List.size()) - End = List.size(); - else - End = List.rfind(' ',Start+ScreenWidth); - - if (End == string::npos || End < Start) - End = Start + ScreenWidth; - out << " " << string(List,Start,End - Start) << endl; - Start = End + 1; - } - } - - return false; -} - /*}}}*/ // ShowBroken - Debugging aide /*{{{*/ // --------------------------------------------------------------------- /* This prints out the names of all the packages that are broken along diff --git a/apt-private/private-output.h b/apt-private/private-output.h index b9151b245..4930fd981 100644 --- a/apt-private/private-output.h +++ b/apt-private/private-output.h @@ -34,11 +34,11 @@ void ListSingleVersion(pkgCacheFile &CacheFile, pkgRecords &records, APT_PUBLIC void ShowBroken(std::ostream &out, CacheFile &Cache, bool const Now); APT_PUBLIC void ShowBroken(std::ostream &out, pkgCacheFile &Cache, bool const Now); -template APT_PUBLIC bool ShowList(std::ostream &out, std::string const &Title, +template APT_PUBLIC bool ShowList(std::ostream &out, std::string const &Title, Container const &cont, - std::function Predicate, - std::function PkgDisplay, - std::function VerboseDisplay) + PredicateC Predicate, + DisplayP PkgDisplay, + DisplayV VerboseDisplay) { size_t const ScreenWidth = (::ScreenWidth > 3) ? ::ScreenWidth - 3 : 0; int ScreenUsed = 0; @@ -88,8 +88,6 @@ template APT_PUBLIC bool ShowList(std::ostream &out, std::strin } return true; } -APT_DEPRECATED APT_PUBLIC bool ShowList(std::ostream &out, std::string Title, std::string List, - std::string VersionsList); void ShowNew(std::ostream &out,CacheFile &Cache); void ShowDel(std::ostream &out,CacheFile &Cache); @@ -106,12 +104,12 @@ void Stats(std::ostream &out, pkgDepCache &Dep); bool YnPrompt(bool Default=true); bool AnalPrompt(const char *Text); -APT_PUBLIC std::string PrettyFullName(pkgCache::PkgIterator const &Pkg); -APT_PUBLIC std::string CandidateVersion(pkgCacheFile * const Cache, pkgCache::PkgIterator const &Pkg); -APT_PUBLIC std::function CandidateVersion(pkgCacheFile * const Cache); -APT_PUBLIC std::string CurrentToCandidateVersion(pkgCacheFile * const Cache, pkgCache::PkgIterator const &Pkg); -APT_PUBLIC std::function CurrentToCandidateVersion(pkgCacheFile * const Cache); -APT_PUBLIC std::string EmptyString(pkgCache::PkgIterator const &); -APT_PUBLIC bool AlwaysTrue(pkgCache::PkgIterator const &); +std::string PrettyFullName(pkgCache::PkgIterator const &Pkg); +std::string CandidateVersion(pkgCacheFile * const Cache, pkgCache::PkgIterator const &Pkg); +std::function CandidateVersion(pkgCacheFile * const Cache); +std::string CurrentToCandidateVersion(pkgCacheFile * const Cache, pkgCache::PkgIterator const &Pkg); +std::function CurrentToCandidateVersion(pkgCacheFile * const Cache); +std::string EmptyString(pkgCache::PkgIterator const &); +bool AlwaysTrue(pkgCache::PkgIterator const &); #endif -- cgit v1.2.3