summaryrefslogtreecommitdiff
path: root/apt-pkg
diff options
context:
space:
mode:
authorDavid Kalnischkies <kalnischkies@gmail.com>2010-02-12 00:04:31 +0100
committerDavid Kalnischkies <kalnischkies@gmail.com>2010-02-12 00:04:31 +0100
commit803ea2a87f81252b2c0d541b8502ed206ce57c84 (patch)
treef6d5f02637a7bcd62330c1a51bca42a34378c0b1 /apt-pkg
parentc5dac10c3dd6d8f54d97d3105803d07fa891fcd4 (diff)
downloadapt-803ea2a87f81252b2c0d541b8502ed206ce57c84.tar.gz
Add yet another pseudo package which isn't as pseudo as the others:
Arch all packages are now represented by arch depending packages which all depend on a package with the same name and the special arch "all". This packages has NO dependencies, but beside this the same information. It is the only package which has a size, the arch depending ones all have a zero size. While the arch depending pseudo packages are used for dependency resolution the arch "all" package is used for downloading and ordering of the package.
Diffstat (limited to 'apt-pkg')
-rw-r--r--apt-pkg/algorithms.cc52
-rw-r--r--apt-pkg/cacheiterators.h1
-rw-r--r--apt-pkg/deb/deblistparser.cc22
-rw-r--r--apt-pkg/depcache.cc4
-rw-r--r--apt-pkg/depcache.h1
-rw-r--r--apt-pkg/orderlist.cc4
-rw-r--r--apt-pkg/packagemanager.cc23
-rw-r--r--apt-pkg/pkgcache.cc12
-rw-r--r--apt-pkg/pkgcache.h2
-rw-r--r--apt-pkg/pkgcachegen.cc20
10 files changed, 124 insertions, 17 deletions
diff --git a/apt-pkg/algorithms.cc b/apt-pkg/algorithms.cc
index 34da745de..c905cffa9 100644
--- a/apt-pkg/algorithms.cc
+++ b/apt-pkg/algorithms.cc
@@ -83,13 +83,28 @@ void pkgSimulate::Describe(PkgIterator Pkg,ostream &out,bool Current,bool Candid
bool pkgSimulate::Install(PkgIterator iPkg,string /*File*/)
{
// Adapt the iterator
- PkgIterator Pkg = Sim.FindPkg(iPkg.Name());
+ PkgIterator Pkg = Sim.FindPkg(iPkg.Name(), iPkg.Arch());
Flags[Pkg->ID] = 1;
cout << "Inst ";
Describe(Pkg,cout,true,true);
Sim.MarkInstall(Pkg,false);
-
+
+ if (strcmp(Pkg.Arch(),"all") == 0)
+ {
+ pkgCache::GrpIterator G = Pkg.Group();
+ pkgCache::GrpIterator iG = iPkg.Group();
+ for (pkgCache::PkgIterator P = G.FindPkg("any"); P.end() != true; P = G.NextPkg(P))
+ {
+ if (strcmp(P.Arch(), "all") == 0)
+ continue;
+ if (iG.FindPkg(P.Arch())->CurrentVer == 0)
+ continue;
+ Flags[P->ID] = 1;
+ Sim.MarkInstall(P, false);
+ }
+ }
+
// Look for broken conflicts+predepends.
for (PkgIterator I = Sim.PkgBegin(); I.end() == false; I++)
{
@@ -131,9 +146,22 @@ bool pkgSimulate::Install(PkgIterator iPkg,string /*File*/)
bool pkgSimulate::Configure(PkgIterator iPkg)
{
// Adapt the iterator
- PkgIterator Pkg = Sim.FindPkg(iPkg.Name());
+ PkgIterator Pkg = Sim.FindPkg(iPkg.Name(), iPkg.Arch());
Flags[Pkg->ID] = 2;
+
+ if (strcmp(Pkg.Arch(),"all") == 0)
+ {
+ pkgCache::GrpIterator G = Pkg.Group();
+ for (pkgCache::PkgIterator P = G.FindPkg("any"); P.end() != true; P = G.NextPkg(P))
+ {
+ if (strcmp(P.Arch(), "all") == 0)
+ continue;
+ if (Flags[P->ID] == 1)
+ Flags[P->ID] = 2;
+ }
+ }
+
// Sim.MarkInstall(Pkg,false);
if (Sim[Pkg].InstBroken() == true)
{
@@ -181,10 +209,26 @@ bool pkgSimulate::Configure(PkgIterator iPkg)
bool pkgSimulate::Remove(PkgIterator iPkg,bool Purge)
{
// Adapt the iterator
- PkgIterator Pkg = Sim.FindPkg(iPkg.Name());
+ PkgIterator Pkg = Sim.FindPkg(iPkg.Name(), iPkg.Arch());
Flags[Pkg->ID] = 3;
Sim.MarkDelete(Pkg);
+
+ if (strcmp(Pkg.Arch(),"all") == 0)
+ {
+ pkgCache::GrpIterator G = Pkg.Group();
+ pkgCache::GrpIterator iG = iPkg.Group();
+ for (pkgCache::PkgIterator P = G.FindPkg("any"); P.end() != true; P = G.NextPkg(P))
+ {
+ if (strcmp(P.Arch(), "all") == 0)
+ continue;
+ if (iG.FindPkg(P.Arch())->CurrentVer == 0)
+ continue;
+ Flags[P->ID] = 3;
+ Sim.MarkDelete(P);
+ }
+ }
+
if (Purge == true)
cout << "Purg ";
else
diff --git a/apt-pkg/cacheiterators.h b/apt-pkg/cacheiterators.h
index e8cf28496..43cbe1377 100644
--- a/apt-pkg/cacheiterators.h
+++ b/apt-pkg/cacheiterators.h
@@ -200,6 +200,7 @@ class pkgCache::VerIterator : public Iterator<Version, VerIterator> {
string RelStr();
bool Automatic() const;
+ bool Pseudo() const;
VerFileIterator NewestFile() const;
inline VerIterator(pkgCache &Owner,Version *Trg = 0) : Iterator<Version, VerIterator>(Owner, Trg) {
diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc
index 3726a6a04..b3d95164a 100644
--- a/apt-pkg/deb/deblistparser.cc
+++ b/apt-pkg/deb/deblistparser.cc
@@ -148,6 +148,24 @@ bool debListParser::NewVersion(pkgCache::VerIterator Ver)
Ver->Priority = pkgCache::State::Extra;
}
+ if (Ver->MultiArch == pkgCache::Version::All)
+ {
+ /* We maintain a "pseudo" arch=all package for architecture all versions
+ on which these versions can depend on. This pseudo package is many used
+ for downloading/installing: The other pseudo-packages will degenerate
+ to a NOP in the download/install step - this package will ensure that
+ it is downloaded only one time and installed only one time -- even if
+ the architecture bound versions coming in and out on regular basis. */
+ if (strcmp(Ver.Arch(true),"all") == 0)
+ return true;
+ else
+ {
+ // our pseudo packages have no size to not confuse the fetcher
+ Ver->Size = 0;
+ Ver->InstalledSize = 0;
+ }
+ }
+
if (ParseDepends(Ver,"Depends",pkgCache::Dep::Depends) == false)
return false;
if (ParseDepends(Ver,"Pre-Depends",pkgCache::Dep::PreDepends) == false)
@@ -593,7 +611,7 @@ bool debListParser::ParseDepends(pkgCache::VerIterator Ver,
return true;
string Package;
- string const pkgArch = Ver.Arch();
+ string const pkgArch = Ver.Arch(true);
string Version;
unsigned int Op;
@@ -622,7 +640,7 @@ bool debListParser::ParseProvides(pkgCache::VerIterator Ver)
{
string Package;
string Version;
- string const Arch = Ver.Arch();
+ string const Arch = Ver.Arch(true);
unsigned int Op;
while (1)
diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc
index b04181d76..e817adb77 100644
--- a/apt-pkg/depcache.cc
+++ b/apt-pkg/depcache.cc
@@ -896,6 +896,10 @@ void pkgDepCache::MarkDelete(PkgIterator const &Pkg, bool rPurge,
AddStates(Pkg);
Update(Pkg);
AddSizes(Pkg);
+
+ // if we remove the pseudo package, we also need to remove the "real"
+ if (Pkg->CurrentVer != 0 && Pkg.CurrentVer().Pseudo() == true)
+ MarkDelete(Pkg.Group().FindPkg("all"), rPurge, Depth+1, FromUser);
}
/*}}}*/
// DepCache::IsDeleteOk - check if it is ok to remove this package /*{{{*/
diff --git a/apt-pkg/depcache.h b/apt-pkg/depcache.h
index 63cd954ad..ab1021a44 100644
--- a/apt-pkg/depcache.h
+++ b/apt-pkg/depcache.h
@@ -333,6 +333,7 @@ class pkgDepCache : protected pkgCache::Namespace
inline Header &Head() {return *Cache->HeaderP;};
inline PkgIterator PkgBegin() {return Cache->PkgBegin();};
inline PkgIterator FindPkg(string const &Name) {return Cache->FindPkg(Name);};
+ inline PkgIterator FindPkg(string const &Name, string const &Arch) {return Cache->FindPkg(Name, Arch);};
inline pkgCache &GetCache() {return *Cache;};
inline pkgVersioningSystem &VS() {return *Cache->VS;};
diff --git a/apt-pkg/orderlist.cc b/apt-pkg/orderlist.cc
index 0ee2e2bc8..2e7618b55 100644
--- a/apt-pkg/orderlist.cc
+++ b/apt-pkg/orderlist.cc
@@ -126,6 +126,10 @@ bool pkgOrderList::IsMissing(PkgIterator Pkg)
if (FileList[Pkg->ID].empty() == false)
return false;
+
+ if (pkgCache::VerIterator(Cache, Cache[Pkg].CandidateVer).Pseudo() == true)
+ return false;
+
return true;
}
/*}}}*/
diff --git a/apt-pkg/packagemanager.cc b/apt-pkg/packagemanager.cc
index 1ab3203a1..08e7fc00f 100644
--- a/apt-pkg/packagemanager.cc
+++ b/apt-pkg/packagemanager.cc
@@ -80,7 +80,10 @@ bool pkgPackageManager::GetArchives(pkgAcquire *Owner,pkgSourceList *Sources,
// Skip already processed packages
if (List->IsNow(Pkg) == false)
continue;
-
+
+ if (pkgCache::VerIterator(Cache, Cache[Pkg].CandidateVer).Pseudo() == true)
+ continue;
+
new pkgAcqArchive(Owner,Sources,Recs,Cache[Pkg].InstVerIter(Cache),
FileNames[Pkg->ID]);
}
@@ -277,8 +280,10 @@ bool pkgPackageManager::ConfigureAll()
for (pkgOrderList::iterator I = OList.begin(); I != OList.end(); I++)
{
PkgIterator Pkg(Cache,*I);
-
- if (ConfigurePkgs == true && Configure(Pkg) == false)
+
+ if (ConfigurePkgs == true &&
+ pkgCache::VerIterator(Cache, Cache[Pkg].CandidateVer).Pseudo() == false &&
+ Configure(Pkg) == false)
return false;
List->Flag(Pkg,pkgOrderList::Configured,pkgOrderList::States);
@@ -310,7 +315,9 @@ bool pkgPackageManager::SmartConfigure(PkgIterator Pkg)
{
PkgIterator Pkg(Cache,*I);
- if (ConfigurePkgs == true && Configure(Pkg) == false)
+ if (ConfigurePkgs == true &&
+ pkgCache::VerIterator(Cache, Cache[Pkg].CandidateVer).Pseudo() == false &&
+ Configure(Pkg) == false)
return false;
List->Flag(Pkg,pkgOrderList::Configured,pkgOrderList::States);
@@ -457,7 +464,10 @@ bool pkgPackageManager::SmartRemove(PkgIterator Pkg)
return true;
List->Flag(Pkg,pkgOrderList::Configured,pkgOrderList::States);
- return Remove(Pkg,(Cache[Pkg].iFlags & pkgDepCache::Purge) == pkgDepCache::Purge);
+
+ if (pkgCache::VerIterator(Cache, Cache[Pkg].CandidateVer).Pseudo() == false)
+ return Remove(Pkg,(Cache[Pkg].iFlags & pkgDepCache::Purge) == pkgDepCache::Purge);
+ return true;
}
/*}}}*/
// PM::SmartUnPack - Install helper /*{{{*/
@@ -565,7 +575,8 @@ bool pkgPackageManager::SmartUnPack(PkgIterator Pkg)
P.end() == false; P++)
CheckRConflicts(Pkg,P.ParentPkg().RevDependsList(),P.ProvideVersion());
- if (Install(Pkg,FileNames[Pkg->ID]) == false)
+ if (pkgCache::VerIterator(Cache, Cache[Pkg].CandidateVer).Pseudo() == false &&
+ Install(Pkg,FileNames[Pkg->ID]) == false)
return false;
List->Flag(Pkg,pkgOrderList::UnPacked,pkgOrderList::States);
diff --git a/apt-pkg/pkgcache.cc b/apt-pkg/pkgcache.cc
index 2d4ee1010..04a2c7234 100644
--- a/apt-pkg/pkgcache.cc
+++ b/apt-pkg/pkgcache.cc
@@ -649,6 +649,18 @@ bool pkgCache::VerIterator::Automatic() const
return false;
}
/*}}}*/
+// VerIterator::Pseudo - Check if this version is a pseudo one /*{{{*/
+// ---------------------------------------------------------------------
+/* Sometimes you have the need to express dependencies with versions
+ which doesn't really exist or exist multiply times for "different"
+ packages. We need these versions for dependency resolution but they
+ are a problem everytime we need to download/install something. */
+bool pkgCache::VerIterator::Pseudo() const
+{
+ return (S->MultiArch == pkgCache::Version::All &&
+ strcmp(Arch(true),"all") != 0);
+}
+ /*}}}*/
// VerIterator::NewestFile - Return the newest file version relation /*{{{*/
// ---------------------------------------------------------------------
/* This looks at the version numbers associated with all of the sources
diff --git a/apt-pkg/pkgcache.h b/apt-pkg/pkgcache.h
index 5edeedfd1..012caac76 100644
--- a/apt-pkg/pkgcache.h
+++ b/apt-pkg/pkgcache.h
@@ -357,7 +357,7 @@ inline pkgCache::PkgFileIterator pkgCache::FileEnd()
class pkgCache::Namespace /*{{{*/
{
public:
-
+ typedef pkgCache::GrpIterator GrpIterator;
typedef pkgCache::PkgIterator PkgIterator;
typedef pkgCache::VerIterator VerIterator;
typedef pkgCache::DescIterator DescIterator;
diff --git a/apt-pkg/pkgcachegen.cc b/apt-pkg/pkgcachegen.cc
index ebda325f7..c1b546a00 100644
--- a/apt-pkg/pkgcachegen.cc
+++ b/apt-pkg/pkgcachegen.cc
@@ -115,9 +115,10 @@ bool pkgCacheGenerator::MergeList(ListParser &List,
/* As we handle Arch all packages as architecture bounded
we add all information to every (simulated) arch package */
std::vector<string> genArch;
- if (List.ArchitectureAll() == true)
+ if (List.ArchitectureAll() == true) {
genArch = APT::Configuration::getArchitectures();
- else
+ genArch.push_back("all");
+ } else
genArch.push_back(List.Architecture());
for (std::vector<string>::const_iterator arch = genArch.begin();
@@ -531,8 +532,11 @@ bool pkgCacheGenerator::FinishCache(OpProgress &Progress) {
for (pkgCache::GrpIterator G = GetCache().GrpBegin(); G.end() != true; G++) {
string const PkgName = G.Name();
for (pkgCache::PkgIterator P = G.PackageList(); P.end() != true; P = G.NextPkg(P)) {
+ if (strcmp(P.Arch(),"all") == 0)
+ continue;
+ pkgCache::PkgIterator allPkg;
for (pkgCache::VerIterator V = P.VersionList(); V.end() != true; V++) {
- string const Arch = V.Arch();
+ string const Arch = V.Arch(true);
map_ptrloc *OldDepLast = NULL;
/* MultiArch handling introduces a lot of implicit Dependencies:
- MultiArch: same → Co-Installable if they have the same version
@@ -540,6 +544,8 @@ bool pkgCacheGenerator::FinishCache(OpProgress &Progress) {
- All others conflict with all other group members */
bool const coInstall = (V->MultiArch == pkgCache::Version::All ||
V->MultiArch == pkgCache::Version::Same);
+ if (V->MultiArch == pkgCache::Version::All && allPkg.end() == true)
+ allPkg = G.FindPkg("all");
for (vector<string>::const_iterator A = archs.begin(); A != archs.end(); ++A) {
if (*A == Arch)
continue;
@@ -561,6 +567,12 @@ bool pkgCacheGenerator::FinishCache(OpProgress &Progress) {
NewDepends(D, V, V.VerStr(),
pkgCache::Dep::Greater, pkgCache::Dep::DpkgBreaks,
OldDepLast);
+ if (V->MultiArch == pkgCache::Version::All) {
+ // Depend on ${self}:all which does depend on nothing
+ NewDepends(allPkg, V, V.VerStr(),
+ pkgCache::Dep::Equals, pkgCache::Dep::Depends,
+ OldDepLast);
+ }
} else {
// Conflicts: ${self}:other
NewDepends(D, V, "",
@@ -675,7 +687,7 @@ bool pkgCacheGenerator::ListParser::NewProvides(pkgCache::VerIterator Ver,
pkgCache &Cache = Owner->Cache;
// We do not add self referencing provides
- if (Ver.ParentPkg().Name() == PkgName && PkgArch == Ver.Arch())
+ if (Ver.ParentPkg().Name() == PkgName && PkgArch == Ver.Arch(true))
return true;
// Get a structure