#include <apt-pkg/packagemanager.h>
#include <apt-pkg/pkgcache.h>
#include <apt-pkg/cacheiterators.h>
+#include <apt-pkg/prettyprinters.h>
+#include <apt-pkg/dpkgpm.h>
#include <string.h>
#include <string>
#include <cstdlib>
#include <iostream>
+#include <utility>
#include <apti18n.h>
/*}}}*/
using namespace std;
+class APT_HIDDEN pkgSimulatePrivate
+{
+public:
+ std::vector<pkgDPkgPM::Item> List;
+};
// Simulate::Simulate - Constructor /*{{{*/
// ---------------------------------------------------------------------
/* The legacy translations here of input Pkg iterators is obsolete,
this is not necessary since the pkgCaches are fully shared now. */
pkgSimulate::pkgSimulate(pkgDepCache *Cache) : pkgPackageManager(Cache),
- d(NULL), iPolicy(Cache),
+ d(new pkgSimulatePrivate()), iPolicy(Cache),
Sim(&Cache->GetCache(),&iPolicy),
group(Sim)
{
pkgSimulate::~pkgSimulate()
{
delete[] Flags;
+ delete d;
}
/*}}}*/
// Simulate::Describe - Describe a package /*{{{*/
// Simulate::Install - Simulate unpacking of a package /*{{{*/
// ---------------------------------------------------------------------
/* */
-bool pkgSimulate::Install(PkgIterator iPkg,string /*File*/)
+bool pkgSimulate::Install(PkgIterator iPkg,string File)
+{
+ if (iPkg.end() || File.empty())
+ return false;
+ d->List.emplace_back(pkgDPkgPM::Item::Install, iPkg, File);
+ return true;
+}
+bool pkgSimulate::RealInstall(PkgIterator iPkg,string /*File*/)
{
// Adapt the iterator
PkgIterator Pkg = Sim.FindPkg(iPkg.Name(), iPkg.Arch());
install the package.. For some investigations it may be necessary
however. */
bool pkgSimulate::Configure(PkgIterator iPkg)
+{
+ if (iPkg.end())
+ return false;
+ d->List.emplace_back(pkgDPkgPM::Item::Configure, iPkg);
+ return true;
+}
+bool pkgSimulate::RealConfigure(PkgIterator iPkg)
{
// Adapt the iterator
PkgIterator Pkg = Sim.FindPkg(iPkg.Name(), iPkg.Arch());
// ---------------------------------------------------------------------
/* */
bool pkgSimulate::Remove(PkgIterator iPkg,bool Purge)
+{
+ if (iPkg.end())
+ return false;
+ d->List.emplace_back(Purge ? pkgDPkgPM::Item::Purge : pkgDPkgPM::Item::Remove, iPkg);
+ return true;
+}
+bool pkgSimulate::RealRemove(PkgIterator iPkg,bool Purge)
{
// Adapt the iterator
PkgIterator Pkg = Sim.FindPkg(iPkg.Name(), iPkg.Arch());
cout << ']' << endl;
}
/*}}}*/
+bool pkgSimulate::Go2(APT::Progress::PackageManager *) /*{{{*/
+{
+ if (pkgDPkgPM::ExpandPendingCalls(d->List, Cache) == false)
+ return false;
+ for (auto && I : d->List)
+ switch (I.Op)
+ {
+ case pkgDPkgPM::Item::Install:
+ if (RealInstall(I.Pkg, I.File) == false)
+ return false;
+ break;
+ case pkgDPkgPM::Item::Configure:
+ if (RealConfigure(I.Pkg) == false)
+ return false;
+ break;
+ case pkgDPkgPM::Item::Remove:
+ if (RealRemove(I.Pkg, false) == false)
+ return false;
+ break;
+ case pkgDPkgPM::Item::Purge:
+ if (RealRemove(I.Pkg, true) == false)
+ return false;
+ break;
+ case pkgDPkgPM::Item::ConfigurePending:
+ case pkgDPkgPM::Item::TriggersPending:
+ case pkgDPkgPM::Item::RemovePending:
+ case pkgDPkgPM::Item::PurgePending:
+ return _error->Error("Internal error, simulation encountered unexpected pending item");
+ }
+ return true;
+}
+ /*}}}*/
// ApplyStatus - Adjust for non-ok packages /*{{{*/
// ---------------------------------------------------------------------
/* We attempt to change the state of the all packages that have failed
bool pkgProblemResolver::Resolve(bool BrokenFix, OpProgress * const Progress)
{
std::string const solver = _config->Find("APT::Solver", "internal");
+ auto const ret = EDSP::ResolveExternal(solver.c_str(), Cache, 0, Progress);
if (solver != "internal")
- return EDSP::ResolveExternal(solver.c_str(), Cache, false, false, false, Progress);
+ return ret;
return ResolveInternal(BrokenFix);
}
/*}}}*/
if (Scores[(*K)->ID] != 0)
{
pkgCache::PkgIterator Pkg(Cache,*K);
- clog << Scores[(*K)->ID] << ' ' << Pkg << std::endl;
+ clog << Scores[(*K)->ID] << ' ' << APT::PrettyPkg(&Cache, Pkg) << std::endl;
}
}
changing a breaks c) */
bool Change = true;
bool const TryFixByInstall = _config->FindB("pkgProblemResolver::FixByInstall", true);
+ std::vector<PackageKill> KillList;
for (int Counter = 0; Counter != 10 && Change == true; Counter++)
{
Change = false;
continue;
if (Debug == true)
- clog << "Investigating (" << Counter << ") " << I << endl;
+ clog << "Investigating (" << Counter << ") " << APT::PrettyPkg(&Cache, I) << endl;
// Isolate the problem dependency
- PackageKill KillList[100];
- PackageKill *LEnd = KillList;
bool InOr = false;
pkgCache::DepIterator Start;
pkgCache::DepIterator End;
- PackageKill *OldEnd = LEnd;
+ size_t OldSize = 0;
+
+ KillList.resize(0);
enum {OrRemove,OrKeep} OrOp = OrRemove;
for (pkgCache::DepIterator D = Cache[I].InstVerIter(Cache).DependsList();
if (Start == End)
{
// Decide what to do
- if (InOr == true && OldEnd == LEnd)
+ if (InOr == true && OldSize == KillList.size())
{
if (OrOp == OrRemove)
{
continue;
InOr = Start != End;
- OldEnd = LEnd;
+ OldSize = KillList.size();
}
else
{
}
if (Debug == true)
- clog << "Broken " << Start << endl;
+ clog << "Broken " << APT::PrettyDep(&Cache, Start) << endl;
/* Look across the version list. If there are no possible
targets then we keep the package and bail. This is necessary
is removed by the resolver because of a conflict or alike but it is
dangerous as it could trigger new breaks/conflicts… */
if (Debug == true)
- clog << " Try Installing " << Start.TargetPkg() << " before changing " << I.FullName(false) << std::endl;
+ clog << " Try Installing " << APT::PrettyPkg(&Cache, Start.TargetPkg()) << " before changing " << I.FullName(false) << std::endl;
unsigned long const OldBroken = Cache.BrokenCount();
Cache.MarkInstall(Start.TargetPkg(), true, 1, false);
// FIXME: we should undo the complete MarkInstall process here
if (Debug == true)
clog << " Added " << Pkg.FullName(false) << " to the remove list" << endl;
-
- LEnd->Pkg = Pkg;
- LEnd->Dep = End;
- LEnd++;
+
+ KillList.push_back({Pkg, End});
if (Start.IsNegative() == false)
break;
// Apply the kill list now
if (Cache[I].InstallVer != 0)
{
- for (PackageKill *J = KillList; J != LEnd; J++)
+ for (auto J = KillList.begin(); J != KillList.end(); J++)
{
Change = true;
if ((Cache[J->Dep] & pkgDepCache::DepGNow) == 0)
if (Cache[I].InstBroken() == true)
{
if (Debug == true)
- std::clog << " Dependencies are not satisfied for " << I << std::endl;
+ std::clog << " Dependencies are not satisfied for " << APT::PrettyPkg(&Cache, I) << std::endl;
return true;
}
Cache[I].InstPolicyBroken() == true)
{
if (Debug == true)
- std::clog << " Policy breaks with upgrade of " << I << std::endl;
+ std::clog << " Policy breaks with upgrade of " << APT::PrettyPkg(&Cache, I) << std::endl;
return true;
}
bool pkgProblemResolver::ResolveByKeep(OpProgress * const Progress)
{
std::string const solver = _config->Find("APT::Solver", "internal");
+ constexpr auto flags = EDSP::Request::UPGRADE_ALL | EDSP::Request::FORBID_NEW_INSTALL | EDSP::Request::FORBID_REMOVE;
+ auto const ret = EDSP::ResolveExternal(solver.c_str(), Cache, flags, Progress);
if (solver != "internal")
- return EDSP::ResolveExternal(solver.c_str(), Cache, true, false, false, Progress);
+ return ret;
return ResolveByKeepInternal();
}
/*}}}*/
if (Scores[(*K)->ID] != 0)
{
pkgCache::PkgIterator Pkg(Cache,*K);
- clog << Scores[(*K)->ID] << ' ' << Pkg << std::endl;
+ clog << Scores[(*K)->ID] << ' ' << APT::PrettyPkg(&Cache, Pkg) << std::endl;
}
}
while (true)
{
if (Debug == true)
- clog << "Package " << I.FullName(false) << " " << Start << endl;
+ clog << "Package " << I.FullName(false) << " " << APT::PrettyDep(&Cache, Start) << endl;
// Look at all the possible provides on this package
std::unique_ptr<pkgCache::Version *[]> VList(Start.AllTargets());
struct PrioComp {
pkgCache &PrioCache;
- PrioComp(pkgCache &PrioCache) : PrioCache(PrioCache) {
+ explicit PrioComp(pkgCache &PrioCache) : PrioCache(PrioCache) {
}
bool operator() (pkgCache::Version * const &A, pkgCache::Version * const &B) {