From 1d402298aaca0025c1401223fde2479b89a3330f Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Mon, 23 Jan 2023 15:48:49 +0200 Subject: Move work on Debian implementation --- bpkg/system-package-manager-debian.cxx | 75 +++++++++++++++++++++++++++------- bpkg/system-package-manager.hxx | 4 +- 2 files changed, 64 insertions(+), 15 deletions(-) diff --git a/bpkg/system-package-manager-debian.cxx b/bpkg/system-package-manager-debian.cxx index 1f187c8..2722552 100644 --- a/bpkg/system-package-manager-debian.cxx +++ b/bpkg/system-package-manager-debian.cxx @@ -61,7 +61,7 @@ namespace bpkg reference_wrapper name; string installed_version; // Empty if none. - string candidate_version; // Empty if none. + string candidate_version; // Empty if none and no installed_version. explicit package_policy (const string& n): name (n) {} @@ -78,6 +78,7 @@ namespace bpkg strings extras; vector package_policies; + size_t package_policies_main = 0; // Size of the main group. explicit system_package_status_debian (string m, string d = {}) @@ -323,6 +324,9 @@ namespace bpkg // package result in multiple corresponding blocks. It looks like // there should be not blank lines but who really knows. // + // Note also that if Installed version is not (none), then the + // Candidate version will be that version of better. + // { auto df = make_diag_frame ( [&pe, &args] (diag_record& dr) @@ -781,21 +785,29 @@ namespace bpkg // Return nullopt if there is a component without installed or candidate // version (which means the package cannot be installed). // - // @@ Maybe we shouldn't be considering extras for partially_installed - // determination? + // The main argument specified the size of the main group. Only components + // from this group are considered for partially_installed determination. // using status_type = package_status::status_type; - auto status = [] (const vector& pps) -> optional + auto status = [] (const vector& pps, size_t main) + -> optional { bool i (false), u (false); - for (const package_policy& pp: pps) + for (size_t j (0); j != pps.size (); ++j) { - if (pp.installed_version.empty () && pp.candidate_version.empty ()) - return nullopt; + const package_policy& pp (pps[j]); + + if (pp.installed_version.empty ()) + { + if (pp.candidate_version.empty ()) + return nullopt; - (pp.installed_version.empty () ? u : i) = true; + u = true; + } + else if (j < main) + i = true; } return (!u ? package_status::installed : @@ -816,6 +828,7 @@ namespace bpkg if (!ps->doc.empty () && need_doc) pps.emplace_back (ps->doc); if (!ps->dbg.empty () && need_dbg) pps.emplace_back (ps->dbg); if (!ps->common.empty () && false) pps.emplace_back (ps->common); + ps->package_policies_main = pps.size (); for (const string& n: ps->extras) pps.emplace_back (n); apt_cache_policy (pps); @@ -834,10 +847,11 @@ namespace bpkg guess_main (*ps, dev.installed_version); pps.emplace (pps.begin (), ps->main); + ps->package_policies_main++; apt_cache_policy (pps, 1); } - optional s (status (pps)); + optional s (status (pps, ps->package_policies_main)); if (!s) continue; @@ -900,13 +914,11 @@ namespace bpkg guess_main (*ps, dev.candidate_version); pps.emplace (pps.begin (), ps->main); + ps->package_policies_main++; apt_cache_policy (pps, 1); - - // @@ What if the main version doesn't match dev? Or it must? Or we - // use the candidate_version for main? Fuzzy. } - optional s (status (pps)); + optional s (status (pps, ps->package_policies_main)); if (!s) { @@ -918,6 +930,13 @@ namespace bpkg const package_policy& main (pps.front ()); + // Note that if we are installing something for this main package, + // then we always go for the candidate version even though it may have + // an installed version that may be good enough (especially if what we + // are installing are extras). The reason is that it may as well not + // be good enough (especially if we are installing the -dev package) + // and there is no straightforward way to change our mind. + // ps->status = *s; ps->system_name = main.name; ps->system_version = main.candidate_version; @@ -964,7 +983,35 @@ namespace bpkg if (r != nullptr) { - // @@ TODO: map system version to bpkg version. + // Map the system version to bpkg version. + // + optional v ( + downstream_package_version (r->system_version, + *aps, + os_release_.name_id, + os_release_.version_id, + os_release_.like_ids)); + + if (!v) + { + // Fallback to using system version as downstream version. + // + try + { + v = version (r->system_version); + } + catch (const invalid_argument& e) + { + fail << "unable to map Debian package " << r->system_name + << " version " << r->system_version << " to bpkg package " + << pn << " version" << + info << "Debian version is not a valid bpkg version: " << e.what () << + info << "consider specifying explicit mapping in " << pn + << " package manifest"; + } + } + + r->version = move (*v); } // Cache. diff --git a/bpkg/system-package-manager.hxx b/bpkg/system-package-manager.hxx index f4ce37e..ad3be36 100644 --- a/bpkg/system-package-manager.hxx +++ b/bpkg/system-package-manager.hxx @@ -209,7 +209,9 @@ namespace bpkg // -to-downstream-version values corresponding to // name_id. If none match, then repeat the above process for every // like_ids entry with version_id equal 0. If still no match, then return - // nullopt. + // nullopt (in which case the caller may choose to fallback to the system + // package version or do something more elaborate, like translate + // version_id to the like_id's version and try that). // static optional downstream_package_version (const string& system_version, -- cgit v1.1