aboutsummaryrefslogtreecommitdiff
path: root/bpkg/system-package-manager.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'bpkg/system-package-manager.cxx')
-rw-r--r--bpkg/system-package-manager.cxx101
1 files changed, 64 insertions, 37 deletions
diff --git a/bpkg/system-package-manager.cxx b/bpkg/system-package-manager.cxx
index 4dc9bf7..793dec6 100644
--- a/bpkg/system-package-manager.cxx
+++ b/bpkg/system-package-manager.cxx
@@ -155,7 +155,7 @@ namespace bpkg
os.like_ids.push_back ("debian");
r.reset (new system_package_manager_debian (
- move (os), host, arch, progress, o));
+ move (os), host, arch, progress, &o));
}
else if (is_or_like (os, "fedora") ||
is_or_like (os, "rhel") ||
@@ -213,18 +213,19 @@ namespace bpkg
// Parse the <distribution> component of the specified <distribution>-*
// value into the distribution name and version (return as "0" if not
- // present). Issue diagnostics and fail on parsing errors.
+ // present). Leave in the d argument the string representation of the
+ // version (used to detect the special non-native <name>_0). Issue
+ // diagnostics and fail on parsing errors.
//
// Note: the value_name, ap, and af arguments are only used for diagnostics.
//
static pair<string, semantic_version>
- parse_distribution (string&& d,
+ parse_distribution (string& d, // <name>[_<version>]
const string& value_name,
const shared_ptr<available_package>& ap,
const lazy_shared_ptr<repository_fragment>& af)
{
- string dn (move (d)); // <name>[_<version>]
- size_t p (dn.rfind ('_')); // Version-separating underscore.
+ size_t p (d.rfind ('_')); // Version-separating underscore.
// If the '_' separator is present, then make sure that the right-hand
// part looks like a version (not empty and only contains digits and
@@ -232,11 +233,11 @@ namespace bpkg
//
if (p != string::npos)
{
- if (p != dn.size () - 1)
+ if (p != d.size () - 1)
{
- for (size_t i (p + 1); i != dn.size (); ++i)
+ for (size_t i (p + 1); i != d.size (); ++i)
{
- if (!digit (dn[i]) && dn[i] != '.')
+ if (!digit (d[i]) && d[i] != '.')
{
p = string::npos;
break;
@@ -249,36 +250,43 @@ namespace bpkg
// Parse the distribution version if present and leave it "0" otherwise.
//
+ string dn;
semantic_version dv (0, 0, 0);
if (p != string::npos)
- try
{
- dv = semantic_version (dn,
- p + 1,
- semantic_version::allow_omit_minor);
+ dn.assign (d, 0, p);
+ d.erase (0, p + 1);
- dn.resize (p);
- }
- catch (const invalid_argument& e)
- {
- // Note: the repository fragment may have no database associated when
- // used in tests.
- //
- shared_ptr<repository_fragment> f (af.get_eager ());
- database* db (!(f != nullptr && !af.loaded ()) // Not transient?
- ? &af.database ()
- : nullptr);
+ try
+ {
+ dv = semantic_version (d, semantic_version::allow_omit_minor);
+ }
+ catch (const invalid_argument& e)
+ {
+ // Note: the repository fragment may have no database associated when
+ // used in tests.
+ //
+ shared_ptr<repository_fragment> f (af.get_eager ());
+ database* db (!(f != nullptr && !af.loaded ()) // Not transient?
+ ? &af.database ()
+ : nullptr);
- diag_record dr (fail);
- dr << "invalid distribution version '" << string (dn, p + 1)
- << "' in value " << value_name << " for package " << ap->id.name
- << ' ' << ap->version;
+ diag_record dr (fail);
+ dr << "invalid distribution version '" << d << "' in value "
+ << value_name << " for package " << ap->id.name << ' '
+ << ap->version;
- if (db != nullptr)
- dr << *db;
+ if (db != nullptr)
+ dr << *db;
- dr << " in repository " << (f != nullptr ? f : af.load ())->location
- << ": " << e;
+ dr << " in repository " << (f != nullptr ? f : af.load ())->location
+ << ": " << e;
+ }
+ }
+ else
+ {
+ dn = move (d);
+ d.clear ();
}
return make_pair (move (dn), move (dv));
@@ -288,7 +296,8 @@ namespace bpkg
system_package_names (const available_packages& aps,
const string& name_id,
const string& version_id,
- const vector<string>& like_ids)
+ const vector<string>& like_ids,
+ bool native)
{
assert (!aps.empty ());
@@ -300,7 +309,8 @@ namespace bpkg
// if not present) is less or equal the specified distribution version.
// Suppress duplicate values.
//
- auto name_values = [&aps] (const string& n, const semantic_version& v)
+ auto name_values = [&aps, native] (const string& n,
+ const semantic_version& v)
{
strings r;
@@ -322,14 +332,31 @@ namespace bpkg
if (optional<string> d = dv.distribution ("-name"))
{
pair<string, semantic_version> dnv (
- parse_distribution (move (*d), dv.name, ap, a.second));
+ parse_distribution (*d, dv.name, ap, a.second));
+
+ // Skip <name>_0 if we are only interested in the native mappings.
+ // If we are interested in the non-native mapping, then we treat
+ // <name>_0 as the matching version.
+ //
+ bool nn (*d == "0");
+ if (nn && native)
+ continue;
semantic_version& dvr (dnv.second);
- if (dnv.first == n && dvr <= v)
+ if (dnv.first == n && (nn || dvr <= v))
{
// Add the name/version pair to the sorted vector.
//
+ // If this is the non-native mapping, then return just that.
+ //
+ if (nn)
+ {
+ r.clear (); // Drop anything we have accumulated so far.
+ r.push_back (move (dv.value));
+ return r;
+ }
+
name_version nv (make_pair (dv.value, move (dvr)));
nvs.insert (upper_bound (nvs.begin (), nvs.end (), nv,
@@ -413,7 +440,7 @@ namespace bpkg
if (optional<string> d = dv.distribution ("-version"))
{
pair<string, semantic_version> dnv (
- parse_distribution (move (*d), dv.name, ap, af));
+ parse_distribution (*d, dv.name, ap, af));
semantic_version& dvr (dnv.second);
@@ -509,7 +536,7 @@ namespace bpkg
if (optional<string> d = nv.distribution ("-to-downstream-version"))
{
pair<string, semantic_version> dnv (
- parse_distribution (move (*d), nv.name, ap, a.second));
+ parse_distribution (*d, nv.name, ap, a.second));
semantic_version& dvr (dnv.second);