Просмотр исходного кода

* merged ians changes for apt support for breaks

Michael Vogt лет назад: 20
Родитель
Сommit
94915e3424

+ 22 - 1
apt-pkg/algorithms.cc

@@ -102,6 +102,7 @@ bool pkgSimulate::Install(PkgIterator iPkg,string /*File*/)
 	 DepIterator End;
 	 D.GlobOr(Start,End);
 	 if (Start->Type == pkgCache::Dep::Conflicts ||
+	     Start->Type == pkgCache::Dep::DpkgBreaks ||
 	     Start->Type == pkgCache::Dep::Obsoletes ||
 	     End->Type == pkgCache::Dep::PreDepends)
          {
@@ -151,6 +152,8 @@ bool pkgSimulate::Configure(PkgIterator iPkg)
 	    cout << " Obsoletes:" << D.TargetPkg().Name();
 	 else if (D->Type == pkgCache::Dep::Conflicts)
 	    cout << " Conflicts:" << D.TargetPkg().Name();
+	 else if (D->Type == pkgCache::Dep::DpkgBreaks)
+	    cout << " Breaks:" << D.TargetPkg().Name();
 	 else
 	    cout << " Depends:" << D.TargetPkg().Name();
       }	    
@@ -651,6 +654,7 @@ bool pkgProblemResolver::DoUpgrade(pkgCache::PkgIterator Pkg)
 	       /* We let the algorithm deal with conflicts on its next iteration,
 		it is much smarter than us */
 	       if (Start->Type == pkgCache::Dep::Conflicts || 
+		   Start->Type == pkgCache::Dep::DpkgBreaks || 
 		   Start->Type == pkgCache::Dep::Obsoletes)
 		   break;
 	       
