aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKaren Arutyunov <karen@codesynthesis.com>2023-01-17 11:25:57 +0300
committerKaren Arutyunov <karen@codesynthesis.com>2023-01-17 11:25:57 +0300
commit80bbbcd5307d7ae8abacbaa99a2b577f5571f00b (patch)
treec50bd65ae841ac58f4e16863011100e183ec104a
parent8e20c1ed163be60cb576b5ad8f5d27b6320154a6 (diff)
Implement system_package_names()
-rw-r--r--bpkg/package-query.cxx22
-rw-r--r--bpkg/package-query.hxx12
-rw-r--r--bpkg/package.hxx9
-rw-r--r--bpkg/pkg-build.cxx4
-rw-r--r--bpkg/system-package-manager.cxx142
-rw-r--r--bpkg/system-package-manager.hxx5
6 files changed, 166 insertions, 28 deletions
diff --git a/bpkg/package-query.cxx b/bpkg/package-query.cxx
index 66cb7f0..ea64e71 100644
--- a/bpkg/package-query.cxx
+++ b/bpkg/package-query.cxx
@@ -315,9 +315,7 @@ namespace bpkg
// revisions.
//
static void
- sort_dedup (vector<pair<shared_ptr<available_package>,
- lazy_shared_ptr<repository_fragment>>>& pfs,
- bool suppress_older_revisions = false)
+ sort_dedup (available_packages& pfs, bool suppress_older_revisions = false)
{
sort (pfs.begin (), pfs.end (),
[] (const auto& x, const auto& y)
@@ -335,14 +333,12 @@ namespace bpkg
pfs.end ());
}
- vector<pair<shared_ptr<available_package>,
- lazy_shared_ptr<repository_fragment>>>
+ available_packages
find_available (const linked_databases& dbs,
const package_name& name,
const optional<version_constraint>& c)
{
- vector<pair<shared_ptr<available_package>,
- lazy_shared_ptr<repository_fragment>>> r;
+ available_packages r;
for (database& db: dbs)
{
@@ -380,15 +376,13 @@ namespace bpkg
return r;
}
- vector<pair<shared_ptr<available_package>,
- lazy_shared_ptr<repository_fragment>>>
+ available_packages
find_available (const package_name& name,
const optional<version_constraint>& c,
const config_repo_fragments& rfs,
bool prereq)
{
- vector<pair<shared_ptr<available_package>,
- lazy_shared_ptr<repository_fragment>>> r;
+ available_packages r;
for (const auto& dfs: rfs)
{
@@ -550,8 +544,7 @@ namespace bpkg
return make_pair (find_available (options, db, sp), nullptr);
}
- vector<pair<shared_ptr<available_package>,
- lazy_shared_ptr<repository_fragment>>>
+ available_packages
find_available_all (const linked_databases& dbs,
const package_name& name,
bool suppress_older_revisions)
@@ -591,8 +584,7 @@ namespace bpkg
// Collect all the available packages from all the collected databases.
//
- vector<pair<shared_ptr<available_package>,
- lazy_shared_ptr<repository_fragment>>> r;
+ available_packages r;
for (database& db: all_dbs)
{
diff --git a/bpkg/package-query.hxx b/bpkg/package-query.hxx
index 1fbedd7..ee9b595 100644
--- a/bpkg/package-query.hxx
+++ b/bpkg/package-query.hxx
@@ -81,8 +81,7 @@ namespace bpkg
// Note that we return (loaded) lazy_shared_ptr in order to also convey
// the database to which it belongs.
//
- vector<pair<shared_ptr<available_package>,
- lazy_shared_ptr<repository_fragment>>>
+ available_packages
find_available (const linked_databases&,
const package_name&,
const optional<version_constraint>&);
@@ -94,8 +93,8 @@ namespace bpkg
using config_repo_fragments =
database_map<vector<shared_ptr<repository_fragment>>>;
- vector<pair<shared_ptr<available_package>,
- lazy_shared_ptr<repository_fragment>>>
+
+ available_packages
find_available (const package_name&,
const optional<version_constraint>&,
const config_repo_fragments&,
@@ -182,10 +181,7 @@ namespace bpkg
// Note that we return (loaded) lazy_shared_ptr in order to also convey
// the database to which it belongs.
//
- // @@ Add available_packages typedef and use everywhere.
- //
- vector<pair<shared_ptr<available_package>,
- lazy_shared_ptr<repository_fragment>>>
+ available_packages
find_available_all (const linked_databases&,
const package_name&,
bool suppress_older_revisions = true);
diff --git a/bpkg/package.hxx b/bpkg/package.hxx
index 14cd296..6afc624 100644
--- a/bpkg/package.hxx
+++ b/bpkg/package.hxx
@@ -882,6 +882,15 @@ namespace bpkg
available_package () = default;
};
+ // The available packages together with the repository fragments they belong
+ // to.
+ //
+ // Note that lazy_shared_ptr is used to also convey the databases the
+ // objects belong to.
+ //
+ using available_packages = vector<pair<shared_ptr<available_package>,
+ lazy_shared_ptr<repository_fragment>>>;
+
#pragma db view object(available_package)
struct available_package_count
{
diff --git a/bpkg/pkg-build.cxx b/bpkg/pkg-build.cxx
index 14b0852..61bd1da 100644
--- a/bpkg/pkg-build.cxx
+++ b/bpkg/pkg-build.cxx
@@ -538,9 +538,7 @@ namespace bpkg
else if (!dsys || !wildcard (*dvc))
c = dvc;
- vector<pair<shared_ptr<available_package>,
- lazy_shared_ptr<repository_fragment>>> afs (
- find_available (nm, c, rfs));
+ available_packages afs (find_available (nm, c, rfs));
if (afs.empty () && dsys && c)
afs = find_available (nm, nullopt, rfs);
diff --git a/bpkg/system-package-manager.cxx b/bpkg/system-package-manager.cxx
index aa9bed8..c170041 100644
--- a/bpkg/system-package-manager.cxx
+++ b/bpkg/system-package-manager.cxx
@@ -3,8 +3,18 @@
#include <bpkg/system-package-manager.hxx>
+#include <iterator> // back_inserter
+
+#include <libbutl/semantic-version.hxx>
+
+#include <bpkg/package.hxx>
+#include <bpkg/package-odb.hxx>
+#include <bpkg/database.hxx>
#include <bpkg/diagnostics.hxx>
+using namespace std;
+using namespace butl;
+
namespace bpkg
{
system_package_manager::
@@ -47,4 +57,136 @@ namespace bpkg
return r;
}
+
+ strings system_package_manager::
+ system_package_names (const available_packages& aps,
+ const string& name_id,
+ const string& version_id,
+ const string& like_id)
+ {
+ assert (!aps.empty ());
+
+ // Parse the version id if it is not empty and leave it "0" otherwise.
+ //
+ semantic_version vid;
+
+ if (!version_id.empty ())
+ try
+ {
+ vid = semantic_version (version_id, semantic_version::allow_omit_minor);
+ }
+ catch (const invalid_argument& e)
+ {
+ fail << "invalid VERSION_ID '" << version_id << "' for " << name_id
+ << " operating system identification data: " << e;
+ }
+
+ // Return those <name>[_<version>]-name distribution values of the
+ // specified available packages, whose <name> component matches the
+ // specified distribution name and the <version> component (assumed as "0"
+ // if not present) is less or equal the specified distribution version.
+ // Suppress the duplicate entries with the same name (so that distribution
+ // values of the later available package versions are preferred) or value.
+ //
+ using values = vector<reference_wrapper<const distribution_name_value>>;
+
+ auto name_vals = [&aps] (const string& n, const semantic_version& v)
+ {
+ values r;
+ for (const auto& a: aps)
+ {
+ const shared_ptr<available_package>& ap (a.first);
+
+ for (const distribution_name_value& nv: ap->distribution_values)
+ {
+ const string& nm (nv.name);
+
+ if (nm.size () > 5 && nm.compare (nm.size () - 5, 5, "-name") == 0)
+ {
+ string dn (nm, 0, nm.size () - 5); // <name>[_<version>]
+ size_t p (dn.rfind ('_')); // Version-separating underscore.
+
+ // If '_' separator is present, then make sure that the right-hand
+ // part looks like a version (not empty and only contains digits
+ // and dots).
+ //
+ if (p != string::npos)
+ {
+ if (p != dn.size () - 1)
+ {
+ for (size_t i (p); i != dn.size (); ++i)
+ {
+ if (!digit (dn[i]) && dn[i] != '.')
+ {
+ p = string::npos;
+ break;
+ }
+ }
+ }
+ else
+ p = string::npos;
+ }
+
+ // Parse the distribution version if present and leave it "0"
+ // otherwise.
+ //
+ semantic_version dv;
+ if (p != string::npos)
+ try
+ {
+ dv = semantic_version (dn,
+ p + 1,
+ semantic_version::allow_omit_minor);
+ }
+ catch (const invalid_argument& e)
+ {
+ const std::string& s (a.second.database ().string);
+
+ fail << "invalid distribution value " << nm << " for package "
+ << ap->id.name << ' ' << ap->version
+ << (!s.empty () ? ' ' + s : empty_string)
+ << " in repository " << a.second.load ()->location << ": "
+ << e;
+ }
+
+ dn.resize (p);
+
+ if (dn == n &&
+ dv <= v &&
+ find_if (r.begin (), r.end (),
+ [&nm, &nv] (const distribution_name_value& v)
+ {return v.name == nm || v.value == nv.value;}) ==
+ r.end ())
+ {
+ r.push_back (nv);
+ }
+ }
+ }
+ }
+
+ return r;
+ };
+
+ // Collect the <distribution>-name values that match the name id and refer
+ // to the version which is less or equal than the version id.
+ //
+ values vs (name_vals (name_id, vid));
+
+ // If the resulting list is empty and the like id is specified, then
+ // re-collect but now using the like id and "0" version id instead.
+ //
+ if (vs.empty () && !like_id.empty ())
+ vs = name_vals (like_id, semantic_version (0, 0, 0));
+
+ // Return the values of the collected name/values list.
+ //
+ strings r;
+ r.reserve (vs.size ());
+
+ transform (vs.begin (), vs.end (),
+ back_inserter (r),
+ [] (const distribution_name_value& v) {return v.value;});
+
+ return r;
+ }
}
diff --git a/bpkg/system-package-manager.hxx b/bpkg/system-package-manager.hxx
index 4f01d1d..131c670 100644
--- a/bpkg/system-package-manager.hxx
+++ b/bpkg/system-package-manager.hxx
@@ -10,6 +10,7 @@
#include <bpkg/types.hxx>
#include <bpkg/utility.hxx>
+#include <bpkg/package.hxx>
#include <bpkg/host-os-release.hxx>
namespace bpkg
@@ -71,8 +72,8 @@ namespace bpkg
// something more elaborate, like translate version_id to the like_id's
// version and try that).
//
- static vector<string>
- system_package_names (/*const available_packages&,*/
+ static strings
+ system_package_names (const available_packages&,
const string& name_id,
const string& version_id,
const string& like_id);