瀏覽代碼

if the package has no installed & candidate but is virtual see if only
one package provides it - if it is only one use this package instead

David Kalnischkies 16 年之前
父節點
當前提交
cf28bcadb3
共有 3 個文件被更改,包括 59 次插入37 次删除
  1. 49 37
      cmdline/apt-get.cc
  2. 8 0
      cmdline/cacheset.cc
  3. 2 0
      cmdline/cacheset.h

+ 49 - 37
cmdline/apt-get.cc

@@ -1081,41 +1081,6 @@ bool TryToInstall(pkgCache::PkgIterator Pkg,pkgDepCache &Cache,
 		  pkgProblemResolver &Fix,bool Remove,bool BrokenFix,
 		  pkgProblemResolver &Fix,bool Remove,bool BrokenFix,
 		  bool AllowFail = true)
 		  bool AllowFail = true)
 {
 {
-   /* This is a pure virtual package and there is a single available
-      candidate providing it. */
-   if (Cache[Pkg].CandidateVer == 0 && Pkg->ProvidesList != 0)
-   {
-      pkgCache::PkgIterator Prov;
-      bool found_one = false;
-
-      for (pkgCache::PrvIterator P = Pkg.ProvidesList(); P; P++)
-      {
-	 pkgCache::VerIterator const PVer = P.OwnerVer();
-	 pkgCache::PkgIterator const PPkg = PVer.ParentPkg();
-
-	 /* Ignore versions that are not a candidate. */
-	 if (Cache[PPkg].CandidateVer != PVer)
-	     continue;
-
-	 if (found_one == false)
-	 {
-	    Prov = PPkg;
-	    found_one = true;
-	 }
-	 else if (PPkg != Prov)
-	 {
-	    found_one = false; // we found at least two
-	    break;
-	 }
-      }
-
-      if (found_one == true)
-      {
-	 ioprintf(c1out,_("Note, selecting %s instead of %s\n"),
-		  Prov.FullName(true).c_str(),Pkg.FullName(true).c_str());
-	 Pkg = Prov;
-      }
-   }
 
 
    // Handle the no-upgrade case
    // Handle the no-upgrade case
    if (_config->FindB("APT::Get::upgrade",true) == false &&
    if (_config->FindB("APT::Get::upgrade",true) == false &&
@@ -1601,13 +1566,13 @@ public:
 
 
 	virtual void showTaskSelection(APT::PackageSet const &pkgset, string const &pattern) {
 	virtual void showTaskSelection(APT::PackageSet const &pkgset, string const &pattern) {
 		for (APT::PackageSet::const_iterator Pkg = pkgset.begin(); Pkg != pkgset.end(); ++Pkg)
 		for (APT::PackageSet::const_iterator Pkg = pkgset.begin(); Pkg != pkgset.end(); ++Pkg)
-			ioprintf(out, _("Note, selecting %s for task '%s'\n"),
+			ioprintf(out, _("Note, selecting '%s' for task '%s'\n"),
 				 Pkg.FullName(true).c_str(), pattern.c_str());
 				 Pkg.FullName(true).c_str(), pattern.c_str());
 		explicitlyNamed = false;
 		explicitlyNamed = false;
 	}
 	}
 	virtual void showRegExSelection(APT::PackageSet const &pkgset, string const &pattern) {
 	virtual void showRegExSelection(APT::PackageSet const &pkgset, string const &pattern) {
 		for (APT::PackageSet::const_iterator Pkg = pkgset.begin(); Pkg != pkgset.end(); ++Pkg)
 		for (APT::PackageSet::const_iterator Pkg = pkgset.begin(); Pkg != pkgset.end(); ++Pkg)
-			ioprintf(out, _("Note, selecting %s for regex '%s'\n"),
+			ioprintf(out, _("Note, selecting '%s' for regex '%s'\n"),
 				 Pkg.FullName(true).c_str(), pattern.c_str());
 				 Pkg.FullName(true).c_str(), pattern.c_str());
 		explicitlyNamed = false;
 		explicitlyNamed = false;
 	}
 	}
@@ -1618,6 +1583,53 @@ public:
 				 Ver.VerStr(), Ver.RelStr().c_str(), Pkg.FullName(true).c_str());
 				 Ver.VerStr(), Ver.RelStr().c_str(), Pkg.FullName(true).c_str());
 	}
 	}
 
 
