summaryrefslogtreecommitdiff
path: root/apt-pkg
diff options
context:
space:
mode:
authorDavid Kalnischkies <david@kalnischkies.de>2020-05-26 19:19:38 +0200
committerDavid Kalnischkies <david@kalnischkies.de>2020-05-27 11:15:25 +0200
commit572810e9f321237873d1536c88991d7825c6f1db (patch)
treed9c5b07bc2d4ee4030214aef620a044bd1a6a6ad /apt-pkg
parent5eff00606c0c55cb6e456e521c8c4059e37264a0 (diff)
Allow =version and /release selector on virtual packages
We already have code for figuring out if a virtual package is only provided by a single provider (and otherwise show a list) we can auto-select for the user, so we can adapt that to work with versioned provides as well and while at it also release selectors. The code tries to keep ABI backward compatible and hence turns relatively ugly as we need a parameter (the selector) to be passed around without adding a parameter or new virtual methods.
Diffstat (limited to 'apt-pkg')
-rw-r--r--apt-pkg/cacheset.cc65
-rw-r--r--apt-pkg/cacheset.h10
2 files changed, 58 insertions, 17 deletions
diff --git a/apt-pkg/cacheset.cc b/apt-pkg/cacheset.cc
index 565a2b298..e029732f1 100644
--- a/apt-pkg/cacheset.cc
+++ b/apt-pkg/cacheset.cc
@@ -488,14 +488,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)
@@ -568,9 +566,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;
}
@@ -728,10 +742,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 /*{{{*/
@@ -762,10 +774,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);
}
@@ -811,6 +823,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,
@@ -875,9 +901,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 :