From 6910a2accecd7c8e8493b74130d8dbf3972014a8 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Tue, 30 Jun 2009 21:44:24 +0200 Subject: [PATCH] * add hook for MarkInstall and MarkDelete (closes: #470035) * honor the dpkg hold state in new Marker hooks (closes: #64141) Combine the proposed AutoInstOk and IsAutoInstallOk to more general hooks for MarkInstall (and another one for MarkDelete) with the same parameters as the call these hooks should check. --- apt-pkg/algorithms.cc | 25 ++++------------ apt-pkg/depcache.cc | 67 +++++++++++++++++++++++++++++++------------ apt-pkg/depcache.h | 40 +++++++++++++++----------- debian/changelog | 5 ++-- po/apt-all.pot | 8 +++--- 5 files changed, 84 insertions(+), 61 deletions(-) diff --git a/apt-pkg/algorithms.cc b/apt-pkg/algorithms.cc index 68a4af8ed..a30a02edb 100644 --- a/apt-pkg/algorithms.cc +++ b/apt-pkg/algorithms.cc @@ -984,26 +984,11 @@ bool pkgProblemResolver::Resolve(bool BrokenFix) // Consider other options if (InOr == false) { - if (Cache.AutoInstOk(I, Cache[I].CandidateVerIter(Cache),Start) == true) - { - if (Debug == true) - clog << " Removing " << I.Name() << " rather than change " << Start.TargetPkg().Name() << endl; - Cache.MarkDelete(I); - if (Counter > 1) - { - if (Scores[Pkg->ID] > Scores[I->ID]) - Scores[I->ID] = Scores[Pkg->ID]; - } - } else { - /* The dependency of the TargetPkg would be satisfiable with I but it is - forbidden to install I automatical, so anything we can do is hold - back the TargetPkg. - */ - if (Debug == true) - clog << " Hold back " << Start.TargetPkg().Name() << - " rather than change denied AutoInstall " << I.Name() << endl; - Cache.MarkKeep(Start.TargetPkg()); - } + if (Debug == true) + clog << " Removing " << I.Name() << " rather than change " << Start.TargetPkg().Name() << endl; + Cache.MarkDelete(I); + if (Counter > 1 && Scores[Pkg->ID] > Scores[I->ID]) + Scores[I->ID] = Scores[Pkg->ID]; } } } diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc index a284a05c7..7c86204f5 100644 --- a/apt-pkg/depcache.cc +++ b/apt-pkg/depcache.cc @@ -769,7 +769,7 @@ void pkgDepCache::MarkKeep(PkgIterator const &Pkg, bool Soft, bool FromUser, // --------------------------------------------------------------------- /* */ void pkgDepCache::MarkDelete(PkgIterator const &Pkg, bool rPurge, - unsigned long Depth) + unsigned long Depth, bool FromUser) { // Simplifies other routines. if (Pkg.end() == true) @@ -791,6 +791,13 @@ void pkgDepCache::MarkDelete(PkgIterator const &Pkg, bool rPurge, if (Pkg->VersionList == 0) return; + // check if we are allowed to install the package + if (IsDeleteOk(Pkg,rPurge,Depth,FromUser) == false) + { + MarkKeep(Pkg,false,FromUser,Depth+1); + return; + } + if (DebugMarker == true) std::clog << OutputInDepth(Depth) << "MarkDelete " << Pkg << std::endl; @@ -808,6 +815,23 @@ void pkgDepCache::MarkDelete(PkgIterator const &Pkg, bool rPurge, AddSizes(Pkg); } /*}}}*/ +// DepCache::IsDeleteOk - check if it is ok to remove this package /*{{{*/ +// --------------------------------------------------------------------- +/* The default implementation just honors dpkg hold + But an application using this library can override this method + to control the MarkDelete behaviour */ +bool pkgDepCache::IsDeleteOk(PkgIterator const &Pkg,bool rPurge, + unsigned long Depth, bool FromUser) +{ + if (FromUser == false && Pkg->SelectedState == pkgCache::State::Hold) + { + if (DebugMarker == true) + std::clog << OutputInDepth(Depth) << "Hold prevents MarkDelete of " << Pkg << std::endl; + return false; + } + return true; +} + /*}}}*/ // DepCache::MarkInstall - Put the package in the install state /*{{{*/ // --------------------------------------------------------------------- /* */ @@ -843,6 +867,14 @@ void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst, // We dont even try to install virtual packages.. if (Pkg->VersionList == 0) return; + + // check if we are allowed to install the package + if (IsInstallOk(Pkg,AutoInst,Depth,FromUser) == false) + { + MarkKeep(Pkg,false,FromUser,Depth+1); + return; + } + /* Target the candidate version and remove the autoflag. We reset the autoflag below if this was called recursively. Otherwise the user should have the ability to de-auto a package by changing its state */ @@ -871,7 +903,7 @@ void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst, AddStates(Pkg); Update(Pkg); AddSizes(Pkg); - + if (AutoInst == false) return; @@ -1001,8 +1033,7 @@ void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst, } } - if (InstPkg.end() == false && - AutoInstOk(InstPkg, (*this)[InstPkg].CandidateVerIter(*this), Start)) + if (InstPkg.end() == false) { if(DebugAutoInstall == true) std::clog << OutputInDepth(Depth) << "Installing " << InstPkg.Name() @@ -1040,30 +1071,30 @@ void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst, PkgIterator Pkg = Ver.ParentPkg(); if (Start->Type != Dep::DpkgBreaks) - { - if(AutoInstOk(Pkg, VerIterator(*this), Start)) - MarkDelete(Pkg); - } - else - if (PkgState[Pkg->ID].CandidateVer != *I && - AutoInstOk(Pkg, VerIterator(*this, PkgState[Pkg->ID].CandidateVer), Start)) - MarkInstall(Pkg,true,Depth + 1, false, ForceImportantDeps); + MarkDelete(Pkg,false,Depth + 1, false); + else if (PkgState[Pkg->ID].CandidateVer != *I) + MarkInstall(Pkg,true,Depth + 1, false, ForceImportantDeps); } continue; } } } /*}}}*/ -// DepCache::AutoInstOk - check if it is to install this package /*{{{*/ +// DepCache::IsInstallOk - check if it is ok to install this package /*{{{*/ // --------------------------------------------------------------------- /* The default implementation just honors dpkg hold - But an application using this library can override this method + But an application using this library can override this method to control the MarkInstall behaviour */ -bool pkgDepCache::AutoInstOk(const PkgIterator &Pkg, - const VerIterator &v, - const DepIterator &d) +bool pkgDepCache::IsInstallOk(PkgIterator const &Pkg,bool AutoInst, + unsigned long Depth, bool FromUser) { - return (Pkg->SelectedState != pkgCache::State::Hold); + if (FromUser == false && Pkg->SelectedState == pkgCache::State::Hold) + { + if (DebugMarker == true) + std::clog << OutputInDepth(Depth) << "Hold prevents MarkInstall of " << Pkg << std::endl; + return false; + } + return true; } /*}}}*/ // DepCache::SetReInstall - Set the reinstallation flag /*{{{*/ diff --git a/apt-pkg/depcache.h b/apt-pkg/depcache.h index 10f9c1091..44a7f8c02 100644 --- a/apt-pkg/depcache.h +++ b/apt-pkg/depcache.h @@ -363,20 +363,6 @@ class pkgDepCache : protected pkgCache::Namespace */ virtual bool MarkFollowsSuggests(); - /** \return \b true if it's OK for MarkInstall to recursively - * install the given version of the given package. - * - * \param p the package that MarkInstall wants to install. - * \param v the version being installed, or an end iterator - * if p is being removed. - * \param d the dependency being fixed. - * - * The default implementation unconditionally returns \b true. - */ - virtual bool AutoInstOk(const PkgIterator &p, - const VerIterator &v, - const DepIterator &d); - /** \brief Update the Marked and Garbage fields of all packages. * * This routine is implicitly invoked after all state manipulators @@ -406,7 +392,7 @@ class pkgDepCache : protected pkgCache::Namespace void MarkKeep(PkgIterator const &Pkg, bool Soft = false, bool FromUser = true, unsigned long Depth = 0); void MarkDelete(PkgIterator const &Pkg, bool Purge = false, - unsigned long Depth = 0); + unsigned long Depth = 0, bool FromUser = true); void MarkInstall(PkgIterator const &Pkg,bool AutoInst = true, unsigned long Depth = 0, bool FromUser = true, bool ForceImportantDeps = false); @@ -417,7 +403,29 @@ class pkgDepCache : protected pkgCache::Namespace /** Set the "is automatically installed" flag of Pkg. */ void MarkAuto(const PkgIterator &Pkg, bool Auto); // @} - + + /** \return \b true if it's OK for MarkInstall to install + * the given package. + * + * \param Pkg the package that MarkInstall wants to install. + * \param AutoInst needs a previous MarkInstall this package? + * \param Depth recursive deep of this Marker call + * \param FromUser was the install requested by the user? + */ + virtual bool IsInstallOk(const PkgIterator &Pkg,bool AutoInst = true, + unsigned long Depth = 0, bool FromUser = true); + + /** \return \b true if it's OK for MarkDelete to remove + * the given package. + * + * \param Pkg the package that MarkDelete wants to remove. + * \param Purge should we purge instead of "only" remove? + * \param Depth recursive deep of this Marker call + * \param FromUser was the remove requested by the user? + */ + virtual bool IsDeleteOk(const PkgIterator &Pkg,bool Purge = false, + unsigned long Depth = 0, bool FromUser = true); + // This is for debuging void Update(OpProgress *Prog = 0); diff --git a/debian/changelog b/debian/changelog index 8d6109224..ab8da4c6c 100644 --- a/debian/changelog +++ b/debian/changelog @@ -29,14 +29,13 @@ apt (0.7.22) UNRELEASED; urgency=low * add Debug::pkgProblemResolver::ShowScores and make the scores adjustable * do not write state file in simulate mode (closes: #433007) - * add hook for auto-install (closes: #470035) - * support IsAutoInstallOk in the resolver too + * add hook for MarkInstall and MarkDelete (closes: #470035) * fix typo in apt-pkg/acquire.cc which prevents Dl-Limit to work correctly when downloading from multiple sites (Closes: #534752) * add the various foldmarkers in apt-pkg & cmdline (no code change) [ Michael Vogt ] - * honor the dpkg hold state in AutoInstOk (closes: #64141) + * honor the dpkg hold state in new Marker hooks (closes: #64141) [ Julian Andres Klode ] * apt-pkg/contrib/configuration.cc: Fix a small memory leak in diff --git a/po/apt-all.pot b/po/apt-all.pot index edcf59cc7..12e15110e 100644 --- a/po/apt-all.pot +++ b/po/apt-all.pot @@ -780,7 +780,7 @@ msgstr "" msgid "Do you want to continue [Y/n]? " msgstr "" -#: cmdline/apt-get.cc:986 cmdline/apt-get.cc:2225 apt-pkg/algorithms.cc:1397 +#: cmdline/apt-get.cc:986 cmdline/apt-get.cc:2225 apt-pkg/algorithms.cc:1382 #, c-format msgid "Failed to fetch %s %s\n" msgstr "" @@ -2302,17 +2302,17 @@ msgid "" "The package %s needs to be reinstalled, but I can't find an archive for it." msgstr "" -#: apt-pkg/algorithms.cc:1146 +#: apt-pkg/algorithms.cc:1131 msgid "" "Error, pkgProblemResolver::Resolve generated breaks, this may be caused by " "held packages." msgstr "" -#: apt-pkg/algorithms.cc:1148 +#: apt-pkg/algorithms.cc:1133 msgid "Unable to correct problems, you have held broken packages." msgstr "" -#: apt-pkg/algorithms.cc:1423 apt-pkg/algorithms.cc:1425 +#: apt-pkg/algorithms.cc:1408 apt-pkg/algorithms.cc:1410 msgid "" "Some index files failed to download, they have been ignored, or old ones " "used instead." -- 2.45.2