aboutsummaryrefslogtreecommitdiff
path: root/bpkg/system-package-manager-fedora.cxx
diff options
context:
space:
mode:
authorKaren Arutyunov <karen@codesynthesis.com>2023-02-08 20:48:01 +0300
committerKaren Arutyunov <karen@codesynthesis.com>2023-02-10 11:53:44 +0300
commit63ef45cd77b9db7ab0b08a2c4eab8a831aafdb73 (patch)
tree08299b9510558c905fb911b81e51cd22c54a9e4d /bpkg/system-package-manager-fedora.cxx
parentf1d08308522bbcbc655f6e55b4b84af9253d8679 (diff)
Fix Fedora's main/devel package name resolution based on the project name
Diffstat (limited to 'bpkg/system-package-manager-fedora.cxx')
-rw-r--r--bpkg/system-package-manager-fedora.cxx175
1 files changed, 100 insertions, 75 deletions
diff --git a/bpkg/system-package-manager-fedora.cxx b/bpkg/system-package-manager-fedora.cxx
index b117eab..ab4b33c 100644
--- a/bpkg/system-package-manager-fedora.cxx
+++ b/bpkg/system-package-manager-fedora.cxx
@@ -1204,95 +1204,78 @@ namespace bpkg
package_status::partially_installed);
};
- // First, choose between the package name-based and project-based system
- // package names.
+ // First look for an already fully installed package.
//
- for (package_status& ps: candidates)
+ optional<package_status> r;
+
{
- vector<package_info>& pis (ps.package_infos);
+ diag_record dr; // Ambiguity diagnostics.
- // Query both main and fallback packages with a single dns_list()
- // invocation.
- //
- if (!ps.main.empty ()) pis.emplace_back (ps.main);
- if (!ps.devel.empty ()) pis.emplace_back (ps.devel);
- if (!ps.fallback.empty ()) pis.emplace_back (ps.fallback);
- if (!ps.static_.empty ()) pis.emplace_back (ps.static_);
- if (!ps.doc.empty () && need_doc) pis.emplace_back (ps.doc);
+ for (package_status& ps: candidates)
+ {
+ vector<package_info>& pis (ps.package_infos);
- if (!ps.debuginfo.empty () && need_debuginfo)
- pis.emplace_back (ps.debuginfo);
+ // Query both main and fallback packages with a single dns_list()
+ // invocation.
+ //
+ if (!ps.main.empty ()) pis.emplace_back (ps.main);
+ if (!ps.devel.empty ()) pis.emplace_back (ps.devel);
+ if (!ps.fallback.empty ()) pis.emplace_back (ps.fallback);
+ if (!ps.static_.empty ()) pis.emplace_back (ps.static_);
+ if (!ps.doc.empty () && need_doc) pis.emplace_back (ps.doc);
- if (!ps.debugsource.empty () && need_debugsource)
- pis.emplace_back (ps.debugsource);
+ if (!ps.debuginfo.empty () && need_debuginfo)
+ pis.emplace_back (ps.debuginfo);
- if (!ps.common.empty () && false) pis.emplace_back (ps.common);
- ps.package_infos_main = pis.size ();
- for (const string& n: ps.extras) pis.emplace_back (n);
+ if (!ps.debugsource.empty () && need_debugsource)
+ pis.emplace_back (ps.debugsource);
- dnf_list (pis);
+ if (!ps.common.empty () && false) pis.emplace_back (ps.common);
+ ps.package_infos_main = pis.size ();
+ for (const string& n: ps.extras) pis.emplace_back (n);
- // If the project-based (fallback) system package name is specified,
- // then choose between the main/devel and fallback names depending on
- // which of them is known to the system package manager.
- //
- // Specifically, if the main/devel system package exists we use that.
- // Otherwise, if the fallback system package exists we use that and fail
- // otherwise.
- //
- if (!ps.fallback.empty ())
- {
- assert (pis.size () > 1); // devel, fallback,... or main, fallback,...
+ dnf_list (pis);
- // Either devel or main is specified.
+ // Handle the fallback package name, if specified.
//
- bool devel (!ps.devel.empty ());
- assert (devel == ps.main.empty ());
-
- string& name (devel ? ps.devel : ps.main);
+ // Specifically, if the main/devel package is known to the system
+ // package manager we use that. Otherwise, if the fallback package is
+ // known we use that. And if neither is known, then we skip this
+ // candidate (ps).
+ //
+ if (!ps.fallback.empty ())
+ {
+ assert (pis.size () > 1); // devel+fallback or main+fallback
- package_info& mi (pis[0]); // Main/devel package info.
- package_info& fi (pis[1]); // Fallback package info.
+ package_info& mp (pis[0]); // Main/devel package info.
+ package_info& fp (pis[1]); // Fallback package info.
- if (mi.unknown ())
- {
- if (fi.known ())
- {
- name = move (ps.fallback);
- mi = move (fi);
- }
- else
+ // Note that at this stage we can only use the installed main/devel
+ // and fallback packages (since the candidate versions may change
+ // after fetch).
+ //
+ // Also note that this logic prefers installed fallback package to
+ // potentially available non-fallback package.
+ //
+ if (mp.installed_version.empty ())
{
- // @@ This feels incorrect: there can be another candidate that is
- // found. Double-check Debian semantics.
- //
- fail << "unable to guess " << (devel ? "devel" : "main")
- << ' ' << os_release.name_id << " package for " << pn <<
- info << "neither " << name << " nor " << ps.fallback
- << ' ' << os_release.name_id << " package exists" <<
- info << "consider specifying explicit mapping in " << pn
- << " package manifest";
+ if (!fp.installed_version.empty ())
+ {
+ // Use the fallback.
+ //
+ (ps.main.empty () ? ps.devel : ps.main) = move (ps.fallback);
+ mp = move (fp);
+ }
+ else
+ continue; // Skip the candidate at this stage.
}
- }
- // Whether it was used or not, cleanup the fallback information.
- //
- ps.fallback.clear ();
- pis.erase (pis.begin () + 1);
- --ps.package_infos_main;
- }
- }
-
- // Next look for an already fully installed package.
- //
- optional<package_status> r;
-
- {
- diag_record dr; // Ambiguity diagnostics.
-
- for (package_status& ps: candidates)
- {
- vector<package_info>& pis (ps.package_infos);
+ // Whether it was used or not, cleanup the fallback information.
+ //
+ ps.fallback.clear ();
+ pis.erase (pis.begin () + 1);
+ --ps.package_infos_main;
+ }
// Handle the unknown main package.
//
@@ -1343,7 +1326,7 @@ namespace bpkg
dr << info << "consider specifying the desired version manually";
}
- // Finally look for available versions if we are allowed to install.
+ // Next look for available versions if we are allowed to install.
//
if (!r && install_)
{
@@ -1367,6 +1350,48 @@ namespace bpkg
if (requery)
dnf_list (pis);
+ // Handle the fallback package name, if specified.
+ //
+ if (!ps.fallback.empty ())
+ {
+ assert (pis.size () > 1); // devel+fallback or main+fallback
+
+ package_info& mp (pis[0]); // Main/devel package info.
+ package_info& fp (pis[1]); // Fallback package info.
+
+ // Note that this time we use the candidate versions.
+ //
+ if (mp.candidate_version.empty ())
+ {
+ if (!fp.candidate_version.empty ())
+ {
+ // Use the fallback.
+ //
+ (ps.main.empty () ? ps.devel : ps.main) = move (ps.fallback);
+ mp = move (fp);
+ }
+ else
+ {
+ // Otherwise, we would have resolved the name on the previous
+ // stage.
+ //
+ assert (mp.installed_version.empty () &&
+ fp.installed_version.empty ());
+
+ // Main/devel package is not installable.
+ //
+ ps.main.clear ();
+ continue;
+ }
+ }
+
+ // Whether it was used or not, cleanup the fallback information.
+ //
+ ps.fallback.clear ();
+ pis.erase (pis.begin () + 1);
+ --ps.package_infos_main;
+ }
+
// Handle the unknown main package.
//
if (ps.main.empty ())