+	virtual APT::VersionSet canNotFindCandInstVer(pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg) {
+		return tryVirtualPackage(Cache, Pkg, APT::VersionSet::CANDINST);
+	}
+
+	virtual APT::VersionSet canNotFindInstCandVer(pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg) {
+		return tryVirtualPackage(Cache, Pkg, APT::VersionSet::INSTCAND);
+	}
+
+	APT::VersionSet tryVirtualPackage(pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg,
+						APT::VersionSet::Version const &select) {
+		/* This is a pure virtual package and there is a single available
+		   candidate providing it. */
+		if (unlikely(Cache[Pkg].CandidateVer != 0) || Pkg->ProvidesList == 0) {
+			if (select == APT::VersionSet::CANDINST)
+				return APT::CacheSetHelper::canNotFindCandInstVer(Cache, Pkg);
+			return APT::CacheSetHelper::canNotFindInstCandVer(Cache, Pkg);
+		}
+
+		pkgCache::PkgIterator Prov;
+		bool found_one = false;
+		for (pkgCache::PrvIterator P = Pkg.ProvidesList(); P; ++P) {
+			pkgCache::VerIterator const PVer = P.OwnerVer();
+			pkgCache::PkgIterator const PPkg = PVer.ParentPkg();
+
+			/* Ignore versions that are not a candidate. */
+			if (Cache[PPkg].CandidateVer != PVer)
+				continue;
+
+			if (found_one == false) {
+				Prov = PPkg;
+				found_one = true;
+			} else if (PPkg != Prov) {
+				found_one = false; // we found at least two
+				break;
+			}
+		}
+
+		if (found_one == true) {
+			ioprintf(out, _("Note, selecting '%s' instead of '%s'\n"),
+				 Prov.FullName(true).c_str(), Pkg.FullName(true).c_str());
+			return APT::VersionSet::FromPackage(Cache, Prov, select, *this);
+		}
+		if (select == APT::VersionSet::CANDINST)
+			return APT::CacheSetHelper::canNotFindCandInstVer(Cache, Pkg);
+		return APT::CacheSetHelper::canNotFindInstCandVer(Cache, Pkg);
+	}
+
 	inline bool allPkgNamedExplicitly() const { return explicitlyNamed; }
 	inline bool allPkgNamedExplicitly() const { return explicitlyNamed; }
 
 
 };
 };

+ 8 - 0
cmdline/cacheset.cc

@@ -474,6 +474,14 @@ VersionSet CacheSetHelper::canNotFindInstCandVer(pkgCacheFile &Cache,
 	return VersionSet();
 	return VersionSet();
 }
 }
 									/*}}}*/
 									/*}}}*/
+// canNotFindInstCandVer						/*{{{*/
+VersionSet CacheSetHelper::canNotFindCandInstVer(pkgCacheFile &Cache,
+		pkgCache::PkgIterator const &Pkg) {
+	if (ShowError == true)
+		_error->Error(_("Can't select installed nor candidate version from package '%s' as it has neither of them"), Pkg.FullName(true).c_str());
+	return VersionSet();
+}
+									/*}}}*/
 // canNotFindNewestVer							/*{{{*/
 // canNotFindNewestVer							/*{{{*/
 pkgCache::VerIterator CacheSetHelper::canNotFindNewestVer(pkgCacheFile &Cache,
 pkgCache::VerIterator CacheSetHelper::canNotFindNewestVer(pkgCacheFile &Cache,
 		pkgCache::PkgIterator const &Pkg) {
 		pkgCache::PkgIterator const &Pkg) {

+ 2 - 0
cmdline/cacheset.h

@@ -47,6 +47,8 @@ public:									/*{{{*/
 	virtual VersionSet canNotFindAllVer(pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg);
 	virtual VersionSet canNotFindAllVer(pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg);
 	virtual VersionSet canNotFindInstCandVer(pkgCacheFile &Cache,
 	virtual VersionSet canNotFindInstCandVer(pkgCacheFile &Cache,
 				pkgCache::PkgIterator const &Pkg);
 				pkgCache::PkgIterator const &Pkg);
+	virtual VersionSet canNotFindCandInstVer(pkgCacheFile &Cache,
+				pkgCache::PkgIterator const &Pkg);
 	virtual pkgCache::VerIterator canNotFindNewestVer(pkgCacheFile &Cache,
 	virtual pkgCache::VerIterator canNotFindNewestVer(pkgCacheFile &Cache,
 				pkgCache::PkgIterator const &Pkg);
 				pkgCache::PkgIterator const &Pkg);
 	virtual pkgCache::VerIterator canNotFindCandidateVer(pkgCacheFile &Cache,
 	virtual pkgCache::VerIterator canNotFindCandidateVer(pkgCacheFile &Cache,