From 7014e1482942d00b66eb30061b0cf5d2a7b3ebf3 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Thu, 5 Dec 2013 08:11:11 +0100 Subject: * enable release based selection for deb-src (closes: 731102) --- apt-pkg/deb/debmetaindex.cc | 17 +++++- apt-pkg/deb/debmetaindex.h | 7 +++ apt-pkg/indexfile.h | 4 +- apt-pkg/indexrecords.cc | 5 ++ apt-pkg/indexrecords.h | 1 + apt-pkg/metaindex.h | 24 ++++++--- cmdline/apt-get.cc | 122 +++++++++++++++++++++++++++++++++++--------- 7 files changed, 145 insertions(+), 35 deletions(-) diff --git a/apt-pkg/deb/debmetaindex.cc b/apt-pkg/deb/debmetaindex.cc index b597b6f3c..504877558 100644 --- a/apt-pkg/deb/debmetaindex.cc +++ b/apt-pkg/deb/debmetaindex.cc @@ -1,4 +1,3 @@ -// ijones, walters #include #include @@ -72,6 +71,22 @@ string debReleaseIndex::MetaIndexURI(const char *Type) const return Res; } +#if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR >= 13) +std::string debReleaseIndex::LocalFileName() const +{ + // see if we have a InRelease file + std::string PathInRelease = MetaIndexFile("InRelease"); + if (FileExists(PathInRelease)) + return PathInRelease; + + // and if not return the normal one + if (FileExists(PathInRelease)) + return MetaIndexFile("Release"); + + return ""; +} +#endif + string debReleaseIndex::IndexURISuffix(const char *Type, string const &Section, string const &Arch) const { string Res =""; diff --git a/apt-pkg/deb/debmetaindex.h b/apt-pkg/deb/debmetaindex.h index b9ecab97c..cef8d68f7 100644 --- a/apt-pkg/deb/debmetaindex.h +++ b/apt-pkg/deb/debmetaindex.h @@ -3,6 +3,7 @@ #define PKGLIB_DEBMETAINDEX_H #include +#include #include #include @@ -39,9 +40,15 @@ class debReleaseIndex : public metaIndex { virtual bool GetIndexes(pkgAcquire *Owner, bool const &GetAll=false) const; std::vector * ComputeIndexTargets() const; std::string Info(const char *Type, std::string const &Section, std::string const &Arch="") const; + std::string MetaIndexInfo(const char *Type) const; std::string MetaIndexFile(const char *Types) const; std::string MetaIndexURI(const char *Type) const; + +#if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR >= 13) + virtual std::string LocalFileName() const; +#endif + std::string IndexURI(const char *Type, std::string const &Section, std::string const &Arch="native") const; std::string IndexURISuffix(const char *Type, std::string const &Section, std::string const &Arch="native") const; std::string SourceIndexURI(const char *Type, const std::string &Section) const; diff --git a/apt-pkg/indexfile.h b/apt-pkg/indexfile.h index 1d34dc773..2d433b60a 100644 --- a/apt-pkg/indexfile.h +++ b/apt-pkg/indexfile.h @@ -78,10 +78,10 @@ class pkgIndexFile virtual bool Exists() const = 0; virtual bool HasPackages() const = 0; virtual unsigned long Size() const = 0; - virtual bool Merge(pkgCacheGenerator &/*Gen*/,OpProgress* /*Prog*/) const { return false; }; + virtual bool Merge(pkgCacheGenerator &Gen, OpProgress* Prog) const { return false; }; __deprecated virtual bool Merge(pkgCacheGenerator &Gen, OpProgress &Prog) const { return Merge(Gen, &Prog); }; - virtual bool MergeFileProvides(pkgCacheGenerator &/*Gen*/,OpProgress* /*Prog*/) const {return true;}; + virtual bool MergeFileProvides(pkgCacheGenerator &Gen,OpProgress* Prog) const {return true;}; __deprecated virtual bool MergeFileProvides(pkgCacheGenerator &Gen, OpProgress &Prog) const {return MergeFileProvides(Gen, &Prog);}; virtual pkgCache::PkgFileIterator FindInCache(pkgCache &Cache) const; diff --git a/apt-pkg/indexrecords.cc b/apt-pkg/indexrecords.cc index 8a72ca151..f8097c3c6 100644 --- a/apt-pkg/indexrecords.cc +++ b/apt-pkg/indexrecords.cc @@ -27,6 +27,11 @@ string indexRecords::GetDist() const return this->Dist; } +string indexRecords::GetSuite() const +{ + return this->Suite; +} + bool indexRecords::CheckDist(const string MaybeDist) const { return (this->Dist == MaybeDist diff --git a/apt-pkg/indexrecords.h b/apt-pkg/indexrecords.h index a98b939bc..d003ec0fa 100644 --- a/apt-pkg/indexrecords.h +++ b/apt-pkg/indexrecords.h @@ -46,6 +46,7 @@ class indexRecords virtual bool Load(std::string Filename); std::string GetDist() const; + std::string GetSuite() const; time_t GetValidUntil() const; virtual bool CheckDist(const std::string MaybeDist) const; std::string GetExpectedDist() const; diff --git a/apt-pkg/metaindex.h b/apt-pkg/metaindex.h index 5783735ff..18a90a29d 100644 --- a/apt-pkg/metaindex.h +++ b/apt-pkg/metaindex.h @@ -5,6 +5,7 @@ #include #include #include +#include #ifndef APT_8_CLEANER_HEADERS #include @@ -28,27 +29,36 @@ class metaIndex public: - // Various accessors virtual std::string GetURI() const {return URI;} virtual std::string GetDist() const {return Dist;} virtual const char* GetType() const {return Type;} + // interface to to query it +#if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR >= 13) + // returns the path of the local file (or "" if its not available) + virtual std::string LocalFileName() const {return "";}; +#endif + // Interface for acquire - virtual std::string ArchiveURI(std::string const& /*File*/) const = 0; + virtual std::string ArchiveURI(std::string const& File) const = 0; virtual bool GetIndexes(pkgAcquire *Owner, bool const &GetAll=false) const = 0; - virtual std::vector *GetIndexFiles() = 0; virtual bool IsTrusted() const = 0; - metaIndex(std::string const &URI, std::string const &Dist, char const * const Type) : - Indexes(NULL), Type(Type), URI(URI), Dist(Dist) { + metaIndex(std::string const &URI, std::string const &Dist, + char const * const Type) + : Indexes(NULL), Type(Type), URI(URI), Dist(Dist) + { + /* nothing */ } - virtual ~metaIndex() { + virtual ~metaIndex() + { if (Indexes == 0) return; - for (std::vector::iterator I = (*Indexes).begin(); I != (*Indexes).end(); ++I) + for (std::vector::iterator I = (*Indexes).begin(); + I != (*Indexes).end(); ++I) delete *I; delete Indexes; } diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc index 912b2d609..7e59f3d67 100644 --- a/cmdline/apt-get.cc +++ b/cmdline/apt-get.cc @@ -50,6 +50,8 @@ #include #include #include +#include +#include #include #include @@ -61,6 +63,8 @@ #include #include +#include + #include #include @@ -130,22 +134,80 @@ bool TryToInstallBuildDep(pkgCache::PkgIterator Pkg,pkgCacheFile &Cache, return true; } /*}}}*/ + + +// helper that can go wit hthe next ABI break +#if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR < 13) +std::string MetaIndexFileNameOnDisk(metaIndex *metaindex) +{ + // FIXME: this cast is the horror, the horror + debReleaseIndex *r = (debReleaseIndex*)metaindex; + + // see if we have a InRelease file + std::string PathInRelease = r->MetaIndexFile("InRelease"); + if (FileExists(PathInRelease)) + return PathInRelease; + + // and if not return the normal one + if (FileExists(PathInRelease)) + return r->MetaIndexFile("Release"); + + return ""; +} +#endif + +// GetReleaseForSourceRecord - Return Suite for the given srcrecord /*{{{*/ +// --------------------------------------------------------------------- +/* */ +std::string GetReleaseForSourceRecord(pkgSourceList *SrcList, + pkgSrcRecords::Parser *Parse) +{ + // try to find release + const pkgIndexFile& CurrentIndexFile = Parse->Index(); + + for (pkgSourceList::const_iterator S = SrcList->begin(); + S != SrcList->end(); ++S) + { + vector *Indexes = (*S)->GetIndexFiles(); + for (vector::const_iterator IF = Indexes->begin(); + IF != Indexes->end(); ++IF) + { + if (&CurrentIndexFile == (*IF)) + { +#if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR < 13) + std::string path = MetaIndexFileNameOnDisk(*S); +#else + std::string path = (*S)->LocalFileName(); +#endif + if (path != "") + { + indexRecords records; + records.Load(path); + return records.GetSuite(); + } + } + } + } + return ""; +} + /*}}}*/ // FindSrc - Find a source record /*{{{*/ // --------------------------------------------------------------------- /* */ pkgSrcRecords::Parser *FindSrc(const char *Name,pkgRecords &Recs, pkgSrcRecords &SrcRecs,string &Src, - pkgDepCache &Cache) + CacheFile &CacheFile) { string VerTag; - string DefRel = _config->Find("APT::Default-Release"); + string RelTag = _config->Find("APT::Default-Release"); string TmpSrc = Name; + pkgDepCache *Cache = CacheFile.GetDepCache(); // extract the version/release from the pkgname const size_t found = TmpSrc.find_last_of("/="); if (found != string::npos) { if (TmpSrc[found] == '/') - DefRel = TmpSrc.substr(found+1); + RelTag = TmpSrc.substr(found+1); else VerTag = TmpSrc.substr(found+1); TmpSrc = TmpSrc.substr(0,found); @@ -155,10 +217,10 @@ pkgSrcRecords::Parser *FindSrc(const char *Name,pkgRecords &Recs, install a version and determine the source package name, then look in the archive for a source package of the same name. */ bool MatchSrcOnly = _config->FindB("APT::Get::Only-Source"); - const pkgCache::PkgIterator Pkg = Cache.FindPkg(TmpSrc); + const pkgCache::PkgIterator Pkg = Cache->FindPkg(TmpSrc); if (MatchSrcOnly == false && Pkg.end() == false) { - if(VerTag.empty() == false || DefRel.empty() == false) + if(VerTag.empty() == false || RelTag.empty() == false) { bool fuzzy = false; // we have a default release, try to locate the pkg. we do it like @@ -180,7 +242,7 @@ pkgSrcRecords::Parser *FindSrc(const char *Name,pkgRecords &Recs, } // We match against a concrete version (or a part of this version) if (VerTag.empty() == false && - (fuzzy == true || Cache.VS().CmpVersion(VerTag, Ver.VerStr()) != 0) && // exact match + (fuzzy == true || Cache->VS().CmpVersion(VerTag, Ver.VerStr()) != 0) && // exact match (fuzzy == false || strncmp(VerTag.c_str(), Ver.VerStr(), VerTag.size()) != 0)) // fuzzy match continue; @@ -198,8 +260,8 @@ pkgSrcRecords::Parser *FindSrc(const char *Name,pkgRecords &Recs, // or we match against a release if(VerTag.empty() == false || - (VF.File().Archive() != 0 && VF.File().Archive() == DefRel) || - (VF.File().Codename() != 0 && VF.File().Codename() == DefRel)) + (VF.File().Archive() != 0 && VF.File().Archive() == RelTag) || + (VF.File().Codename() != 0 && VF.File().Codename() == RelTag)) { pkgRecords::Parser &Parse = Recs.Lookup(VF); Src = Parse.SourcePkg(); @@ -217,22 +279,14 @@ pkgSrcRecords::Parser *FindSrc(const char *Name,pkgRecords &Recs, if (Src.empty() == false) break; } - if (Src.empty() == true) - { - // Sources files have no codename information - if (VerTag.empty() == true && DefRel.empty() == false) - { - _error->Error(_("Ignore unavailable target release '%s' of package '%s'"), DefRel.c_str(), TmpSrc.c_str()); - return 0; - } - } } if (Src.empty() == true) { // if we don't have found a fitting package yet so we will // choose a good candidate and proceed with that. // Maybe we will find a source later on with the right VerTag - pkgCache::VerIterator Ver = Cache.GetCandidateVer(Pkg); + // or RelTag + pkgCache::VerIterator Ver = Cache->GetCandidateVer(Pkg); if (Ver.end() == false) { pkgRecords::Parser &Parse = Recs.Lookup(Ver.FileList()); @@ -244,7 +298,9 @@ pkgSrcRecords::Parser *FindSrc(const char *Name,pkgRecords &Recs, } if (Src.empty() == true) + { Src = TmpSrc; + } else { /* if we have a source pkg name, make sure to only search @@ -262,6 +318,7 @@ pkgSrcRecords::Parser *FindSrc(const char *Name,pkgRecords &Recs, pkgSrcRecords::Parser *Last = 0; unsigned long Offset = 0; string Version; + pkgSourceList *SrcList = CacheFile.GetSourceList(); /* Iterate over all of the hits, which includes the resulting binary packages in the search */ @@ -273,25 +330,40 @@ pkgSrcRecords::Parser *FindSrc(const char *Name,pkgRecords &Recs, { const string Ver = Parse->Version(); + // See if we need to look for a specific release tag + if (RelTag != "") + { + const string Rel = GetReleaseForSourceRecord(SrcList, Parse); + + if (Rel == RelTag) + { + ioprintf(c1out, "Selectied version '%s' (%s) for %s\n", + Ver.c_str(), RelTag.c_str(), Src.c_str()); + Last = Parse; + Offset = Parse->Offset(); + break; + } + } + // Ignore all versions which doesn't fit if (VerTag.empty() == false && - Cache.VS().CmpVersion(VerTag, Ver) != 0) // exact match + Cache->VS().CmpVersion(VerTag, Ver) != 0) // exact match continue; // Newer version or an exact match? Save the hit - if (Last == 0 || Cache.VS().CmpVersion(Version,Ver) < 0) { + if (Last == 0 || Cache->VS().CmpVersion(Version,Ver) < 0) { Last = Parse; Offset = Parse->Offset(); Version = Ver; } - // was the version check above an exact match? If so, we don't need to look further - if (VerTag.empty() == false && VerTag.size() == Ver.size()) + // was the version check above an exact match? + // If so, we don't need to look further + if (VerTag.empty() == false && (VerTag == Ver)) break; } if (Last != 0 || VerTag.empty() == true) break; - //if (VerTag.empty() == false && Last == 0) _error->Error(_("Ignore unavailable version '%s' of package '%s'"), VerTag.c_str(), TmpSrc.c_str()); return 0; } @@ -628,7 +700,7 @@ bool DoSource(CommandLine &CmdL) for (const char **I = CmdL.FileList + 1; *I != 0; I++, J++) { string Src; - pkgSrcRecords::Parser *Last = FindSrc(*I,Recs,SrcRecs,Src,*Cache); + pkgSrcRecords::Parser *Last = FindSrc(*I,Recs,SrcRecs,Src,Cache); if (Last == 0) { delete[] Dsc; @@ -925,7 +997,7 @@ bool DoBuildDep(CommandLine &CmdL) for (const char **I = CmdL.FileList + 1; *I != 0; I++, J++) { string Src; - pkgSrcRecords::Parser *Last = FindSrc(*I,Recs,SrcRecs,Src,*Cache); + pkgSrcRecords::Parser *Last = FindSrc(*I,Recs,SrcRecs,Src,Cache); if (Last == 0) return _error->Error(_("Unable to find a source package for %s"),Src.c_str()); -- cgit v1.2.3