@@ -873,6 +877,7 @@ bool pkgProblemResolver::Resolve(bool BrokenFix)
 	    SPtrArray<pkgCache::Version *> VList = Start.AllTargets();
 	    if (*VList == 0 && (Flags[I->ID] & Protected) != Protected &&
 		Start->Type != pkgCache::Dep::Conflicts &&
+		Start->Type != pkgCache::Dep::DpkgBreaks &&
 		Start->Type != pkgCache::Dep::Obsoletes &&
 		Cache[I].NowBroken() == false)
 	    {	       
@@ -903,6 +908,7 @@ bool pkgProblemResolver::Resolve(bool BrokenFix)
 	       if (Scores[I->ID] <= Scores[Pkg->ID] ||
 		   ((Cache[Start] & pkgDepCache::DepNow) == 0 &&
 		    End->Type != pkgCache::Dep::Conflicts &&
+		    End->Type != pkgCache::Dep::DpkgBreaks &&
 		    End->Type != pkgCache::Dep::Obsoletes))
 	       {
 		  // Try a little harder to fix protected packages..
@@ -968,7 +974,21 @@ bool pkgProblemResolver::Resolve(bool BrokenFix)
 		      (Start->Type == pkgCache::Dep::Conflicts ||
 		       Start->Type == pkgCache::Dep::Obsoletes))
 		     continue;
-		  
+
+		  if (Start->Type == pkgCache::Dep::DpkgBreaks)
+		  {
+		     /* Would it help if we upgraded? */
+		     if (Cache[End] & pkgDepCache::DepGCVer) {
+			if (Debug)
+			   clog << "  Upgrading " << Pkg.Name() << " due to Breaks field in " << I.Name() << endl;
+			Cache.MarkInstall(Pkg, false, 0, false);
+			continue;
+		     }
+		     if (Debug)
+			clog << "  Will not break " << Pkg.Name() << " as stated in Breaks field in " << I.Name() <<endl;
+		     continue;
+		  }
+
 		  // Skip adding to the kill list if it is protected
 		  if ((Flags[Pkg->ID] & Protected) != 0)
 		     continue;
@@ -989,6 +1009,7 @@ bool pkgProblemResolver::Resolve(bool BrokenFix)
 	    // Hm, nothing can possibly satisify this dep. Nuke it.
 	    if (VList[0] == 0 && 
 		Start->Type != pkgCache::Dep::Conflicts &&
+		Start->Type != pkgCache::Dep::DpkgBreaks &&
 		Start->Type != pkgCache::Dep::Obsoletes &&
 		(Flags[I->ID] & Protected) != Protected)
 	    {

+ 3 - 0
apt-pkg/deb/deblistparser.cc

@@ -105,6 +105,8 @@ bool debListParser::NewVersion(pkgCache::VerIterator Ver)
       return false;
    if (ParseDepends(Ver,"Conflicts",pkgCache::Dep::Conflicts) == false)
       return false;
+   if (ParseDepends(Ver,"Breaks",pkgCache::Dep::DpkgBreaks) == false)
+      return false;
    if (ParseDepends(Ver,"Replaces",pkgCache::Dep::Replaces) == false)
       return false;
 
@@ -193,6 +195,7 @@ unsigned short debListParser::VersionHash()
 //                            "Suggests",
 //                            "Recommends",
                             "Conflicts",
+                            "Breaks",
                             "Replaces",0};
    unsigned long Result = INIT_FCS;
    char S[1024];

+ 28 - 12
apt-pkg/depcache.cc

@@ -273,7 +273,7 @@ bool pkgDepCache::CheckDep(DepIterator Dep,int Type,PkgIterator &Res)
       we allow it anyhow because dpkg does. Technically it is a packaging
       bug. Conflicts may never self match */
    if (Dep.TargetPkg() != Dep.ParentPkg() || 
-       (Dep->Type != Dep::Conflicts && Dep->Type != Dep::Obsoletes))
+       (Dep->Type != Dep::Conflicts && Dep->Type != Dep::DpkgBreaks && Dep->Type != Dep::Obsoletes))
    {
       PkgIterator Pkg = Dep.TargetPkg();
       // Check the base package
@@ -303,7 +303,8 @@ bool pkgDepCache::CheckDep(DepIterator Dep,int Type,PkgIterator &Res)
    {
       /* Provides may never be applied against the same package if it is
          a conflicts. See the comment above. */
-      if (P.OwnerPkg() == Pkg && Dep->Type == Dep::Conflicts)
+      if (P.OwnerPkg() == Pkg &&
+	  (Dep->Type == Dep::Conflicts || Dep->Type == Dep::DpkgBreaks))
 	 continue;
       
       // Check if the provides is a hit
@@ -457,7 +458,9 @@ void pkgDepCache::BuildGroupOrs(VerIterator const &V)
 
       /* Invert for Conflicts. We have to do this twice to get the
          right sense for a conflicts group */
-      if (D->Type == Dep::Conflicts || D->Type == Dep::Obsoletes)
+      if (D->Type == Dep::Conflicts ||
+	  D->Type == Dep::DpkgBreaks ||
+	  D->Type == Dep::Obsoletes)
 	 State = ~State;
       
       // Add to the group if we are within an or..
@@ -468,7 +471,9 @@ void pkgDepCache::BuildGroupOrs(VerIterator const &V)
 	 Group = 0;
       
       // Invert for Conflicts
-      if (D->Type == Dep::Conflicts || D->Type == Dep::Obsoletes)
+      if (D->Type == Dep::Conflicts ||
+	  D->Type == Dep::DpkgBreaks ||
+	  D->Type == Dep::Obsoletes)
 	 State = ~State;
    }	 
 }
@@ -601,7 +606,9 @@ void pkgDepCache::Update(OpProgress *Prog)
 	       Group = 0;
 
 	    // Invert for Conflicts
-	    if (D->Type == Dep::Conflicts || D->Type == Dep::Obsoletes)
+	    if (D->Type == Dep::Conflicts ||
+		D->Type == Dep::DpkgBreaks ||
+		D->Type == Dep::Obsoletes)
 	       State = ~State;
 	 }	 
       }
@@ -631,7 +638,9 @@ void pkgDepCache::Update(DepIterator D)
       State = DependencyState(D);
     
       // Invert for Conflicts
-      if (D->Type == Dep::Conflicts || D->Type == Dep::Obsoletes)
+      if (D->Type == Dep::Conflicts ||
+	  D->Type == Dep::DpkgBreaks ||
+	  D->Type == Dep::Obsoletes)
 	 State = ~State;
 
       RemoveStates(D.ParentPkg());
@@ -894,7 +903,8 @@ void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst,
       /* This bit is for processing the possibilty of an install/upgrade
          fixing the problem */
       SPtrArray<Version *> List = Start.AllTargets();
