Browse Source

initial Breaks implementation

tags/debian/0.7.21
Ian Jackson 15 years ago
parent
commit
308c7d30ed
13 changed files with 344 additions and 539 deletions
  1. +22
    -1
      apt-pkg/algorithms.cc
  2. +3
    -0
      apt-pkg/deb/deblistparser.cc
  3. +28
    -12
      apt-pkg/depcache.cc
  4. +16
    -1
      apt-pkg/orderlist.cc
  5. +6
    -3
      apt-pkg/pkgcache.cc
  6. +5
    -1
      apt-pkg/pkgcache.h
  7. +1
    -0
      apt-pkg/tagfile.cc
  8. +8
    -2
      cmdline/apt-cache.cc
  9. +7
    -0
      debian/changelog
  10. +1
    -1
      doc/apt-cache.8.xml
  11. +2
    -1
      doc/cache.sgml
  12. +2
    -0
      doc/dpkg-tech.sgml
  13. +243
    -517
      po/apt-all.pot

+ 22
- 1
apt-pkg/algorithms.cc View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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


+ 6
- 3
apt-pkg/pkgcache.cc View File

@@ -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 View File

@@ -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 View File

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


+ 8
- 2
cmdline/apt-cache.cc View File

@@ -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;


+ 7
- 0
debian/changelog View File

@@ -1,3 +1,10 @@
apt (0.6.45ubuntu6~iwj) unstable; urgency=low

* Initial draft of `Breaks' implementation. Appears to compile,
but as yet *completely untested*.

-- Ian Jackson <ian@davenant.greenend.org.uk> Fri, 25 Aug 2006 15:39:07 +0100

apt (0.6.45ubuntu5) edgy; urgency=low

* apt-pkg/pkgcachegen.cc:


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

@@ -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 View File

@@ -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 View File

@@ -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
File diff suppressed because it is too large
View File


Loading…
Cancel
Save