summaryrefslogtreecommitdiff
path: root/apt-private/private-install.cc
diff options
context:
space:
mode:
authorDavid Kalnischkies <david@kalnischkies.de>2015-07-13 03:36:59 +0200
committerDavid Kalnischkies <david@kalnischkies.de>2015-08-10 17:27:18 +0200
commit9112f77703c39d46e2e0471c48c8a5e1f93f4abf (patch)
tree63d990155a5e3e3f77daeabcc36529394e08fc9b /apt-private/private-install.cc
parent6cfadda161ce19e6c8076d0aa118f8f436805a6a (diff)
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.
Diffstat (limited to 'apt-private/private-install.cc')
-rw-r--r--apt-private/private-install.cc135
1 files changed, 67 insertions, 68 deletions
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<std::string> const disappearedPkgs = PM->GetDisappearedPackages();
- if (disappearedPkgs.empty() == true)
- return true;
-
- std::string disappear;
- for (std::set<std::string>::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<std::string> 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<std::string> &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<std::string> 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<std::string> &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);
}
/*}}}*/