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

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.

David Kalnischkies лет назад: 16
Родитель
Сommit
803ea2a87f

+ 48 - 4
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

+ 1 - 0
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) {

+ 20 - 2
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)

+ 4 - 0
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	/*{{{*/

+ 1 - 0
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;};

+ 4 - 0
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;
 }
 									/*}}}*/

+ 17 - 6
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);

+ 12 - 0
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

+ 1 - 1
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;

+ 16 - 4
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

+ 2 - 0
cmdline/apt-cache.cc

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

+ 11 - 3
cmdline/apt-get.cc

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