From 64e3414e00906e6eaa72d7b63ca76d1c59ecadf6 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Fri, 25 Sep 2015 19:58:43 +0200 Subject: allow all dpkg selections to be set via apt-mark and libapt As we have support for 'hold', we need support for undoing a hold which in effect means that we implemented most other states as well, just that they weren't exposed in the interface directly so far. --- apt-pkg/statechanges.cc | 88 ++++++++++++++++++++++++++++++++++--------------- 1 file changed, 61 insertions(+), 27 deletions(-) (limited to 'apt-pkg/statechanges.cc') diff --git a/apt-pkg/statechanges.cc b/apt-pkg/statechanges.cc index a20319d2d..dc446a665 100644 --- a/apt-pkg/statechanges.cc +++ b/apt-pkg/statechanges.cc @@ -14,46 +14,62 @@ class StateChanges::Private { public: APT::VersionVector hold; + APT::VersionVector unhold; APT::VersionVector install; + APT::VersionVector deinstall; + APT::VersionVector purge; APT::VersionVector error; }; -void StateChanges::Hold(pkgCache::VerIterator const &Ver) -{ - d->hold.push_back(Ver); -} -APT::VersionVector& StateChanges::Hold() -{ - return d->hold; -} -void StateChanges::Unhold(pkgCache::VerIterator const &Ver) -{ - d->install.push_back(Ver); -} -APT::VersionVector& StateChanges::Unhold() -{ - return d->install; +#define APT_GETTERSETTER(Name, Container) \ +void StateChanges::Name(pkgCache::VerIterator const &Ver) \ +{ \ + Container.push_back(Ver); \ +}\ +APT::VersionVector& StateChanges::Name() \ +{ \ + return Container; \ } +APT_GETTERSETTER(Hold, d->hold) +APT_GETTERSETTER(Unhold, d->unhold) +APT_GETTERSETTER(Install, d->install) +APT_GETTERSETTER(Remove, d->deinstall) +APT_GETTERSETTER(Purge, d->purge) +#undef APT_GETTERSETTER APT::VersionVector& StateChanges::Error() { return d->error; } -void StateChanges::Discard() +void StateChanges::clear() { d->hold.clear(); + d->unhold.clear(); d->install.clear(); + d->deinstall.clear(); + d->purge.clear(); d->error.clear(); } +bool StateChanges::empty() const +{ + return d->hold.empty() && + d->unhold.empty() && + d->install.empty() && + d->deinstall.empty() && + d->purge.empty() && + d->error.empty(); +} + bool StateChanges::Save(bool const DiscardOutput) { d->error.clear(); - if (d->hold.empty() && d->install.empty()) + if (d->hold.empty() && d->unhold.empty() && d->install.empty() && d->deinstall.empty() && d->purge.empty()) return true; std::vector Args = debSystem::GetDpkgBaseCommand(); // ensure dpkg knows about the package so that it keeps the status we set + if (d->hold.empty() == false || d->install.empty() == false) { APT::VersionVector makeDpkgAvailable; auto const notInstalled = [](pkgCache::VerIterator const &V) { return V.ParentPkg()->CurrentVer == 0; }; @@ -94,6 +110,24 @@ bool StateChanges::Save(bool const DiscardOutput) else fprintf(dpkg, "%s:%s %s\n", P.Name(), V.Arch(), state.c_str()); }; + for (auto const &V: d->unhold) + { + if (V.ParentPkg()->CurrentVer != 0) + state = "install"; + else + state = "deinstall"; + dpkgName(V); + } + if (d->purge.empty() == false) + { + state = "purge"; + std::for_each(d->purge.begin(), d->purge.end(), dpkgName); + } + if (d->deinstall.empty() == false) + { + state = "deinstall"; + std::for_each(d->deinstall.begin(), d->deinstall.end(), dpkgName); + } if (d->hold.empty() == false) { state = "hold"; @@ -108,16 +142,16 @@ bool StateChanges::Save(bool const DiscardOutput) if (ExecWait(dpkgSelections, "dpkg --set-selections") == false) { - if (d->hold.empty()) - std::swap(d->install, d->error); - else if (d->install.empty()) - std::swap(d->hold, d->error); - else - { - std::swap(d->hold, d->error); - std::move(d->install.begin(), d->install.end(), std::back_inserter(d->error)); - d->install.clear(); - } + std::move(d->purge.begin(), d->purge.end(), std::back_inserter(d->error)); + d->purge.clear(); + std::move(d->deinstall.begin(), d->deinstall.end(), std::back_inserter(d->error)); + d->deinstall.clear(); + std::move(d->hold.begin(), d->hold.end(), std::back_inserter(d->error)); + d->hold.clear(); + std::move(d->unhold.begin(), d->unhold.end(), std::back_inserter(d->error)); + d->unhold.clear(); + std::move(d->install.begin(), d->install.end(), std::back_inserter(d->error)); + d->install.clear(); } return d->error.empty(); } -- cgit v1.2.3