[PATCH setup 2/2] Keep track of all known sites for a given version of a package

Jon Turney jon.turney@dronecode.org.uk
Mon Jul 9 18:19:00 GMT 2018


When adding a packageversion, extend it's packagesource::sites vector to
include the sites from any similar packageversions previously processed.

Also remove those packageversions from the libsolv pool so that libsolv will
always find the one that lists all the sites.

This is needed for:

- Correct handling of local installs where required packages are spread
between cache directories for more than one mirror

- Correctly falling back to a second site when multiple mirrors are used and
a problem occurs connecting to the first mirror tried.
---
 package_db.cc   | 14 +++------
 package_meta.cc | 80 ++++++++++++++++++++++++++++++++++++++-----------
 package_meta.h  |  2 +-
 3 files changed, 67 insertions(+), 29 deletions(-)

diff --git a/package_db.cc b/package_db.cc
index 945b339..b74aafd 100644
--- a/package_db.cc
+++ b/package_db.cc
@@ -245,11 +245,8 @@ packagedb::addBinary (const std::string &pkgname,
       packages.insert (packagedb::packagecollection::value_type(pkgname, pkg));
     }
 
-  /* Create the SolvableVersion  */
-  SolvableVersion sv = solver.addPackage(pkgname, pkgdata);
-
-  /* Register it in packagemeta */
-  pkg->add_version (sv, pkgdata);
+  /* Create the SolvableVersion and register it in packagemeta */
+  pkg->add_version (pkgdata);
 
   return pkg;
 }
@@ -266,11 +263,8 @@ packagedb::addSource (const std::string &pkgname,
       sourcePackages.insert (packagedb::packagecollection::value_type(pkgname, pkg));
     }
 
-  /* Create the SolvableVersion  */
-  SolvableVersion sv = solver.addPackage(pkgname, pkgdata);
-
-  /* Register it in packagemeta */
-  pkg->add_version (sv, pkgdata);
+  /* Create the SolvableVersion and register it in packagemeta */
+  SolvableVersion sv = pkg->add_version (pkgdata);
 
   return sv;
 }
diff --git a/package_meta.cc b/package_meta.cc
index a651d28..f765baf 100644
--- a/package_meta.cc
+++ b/package_meta.cc
@@ -123,11 +123,26 @@ packagemeta::~packagemeta()
   versions.clear ();
 }
 
-void
-packagemeta::add_version (packageversion & thepkg, const SolverPool::addPackageData &pkgdata)
+SolvableVersion
+packagemeta::add_version (const SolverPool::addPackageData &inpkgdata)
 {
+  SolverPool::addPackageData pkgdata = inpkgdata;
+
+  packageversion *v = NULL;
+  switch (pkgdata.stability)
+    {
+    case TRUST_CURR:
+      v = &(this->curr);
+      break;
+    case TRUST_TEST:
+      v = &(this->exp);
+      break;
+    default:
+      break;
+    }
+
   /*
-    If a packageversion for the same version number is already present,allow
+    If a packageversion for the same version number is already present, allow
     this version to replace it.
 
     There is a problem where multiple repos provide a package.  It's never been
@@ -137,12 +152,52 @@ packagemeta::add_version (packageversion & thepkg, const SolverPool::addPackageD
     We rely on this by adding packages from installed.db last.
    */
 
-  set <packageversion>::iterator i = versions.find(thepkg);
-  if (i != versions.end())
+  for (set <packageversion>::iterator i = versions.begin();
+       i != versions.end();
+       i++)
     {
+      if (i->Canonical_version() != pkgdata.version)
+        continue;
+
+      if (pkgdata.vendor == i->Vendor())
+        {
+          /* Merge the site-list from any existing packageversion with the same
+             repository 'release:' label */
+          pkgdata.archive.sites.insert(pkgdata.archive.sites.end(),
+                                       i->source()->sites.begin(),
+                                       i->source()->sites.end());
+
+          /* Installed packages do not supersede repo packages */
+          if (pkgdata.reponame != "_installed")
+            {
+              /* Ensure a stability level doesn't point to a version we're about
+                 to remove */
+              if (v && (*v == *i))
+                *v = packageversion();
+
+              i->remove();
+            }
+        }
+      else
+        {
+          /* Otherwise... if we had a way to set repo priorities, that could be
+             used to control which packageversion the solver picks. For the
+             moment, just warn that you might not be getting what you think you
+             should... */
+          Log (LOG_PLAIN) << "Version " << pkgdata.version << " of package " <<
+            name << " is present in releases labelled " << pkgdata.vendor <<
+            " and " << i->Vendor() << endLog;
+        }
+
       versions.erase(i);
+
+      break;
     }
 
+  /* Create the SolvableVersion  */
+  packagedb db;
+  SolvableVersion thepkg = db.solver.addPackage(name, pkgdata);
+
   /* Add the version */
   std::pair<std::set <packageversion>::iterator, bool> result = versions.insert (thepkg);
 
@@ -154,19 +209,6 @@ packagemeta::add_version (packageversion & thepkg, const SolverPool::addPackageD
 #endif
 
   /* Record the highest version at a given stability level */
-  packageversion *v = NULL;
-  switch (pkgdata.stability)
-    {
-    case TRUST_CURR:
-      v = &(this->curr);
-      break;
-    case TRUST_TEST:
-      v = &(this->exp);
-      break;
-    default:
-      break;
-    }
-
   if (v)
     {
       /* Any version is always greater than no version */
@@ -184,6 +226,8 @@ packagemeta::add_version (packageversion & thepkg, const SolverPool::addPackageD
           *v = thepkg;
         }
     }
+
+  return thepkg;
 }
 
 bool
diff --git a/package_meta.h b/package_meta.h
index 600a163..8db10e2 100644
--- a/package_meta.h
+++ b/package_meta.h
@@ -43,7 +43,7 @@ public:
 
   ~packagemeta ();
 
-  void add_version (packageversion &, const SolverPool::addPackageData &);
+  SolvableVersion add_version (const SolverPool::addPackageData &);
   void set_installed_version (const std::string &);
   void addToCategoryBase();
   bool hasNoCategories() const;
-- 
2.17.0



More information about the Cygwin-apps mailing list