-      if ((DepState[Start->ID] & DepCVer) == DepCVer)
+      if (Start->Type != Dep::DpkgBreaks &&
+	  (DepState[Start->ID] & DepCVer) == DepCVer)
       {
 	 // Right, find the best version to install..
 	 Version **Cur = List;
@@ -939,17 +949,23 @@ void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst,
 	 }
 	 continue;
       }
-      
+
       /* For conflicts we just de-install the package and mark as auto,
-         Conflicts may not have or groups */
-      if (Start->Type == Dep::Conflicts || Start->Type == Dep::Obsoletes)
+         Conflicts may not have or groups.  For dpkg's Breaks we try to
+         upgrade the package. */
+      if (Start->Type == Dep::Conflicts || Start->Type == Dep::Obsoletes ||
+	  Start->Type == Dep::DpkgBreaks)
       {
 	 for (Version **I = List; *I != 0; I++)
 	 {
 	    VerIterator Ver(*this,*I);
 	    PkgIterator Pkg = Ver.ParentPkg();
-      
-	    MarkDelete(Pkg);
+
+	    if (Start->Type != Dep::DpkgBreaks)
+	       MarkDelete(Pkg);
+	    else
+	       if (PkgState[Pkg->ID].CandidateVer != *I)
+		  MarkInstall(Pkg,true,Depth + 1, false, ForceImportantDeps);
 	 }
 	 continue;
       }      

+ 16 - 1
apt-pkg/orderlist.cc

@@ -491,11 +491,13 @@ bool pkgOrderList::VisitProvides(DepIterator D,bool Critical)
 	 continue;
       
       if (D->Type != pkgCache::Dep::Conflicts &&
+	  D->Type != pkgCache::Dep::DpkgBreaks &&
 	  D->Type != pkgCache::Dep::Obsoletes &&
 	  Cache[Pkg].InstallVer != *I)
 	 continue;
       
       if ((D->Type == pkgCache::Dep::Conflicts ||
+	   D->Type == pkgCache::Dep::DpkgBreaks ||
 	   D->Type == pkgCache::Dep::Obsoletes) &&
 	  (Version *)Pkg.CurrentVer() != *I)
 	 continue;
@@ -630,6 +632,7 @@ bool pkgOrderList::DepUnPackCrit(DepIterator D)
 	 /* Forward critical dependencies MUST be correct before the 
 	    package can be unpacked. */
 	 if (D->Type != pkgCache::Dep::Conflicts &&
+	     D->Type != pkgCache::Dep::DpkgBreaks &&
 	     D->Type != pkgCache::Dep::Obsoletes &&
 	     D->Type != pkgCache::Dep::PreDepends)
 	    continue;
@@ -668,7 +671,7 @@ bool pkgOrderList::DepUnPackCrit(DepIterator D)
    }   
    return true;
 }
-									/*}}}*/
+
 // OrderList::DepUnPackPreD - Critical UnPacking ordering with depends	/*{{{*/
 // ---------------------------------------------------------------------
 /* Critical PreDepends (also configure immediate and essential) strives to
@@ -803,9 +806,20 @@ bool pkgOrderList::DepUnPackDep(DepIterator D)
 	       return false;
 	 }
 	 else
+	 {
 	    if (D->Type == pkgCache::Dep::Depends)
 	       if (VisitProvides(D,false) == false)
 		  return false;
+
+	    if (D->Type == pkgCache::Dep::DpkgBreaks)
+	    {
+	       if (CheckDep(D) == true)
+		 continue;
+
+	       if (VisitNode(D.TargetPkg()) == false)
+		 return false;
+	    }
+	 }
       }
    return true;
 }
@@ -953,6 +967,7 @@ bool pkgOrderList::CheckDep(DepIterator D)
       /* Conflicts requires that all versions are not present, depends
          just needs one */
       if (D->Type != pkgCache::Dep::Conflicts && 
+	  D->Type != pkgCache::Dep::DpkgBreaks && 
 	  D->Type != pkgCache::Dep::Obsoletes)
       {
 	 /* Try to find something that does not have the after flag set

+ 7 - 4
apt-pkg/pkgcache.cc

@@ -54,7 +54,7 @@ pkgCache::Header::Header()
    
    /* Whenever the structures change the major version should be bumped,
       whenever the generator changes the minor version should be bumped. */
-   MajorVersion = 5;
+   MajorVersion = 6;
    MinorVersion = 0;
    Dirty = false;
    
@@ -228,8 +228,8 @@ const char *pkgCache::DepType(unsigned char Type)
 {
    const char *Types[] = {"",_("Depends"),_("PreDepends"),_("Suggests"),
                           _("Recommends"),_("Conflicts"),_("Replaces"),
-                          _("Obsoletes")};
-   if (Type < 8)
+                          _("Obsoletes"),_("Breaks")};
+   if (Type < sizeof(Types)/sizeof(*Types))
       return Types[Type];
    return "";
 }
