From: Michael Vogt Date: Tue, 15 Aug 2006 13:18:51 +0000 (+0200) Subject: * merged the install-recommends branch X-Git-Tag: 0.7.21~284^2~24 X-Git-Url: https://git.hcoop.net/ntk/apt.git/commitdiff_plain/7610bb3db43c6dd9062cb57c01415022e14f3fc7 * merged the install-recommends branch --- 7610bb3db43c6dd9062cb57c01415022e14f3fc7 diff --cc apt-pkg/depcache.cc index 369eae70,b5b96dbc..5052c62a --- a/apt-pkg/depcache.cc +++ b/apt-pkg/depcache.cc @@@ -763,7 -598,7 +765,8 @@@ void pkgDepCache::MarkDelete(PkgIterato // --------------------------------------------------------------------- /* */ void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst, - unsigned long Depth, bool FromUser) - unsigned long Depth, bool ForceImportantDeps) ++ unsigned long Depth, bool FromUser, ++ bool ForceImportantDeps) { if (Depth > 100) return; @@@ -898,8 -748,13 +931,12 @@@ std::clog << "Installing " << InstPkg.Name() << " as dep of " << Pkg.Name() << std::endl; - MarkInstall(InstPkg, true, Depth + 1, false); - MarkInstall(InstPkg,true,Depth + 1, ForceImportantDeps); - - // Set the autoflag, after MarkInstall because MarkInstall unsets it ++ MarkInstall(InstPkg, true, Depth + 1, false, ForceImportantDeps); ++ // Set the autoflag, after MarkInstall because MarkInstall ++ // unsets it + if (P->CurrentVer == 0) + PkgState[InstPkg->ID].Flags |= Flag::Auto; } - continue; } @@@ -1060,219 -900,13 +1097,226 @@@ pkgCache::VerIterator pkgDepCache::Poli /* */ bool pkgDepCache::Policy::IsImportantDep(DepIterator Dep) { - return Dep.IsCritical(); + if(Dep.IsCritical()) + return true; + else if(Dep->Type == pkgCache::Dep::Recommends) + return _config->FindB("APT::Install-Recommends", false); + else if(Dep->Type == pkgCache::Dep::Suggests) + return _config->FindB("APT::Install-Suggests", false); + + return false; } /*}}}*/ + +pkgDepCache::DefaultRootSetFunc::DefaultRootSetFunc() + : constructedSuccessfully(false) +{ + Configuration::Item const *Opts; + Opts = _config->Tree("APT::NeverAutoRemove"); + if (Opts != 0 && Opts->Child != 0) + { + Opts = Opts->Child; + for (; Opts != 0; Opts = Opts->Next) + { + if (Opts->Value.empty() == true) + continue; + + regex_t *p = new regex_t; + if(regcomp(p,Opts->Value.c_str(), + REG_EXTENDED | REG_ICASE | REG_NOSUB) != 0) + { + regfree(p); + delete p; + _error->Error("Regex compilation error for APT::NeverAutoRemove"); + return; + } + + rootSetRegexp.push_back(p); + } + } + + constructedSuccessfully = true; +} + +pkgDepCache::DefaultRootSetFunc::~DefaultRootSetFunc() +{ + for(unsigned int i = 0; i < rootSetRegexp.size(); i++) + { + regfree(rootSetRegexp[i]); + delete rootSetRegexp[i]; + } +} + + +bool pkgDepCache::DefaultRootSetFunc::InRootSet(const pkgCache::PkgIterator &pkg) +{ + for(unsigned int i = 0; i < rootSetRegexp.size(); i++) + if (regexec(rootSetRegexp[i], pkg.Name(), 0, 0, 0) == 0) + return true; + + return false; +} + +pkgDepCache::InRootSetFunc *pkgDepCache::GetRootSetFunc() +{ + DefaultRootSetFunc *f = new DefaultRootSetFunc; + if(f->wasConstructedSuccessfully()) + return f; + else + { + delete f; + return NULL; + } +} + +bool pkgDepCache::MarkFollowsRecommends() +{ + return _config->FindB("APT::AutoRemove::RecommendsImportant", true); +} + +bool pkgDepCache::MarkFollowsSuggests() +{ + return _config->FindB("APT::AutoRemove::SuggestsImportant", false); +} + +// the main mark algorithm +bool pkgDepCache::MarkRequired(InRootSetFunc &userFunc) +{ + bool follow_recommends; + bool follow_suggests; + + // init the states + for(PkgIterator p = PkgBegin(); !p.end(); ++p) + { + PkgState[p->ID].Marked = false; + PkgState[p->ID].Garbage = false; + + // debug output + if(_config->FindB("Debug::pkgAutoRemove",false) + && PkgState[p->ID].Flags & Flag::Auto) + std::clog << "AutoDep: " << p.Name() << std::endl; + } + + // init vars + follow_recommends = MarkFollowsRecommends(); + follow_suggests = MarkFollowsSuggests(); + + + + // do the mark part, this is the core bit of the algorithm + for(PkgIterator p = PkgBegin(); !p.end(); ++p) + { + if(!(PkgState[p->ID].Flags & Flag::Auto) || + (p->Flags & Flag::Essential) || + userFunc.InRootSet(p)) + + { + // the package is installed (and set to keep) + if(PkgState[p->ID].Keep() && !p.CurrentVer().end()) + MarkPackage(p, p.CurrentVer(), + follow_recommends, follow_suggests); + // the package is to be installed + else if(PkgState[p->ID].Install()) + MarkPackage(p, PkgState[p->ID].InstVerIter(*this), + follow_recommends, follow_suggests); + } + } + + return true; +} + +// mark a single package in Mark-and-Sweep +void pkgDepCache::MarkPackage(const pkgCache::PkgIterator &pkg, + const pkgCache::VerIterator &ver, + bool follow_recommends, + bool follow_suggests) +{ + pkgDepCache::StateCache &state = PkgState[pkg->ID]; + VerIterator candver = state.CandidateVerIter(*this); + VerIterator instver = state.InstVerIter(*this); + +#if 0 + // If a package was garbage-collected but is now being marked, we + // should re-select it + // For cases when a pkg is set to upgrade and this trigger the + // removal of a no-longer used dependency. if the pkg is set to + // keep again later it will result in broken deps + if(state.Delete() && state.RemoveReason = Unused) + { + if(ver==candver) + mark_install(pkg, false, false, NULL); + else if(ver==pkg.CurrentVer()) + MarkKeep(pkg, false, false); + + instver=state.InstVerIter(*this); + } +#endif + + // Ignore versions other than the InstVer, and ignore packages + // that are already going to be removed or just left uninstalled. + if(!(ver == instver && !instver.end())) + return; + + // if we are marked already we are done + if(state.Marked) + return; + + //std::cout << "Setting Marked for: " << pkg.Name() << std::endl; + state.Marked=true; + + if(!ver.end()) + { + for(DepIterator d = ver.DependsList(); !d.end(); ++d) + { + if(d->Type == Dep::Depends || + d->Type == Dep::PreDepends || + (follow_recommends && + d->Type == Dep::Recommends) || + (follow_suggests && + d->Type == Dep::Suggests)) + { + // Try all versions of this package. + for(VerIterator V = d.TargetPkg().VersionList(); + !V.end(); ++V) + { + if(_system->VS->CheckDep(V.VerStr(), d->CompareOp, d.TargetVer())) + { + MarkPackage(V.ParentPkg(), V, + follow_recommends, follow_suggests); + } + } + // Now try virtual packages + for(PrvIterator prv=d.TargetPkg().ProvidesList(); + !prv.end(); ++prv) + { + if(_system->VS->CheckDep(prv.ProvideVersion(), d->CompareOp, + d.TargetVer())) + { + MarkPackage(prv.OwnerPkg(), prv.OwnerVer(), + follow_recommends, follow_suggests); + } + } + } + } + } +} + +bool pkgDepCache::Sweep() +{ + // do the sweep + for(PkgIterator p=PkgBegin(); !p.end(); ++p) + { + StateCache &state=PkgState[p->ID]; + + // if it is not marked and it is installed, it's garbage + if(!state.Marked && (!p.CurrentVer().end() || state.Install()) && + !state.Delete()) + { + state.Garbage=true; + if(_config->FindB("Debug::pkgAutoRemove",false)) + std::cout << "Garbage: " << p.Name() << std::endl; + } + } + + return true; +} diff --cc apt-pkg/depcache.h index fd935c26,042abb5c..5cd5ea35 --- a/apt-pkg/depcache.h +++ b/apt-pkg/depcache.h @@@ -341,61 -185,13 +344,62 @@@ class pkgDepCache : protected pkgCache: inline StateCache &operator [](PkgIterator const &I) {return PkgState[I->ID];}; inline unsigned char &operator [](DepIterator const &I) {return DepState[I->ID];}; - // Manipulators - void MarkKeep(PkgIterator const &Pkg,bool Soft = false); + /** \return A function identifying packages in the root set other + * than manually installed packages and essential packages, or \b + * NULL if an error occurs. + * + * \todo Is this the best place for this function? Perhaps the + * settings for mark-and-sweep should be stored in a single + * external class? + */ + virtual InRootSetFunc *GetRootSetFunc(); + + /** \return \b true if the garbage collector should follow recommendations. + */ + virtual bool MarkFollowsRecommends(); + + /** \return \b true if the garbage collector should follow suggestions. + */ + virtual bool MarkFollowsSuggests(); + + /** \brief Update the Marked and Garbage fields of all packages. + * + * This routine is implicitly invoked after all state manipulators + * and when an ActionGroup is destroyed. It invokes #MarkRequired + * and #Sweep to do its dirty work. + * + * \param rootFunc A predicate that returns \b true for packages + * that should be added to the root set. + */ + bool MarkAndSweep(InRootSetFunc &rootFunc) + { + return MarkRequired(rootFunc) && Sweep(); + } + + bool MarkAndSweep() + { + std::auto_ptr f(GetRootSetFunc()); + if(f.get() != NULL) + return MarkAndSweep(*f.get()); + else + return false; + } + + /** \name State Manipulators + */ + // @{ + void MarkKeep(PkgIterator const &Pkg, bool Soft = false, + bool FromUser = true); void MarkDelete(PkgIterator const &Pkg,bool Purge = false); void MarkInstall(PkgIterator const &Pkg,bool AutoInst = true, - unsigned long Depth = 0, bool FromUser = true); - unsigned long Depth = 0, bool ForceImportantDeps = false); ++ unsigned long Depth = 0, bool FromUser = true, ++ bool ForceImportantDeps = false); void SetReInstall(PkgIterator const &Pkg,bool To); void SetCandidateVersion(VerIterator TargetVer); + + /** Set the "is automatically installed" flag of Pkg. */ + void MarkAuto(const PkgIterator &Pkg, bool Auto); + // @} // This is for debuging void Update(OpProgress *Prog = 0); diff --cc apt-pkg/init.h index 51a7ba2e,8255b406..c6457cbc --- a/apt-pkg/init.h +++ b/apt-pkg/init.h @@@ -17,8 -17,8 +17,8 @@@ #include // See the makefile -#define APT_PKG_MAJOR 3 -#define APT_PKG_MINOR 11 +#define APT_PKG_MAJOR 4 - #define APT_PKG_MINOR 1 ++#define APT_PKG_MINOR 2 #define APT_PKG_RELEASE 0 extern const char *pkgVersion; diff --cc apt-pkg/makefile index 29c8ee13,7e5feae5..59df6c0e --- a/apt-pkg/makefile +++ b/apt-pkg/makefile @@@ -13,7 -13,7 +13,7 @@@ include ../buildlib/defaults.ma # methods/makefile - FIXME LIBRARY=apt-pkg LIBEXT=$(GLIBC_VER)$(LIBSTDCPP_VER) - MAJOR=4.1 -MAJOR=3.11 ++MAJOR=4.2 MINOR=0 SLIBS=$(PTHREADLIB) $(INTLLIBS) APT_DOMAIN:=libapt-pkg$(MAJOR) diff --cc cmdline/apt-get.cc index 8b3c6857,58976351..4dfb3325 --- a/cmdline/apt-get.cc +++ b/cmdline/apt-get.cc @@@ -640,6 -641,18 +642,18 @@@ bool CacheFile::CheckDeps(bool AllowBro if (pkgApplyStatus(*DCache) == false) return false; + if (_config->FindB("APT::Get::Fix-Policy-Broken",false) == true) + { + FixBroken = true; + if ((DCache->PolicyBrokenCount() > 0)) + { + // upgrade all policy-broken packages with ForceImportantDeps=True + for (pkgCache::PkgIterator I = Cache->PkgBegin(); !I.end(); I++) + if ((*DCache)[I].NowPolicyBroken() == true) - DCache->MarkInstall(I,true,0,true); ++ DCache->MarkInstall(I,true,0, false, true); + } + } + // Nothing is broken if (DCache->BrokenCount() == 0 || AllowBroken == true) return true; @@@ -2581,8 -2555,9 +2615,10 @@@ int main(int argc,const char *argv[] {0,"remove","APT::Get::Remove",0}, {0,"only-source","APT::Get::Only-Source",0}, {0,"arch-only","APT::Get::Arch-Only",0}, + {0,"auto-remove","APT::Get::AutomaticRemove",0}, {0,"allow-unauthenticated","APT::Get::AllowUnauthenticated",0}, + {0,"install-recommends","APT::Install-Recommends",CommandLine::Boolean}, + {0,"fix-policy","APT::Get::Fix-Policy-Broken",0}, {'c',"config-file",0,CommandLine::ConfigFile}, {'o',"option",0,CommandLine::ArbItem}, {0,0,0,0}}; diff --cc configure.in index e8e89e02,f0b0d670..830fef82 --- a/configure.in +++ b/configure.in @@@ -18,7 -18,7 +18,7 @@@ AC_CONFIG_AUX_DIR(buildlib AC_CONFIG_HEADER(include/config.h:buildlib/config.h.in include/apti18n.h:buildlib/apti18n.h.in) dnl -- SET THIS TO THE RELEASE VERSION -- - AC_DEFINE_UNQUOTED(VERSION,"0.6.45exp1") -AC_DEFINE_UNQUOTED(VERSION,"0.6.45.1") ++AC_DEFINE_UNQUOTED(VERSION,"0.6.45exp2") PACKAGE="apt" AC_DEFINE_UNQUOTED(PACKAGE,"$PACKAGE") AC_SUBST(PACKAGE) diff --cc debian/changelog index 25b015dd,65ec82cc..fb07ca68 --- a/debian/changelog +++ b/debian/changelog @@@ -1,4 -1,23 +1,10 @@@ -apt (0.6.45.2) unstable; urgency=low ++apt (0.6.45exp2) experimental; urgency=low + - * added "--install-recommends" to handle recommends as - dependencies (closes: #42266) ++ * merged "install-recommends" branch (ABI break) + - -- ++ -- Michael Vogt Mon, 14 Aug 2006 17:47:25 +0200 + -apt (0.6.45.1) unstable; urgency=low - - * debian/control: - - switched to libdb4.4 for building (closes: #381019) - * cmdline/apt-get.cc: - - show only the recommends/suggests for the candidate-version, not for all - versions of the package (closes: #257054) - - properly handle recommends/suggests or-groups when printing the list of - suggested/recommends packages (closes: #311619) - - -- Michael Vogt Wed, 9 Aug 2006 14:27:54 +0200 - -apt (0.6.45) unstable; urgency=low +apt (0.6.45exp1) experimental; urgency=low * apt-pkg/contrib/sha256.cc: - fixed the sha256 generation (closes: #378183) diff --cc methods/makefile index 10fce8bf,1e3b1ef8..5bd05eae --- a/methods/makefile +++ b/methods/makefile @@@ -7,7 -7,7 +7,7 @@@ include ../buildlib/defaults.ma BIN := $(BIN)/methods # FIXME.. - LIB_APT_PKG_MAJOR = 4.1 -LIB_APT_PKG_MAJOR = 3.11 ++LIB_APT_PKG_MAJOR = 4.2 APT_DOMAIN := libapt-pkg$(LIB_APT_PKG_MAJOR) # The file method