aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2023-03-09 08:07:33 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2023-03-09 12:33:59 +0200
commit65260526aa5cc7a08082cc887b75e6b8fc5e104a (patch)
treed0db83745c1e20984e6a363efef27676d1205eb7
parent854c668b5e63e26a9d7a6e55226a0940638e0453 (diff)
Strip Debian metadata from Debian package version
-rw-r--r--bpkg/system-package-manager-debian.cxx40
1 files changed, 34 insertions, 6 deletions
diff --git a/bpkg/system-package-manager-debian.cxx b/bpkg/system-package-manager-debian.cxx
index 747d037..3037730 100644
--- a/bpkg/system-package-manager-debian.cxx
+++ b/bpkg/system-package-manager-debian.cxx
@@ -1292,13 +1292,41 @@ namespace bpkg
//
string sv (r->system_version, 0, r->system_version.rfind ('-'));
+ // Debian package versions sometimes include metadata introduced with
+ // the `+` character that established relationships between Debian and
+ // upstream packages, backports, and some other murky stuff (see Debian
+ // Policy with a strong cup of coffee for details). Normally such
+ // metadata is included in the revision, as in, for example,
+ // 1.4.0-1+deb10u1. However, sometimes you see it included in the
+ // version directly, as in, for example: 3.2.4+debian-1 (see Debian bug
+ // 542288 for a potential explanation; might need to refill you cup).
+ //
+ // Since our upstream version may not contain `+`, it feels reasonable
+ // to remove such metadata. What's less clear is whether we should do
+ // the same before trying the to-downstream mapping. In fact, it's
+ // possible `+` belongs to the upstream version rather than Debian
+ // metadata or that there are both (there is also no guarantee that
+ // Debian metadata may not contain multiple `+`). So what we are going
+ // to do is try the mapping with more and more `+` components stripped
+ // (naturally ending up with all of them stripped for the fallback
+ // below).
+ //
optional<version> v;
- if (!aps.empty ())
- v = downstream_package_version (sv,
- aps,
- os_release.name_id,
- os_release.version_id,
- os_release.like_ids);
+ for (size_t p (sv.size ()); p != string::npos; p = sv.rfind ('+'))
+ {
+ sv.resize (p);
+
+ if (!aps.empty ())
+ {
+ v = downstream_package_version (sv,
+ aps,
+ os_release.name_id,
+ os_release.version_id,
+ os_release.like_ids);
+ if (v)
+ break;
+ }
+ }
if (!v)
{