@@ -292,10 +292,11 @@ pkgCache::PkgIterator::OkState pkgCache::PkgIterator::State() const
 // DepIterator::IsCritical - Returns true if the dep is important	/*{{{*/
 // ---------------------------------------------------------------------
 /* Currently critical deps are defined as depends, predepends and
-   conflicts. */
+   conflicts (including dpkg's Breaks fields). */
 bool pkgCache::DepIterator::IsCritical()
 {
    if (Dep->Type == pkgCache::Dep::Conflicts ||
+       Dep->Type == pkgCache::Dep::DpkgBreaks ||
        Dep->Type == pkgCache::Dep::Obsoletes ||
        Dep->Type == pkgCache::Dep::Depends ||
        Dep->Type == pkgCache::Dep::PreDepends)
@@ -381,6 +382,7 @@ pkgCache::Version **pkgCache::DepIterator::AllTargets()
 	    continue;
 
 	 if ((Dep->Type == pkgCache::Dep::Conflicts ||
+	      Dep->Type == pkgCache::Dep::DpkgBreaks ||
 	      Dep->Type == pkgCache::Dep::Obsoletes) &&
 	     ParentPkg() == I.ParentPkg())
 	    continue;
@@ -397,6 +399,7 @@ pkgCache::Version **pkgCache::DepIterator::AllTargets()
 	    continue;
 	 
 	 if ((Dep->Type == pkgCache::Dep::Conflicts ||
+	      Dep->Type == pkgCache::Dep::DpkgBreaks ||
 	      Dep->Type == pkgCache::Dep::Obsoletes) &&
 	     ParentPkg() == I.OwnerPkg())
 	    continue;

+ 5 - 1
apt-pkg/pkgcache.h

@@ -66,10 +66,14 @@ class pkgCache
    class Namespace;
    
    // These are all the constants used in the cache structures
+
+   // WARNING - if you change these lists you must also edit
+   // the stringification in pkgcache.cc and also consider whether
+   // the cache file will become incompatible.
    struct Dep
    {
       enum DepType {Depends=1,PreDepends=2,Suggests=3,Recommends=4,
-	 Conflicts=5,Replaces=6,Obsoletes=7};
+	 Conflicts=5,Replaces=6,Obsoletes=7,DpkgBreaks=8};
       enum DepCompareOp {Or=0x10,NoOp=0,LessEq=0x1,GreaterEq=0x2,Less=0x3,
 	 Greater=0x4,Equals=0x5,NotEquals=0x6};
    };

+ 1 - 0
apt-pkg/tagfile.cc

@@ -422,6 +422,7 @@ static const char *iTFRewritePackageOrder[] = {
                           "Recommends",
                           "Suggests",
                           "Conflicts",
+                          "Breaks",
                           "Conffiles",
                           "Filename",
                           "Size",

+ 8 - 2
cmdline/apt-cache.cc

@@ -102,13 +102,15 @@ bool UnMet(CommandLine &CmdL)
 	    if (End->Type != pkgCache::Dep::PreDepends &&
 		End->Type != pkgCache::Dep::Depends && 
 		End->Type != pkgCache::Dep::Suggests &&
-		End->Type != pkgCache::Dep::Recommends)
+		End->Type != pkgCache::Dep::Recommends &&
+		End->Type != pkgCache::Dep::DpkgBreaks)
 	       continue;
 
 	    // Important deps only
 	    if (Important == true)
 	       if (End->Type != pkgCache::Dep::PreDepends &&
-		   End->Type != pkgCache::Dep::Depends)
+		   End->Type != pkgCache::Dep::Depends &&
+		   End->Type != pkgCache::Dep::DpkgBreaks)
 		  continue;
 	    
 	    // Verify the or group
