]> git.saurik.com Git - apt.git/commitdiff
Add yet another pseudo package which isn't as pseudo as the others:
authorDavid Kalnischkies <kalnischkies@gmail.com>
Thu, 11 Feb 2010 23:04:31 +0000 (00:04 +0100)
committerDavid Kalnischkies <kalnischkies@gmail.com>
Thu, 11 Feb 2010 23:04:31 +0000 (00:04 +0100)
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.

12 files changed:
apt-pkg/algorithms.cc
apt-pkg/cacheiterators.h
apt-pkg/deb/deblistparser.cc
apt-pkg/depcache.cc
apt-pkg/depcache.h
apt-pkg/orderlist.cc
apt-pkg/packagemanager.cc
apt-pkg/pkgcache.cc
apt-pkg/pkgcache.h
apt-pkg/pkgcachegen.cc
cmdline/apt-cache.cc
cmdline/apt-get.cc

index 34da745dea5ac67a2b25c1e83d7478e96f0a7a27..c905cffa9ca0a763dc8f9868ad93c204c2c9a4e6 100644 (file)
@@ -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
index e8cf28496f9a551b8e6c121db1262ec7443c885f..43cbe1377ba033fd16e989774693ff3d411f5933 100644 (file)
@@ -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) {
index 3726a6a042649d3a43d543bf907735765ec45b73..b3d95164abcd1bca295a5eb2f5ea921608def75c 100644 (file)
@@ -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)
index b04181d763b9d78cd9072ea0f421b3e3da1ec7be..e817adb775408beca8a3948876869a5f961e1369 100644 (file)
@@ -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     /*{{{*/
index 63cd954adfe89305bd952fa45e9c0582fb8f80b1..ab1021a4424859b558cc3a04c52d7ec0e235e541 100644 (file)
@@ -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;};
index 0ee2e2bc8bfccea7de8e1a5e645020c8ba663e4b..2e7618b5582f0d2f7e9c2ed564f33a7b1edcb913 100644 (file)
@@ -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;
 }
                                                                        /*}}}*/
index 1ab3203a1ed2fdedbda1dd26a573ec2dd44172b8..08e7fc00fa5e5e29c3d9eda18affb4220a8cb945 100644 (file)
@@ -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);
index 2d4ee101071cc82763af79e7055d353bba7fb95f..04a2c7234bc11fb1292e70c1399f4784f31f75f1 100644 (file)
@@ -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
index 5edeedfd12f57e1802261f3b24682525b4dbeac3..012caac76c5a0e5cdd14f7077cd365ff546b0ec3 100644 (file)
@@ -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;
index ebda325f73f36e685d3b57cb831bcd61187f3d1d..c1b546a0089ed57e9df5b158a8d2428dbf5f5354 100644 (file)
@@ -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
index cd806286c780033208164203bf3b44f72f0d9265..275daa1878e430fa7f523942bd2817faafa7679f 100644 (file)
@@ -1587,6 +1587,8 @@ bool Policy(CommandLine &CmdL)
       }
 
       for (; Pkg.end() != true; Pkg = Grp.NextPkg(Pkg)) {
+      if (strcmp(Pkg.Arch(),"all") == 0)
+        continue;
 
       if (myArch == Pkg.Arch())
         cout << Pkg.Name() << ":" << endl;
index 2597a6acb3e0d03fe4d68f91875c2a0cef6b19a4..93065004c98bc7f2f0df7fda377f72a259618282 100644 (file)
@@ -233,7 +233,7 @@ bool ShowList(ostream &out,string Title,string List,string VersionsList)
    if it is not the main architecture */
 string ShowPkg(pkgCache::PkgIterator const Pkg) {
        string p = Pkg.Name();
-       if (_config->Find("APT::Architecture") != Pkg.Arch())
+       if (strcmp(Pkg.Arch(),"all") != 0 && _config->Find("APT::Architecture") != Pkg.Arch())
                p.append(":").append(Pkg.Arch());
        return p;
 }
@@ -385,6 +385,8 @@ void ShowNew(ostream &out,CacheFile &Cache)
    {
       pkgCache::PkgIterator I(Cache,Cache.List[J]);
       if (Cache[I].NewInstall() == true) {
+        if (Cache[I].CandidateVerIter(Cache).Pseudo() == true)
+           continue;
          List += ShowPkg(I) + " ";
          VersionsList += string(Cache[I].CandVersion) + "\n";
       }
@@ -407,6 +409,8 @@ void ShowDel(ostream &out,CacheFile &Cache)
       pkgCache::PkgIterator I(Cache,Cache.List[J]);
       if (Cache[I].Delete() == true)
       {
+        if (Cache[I].CandidateVerIter(Cache).Pseudo() == true)
+           continue;
         if ((Cache[I].iFlags & pkgDepCache::Purge) == pkgDepCache::Purge)
            List += ShowPkg(I) + "* ";
         else
@@ -455,7 +459,9 @@ void ShowUpgraded(ostream &out,CacheFile &Cache)
       // Not interesting
       if (Cache[I].Upgrade() == false || Cache[I].NewInstall() == true)
         continue;
-      
+      if (Cache[I].CandidateVerIter(Cache).Pseudo() == true)
+        continue;
+
       List += ShowPkg(I) + " ";
       VersionsList += string(Cache[I].CurVersion) + " => " + Cache[I].CandVersion + "\n";
    }
@@ -476,7 +482,9 @@ bool ShowDowngraded(ostream &out,CacheFile &Cache)
       // Not interesting
       if (Cache[I].Downgrade() == false || Cache[I].NewInstall() == true)
         continue;
-      
+      if (Cache[I].CandidateVerIter(Cache).Pseudo() == true)
+        continue;
+
       List += ShowPkg(I) + " ";
       VersionsList += string(Cache[I].CurVersion) + " => " + Cache[I].CandVersion + "\n";
    }