aboutsummaryrefslogtreecommitdiff
path: root/bpkg/system-package-manager.hxx
diff options
context:
space:
mode:
Diffstat (limited to 'bpkg/system-package-manager.hxx')
-rw-r--r--bpkg/system-package-manager.hxx125
1 files changed, 70 insertions, 55 deletions
diff --git a/bpkg/system-package-manager.hxx b/bpkg/system-package-manager.hxx
index 78b157a..7d960f4 100644
--- a/bpkg/system-package-manager.hxx
+++ b/bpkg/system-package-manager.hxx
@@ -20,60 +20,44 @@ namespace bpkg
// The system package manager interface. Used by both pkg-build (to query
// and install system packages) and by pkg-bindist (to build them).
//
- class system_package_manager
+ class system_package_status
{
public:
- struct package_status
- {
- // Downstream (as in, bpkg package) version.
- //
- bpkg::version version;
-
- // The system package can be either "available already installed",
- // "available partially installed" (for example, libfoo but not
- // libfoo-dev is installed) or "available not yet installed".
- //
- // Whether not_installed versions can be returned along with installed
- // or partially_installed depends on whether the packager manager can
- // install multiple versions side-by-side.
- //
- enum {installed, partially_installed, not_installed} status;
-
- // System (as in, distribution package) name and version.
- //
- // @@ But these could be multiple. Do we really need this?
- /*
- string system_name;
- string system_version;
- */
-
- // Package manager implementation-specific data.
- //
- public:
- using data_ptr = unique_ptr<void, void (*) (void*)>;
-
- template <typename T>
- T&
- data () { return *static_cast<T*> (data_.get ()); }
-
- template <typename T>
- const T&
- data () const { return *static_cast<const T*> (data_.get ()); }
-
- template <typename T>
- T&
- data (T* d)
- {
- data_ = data_ptr (d, [] (void* p) { delete static_cast<T*> (p); });
- return *d;
- }
-
- static void
- null_data_deleter (void* p) { assert (p == nullptr); }
-
- data_ptr data_ = {nullptr, null_data_deleter};
- };
+ // Downstream (as in, bpkg package) version.
+ //
+ bpkg::version version;
+
+ // The system package can be either "available already installed",
+ // "available partially installed" (for example, libfoo but not
+ // libfoo-dev is installed) or "available not yet installed".
+ //
+ // Whether not_installed versions can be returned along with installed
+ // or partially_installed depends on whether the packager manager can
+ // install multiple versions side-by-side.
+ //
+ enum status_type {installed, partially_installed, not_installed};
+
+ status_type status = not_installed;
+
+ // System (as in, distribution package) name and version.
+ //
+ // @@ But these could be multiple. Do we really need this?
+ // @@ Can now probably provide as virtual functions.
+ /*
+ string system_name;
+ string system_version;
+ */
+
+ public:
+ virtual
+ ~system_package_status ();
+
+ system_package_status () = default;
+ };
+ class system_package_manager
+ {
+ public:
// Query the system package status.
//
// This function has two modes: cache-only (available_packages is NULL)
@@ -83,7 +67,13 @@ namespace bpkg
// the available packages (for the name/version mapping information) if
// really necessary.
//
- // The returned value can be empty, which indicates that no such package
+ // The returned list should be arranged in the preference order with the
+ // first entry having the highest preference. Normally this will be in the
+ // descending version order but can also be something more elaborate, such
+ // as the already installed or partially installed version coming first
+ // with the descending version order after that.
+ //
+ // The returned list can be empty, which indicates that no such package
// is available from the system package manager. Note that empty is also
// returned if no fully installed package is available from the system and
// the install argument is false.
@@ -93,7 +83,7 @@ namespace bpkg
// the available version of the not yet installed or partially installed
// packages.
//
- virtual const vector<package_status>*
+ virtual const vector<unique_ptr<system_package_status>>*
pkg_status (const package_name&,
const available_packages*,
bool install,
@@ -119,7 +109,8 @@ namespace bpkg
protected:
// Given the available packages (as returned by find_available_all())
- // return the list of system package names.
+ // return the list of system package names as mapped by the
+ // <distribution>-name values.
//
// The name_id, version_id, and like_ids are the values from os_release
// (refer there for background). If version_id is empty, then it's treated
@@ -140,15 +131,39 @@ namespace bpkg
// something more elaborate, like translate version_id to the like_id's
// version and try that).
//
+ // @@ TODO: allow multiple -name values per same distribution and handle
+ // here? E.g., libcurl4-openssl-dev libcurl4-gnutls-dev. But they will
+ // have the same available version, how will we deal with that? How
+ // will we pick one? Perhaps this should all be handled by the system
+ // package manager (conceptually, this is configuration negotiation).
+ //
static strings
system_package_names (const available_packages&,
const string& name_id,
const string& version_id,
const vector<string>& like_ids);
+ // Given the system package version and available packages (as returned by
+ // find_available_all()) return the downstream package version as mapped
+ // by one of the <distribution>-to-downstream-version values.
+ //
+ // The rest of the arguments as well as the overalls semantics is the same
+ // as in system_package_names() above. That is, first consider
+ // <distribution>-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.
+ //
+ static optional<version>
+ downstream_package_version (const string& system_version,
+ const available_packages&,
+ const string& name_id,
+ const string& version_id,
+ const vector<string>& like_ids);
protected:
os_release os_release_;
- std::map<package_name, vector<package_status>> status_cache_;
+ std::map<package_name,
+ vector<unique_ptr<system_package_status>>> status_cache_;
};
// Create a package manager instance corresponding to the specified host