summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apt-pkg/cacheiterators.h18
-rw-r--r--apt-pkg/deb/deblistparser.cc8
-rw-r--r--apt-pkg/edsp.cc8
-rw-r--r--apt-pkg/pkgcache.cc61
-rw-r--r--apt-pkg/pkgcache.h16
-rw-r--r--apt-pkg/pkgcachegen.cc32
-rw-r--r--apt-pkg/pkgcachegen.h15
-rw-r--r--apt-private/private-cmndline.cc1
-rw-r--r--cmdline/apt-cache.cc11
-rw-r--r--doc/apt-cache.8.xml15
-rwxr-xr-xtest/integration/test-apt-cache78
-rwxr-xr-xtest/integration/test-ordering-ignore-not-matching-breaks56
12 files changed, 169 insertions, 150 deletions
diff --git a/apt-pkg/cacheiterators.h b/apt-pkg/cacheiterators.h
index 7e6adb92f..1063d6f9e 100644
--- a/apt-pkg/cacheiterators.h
+++ b/apt-pkg/cacheiterators.h
@@ -295,7 +295,16 @@ class pkgCache::DepIterator : public Iterator<Dependency, DepIterator> {
bool IsNegative() const APT_PURE;
bool IsIgnorable(PrvIterator const &Prv) const APT_PURE;
bool IsIgnorable(PkgIterator const &Pkg) const APT_PURE;
- bool IsMultiArchImplicit() const APT_PURE;
+ /* MultiArch can be translated to SingleArch for an resolver and we did so,
+ by adding dependencies to help the resolver understand the problem, but
+ sometimes it is needed to identify these to ignore them… */
+ inline bool IsMultiArchImplicit() const APT_PURE {
+ return (S2->CompareOp & pkgCache::Dep::MultiArchImplicit) == pkgCache::Dep::MultiArchImplicit;
+ }
+ /* This covers additionally negative dependencies, which aren't arch-specific,
+ but change architecture nontheless as a Conflicts: foo does applies for all archs */
+ bool IsImplicit() const APT_PURE;
+
bool IsSatisfied(VerIterator const &Ver) const APT_PURE;
bool IsSatisfied(PrvIterator const &Prv) const APT_PURE;
void GlobOr(DepIterator &Start,DepIterator &End);
@@ -367,7 +376,12 @@ class pkgCache::PrvIterator : public Iterator<Provides, PrvIterator> {
inline VerIterator OwnerVer() const {return VerIterator(*Owner,Owner->VerP + S->Version);}
inline PkgIterator OwnerPkg() const {return PkgIterator(*Owner,Owner->PkgP + Owner->VerP[S->Version].ParentPkg);}
- bool IsMultiArchImplicit() const APT_PURE;
+ /* MultiArch can be translated to SingleArch for an resolver and we did so,
+ by adding provides to help the resolver understand the problem, but
+ sometimes it is needed to identify these to ignore them… */
+ bool IsMultiArchImplicit() const APT_PURE
+ { return (S->Flags & pkgCache::Flag::MultiArchImplicit) == pkgCache::Flag::MultiArchImplicit; }
+
inline PrvIterator() : Iterator<Provides, PrvIterator>(), Type(PrvVer) {}
inline PrvIterator(pkgCache &Owner, Provides *Trg, Version*) :
diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc
index e57a3524f..df0879641 100644
--- a/apt-pkg/deb/deblistparser.cc
+++ b/apt-pkg/deb/deblistparser.cc
@@ -812,7 +812,7 @@ bool debListParser::ParseDepends(pkgCache::VerIterator &Ver,
// … but this is probably the best thing to do.
if (Arch == "native")
Arch = _config->Find("APT::Architecture");
- if (NewDepends(Ver,Package,Arch,Version,Op,Type) == false)
+ if (NewDepends(Ver,Package,Arch,Version,Op | pkgCache::Dep::ArchSpecific,Type) == false)
return false;
}
else
@@ -858,13 +858,13 @@ bool debListParser::ParseProvides(pkgCache::VerIterator &Ver)
} else if (archfound != string::npos) {
string OtherArch = Package.substr(archfound+1, string::npos);
Package = Package.substr(0, archfound);
- if (NewProvides(Ver, Package, OtherArch, Version) == false)
+ if (NewProvides(Ver, Package, OtherArch, Version, pkgCache::Flag::ArchSpecific) == false)
return false;
} else if ((Ver->MultiArch & pkgCache::Version::Foreign) == pkgCache::Version::Foreign) {
if (NewProvidesAllArch(Ver, Package, Version) == false)
return false;
} else {
- if (NewProvides(Ver, Package, Arch, Version) == false)
+ if (NewProvides(Ver, Package, Arch, Version, 0) == false)
return false;
}
@@ -890,7 +890,7 @@ bool debListParser::NewProvidesAllArch(pkgCache::VerIterator &Ver, string const
for (std::vector<string>::const_iterator a = Architectures.begin();
a != Architectures.end(); ++a)
{
- if (NewProvides(Ver, Package, *a, Version) == false)
+ if (NewProvides(Ver, Package, *a, Version, pkgCache::Flag::MultiArchImplicit) == false)
return false;
}
return true;
diff --git a/apt-pkg/edsp.cc b/apt-pkg/edsp.cc
index 5c53581fe..34b0b0cc7 100644
--- a/apt-pkg/edsp.cc
+++ b/apt-pkg/edsp.cc
@@ -102,11 +102,11 @@ static void WriteScenarioDependency( FILE* output, pkgCache::VerIterator const &
bool orGroup = false;
for (pkgCache::DepIterator Dep = Ver.DependsList(); Dep.end() == false; ++Dep)
{
- if (Dep.IsMultiArchImplicit() == true)
+ if (Dep.IsImplicit() == true)
continue;
if (orGroup == false)
dependencies[Dep->Type].append(", ");
- dependencies[Dep->Type].append(Dep.TargetPkg().Name());
+ dependencies[Dep->Type].append(Dep.TargetPkg().FullName((Dep->CompareOp & pkgCache::Dep::ArchSpecific) != pkgCache::Dep::ArchSpecific));
if (Dep->Version != 0)
dependencies[Dep->Type].append(" (").append(pkgCache::CompTypeDeb(Dep->CompareOp)).append(" ").append(Dep.TargetVer()).append(")");
if ((Dep->CompareOp & pkgCache::Dep::Or) == pkgCache::Dep::Or)
@@ -140,7 +140,7 @@ static void WriteScenarioLimitedDependency(FILE* output,
bool orGroup = false;
for (pkgCache::DepIterator Dep = Ver.DependsList(); Dep.end() == false; ++Dep)
{
- if (Dep.IsMultiArchImplicit() == true)
+ if (Dep.IsImplicit() == true)
continue;
if (orGroup == false)
{
@@ -156,7 +156,7 @@ static void WriteScenarioLimitedDependency(FILE* output,
orGroup = false;
continue;
}
- dependencies[Dep->Type].append(Dep.TargetPkg().Name());
+ dependencies[Dep->Type].append(Dep.TargetPkg().FullName((Dep->CompareOp & pkgCache::Dep::ArchSpecific) != pkgCache::Dep::ArchSpecific));
if (Dep->Version != 0)
dependencies[Dep->Type].append(" (").append(pkgCache::CompTypeDeb(Dep->CompareOp)).append(" ").append(Dep.TargetVer()).append(")");
if ((Dep->CompareOp & pkgCache::Dep::Or) == pkgCache::Dep::Or)
diff --git a/apt-pkg/pkgcache.cc b/apt-pkg/pkgcache.cc
index 5034ee38a..e8c95738e 100644
--- a/apt-pkg/pkgcache.cc
+++ b/apt-pkg/pkgcache.cc
@@ -727,21 +727,7 @@ bool pkgCache::DepIterator::IsIgnorable(PkgIterator const &PT) const
// ignore group-conflict on a M-A:same package - but not our implicit dependencies
// so that we can have M-A:same packages conflicting with their own real name
if ((PV->MultiArch & pkgCache::Version::Same) == pkgCache::Version::Same)
- {
- // Replaces: ${self}:other ( << ${binary:Version})
- if (S2->Type == pkgCache::Dep::Replaces)
- {
- if (S2->CompareOp == pkgCache::Dep::Less && strcmp(PV.VerStr(), TargetVer()) == 0)
- return false;
- }
- // Breaks: ${self}:other (!= ${binary:Version})
- else if (S2->Type == pkgCache::Dep::DpkgBreaks)
- {
- if (S2->CompareOp == pkgCache::Dep::NotEquals && strcmp(PV.VerStr(), TargetVer()) == 0)
- return false;
- }
- return true;
- }
+ return IsMultiArchImplicit() == false;
return false;
}
@@ -756,27 +742,12 @@ bool pkgCache::DepIterator::IsIgnorable(PrvIterator const &Prv) const
if (Prv.OwnerPkg()->Group == Pkg->Group)
return true;
// Implicit group-conflicts should not be applied on providers of other groups
- if (Pkg->Group == TargetPkg()->Group && Prv.OwnerPkg()->Group != Pkg->Group)
+ if (IsMultiArchImplicit() && Prv.OwnerPkg()->Group != Pkg->Group)
return true;
return false;
}
/*}}}*/
-// DepIterator::IsMultiArchImplicit - added by the cache generation /*{{{*/
-// ---------------------------------------------------------------------
-/* MultiArch can be translated to SingleArch for an resolver and we did so,
- by adding dependencies to help the resolver understand the problem, but
- sometimes it is needed to identify these to ignore them… */
-bool pkgCache::DepIterator::IsMultiArchImplicit() const
-{
- if (ParentPkg()->Arch != TargetPkg()->Arch &&
- (S2->Type == pkgCache::Dep::Replaces ||
- S2->Type == pkgCache::Dep::DpkgBreaks ||
- S2->Type == pkgCache::Dep::Conflicts))
- return true;
- return false;
-}
- /*}}}*/
// DepIterator::IsSatisfied - check if a version satisfied the dependency /*{{{*/
bool pkgCache::DepIterator::IsSatisfied(VerIterator const &Ver) const
{
@@ -787,6 +758,20 @@ bool pkgCache::DepIterator::IsSatisfied(PrvIterator const &Prv) const
return Owner->VS->CheckDep(Prv.ProvideVersion(),S2->CompareOp,TargetVer());
}
/*}}}*/
+// DepIterator::IsImplicit - added by the cache generation /*{{{*/
+bool pkgCache::DepIterator::IsImplicit() const
+{
+ if (IsMultiArchImplicit() == true)
+ return true;
+ if (IsNegative() || S2->Type == pkgCache::Dep::Replaces)
+ {
+ if ((S2->CompareOp & pkgCache::Dep::ArchSpecific) != pkgCache::Dep::ArchSpecific &&
+ strcmp(ParentPkg().Arch(), TargetPkg().Arch()) != 0)
+ return true;
+ }
+ return false;
+}
+ /*}}}*/
// ostream operator to handle string representation of a dependecy /*{{{*/
// ---------------------------------------------------------------------
/* */
@@ -1067,19 +1052,5 @@ pkgCache::DescIterator pkgCache::VerIterator::TranslatedDescription() const
}
/*}}}*/
-// PrvIterator::IsMultiArchImplicit - added by the cache generation /*{{{*/
-// ---------------------------------------------------------------------
-/* MultiArch can be translated to SingleArch for an resolver and we did so,
- by adding provides to help the resolver understand the problem, but
- sometimes it is needed to identify these to ignore them… */
-bool pkgCache::PrvIterator::IsMultiArchImplicit() const
-{
- pkgCache::PkgIterator const Owner = OwnerPkg();
- pkgCache::PkgIterator const Parent = ParentPkg();
- if (strcmp(Owner.Arch(), Parent.Arch()) != 0 || Owner.Group()->Name == Parent.Group()->Name)
- return true;
- return false;
-}
- /*}}}*/
pkgCache::~pkgCache() {}
diff --git a/apt-pkg/pkgcache.h b/apt-pkg/pkgcache.h
index fba692982..8a726085e 100644
--- a/apt-pkg/pkgcache.h
+++ b/apt-pkg/pkgcache.h
@@ -149,8 +149,12 @@ class pkgCache /*{{{*/
The lower 4 bits are used to indicate what operator is being specified and
the upper 4 bits are flags. OR indicates that the next package is
or'd with the current package. */
- enum DepCompareOp {Or=0x10,NoOp=0,LessEq=0x1,GreaterEq=0x2,Less=0x3,
- Greater=0x4,Equals=0x5,NotEquals=0x6};
+ enum DepCompareOp {NoOp=0,LessEq=0x1,GreaterEq=0x2,Less=0x3,
+ Greater=0x4,Equals=0x5,NotEquals=0x6,
+ Or=0x10, /*!< or'ed with the next dependency */
+ MultiArchImplicit=0x20, /*!< generated internally, not spelled out in the index */
+ ArchSpecific=0x40 /*!< was decorated with an explicit architecture in index */
+ };
};
struct State
@@ -178,6 +182,10 @@ class pkgCache /*{{{*/
NotAutomatic=(1<<0), /*!< archive has a default pin of 1 */
ButAutomaticUpgrades=(1<<1), /*!< (together with the previous) archive has a default pin of 100 */
};
+ enum ProvidesFlags {
+ MultiArchImplicit=pkgCache::Dep::MultiArchImplicit, /*!< generated internally, not spelled out in the index */
+ ArchSpecific=pkgCache::Dep::ArchSpecific /*!< was decorated with an explicit architecture in index */
+ };
};
protected:
@@ -725,9 +733,9 @@ struct pkgCache::Provides
/** \brief version in the provides line (if any)
This version allows dependencies to depend on specific versions of a
- Provides, as well as allowing Provides to override existing packages.
- This is experimental. Note that Debian doesn't allow versioned provides */
+ Provides, as well as allowing Provides to override existing packages. */
map_stringitem_t ProvideVersion;
+ map_flags_t Flags;
/** \brief next provides (based of package) */
map_pointer_t NextProvides; // Provides
/** \brief next provides (based of version) */
diff --git a/apt-pkg/pkgcachegen.cc b/apt-pkg/pkgcachegen.cc
index a82483d15..9acb2563a 100644
--- a/apt-pkg/pkgcachegen.cc
+++ b/apt-pkg/pkgcachegen.cc
@@ -709,16 +709,16 @@ bool pkgCacheGenerator::AddImplicitDepends(pkgCache::GrpIterator &G,
{
// Replaces: ${self}:other ( << ${binary:Version})
NewDepends(D, V, VerStrIdx,
- pkgCache::Dep::Less, pkgCache::Dep::Replaces,
+ pkgCache::Dep::Less | pkgCache::Dep::MultiArchImplicit, pkgCache::Dep::Replaces,
OldDepLast);
// Breaks: ${self}:other (!= ${binary:Version})
NewDepends(D, V, VerStrIdx,
- pkgCache::Dep::NotEquals, pkgCache::Dep::DpkgBreaks,
+ pkgCache::Dep::NotEquals | pkgCache::Dep::MultiArchImplicit, pkgCache::Dep::DpkgBreaks,
OldDepLast);
} else {
// Conflicts: ${self}:other
NewDepends(D, V, 0,
- pkgCache::Dep::NoOp, pkgCache::Dep::Conflicts,
+ pkgCache::Dep::NoOp | pkgCache::Dep::MultiArchImplicit, pkgCache::Dep::Conflicts,
OldDepLast);
}
}
@@ -737,16 +737,16 @@ bool pkgCacheGenerator::AddImplicitDepends(pkgCache::VerIterator &V,
map_stringitem_t const VerStrIdx = V->VerStr;
// Replaces: ${self}:other ( << ${binary:Version})
NewDepends(D, V, VerStrIdx,
- pkgCache::Dep::Less, pkgCache::Dep::Replaces,
+ pkgCache::Dep::Less | pkgCache::Dep::MultiArchImplicit, pkgCache::Dep::Replaces,
OldDepLast);
// Breaks: ${self}:other (!= ${binary:Version})
NewDepends(D, V, VerStrIdx,
- pkgCache::Dep::NotEquals, pkgCache::Dep::DpkgBreaks,
+ pkgCache::Dep::NotEquals | pkgCache::Dep::MultiArchImplicit, pkgCache::Dep::DpkgBreaks,
OldDepLast);
} else {
// Conflicts: ${self}:other
NewDepends(D, V, 0,
- pkgCache::Dep::NoOp, pkgCache::Dep::Conflicts,
+ pkgCache::Dep::NoOp | pkgCache::Dep::MultiArchImplicit, pkgCache::Dep::Conflicts,
OldDepLast);
}
return true;
@@ -913,8 +913,8 @@ map_pointer_t pkgCacheGenerator::NewDescription(pkgCache::DescIterator &Desc,
bool pkgCacheGenerator::NewDepends(pkgCache::PkgIterator &Pkg,
pkgCache::VerIterator &Ver,
string const &Version,
- unsigned int const &Op,
- unsigned int const &Type,
+ uint8_t const Op,
+ uint8_t const Type,
map_stringitem_t* &OldDepLast)
{
map_stringitem_t index = 0;
@@ -940,8 +940,8 @@ bool pkgCacheGenerator::NewDepends(pkgCache::PkgIterator &Pkg,
bool pkgCacheGenerator::NewDepends(pkgCache::PkgIterator &Pkg,
pkgCache::VerIterator &Ver,
map_pointer_t const Version,
- unsigned int const &Op,
- unsigned int const &Type,
+ uint8_t const Op,
+ uint8_t const Type,
map_pointer_t* &OldDepLast)
{
void const * const oldMap = Map.Data();
@@ -1040,8 +1040,8 @@ bool pkgCacheGenerator::ListParser::NewDepends(pkgCache::VerIterator &Ver,
const string &PackageName,
const string &Arch,
const string &Version,
- unsigned int Op,
- unsigned int Type)
+ uint8_t const Op,
+ uint8_t const Type)
{
pkgCache::GrpIterator Grp;
Dynamic<pkgCache::GrpIterator> DynGrp(Grp);
@@ -1073,12 +1073,11 @@ bool pkgCacheGenerator::ListParser::NewDepends(pkgCache::VerIterator &Ver,
}
/*}}}*/
// ListParser::NewProvides - Create a Provides element /*{{{*/
-// ---------------------------------------------------------------------
-/* */
bool pkgCacheGenerator::ListParser::NewProvides(pkgCache::VerIterator &Ver,
- const string &PkgName,
+ const string &PkgName,
const string &PkgArch,
- const string &Version)
+ const string &Version,
+ uint8_t const Flags)
{
pkgCache &Cache = Owner->Cache;
@@ -1097,6 +1096,7 @@ bool pkgCacheGenerator::ListParser::NewProvides(pkgCache::VerIterator &Ver,
pkgCache::PrvIterator Prv(Cache,Cache.ProvideP + Provides,Cache.PkgP);
Dynamic<pkgCache::PrvIterator> DynPrv(Prv);
Prv->Version = Ver.Index();
+ Prv->Flags = Flags;
Prv->NextPkgProv = Ver->ProvidesList;
Ver->ProvidesList = Prv.Index();
if (Version.empty() == false) {
diff --git a/apt-pkg/pkgcachegen.h b/apt-pkg/pkgcachegen.h
index c56b5abae..c5527ff30 100644
--- a/apt-pkg/pkgcachegen.h
+++ b/apt-pkg/pkgcachegen.h
@@ -82,11 +82,11 @@ class APT_HIDDEN pkgCacheGenerator /*{{{*/
bool NewFileVer(pkgCache::VerIterator &Ver,ListParser &List);
bool NewFileDesc(pkgCache::DescIterator &Desc,ListParser &List);
bool NewDepends(pkgCache::PkgIterator &Pkg, pkgCache::VerIterator &Ver,
- std::string const &Version, unsigned int const &Op,
- unsigned int const &Type, map_pointer_t* &OldDepLast);
+ std::string const &Version, uint8_t const Op,
+ uint8_t const Type, map_pointer_t* &OldDepLast);
bool NewDepends(pkgCache::PkgIterator &Pkg, pkgCache::VerIterator &Ver,
- map_pointer_t const Version, unsigned int const &Op,
- unsigned int const &Type, map_pointer_t* &OldDepLast);
+ map_pointer_t const Version, uint8_t const Op,
+ uint8_t const Type, map_pointer_t* &OldDepLast);
map_pointer_t NewVersion(pkgCache::VerIterator &Ver,const std::string &VerStr,map_pointer_t const Next) APT_DEPRECATED
{ return NewVersion(Ver, VerStr, 0, 0, Next); }
map_pointer_t NewVersion(pkgCache::VerIterator &Ver,const std::string &VerStr,
@@ -162,10 +162,11 @@ class APT_HIDDEN pkgCacheGenerator::ListParser
inline map_stringitem_t WriteString(const std::string &S) {return Owner->WriteStringInMap(S);};
inline map_stringitem_t WriteString(const char *S,unsigned int Size) {return Owner->WriteStringInMap(S,Size);};
bool NewDepends(pkgCache::VerIterator &Ver,const std::string &Package, const std::string &Arch,
- const std::string &Version,unsigned int Op,
- unsigned int Type);
+ const std::string &Version,uint8_t const Op,
+ uint8_t const Type);
bool NewProvides(pkgCache::VerIterator &Ver,const std::string &PkgName,
- const std::string &PkgArch, const std::string &Version);
+ const std::string &PkgArch, const std::string &Version,
+ uint8_t const Flags);
public:
diff --git a/apt-private/private-cmndline.cc b/apt-private/private-cmndline.cc
index 71dceb559..cfdc13259 100644
--- a/apt-private/private-cmndline.cc
+++ b/apt-private/private-cmndline.cc
@@ -51,6 +51,7 @@ static bool addArgumentsAPTCache(std::vector<CommandLine::Args> &Args, char cons
addArg(0, "conflicts", "APT::Cache::ShowConflicts", 0);
addArg(0, "enhances", "APT::Cache::ShowEnhances", 0);
addArg(0, "recurse", "APT::Cache::RecurseDepends", 0);
+ addArg(0, "implicit", "APT::Cache::ShowImplicit", 0);
}
else if (CmdMatches("search"))
{
diff --git a/cmdline/apt-cache.cc b/cmdline/apt-cache.cc
index 2fc721f69..1eb891e8e 100644
--- a/cmdline/apt-cache.cc
+++ b/cmdline/apt-cache.cc
@@ -689,6 +689,7 @@ static bool ShowDepends(CommandLine &CmdL, bool const RevDepends)
bool const ShowBreaks = _config->FindB("APT::Cache::ShowBreaks", Important == false);
bool const ShowEnhances = _config->FindB("APT::Cache::ShowEnhances", Important == false);
bool const ShowOnlyFirstOr = _config->FindB("APT::Cache::ShowOnlyFirstOr", false);
+ bool const ShowImplicit = _config->FindB("APT::Cache::ShowImplicit", false);
while (verset.empty() != true)
{
@@ -709,12 +710,16 @@ static bool ShowDepends(CommandLine &CmdL, bool const RevDepends)
case pkgCache::Dep::Depends: if (!ShowDepends) continue; break;
case pkgCache::Dep::Recommends: if (!ShowRecommends) continue; break;
case pkgCache::Dep::Suggests: if (!ShowSuggests) continue; break;
- case pkgCache::Dep::Replaces: if (!ShowReplaces) continue; break; case pkgCache::Dep::Conflicts: if (!ShowConflicts) continue; break;
+ case pkgCache::Dep::Replaces: if (!ShowReplaces) continue; break;
+ case pkgCache::Dep::Conflicts: if (!ShowConflicts) continue; break;
case pkgCache::Dep::DpkgBreaks: if (!ShowBreaks) continue; break;
case pkgCache::Dep::Enhances: if (!ShowEnhances) continue; break;
}
+ if (ShowImplicit == false && D.IsImplicit())
+ continue;
pkgCache::PkgIterator Trg = RevDepends ? D.ParentPkg() : D.TargetPkg();
+ bool const showNoArch = RevDepends || (D->CompareOp & pkgCache::Dep::ArchSpecific) != pkgCache::Dep::ArchSpecific;
if((Installed && Trg->CurrentVer != 0) || !Installed)
{
@@ -728,9 +733,9 @@ static bool ShowDepends(CommandLine &CmdL, bool const RevDepends)
if (ShowDepType == true)
cout << D.DepType() << ": ";
if (Trg->VersionList == 0)
- cout << "<" << Trg.FullName(true) << ">";
+ cout << "<" << Trg.FullName(showNoArch) << ">";
else
- cout << Trg.FullName(true);
+ cout << Trg.FullName(showNoArch);
if (ShowVersion == true && D->Version != 0)
cout << " (" << pkgCache::CompTypeDeb(D->CompareOp) << ' ' << D.TargetVer() << ')';
cout << std::endl;
diff --git a/doc/apt-cache.8.xml b/doc/apt-cache.8.xml
index a9f6c8da2..e20f66770 100644
--- a/doc/apt-cache.8.xml
+++ b/doc/apt-cache.8.xml
@@ -281,12 +281,23 @@ Reverse Provides:
<term><option>--no-breaks</option></term>
<term><option>--no-replaces</option></term>
<term><option>--no-enhances</option></term>
- <listitem><para>Per default the <literal>depends</literal> and
- <literal>rdepends</literal> print all dependencies. This can be tweaked with
+ <listitem><para>Per default the <command>depends</command> and
+ <command>rdepends</command> print all dependencies. This can be tweaked with
these flags which will omit the specified dependency type.
Configuration Item: <literal>APT::Cache::Show<replaceable>DependencyType</replaceable></literal>
e.g. <literal>APT::Cache::ShowRecommends</literal>.</para></listitem>
</varlistentry>
+
+ <varlistentry><term><option>--implicit</option></term>
+ <listitem><para>Per default <command>depends</command> and <command>rdepends</command>
+ print only dependencies explicitly expressed in the metadata. With this flag
+ it will also show dependencies implicitely added based on the encountered data.
+ A <literal>Conflicts: foo</literal> e.g. expresses implicitely that this package
+ also conflicts with the package foo from any other architecture.
+ Configuration Item: <literal>APT::Cache::ShowImplicit</literal>.
+ </para></listitem>
+ </varlistentry>
+
<varlistentry><term><option>-f</option></term><term><option>--full</option></term>
<listitem><para>Print full package records when searching.
Configuration Item: <literal>APT::Cache::ShowFull</literal>.</para></listitem>
diff --git a/test/integration/test-apt-cache b/test/integration/test-apt-cache
index a22b08c20..a8ddfd889 100755
--- a/test/integration/test-apt-cache
+++ b/test/integration/test-apt-cache
@@ -16,6 +16,9 @@ Recommends: cool (>= 2) | cooler (<< 5)' "$DESCR"
insertpackage 'unstable' 'bar' 'all' '1' 'Depends: bar
Breaks: foo (<< 1)
Replaces: foo (<< 1)' "$DESCR"
+insertpackage 'unstable' 'specific' 'all' '1' 'Depends: bar:i386, specific:amd64
+Breaks: foo:amd64 (<< 1)
+Replaces: foo:i386 (<< 1)' "$DESCR"
setupaptarchive
@@ -44,6 +47,7 @@ testsuccess test -s dump.output
testsuccessequal 'dpkg
bar
+specific
fancy
foo' aptcache pkgnames
testsuccessequal 'bar' aptcache pkgnames bar
@@ -57,29 +61,60 @@ testsuccessequal " foo | 1 | file:$(readlink -f .)/aptarchive uns
testsuccessequal 'foo
Depends: bar
Conflicts: <foobar>
- Conflicts: <foobar:i386>
|Recommends: <cool>
Recommends: <cooler>' aptcache depends foo
testsuccessequal 'foo
Depends: bar
Conflicts: <foobar>
Conflicts: <foobar:i386>
+ |Recommends: <cool>
+ Recommends: <cooler>' aptcache depends foo --implicit
+testsuccessequal 'foo
+ Depends: bar
+ Conflicts: <foobar>
Recommends: <cool>' aptcache depends foo -o APT::Cache::ShowOnlyFirstOr=1
testsuccessequal 'foo
Depends: bar
Conflicts: <foobar>
Conflicts: <foobar:i386>
+ Recommends: <cool>' aptcache depends foo -o APT::Cache::ShowOnlyFirstOr=1 --implicit
+testsuccessequal 'foo
+ Depends: bar
+ Conflicts: <foobar>
|Recommends: <cool> (>= 2)
Recommends: <cooler> (<< 5)' aptcache depends foo -o APT::Cache::ShowVersion=1
testsuccessequal 'foo
Depends: bar
Conflicts: <foobar>
- Conflicts: <foobar:i386>' aptcache depends foo --no-recommends
+ Conflicts: <foobar:i386>
+ |Recommends: <cool> (>= 2)
+ Recommends: <cooler> (<< 5)' aptcache depends foo -o APT::Cache::ShowVersion=1 --implicit
testsuccessequal 'foo
- Depends: bar' aptcache depends foo --important
+ Depends: bar
+ Conflicts: <foobar>' aptcache depends foo --no-recommends
+testsuccessequal 'foo
+ Depends: bar
+ Conflicts: <foobar>
+ Conflicts: <foobar:i386>' aptcache depends foo --no-recommends --implicit
+testsuccessequal 'foo
+ Depends: bar' aptcache depends foo --important --implicit
testsuccessequal 'foo
+ Conflicts: <foobar>' aptcache depends foo --important --no-depends --conflicts
+testsuccessequal 'foo
+ Conflicts: <foobar>
+ Conflicts: <foobar:i386>' aptcache depends foo --important --no-depends --conflicts --implicit
+testsuccessequal 'foo
+ Depends: bar
Conflicts: <foobar>
- Conflicts: <foobar:i386>' aptcache depends foo --important --no-depends --conflicts
+ |Recommends: <cool>
+ Recommends: <cooler>
+bar
+ Depends: bar
+ Breaks: foo
+ Replaces: foo
+<foobar>
+<cool>
+<cooler>' aptcache depends foo --recurse
testsuccessequal 'foo
Depends: bar
Conflicts: <foobar>
@@ -96,29 +131,58 @@ bar
<foobar:i386>
<cool>
<cooler>
-<foo:i386>' aptcache depends foo --recurse
+<foo:i386>' aptcache depends foo --recurse --implicit
+testsuccessequal 'foo
+ Depends: bar
+bar
+ Depends: bar
+ Replaces: foo' aptcache depends foo --recurse --important --replaces
testsuccessequal 'foo
Depends: bar
bar
Depends: bar
Replaces: foo
Replaces: <foo:i386>
-<foo:i386>' aptcache depends foo --recurse --important --replaces
+<foo:i386>' aptcache depends foo --recurse --important --replaces --implicit
+testsuccessequal 'bar
+ Depends: bar
+ Breaks: foo
+ Replaces: foo' aptcache depends bar
+testsuccessequal 'bar
+ Depends: bar
+ Breaks: foo
+ Breaks: <foo:i386>
+ Replaces: foo
+ Replaces: <foo:i386>' aptcache depends bar --implicit
+testsuccessequal 'specific
+ Depends: <bar:i386>
+ Depends: specific:amd64
+ Breaks: foo:amd64
+ Replaces: <foo:i386>' aptcache depends specific
+testsuccessequal 'specific
+ Depends: <bar:i386>
+ Depends: specific:amd64
+ Breaks: foo:amd64
+ Replaces: <foo:i386>' aptcache depends specific --implicit
## rdpends
testsuccessequal 'foo
Reverse Depends:
bar
+ specific
bar' aptcache rdepends foo
testsuccessequal 'foo
Reverse Depends:
Breaks: bar
+ Breaks: specific
Replaces: bar' aptcache rdepends foo -o APT::Cache::ShowDependencyType=1
testsuccessequal 'foo
Reverse Depends:
Breaks: bar (<< 1)
+ Breaks: specific (<< 1)
Replaces: bar (<< 1)' aptcache rdepends foo -o APT::Cache::ShowDependencyType=1 -o APT::Cache::ShowVersion=1
testsuccessequal 'foo
Reverse Depends:
- Breaks: bar (<< 1)' aptcache rdepends foo -o APT::Cache::ShowDependencyType=1 -o APT::Cache::ShowVersion=1 --important --breaks
+ Breaks: bar (<< 1)
+ Breaks: specific (<< 1)' aptcache rdepends foo -o APT::Cache::ShowDependencyType=1 -o APT::Cache::ShowVersion=1 --important --breaks
diff --git a/test/integration/test-ordering-ignore-not-matching-breaks b/test/integration/test-ordering-ignore-not-matching-breaks
deleted file mode 100755
index 7c1365bdd..000000000
--- a/test/integration/test-ordering-ignore-not-matching-breaks
+++ /dev/null
@@ -1,56 +0,0 @@
-#!/bin/sh
-set -e
-
-TESTDIR=$(readlink -f $(dirname $0))
-. $TESTDIR/framework
-setupenvironment
-configarchitecture 'amd64' 'i386'
-
-insertpackage 'unstable-mp' 'crda' 'i386,amd64' '1.1.1-1ubuntu4mp' 'Provides: wireless-crda
-Multi-Arch: foreign'
-insertpackage 'unstable-m' 'crda' 'i386,amd64' '1.1.1-1ubuntu4m' 'Multi-Arch: foreign'
-insertpackage 'unstable-p' 'crda' 'i386,amd64' '1.1.1-1ubuntu4p' 'Provides: wireless-crda'
-insertpackage 'unstable' 'wireless-crda' 'i386,amd64' '1.16'
-
-
-insertinstalledpackage 'wireless-crda' 'amd64' '1.14'
-
-setupaptarchive
-
-testsuccessequal 'Reading package lists...
-Building dependency tree...
-The following NEW packages will be installed:
- crda
-0 upgraded, 1 newly installed, 0 to remove and 1 not upgraded.
-Inst crda (1.1.1-1ubuntu4m unstable-m [amd64])
-Conf crda (1.1.1-1ubuntu4m unstable-m [amd64])' aptget install crda -s -t unstable-m
-
-testsuccessequal 'Reading package lists...
-Building dependency tree...
-The following NEW packages will be installed:
- crda
-0 upgraded, 1 newly installed, 0 to remove and 1 not upgraded.
-Inst crda (1.1.1-1ubuntu4p unstable-p [amd64])
-Conf crda (1.1.1-1ubuntu4p unstable-p [amd64])' aptget install crda -s -t unstable-p
-
-testsuccessequal 'Reading package lists...
-Building dependency tree...
-The following NEW packages will be installed:
- crda
-0 upgraded, 1 newly installed, 0 to remove and 1 not upgraded.
-Inst crda (1.1.1-1ubuntu4mp unstable-mp [amd64])
-Conf crda (1.1.1-1ubuntu4mp unstable-mp [amd64])' aptget install crda -s -t unstable-mp
-
-rm rootdir/var/lib/dpkg/status
-insertinstalledpackage 'crda' 'amd64' '1.1.1-1ubuntu4mp' 'Provides: wireless-crda
-Conflicts: wireless-crda (<< 1.15)
-Replaces: wireless-crda ( << 1.15)
-Multi-arch: foreign'
-
-testsuccessequal 'Reading package lists...
-Building dependency tree...
-The following NEW packages will be installed:
- wireless-crda
-0 upgraded, 1 newly installed, 0 to remove and 1 not upgraded.
-Inst wireless-crda (1.16 unstable [amd64])
-Conf wireless-crda (1.16 unstable [amd64])' aptget install wireless-crda -s -t unstable