@@ -869,6 +871,7 @@ bool XVcg(CommandLine &CmdL)
 		     then show the relation but do not recurse */
 		  if (Hit == false && 
 		      (D->Type == pkgCache::Dep::Conflicts ||
+		       D->Type == pkgCache::Dep::DpkgBreaks ||
 		       D->Type == pkgCache::Dep::Obsoletes))
 		  {
 		     if (Show[D.TargetPkg()->ID] == None && 
@@ -890,6 +893,9 @@ bool XVcg(CommandLine &CmdL)
 		  case pkgCache::Dep::Conflicts:
 		    printf("label: \"conflicts\" color: lightgreen }\n");
 		    break;
+		  case pkgCache::Dep::DpkgBreaks:
+		    printf("label: \"breaks\" color: lightgreen }\n");
+		    break;
 		  case pkgCache::Dep::Obsoletes:
 		    printf("label: \"obsoletes\" color: lightgreen }\n");
 		    break;

+ 1 - 1
configure.in

@@ -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.45ubuntu5")
+AC_DEFINE_UNQUOTED(VERSION,"0.6.45ubuntu6")
 PACKAGE="apt"
 AC_DEFINE_UNQUOTED(PACKAGE,"$PACKAGE")
 AC_SUBST(PACKAGE)

+ 12 - 2
debian/changelog

@@ -1,13 +1,23 @@
 apt (0.6.45ubuntu6) edgy; urgency=low
 
+  [Michael Vogt]
   * cmdline/apt-get.cc:
     - always show auto-removable packages and give a hint how to remove 
       them
   * debian/apt.conf.autoremove:
     - exlucde linux-image and linux-restricted-modules from ever being 
       auto-removed
-
- --
+  [Ian Jackson]
+  * Tests pass without code changes!  Except that we need this:
+  * Bump cache file major version to force rebuild so that Breaks
+    dependencies are included.
+  * Don't depend on or suggest any particular dpkg or dpkg-dev versions;
+    --auto-deconfigure is very very old and dpkg-dev's Breaks support
+    is more or less orthogonal.
+  * Initial draft of `Breaks' implementation.  Appears to compile,
+    but as yet *completely untested*.
+
+ -- 
 
 apt (0.6.45ubuntu5) edgy; urgency=low
 

+ 1 - 1
debian/control

@@ -9,7 +9,7 @@ Build-Depends-Indep: debiandoc-sgml, docbook-utils (>= 0.6.12-1)
 
 Package: apt
 Architecture: any
-Depends: ${shlibs:Depends}, dpkg (>= 1.13.22ubuntu4)
+Depends: ${shlibs:Depends}
 Priority: important
 Replaces: libapt-pkg-doc (<< 0.3.7), libapt-pkg-dev (<< 0.3.7)
 Provides: ${libapt-pkg:provides}

+ 1 - 1
doc/apt-cache.8.xml

@@ -151,7 +151,7 @@ Reverse Provides:
        a dependency but were not provided by any package. Missing packages may 
        be in evidence if a full distribution is not accessed, or if a package
        (real or virtual) has been dropped from the distribution. Usually they
-       are referenced from Conflicts statements.</para>
+       are referenced from Conflicts or Breaks statements.</para>
        </listitem>
 
        <listitem><para><literal>Total distinct</literal> versions is the number of package versions 

+ 2 - 1
doc/cache.sgml

@@ -492,7 +492,7 @@ This is the parsed priority value of the package.
 Dependency contains the information for a single dependency record. The records
 are split up like this to ease processing by the client. The base of list
 linked list is Version.DependsList. All forms of dependencies are recorded
-here including Conflicts, Suggests and Recommends.
+here including Conflicts, Breaks, Suggests and Recommends.
 
 <p>
 Multiple depends on the same package must be grouped together in 
@@ -671,6 +671,7 @@ of them.
 #define pkgDEP_Recommends 4
 #define pkgDEP_Conflicts 5
 #define pkgDEP_Replaces 6
+#define pkgDEP_Breaks 8
 </example>
 </sect1>
 

+ 2 - 0
doc/dpkg-tech.sgml

@@ -46,6 +46,8 @@ The basic dpkg package control file supports the following major features:-
 	productivity of the package
 	<item>Conflicts, to specify a package which must NOT be installed
 	in order for the package to be configured
+	<item>Breaks, to specify a package which is broken by the
+	package and which should therefore not be configured while broken
 	</list>
 Each of these dependencies can specify a version and a depedency on that
 version, for example "<= 0.5-1", "== 2.7.2-1", etc. The comparators available

Разница между файлами не показана из-за своего большого размера
+ 243 - 517
po/apt-all.pot