diff options
author | Julian Andres Klode <jak@debian.org> | 2021-10-19 15:02:17 +0000 |
---|---|---|
committer | Julian Andres Klode <jak@debian.org> | 2021-10-19 15:02:17 +0000 |
commit | 9d9ccbbc685035e410e9f3dd5dd488a21d48661d (patch) | |
tree | 858d35d97fa3ac432bb1bebe6c96cf52591c1cde /apt-pkg | |
parent | 400a6895566b67d70bcde43dc8a1cc1c7121f87d (diff) | |
parent | 572810e9f321237873d1536c88991d7825c6f1db (diff) |
Merge branch 'feature/install-versioned-provides' into 'main'
Allow =version and /release selectors on virtual packages
See merge request apt-team/apt!121
Diffstat (limited to 'apt-pkg')
-rw-r--r-- | apt-pkg/cacheset.cc | 65 | ||||
-rw-r--r-- | apt-pkg/cacheset.h | 10 | ||||
-rw-r--r-- | apt-pkg/versionmatch.cc | 15 |
3 files changed, 66 insertions, 24 deletions
diff --git a/apt-pkg/cacheset.cc b/apt-pkg/cacheset.cc index df750cb44..e52f76272 100644 --- a/apt-pkg/cacheset.cc +++ b/apt-pkg/cacheset.cc @@ -489,14 +489,12 @@ bool VersionContainerInterface::FromString(VersionContainerInterface * const vci pkgVersionMatch Match(ver, (verIsRel == true ? pkgVersionMatch::Release : pkgVersionMatch::Version)); V = Match.Find(P); - if (V.end() == true) { + helper.setLastVersionMatcher(ver); + if (V.end()) { if (verIsRel == true) - _error->Error(_("Release '%s' for '%s' was not found"), - ver.c_str(), P.FullName(true).c_str()); + V = helper.canNotGetVersion(CacheSetHelper::RELEASE, Cache, P); else - _error->Error(_("Version '%s' for '%s' was not found"), - ver.c_str(), P.FullName(true).c_str()); - continue; + V = helper.canNotGetVersion(CacheSetHelper::VERSIONNUMBER, Cache, P); } } if (V.end() == true) @@ -569,9 +567,25 @@ bool VersionContainerInterface::FromPackage(VersionContainerInterface * const vc helper.canNotFindVersion(CacheSetHelper::NEWEST, vci, Cache, P); break; case CacheSetHelper::RELEASE: + { + pkgVersionMatch Match(helper.getLastVersionMatcher(), pkgVersionMatch::Release); + V = Match.Find(P); + if (not V.end()) + found |= vci->insert(V); + else + helper.canNotFindVersion(CacheSetHelper::RELEASE, vci, Cache, P); + } + break; case CacheSetHelper::VERSIONNUMBER: - // both make no sense here, so always false - return false; + { + pkgVersionMatch Match(helper.getLastVersionMatcher(), pkgVersionMatch::Version); + V = Match.Find(P); + if (not V.end()) + found |= vci->insert(V); + else + helper.canNotFindVersion(CacheSetHelper::VERSIONNUMBER, vci, Cache, P); + } + break; } return found; } @@ -729,10 +743,8 @@ void CacheSetHelper::canNotFindVersion(enum VerSelector const select, VersionCon case CANDIDATE: canNotFindCandidateVer(Cache, Pkg); break; case INSTALLED: canNotFindInstalledVer(Cache, Pkg); break; case CANDANDINST: canNotGetCandInstVer(Cache, Pkg); break; - case RELEASE: - case VERSIONNUMBER: - // invalid in this branch - break; + case RELEASE: canNotGetVerFromRelease(Cache, Pkg, getLastVersionMatcher()); break; + case VERSIONNUMBER: canNotGetVerFromVersionNumber(Cache, Pkg, getLastVersionMatcher()); break; } } // canNotFindAllVer /*{{{*/ @@ -763,10 +775,10 @@ pkgCache::VerIterator CacheSetHelper::canNotGetVersion(enum VerSelector const se case INSTALLED: return canNotFindInstalledVer(Cache, Pkg); case CANDINST: return canNotGetCandInstVer(Cache, Pkg); case INSTCAND: return canNotGetInstCandVer(Cache, Pkg); + case RELEASE: return canNotGetVerFromRelease(Cache, Pkg, getLastVersionMatcher()); + case VERSIONNUMBER: return canNotGetVerFromVersionNumber(Cache, Pkg, getLastVersionMatcher()); case ALL: case CANDANDINST: - case RELEASE: - case VERSIONNUMBER: // invalid in this branch return pkgCache::VerIterator(Cache, 0); } @@ -812,6 +824,20 @@ pkgCache::VerIterator CacheSetHelper::canNotGetCandInstVer(pkgCacheFile &Cache, return pkgCache::VerIterator(Cache, 0); } /*}}}*/ +// canNotFindMatchingVer /*{{{*/ +pkgCache::VerIterator CacheSetHelper::canNotGetVerFromRelease(pkgCacheFile &Cache, + pkgCache::PkgIterator const &Pkg, std::string const &release) { + if (ShowError == true) + _error->Insert(ErrorType, _("Release '%s' for '%s' was not found"), release.c_str(), Pkg.FullName(true).c_str()); + return pkgCache::VerIterator(Cache, 0); +} +pkgCache::VerIterator CacheSetHelper::canNotGetVerFromVersionNumber(pkgCacheFile &Cache, + pkgCache::PkgIterator const &Pkg, std::string const &verstr) { + if (ShowError == true) + _error->Insert(ErrorType, _("Version '%s' for '%s' was not found"), verstr.c_str(), Pkg.FullName(true).c_str()); + return pkgCache::VerIterator(Cache, 0); +} + /*}}}*/ /*}}}*/ // showPackageSelection - by selector and given pattern /*{{{*/ void CacheSetHelper::showPackageSelection(pkgCache::PkgIterator const &pkg, enum PkgSelector const select, @@ -876,9 +902,16 @@ void CacheSetHelper::showSelectedVersion(pkgCache::PkgIterator const &/*Pkg*/, } /*}}}*/ +class CacheSetHelper::Private { +public: + std::string version_or_release; +}; +std::string CacheSetHelper::getLastVersionMatcher() const { return d->version_or_release; } +void CacheSetHelper::setLastVersionMatcher(std::string const &matcher) { d->version_or_release = matcher; } + CacheSetHelper::CacheSetHelper(bool const ShowError, GlobalError::MsgType ErrorType) : - ShowError(ShowError), ErrorType(ErrorType), d(NULL) {} -CacheSetHelper::~CacheSetHelper() {} + ShowError(ShowError), ErrorType(ErrorType), d(new Private{}) {} +CacheSetHelper::~CacheSetHelper() { delete d; } PackageContainerInterface::PackageContainerInterface() : ConstructedBy(CacheSetHelper::UNKNOWN), d(NULL) {} PackageContainerInterface::PackageContainerInterface(PackageContainerInterface const &by) : PackageContainerInterface() { *this = by; } diff --git a/apt-pkg/cacheset.h b/apt-pkg/cacheset.h index eb9e3e523..383d26b76 100644 --- a/apt-pkg/cacheset.h +++ b/apt-pkg/cacheset.h @@ -157,6 +157,8 @@ public: /*{{{*/ } } + std::string getLastVersionMatcher() const; + void setLastVersionMatcher(std::string const &matcher); /*}}}*/ protected: bool ShowError; @@ -167,6 +169,11 @@ protected: pkgCache::VerIterator canNotGetCandInstVer(pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg); + pkgCache::VerIterator canNotGetVerFromRelease(pkgCacheFile &Cache, + pkgCache::PkgIterator const &Pkg, std::string const &release); + pkgCache::VerIterator canNotGetVerFromVersionNumber(pkgCacheFile &Cache, + pkgCache::PkgIterator const &Pkg, std::string const &verstr); + bool PackageFromTask(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string pattern); bool PackageFromRegEx(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string pattern); bool PackageFromFnmatch(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string pattern); @@ -191,7 +198,8 @@ private: pkgCache::VerIterator canNotFindCandidateVer(pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg); pkgCache::VerIterator canNotFindInstalledVer(pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg); - void * const d; + class Private; + Private * const d; }; /*}}}*/ // Iterator templates for our Containers /*{{{*/ template<typename Interface, typename Master, typename iterator_type, typename container_iterator, typename container_value> class Container_iterator_base : diff --git a/apt-pkg/versionmatch.cc b/apt-pkg/versionmatch.cc index 340f5a64c..82590edfe 100644 --- a/apt-pkg/versionmatch.cc +++ b/apt-pkg/versionmatch.cc @@ -159,15 +159,16 @@ bool pkgVersionMatch::MatchVer(const char *A,string B,bool Prefix) /* */ pkgCache::VerIterator pkgVersionMatch::Find(pkgCache::PkgIterator Pkg) { - pkgCache::VerIterator Ver = Pkg.VersionList(); - for (; Ver.end() == false; ++Ver) - { + for (auto Ver = Pkg.VersionList(); not Ver.end(); ++Ver) if (VersionMatches(Ver)) return Ver; - } - - // This will be Ended by now. - return Ver; + // check if the package provides itself in a matching version + for (auto Prov = Pkg.ProvidesList(); not Prov.end(); ++Prov) + if (Prov->ProvideVersion != 0 && Prov.OwnerPkg() == Prov.ParentPkg()) + if (MatchVer(Prov.ProvideVersion(), VerStr, VerPrefixMatch) || + ExpressionMatches(VerStr, Prov.ProvideVersion())) + return Prov.OwnerVer(); + return pkgCache::VerIterator{}; } /*}}}*/ |