mamba/libmamba/ext/solv-cpp/include/solv-cpp/solvable.hpp

489 lines
16 KiB
C++

// Copyright (c) 2023, QuantStack and Mamba Contributors
//
// Distributed under the terms of the BSD 3-Clause License.
//
// The full license is in the file LICENSE, distributed with this software.
#ifndef MAMBA_SOLV_SOLVABLE_HPP
#define MAMBA_SOLV_SOLVABLE_HPP
#include <string>
#include <string_view>
#include <solv/pooltypes.h>
#include "solv-cpp/ids.hpp"
#include "solv-cpp/queue.hpp"
extern "C"
{
using Solvable = struct s_Solvable;
}
namespace solv
{
/**
* We use solvable for all sort of things, including virtual packages and pins.
*/
enum class SolvableType : unsigned long long
{
Package,
Virtualpackage,
Pin,
};
class ObjSolvableViewConst
{
public:
explicit ObjSolvableViewConst(const ::Solvable& solvable) noexcept;
~ObjSolvableViewConst() noexcept;
auto raw() const -> const ::Solvable*;
auto id() const -> SolvableId;
/** The package name of the solvable. */
auto name() const -> std::string_view;
/** The package version of the solvable. */
auto version() const -> std::string_view;
auto build_number() const -> std::size_t;
auto build_string() const -> std::string_view;
auto file_name() const -> std::string_view;
auto license() const -> std::string_view;
auto md5() const -> std::string_view;
auto noarch() const -> std::string_view;
auto sha256() const -> std::string_view;
auto signatures() const -> std::string_view;
auto size() const -> std::size_t;
auto timestamp() const -> std::size_t;
/**
* The url of the solvable.
*
* @see ObjSolvableView::set_url
**/
auto url() const -> std::string_view;
/**
* The channel of the solvable.
*
* @see ObjSolvableView::set_channel
**/
auto channel() const -> std::string_view;
/**
* The platform of the solvable.
*
* @see ObjSolvableView::set_subdir
**/
auto platform() const -> std::string_view;
/**
* Queue of ``DependencyId``.
*
* When the array is split in two using a maker, @p marker can be used to get
* only a part of the the dependency array.
* Use ``-1`` to get the first part, ``1`` to get the second part, and ``0`` to get
* everything including the marker.
*/
auto dependencies(DependencyMarker marker = -1) const -> ObjQueue;
/** Queue of ``DependencyId``. */
auto provides() const -> ObjQueue;
/** Queue of ``DependencyId``. */
auto constraints() const -> ObjQueue;
/** Queue of ``StringId``. */
auto track_features() const -> ObjQueue;
/** Whether the solvable is in the installed repo. */
auto installed() const -> bool;
/** The type for which the solvable is used. */
auto type() const -> SolvableType;
private:
const ::Solvable* m_solvable = nullptr;
};
class ObjSolvableView : public ObjSolvableViewConst
{
public:
using raw_str_view = const char*;
explicit ObjSolvableView(::Solvable& repo) noexcept;
auto raw() const -> ::Solvable*;
void set_name(StringId id) const;
void set_name(std::string_view str) const;
void set_version(StringId id) const;
void set_version(std::string_view str) const;
/**
* Set the build number of the solvable.
*
* @warning The pool must be of type conda for this to have an impact in during solving
* @ref ``ObjPool::set_disttype``.
* @note A call to @ref ObjRepoView::internalize is required for this attribute to
* be available for lookup.
*/
void set_build_number(std::size_t n) const;
/**
* Set the build string of the solvable.
*
* This is not used by libsolv and is purely for data storing.
*
* @note A call to @ref ObjRepoView::internalize is required for this attribute to
* be available for lookup.
*/
void set_build_string(std::string_view bld) const;
/**
* Set the file name of the solvable.
*
* This is not used by libsolv and is purely for data storing.
*
* @note A call to @ref ObjRepoView::internalize is required for this attribute to
* be available for lookup.
*/
void set_file_name(raw_str_view fn) const;
void set_file_name(const std::string& fn) const;
/**
* Set the license of the solvable.
*
* This is not used by libsolv and is purely for data storing.
*
* @note A call to @ref ObjRepoView::internalize is required for this attribute to
* be available for lookup.
*/
void set_license(raw_str_view str) const;
void set_license(const std::string& str) const;
/**
* Set the md5 hash of the solvable file.
*
* This is not used by libsolv and is purely for data storing.
*
* @note A call to @ref ObjRepoView::internalize is required for this attribute to
* be available for lookup.
*/
void set_md5(raw_str_view str) const;
void set_md5(const std::string& str) const;
/**
* Set the noarch type of the solvable.
*
* This is not used by libsolv and is purely for data storing.
*
* @note A call to @ref ObjRepoView::internalize is required for this attribute to
* be available for lookup.
*/
void set_noarch(raw_str_view str) const;
void set_noarch(const std::string& str) const;
/**
* Set the sha256 hash of the solvable file.
*
* This is not used by libsolv and is purely for data storing.
*
* @note A call to @ref ObjRepoView::internalize is required for this attribute to
* be available for lookup.
*/
void set_sha256(raw_str_view str) const;
void set_sha256(const std::string& str) const;
/**
* Set the signatures of the solvable file.
*/
void set_signatures(raw_str_view str) const;
void set_signatures(const std::string& str) const;
/**
* Set the size of the solvable size.
*
* This is not used by libsolv and is purely for data storing.
*
* @note A call to @ref ObjRepoView::internalize is required for this attribute to
* be available for lookup.
*/
void set_size(std::size_t n) const;
/**
* Set the timestamp of the solvable.
*
* This is not used by libsolv and is purely for data storing.
*
* @note A call to @ref ObjRepoView::internalize is required for this attribute to
* be available for lookup.
*/
void set_timestamp(std::size_t n) const;
/**
* Set the url of the solvable.
*
* This has no effect for libsolv and is purely for data storing.
* This may not be the same as @ref ObjRepoViewConst::url, for instance the install
* repository may have no url but its packages do.
*
* @note A call to @ref ObjRepoView::internalize is required for this attribute to
* be available for lookup.
*/
void set_url(raw_str_view str) const;
void set_url(const std::string& str) const;
/**
* Set the channel of the solvable.
*
* This has no effect for libsolv and is purely for data storing.
* This may not be the same as @ref ObjRepoViewConst::channel, for instance the install
* repository may have no channel but its packages do.
*
* @note A call to @ref ObjRepoView::internalize is required for this attribute to
* be available for lookup.
*/
void set_channel(raw_str_view str) const;
void set_channel(const std::string& str) const;
/**
* Set the platform of the solvable.
*
* This has no effect for libsolv and is purely for data storing.
* This may not be the same as @ref ObjRepoViewConst::channel, for instance the install
* repository may have no subdir but its packages do.
*
* @note A call to @ref ObjRepoView::internalize is required for this attribute to
* be available for lookup.
*/
void set_platform(raw_str_view str) const;
void set_platform(const std::string& str) const;
/** Set the dependencies of the solvable. */
void set_dependencies(const ObjQueue& q, DependencyMarker marker = 0) const;
/**
* Add a additional dependency to the solvable.
*
* Dependency array can be split in two using the given @p marker.
*
* @see dependencies
*/
void add_dependency(DependencyId dep, DependencyMarker marker = 0) const;
/** Add multiple additional dependencies to the solvable. */
template <typename Iter>
void add_dependencies(Iter first, Iter last) const;
template <typename Range>
void add_dependencies(const Range& deps) const;
/**
* Set the provides list of a solvable.
*
* In libsolv, a dependency is not match against a solvable name but against its
* ``provides``.
* A package can provide multiple names, for instance an ``openblas 1.0.0`` package
* could provide ```openblas==1.0.0`` and ``blas<=1.5``.
* This is not possible in conda, hence we always use the
* @ref ObjSolvableView::add_self_provide function.
*/
void set_provides(const ObjQueue& q) const;
/**
* Add an additional provide to the sovable.
*
* @see ObjSolvableView::set_provides.
*/
void add_provide(DependencyId dep) const;
/**
* Add an additional provide to the sovable stating the solvable provides itself.
*
* Namely the solvable ``s`` provides ``s.name() == s.version()``.
*
* @see ObjSolvableView::set_provides.
*/
void add_self_provide() const;
/** Add multiple provides to the solvable. */
template <typename Iter>
void add_provides(Iter first, Iter last) const;
template <typename Range>
void add_provides(const Range& deps) const;
/**
* Set all constraints.
*
* A constraint is like a dependency that is not part of the solving outcome.
* In other words, if a solvable has a constraint, it is only activated if another solvable
* in the solving requires that package as a dependency
*
* @warning The pool must be of type conda for this to have an impact in during solving
* @ref ``ObjPool::set_disttype``.
* @note A call to @ref ObjRepoView::internalize is required for this attribute to
* be available for lookup.
**/
void set_constraints(const ObjQueue& q) const;
/**
* Add a constraint.
*
* This function can be used to add constraints one by one.
* @warning The pool must be of type conda for this to have an impact in during solving
* @ref ``ObjPool::set_disttype``.
* @note A call to @ref ObjRepoView::internalize is required for this attribute to
* be available for lookup.
* If some constraints were already internalized, the effect of this function is to
* start a new set of constraints that will replace the old ones rather than add
* to it.
*/
void add_constraint(DependencyId dep) const;
template <typename Iter>
/**
* Add multiple constraints to the solvable.
*
* @warning The pool must be of type conda for this to have an impact in during solving
* @ref ``ObjPool::set_disttype``.
* @note A call to @ref ObjRepoView::internalize is required for this attribute to
* be available for lookup.
* @see ObjSolvableView::add_constraint.
*/
void add_constraints(Iter first, Iter last) const;
template <typename Range>
void add_constraints(const Range& deps) const;
/**
* Set all track features.
*
* The number of track features is used to de-prioritize solvable during solving.
*
* @warning The pool must be of type conda for this to have an impact in during solving
* @ref ``ObjPool::set_disttype``.
* @note A call to @ref ObjRepoView::internalize is required for this attribute to
* be available for lookup.
* @param q A queue of of pool @ref StringId
**/
void set_track_features(const ObjQueue& q) const;
/**
* Add a tracked feature.
*
* This function can be used to add tracked feature one by one.
*
* @warning The pool must be of type conda for this to have an impact in during solving
* @ref ``ObjPool::set_disttype``.
* @note A call to @ref ObjRepoView::internalize is required for this attribute to
* be available for lookup.
* If some constraints were already internalized, the effect of this function is to
* start a new set of constraints that will replace the old ones rather than add
* to it.
* @see ObjSolvableView::add_track_feature
* @param feat A pool @ref StringId of the feature string.
* @return The same id as @p feat.
*/
auto add_track_feature(StringId feat) const -> StringId;
/**
* Add a tracked feature from a string.
*
* @see add_track_feature
* @param feat The feature to add is also added to the pool.
* @return The pool @ref StringId associated with @p feat.
*/
auto add_track_feature(std::string_view feat) const -> StringId;
/**
* Add multiple track features to the solvable.
*
* The range can contain strings or StringId.
*
* @see add_track_feature
*/
template <typename Iter>
void add_track_features(Iter first, Iter last) const;
template <typename Range>
void add_track_features(const Range& features) const;
/**
* Mark mark the package as being of a specific type.
*
* @see ObjSolvableViewConst::type
*/
void set_type(SolvableType val) const;
};
/***************************************
* Implementation of ObjSolvableView *
***************************************/
template <typename Iter>
void ObjSolvableView::add_dependencies(Iter first, Iter last) const
{
for (; first != last; ++first)
{
add_dependency(*first);
}
}
template <typename Range>
void ObjSolvableView::add_dependencies(const Range& deps) const
{
return add_dependencies(deps.cbegin(), deps.cend());
}
template <typename Iter>
void ObjSolvableView::add_provides(Iter first, Iter last) const
{
for (; first != last; ++first)
{
add_provide(*first);
}
}
template <typename Range>
void ObjSolvableView::add_provides(const Range& deps) const
{
return add_provides(deps.cbegin(), deps.cend());
}
template <typename Iter>
void ObjSolvableView::add_constraints(Iter first, Iter last) const
{
for (; first != last; ++first)
{
add_constraint(*first);
}
}
template <typename Range>
void ObjSolvableView::add_constraints(const Range& deps) const
{
return add_constraints(deps.cbegin(), deps.cend());
}
template <typename Iter>
void ObjSolvableView::add_track_features(Iter first, Iter last) const
{
for (; first != last; ++first)
{
add_track_feature(*first);
}
}
template <typename Range>
void ObjSolvableView::add_track_features(const Range& feats) const
{
return add_track_features(feats.cbegin(), feats.cend());
}
}
#endif