* merged the install-recommends branch
authorMichael Vogt <egon@bottom>
Tue, 15 Aug 2006 13:18:51 +0000 (15:18 +0200)
committerMichael Vogt <egon@bottom>
Tue, 15 Aug 2006 13:18:51 +0000 (15:18 +0200)
1  2 
apt-pkg/depcache.cc
apt-pkg/depcache.h
apt-pkg/init.cc
apt-pkg/init.h
apt-pkg/makefile
cmdline/apt-get.cc
configure.in
debian/changelog
doc/examples/configure-index
methods/makefile

@@@ -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;
               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;
 +}
@@@ -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<InRootSetFunc> 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.cc
Simple merge
diff --cc apt-pkg/init.h
@@@ -17,8 -17,8 +17,8 @@@
  #include <apt-pkg/pkgsystem.h>
  
  // 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;
@@@ -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)
@@@ -640,6 -641,18 +642,18 @@@ bool CacheFile::CheckDeps(bool AllowBro
     if (pkgApplyStatus(*DCache) == false)
        return false;
     
 -             DCache->MarkInstall(I,true,0,true);
+    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, 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
@@@ -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)
@@@ -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 <mvo@debian.org>  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 <michael.vogt@ubuntu.com>  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)
Simple merge
@@@ -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