mirror of https://github.com/mamba-org/mamba.git
DependencyInfo is redundant (#2314)
Removed redundant DependencyInfo and renamed MatchSpec::build
This commit is contained in:
parent
ce1affbaab
commit
8c4212f5d4
|
@ -34,7 +34,7 @@ namespace mamba
|
||||||
std::string channel;
|
std::string channel;
|
||||||
std::string ns;
|
std::string ns;
|
||||||
std::string subdir;
|
std::string subdir;
|
||||||
std::string build;
|
std::string build_string;
|
||||||
std::string fn;
|
std::string fn;
|
||||||
std::string url;
|
std::string url;
|
||||||
std::string build_number;
|
std::string build_number;
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include <fmt/color.h>
|
#include <fmt/color.h>
|
||||||
#include <solv/solver.h>
|
#include <solv/solver.h>
|
||||||
|
|
||||||
|
#include "mamba/core/match_spec.hpp"
|
||||||
#include "mamba/core/package_info.hpp"
|
#include "mamba/core/package_info.hpp"
|
||||||
#include "mamba/core/util_graph.hpp"
|
#include "mamba/core/util_graph.hpp"
|
||||||
|
|
||||||
|
@ -30,34 +31,6 @@ namespace mamba
|
||||||
class MSolver;
|
class MSolver;
|
||||||
class MPool;
|
class MPool;
|
||||||
|
|
||||||
/**
|
|
||||||
* Separate a dependency spec into a package name and the version range.
|
|
||||||
*/
|
|
||||||
class DependencyInfo
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
DependencyInfo(const std::string& dependency);
|
|
||||||
|
|
||||||
DependencyInfo(const DependencyInfo&) = default;
|
|
||||||
DependencyInfo(DependencyInfo&&) noexcept = default;
|
|
||||||
DependencyInfo& operator=(const DependencyInfo&) = default;
|
|
||||||
DependencyInfo& operator=(DependencyInfo&&) noexcept = default;
|
|
||||||
|
|
||||||
const std::string& name() const;
|
|
||||||
const std::string& version() const;
|
|
||||||
const std::string& build_string() const;
|
|
||||||
std::string str() const;
|
|
||||||
|
|
||||||
bool operator==(const DependencyInfo& other) const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
std::string m_name;
|
|
||||||
std::string m_version_range;
|
|
||||||
std::string m_build_range;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class conflict_map : private std::unordered_map<T, vector_set<T>>
|
class conflict_map : private std::unordered_map<T, vector_set<T>>
|
||||||
{
|
{
|
||||||
|
@ -104,7 +77,7 @@ namespace mamba
|
||||||
PackageNode& operator=(const PackageNode&) = default;
|
PackageNode& operator=(const PackageNode&) = default;
|
||||||
PackageNode& operator=(PackageNode&&) noexcept = default;
|
PackageNode& operator=(PackageNode&&) noexcept = default;
|
||||||
};
|
};
|
||||||
struct UnresolvedDependencyNode : DependencyInfo
|
struct UnresolvedDependencyNode : MatchSpec
|
||||||
{
|
{
|
||||||
SolverRuleinfo problem_type;
|
SolverRuleinfo problem_type;
|
||||||
|
|
||||||
|
@ -113,7 +86,7 @@ namespace mamba
|
||||||
UnresolvedDependencyNode& operator=(const UnresolvedDependencyNode&) = default;
|
UnresolvedDependencyNode& operator=(const UnresolvedDependencyNode&) = default;
|
||||||
UnresolvedDependencyNode& operator=(UnresolvedDependencyNode&&) noexcept = default;
|
UnresolvedDependencyNode& operator=(UnresolvedDependencyNode&&) noexcept = default;
|
||||||
};
|
};
|
||||||
struct ConstraintNode : DependencyInfo
|
struct ConstraintNode : MatchSpec
|
||||||
{
|
{
|
||||||
static constexpr SolverRuleinfo problem_type = SOLVER_RULE_PKG_CONSTRAINS;
|
static constexpr SolverRuleinfo problem_type = SOLVER_RULE_PKG_CONSTRAINS;
|
||||||
|
|
||||||
|
@ -124,7 +97,7 @@ namespace mamba
|
||||||
};
|
};
|
||||||
using node_t = std::variant<RootNode, PackageNode, UnresolvedDependencyNode, ConstraintNode>;
|
using node_t = std::variant<RootNode, PackageNode, UnresolvedDependencyNode, ConstraintNode>;
|
||||||
|
|
||||||
using edge_t = DependencyInfo;
|
using edge_t = MatchSpec;
|
||||||
|
|
||||||
using graph_t = DiGraph<node_t, edge_t>;
|
using graph_t = DiGraph<node_t, edge_t>;
|
||||||
using node_id = graph_t::node_id;
|
using node_id = graph_t::node_id;
|
||||||
|
@ -164,7 +137,7 @@ namespace mamba
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct RoughCompare
|
struct RoughCompare
|
||||||
{
|
{
|
||||||
bool operator()(const T& a, const T& b);
|
bool operator()(const T& a, const T& b) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -243,7 +216,7 @@ namespace mamba
|
||||||
UnresolvedDependencyListNode,
|
UnresolvedDependencyListNode,
|
||||||
ConstraintListNode>;
|
ConstraintListNode>;
|
||||||
|
|
||||||
using edge_t = NamedList<DependencyInfo>;
|
using edge_t = NamedList<MatchSpec>;
|
||||||
|
|
||||||
using graph_t = DiGraph<node_t, edge_t>;
|
using graph_t = DiGraph<node_t, edge_t>;
|
||||||
using node_id = graph_t::node_id;
|
using node_id = graph_t::node_id;
|
||||||
|
|
|
@ -19,6 +19,10 @@ namespace mamba
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A sorted vector behaving like a set.
|
* A sorted vector behaving like a set.
|
||||||
|
*
|
||||||
|
* Like, ``std::set``, uniqueness is determined by using the equivalence relation.
|
||||||
|
* In imprecise terms, two objects ``a`` and ``b`` are considered equivalent if neither
|
||||||
|
* compares less than the other: ``!comp(a, b) && !comp(b, a)``
|
||||||
*/
|
*/
|
||||||
template <typename Key, typename Compare = std::less<Key>, typename Allocator = std::allocator<Key>>
|
template <typename Key, typename Compare = std::less<Key>, typename Allocator = std::allocator<Key>>
|
||||||
class vector_set : private std::vector<Key, Allocator>
|
class vector_set : private std::vector<Key, Allocator>
|
||||||
|
@ -86,6 +90,7 @@ namespace mamba
|
||||||
|
|
||||||
key_compare m_compare;
|
key_compare m_compare;
|
||||||
|
|
||||||
|
bool key_eq(const value_type& a, const value_type& b) const;
|
||||||
template <typename U>
|
template <typename U>
|
||||||
std::pair<const_iterator, bool> insert_impl(U&& value);
|
std::pair<const_iterator, bool> insert_impl(U&& value);
|
||||||
void sort_and_remove_duplicates();
|
void sort_and_remove_duplicates();
|
||||||
|
@ -119,6 +124,12 @@ namespace mamba
|
||||||
const vector_set<Key, Compare, Allocator>& rhs
|
const vector_set<Key, Compare, Allocator>& rhs
|
||||||
);
|
);
|
||||||
|
|
||||||
|
template <typename Key, typename Compare, typename Allocator>
|
||||||
|
bool operator!=(
|
||||||
|
const vector_set<Key, Compare, Allocator>& lhs,
|
||||||
|
const vector_set<Key, Compare, Allocator>& rhs
|
||||||
|
);
|
||||||
|
|
||||||
// Simplified implementation of a directed graph
|
// Simplified implementation of a directed graph
|
||||||
template <typename Node, typename Derived>
|
template <typename Node, typename Derived>
|
||||||
class DiGraphBase
|
class DiGraphBase
|
||||||
|
@ -386,11 +397,18 @@ namespace mamba
|
||||||
return insert_impl(std::move(value));
|
return insert_impl(std::move(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename K, typename C, typename A>
|
||||||
|
bool vector_set<K, C, A>::key_eq(const value_type& a, const value_type& b) const
|
||||||
|
{
|
||||||
|
return !m_compare(a, b) && !m_compare(b, a);
|
||||||
|
}
|
||||||
|
|
||||||
template <typename K, typename C, typename A>
|
template <typename K, typename C, typename A>
|
||||||
void vector_set<K, C, A>::sort_and_remove_duplicates()
|
void vector_set<K, C, A>::sort_and_remove_duplicates()
|
||||||
{
|
{
|
||||||
std::sort(Base::begin(), Base::end(), m_compare);
|
std::sort(Base::begin(), Base::end(), m_compare);
|
||||||
Base::erase(std::unique(Base::begin(), Base::end()), Base::end());
|
auto is_eq = [this](const value_type& a, const value_type& b) { return key_eq(a, b); };
|
||||||
|
Base::erase(std::unique(Base::begin(), Base::end(), is_eq), Base::end());
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename K, typename C, typename A>
|
template <typename K, typename C, typename A>
|
||||||
|
@ -406,7 +424,7 @@ namespace mamba
|
||||||
auto vector_set<K, C, A>::insert_impl(U&& value) -> std::pair<const_iterator, bool>
|
auto vector_set<K, C, A>::insert_impl(U&& value) -> std::pair<const_iterator, bool>
|
||||||
{
|
{
|
||||||
auto it = std::lower_bound(begin(), end(), value, m_compare);
|
auto it = std::lower_bound(begin(), end(), value, m_compare);
|
||||||
if ((it == end()) || (!(*it == value)))
|
if ((it == end()) || (!(key_eq(*it, value))))
|
||||||
{
|
{
|
||||||
Base::insert(it, std::forward<U>(value));
|
Base::insert(it, std::forward<U>(value));
|
||||||
}
|
}
|
||||||
|
@ -416,8 +434,14 @@ namespace mamba
|
||||||
template <typename K, typename C, typename A>
|
template <typename K, typename C, typename A>
|
||||||
bool operator==(const vector_set<K, C, A>& lhs, const vector_set<K, C, A>& rhs)
|
bool operator==(const vector_set<K, C, A>& lhs, const vector_set<K, C, A>& rhs)
|
||||||
{
|
{
|
||||||
return static_cast<const std::vector<K, A>&>(lhs)
|
auto is_eq = [&lhs](const auto& a, const auto& b) { return lhs.key_eq(a, b); };
|
||||||
== static_cast<const std::vector<K, A>&>(rhs);
|
return std::equal(lhs.cbegin(), lhs.cend(), rhs.cbegin(), rhs.cend(), is_eq);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename K, typename C, typename A>
|
||||||
|
bool operator!=(const vector_set<K, C, A>& lhs, const vector_set<K, C, A>& rhs)
|
||||||
|
{
|
||||||
|
return !(lhs == rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
/********************************
|
/********************************
|
||||||
|
|
|
@ -350,7 +350,7 @@ namespace mamba
|
||||||
MatchSpec ms(u.substr(0, hash));
|
MatchSpec ms(u.substr(0, hash));
|
||||||
PackageInfo p(ms.name);
|
PackageInfo p(ms.name);
|
||||||
p.url = ms.url;
|
p.url = ms.url;
|
||||||
p.build_string = ms.build;
|
p.build_string = ms.build_string;
|
||||||
p.version = ms.version;
|
p.version = ms.version;
|
||||||
p.channel = ms.channel;
|
p.channel = ms.channel;
|
||||||
p.fn = ms.fn;
|
p.fn = ms.fn;
|
||||||
|
|
|
@ -58,7 +58,7 @@ namespace mamba
|
||||||
package.info.url = package_node["url"].as<std::string>();
|
package.info.url = package_node["url"].as<std::string>();
|
||||||
const MatchSpec spec{ package.info.url };
|
const MatchSpec spec{ package.info.url };
|
||||||
package.info.fn = spec.fn;
|
package.info.fn = spec.fn;
|
||||||
package.info.build_string = spec.build;
|
package.info.build_string = spec.build_string;
|
||||||
package.info.subdir = spec.subdir;
|
package.info.subdir = spec.subdir;
|
||||||
package.info.channel = spec.channel;
|
package.info.channel = spec.channel;
|
||||||
|
|
||||||
|
|
|
@ -94,7 +94,7 @@ namespace mamba
|
||||||
|
|
||||||
name = dist[0];
|
name = dist[0];
|
||||||
version = dist[1];
|
version = dist[1];
|
||||||
build = dist[2];
|
build_string = dist[2];
|
||||||
|
|
||||||
channel = parsed_channel.canonical_name();
|
channel = parsed_channel.canonical_name();
|
||||||
// TODO how to handle this with multiple platforms?
|
// TODO how to handle this with multiple platforms?
|
||||||
|
@ -223,20 +223,20 @@ namespace mamba
|
||||||
auto [pv, pb] = parse_version_and_build(std::string(strip(version)));
|
auto [pv, pb] = parse_version_and_build(std::string(strip(version)));
|
||||||
|
|
||||||
version = pv;
|
version = pv;
|
||||||
build = pb;
|
build_string = pb;
|
||||||
|
|
||||||
// translate version '=1.2.3' to '1.2.3*'
|
// translate version '=1.2.3' to '1.2.3*'
|
||||||
// is it a simple version starting with '='? i.e. '=1.2.3'
|
// is it a simple version starting with '='? i.e. '=1.2.3'
|
||||||
if (version.size() >= 2 && version[0] == '=')
|
if (version.size() >= 2 && version[0] == '=')
|
||||||
{
|
{
|
||||||
auto rest = version.substr(1);
|
auto rest = version.substr(1);
|
||||||
if (version[1] == '=' && build.empty())
|
if (version[1] == '=' && build_string.empty())
|
||||||
{
|
{
|
||||||
version = version.substr(2);
|
version = version.substr(2);
|
||||||
}
|
}
|
||||||
else if (rest.find_first_of("=,|") == rest.npos)
|
else if (rest.find_first_of("=,|") == rest.npos)
|
||||||
{
|
{
|
||||||
if (build.empty() && version.back() != '*')
|
if (build_string.empty() && version.back() != '*')
|
||||||
{
|
{
|
||||||
version = concat(version, "*");
|
version = concat(version, "*");
|
||||||
}
|
}
|
||||||
|
@ -250,7 +250,7 @@ namespace mamba
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
version = "";
|
version = "";
|
||||||
build = "";
|
build_string = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO think about using a hash function here, (and elsewhere), like:
|
// TODO think about using a hash function here, (and elsewhere), like:
|
||||||
|
@ -263,7 +263,7 @@ namespace mamba
|
||||||
}
|
}
|
||||||
else if (k == "build")
|
else if (k == "build")
|
||||||
{
|
{
|
||||||
build = v;
|
build_string = v;
|
||||||
}
|
}
|
||||||
else if (k == "version")
|
else if (k == "version")
|
||||||
{
|
{
|
||||||
|
@ -299,9 +299,9 @@ namespace mamba
|
||||||
{
|
{
|
||||||
res << " " << version;
|
res << " " << version;
|
||||||
// if (!build.empty() && (build != "*"))
|
// if (!build.empty() && (build != "*"))
|
||||||
if (!build.empty())
|
if (!build_string.empty())
|
||||||
{
|
{
|
||||||
res << " " << build;
|
res << " " << build_string;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return res.str();
|
return res.str();
|
||||||
|
@ -356,7 +356,7 @@ namespace mamba
|
||||||
}
|
}
|
||||||
else if (starts_with(version, "!=") || starts_with(version, "~="))
|
else if (starts_with(version, "!=") || starts_with(version, "~="))
|
||||||
{
|
{
|
||||||
if (!build.empty())
|
if (!build_string.empty())
|
||||||
{
|
{
|
||||||
formatted_brackets.push_back(concat("version='", version, "'"));
|
formatted_brackets.push_back(concat("version='", version, "'"));
|
||||||
}
|
}
|
||||||
|
@ -396,23 +396,23 @@ namespace mamba
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!build.empty())
|
if (!build_string.empty())
|
||||||
{
|
{
|
||||||
if (is_complex_relation(build))
|
if (is_complex_relation(build_string))
|
||||||
{
|
{
|
||||||
formatted_brackets.push_back(concat("build='", build, "'"));
|
formatted_brackets.push_back(concat("build='", build_string, "'"));
|
||||||
}
|
}
|
||||||
else if (build.find("*") != build.npos)
|
else if (build_string.find("*") != build_string.npos)
|
||||||
{
|
{
|
||||||
formatted_brackets.push_back(concat("build=", build));
|
formatted_brackets.push_back(concat("build=", build_string));
|
||||||
}
|
}
|
||||||
else if (version_exact)
|
else if (version_exact)
|
||||||
{
|
{
|
||||||
res << "=" << build;
|
res << "=" << build_string;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
formatted_brackets.push_back(concat("build=", build));
|
formatted_brackets.push_back(concat("build=", build_string));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -461,6 +461,6 @@ namespace mamba
|
||||||
|
|
||||||
bool MatchSpec::is_simple() const
|
bool MatchSpec::is_simple() const
|
||||||
{
|
{
|
||||||
return version.empty() && build.empty() && build_number.empty();
|
return version.empty() && build_string.empty() && build_number.empty();
|
||||||
}
|
}
|
||||||
} // namespace mamba
|
} // namespace mamba
|
||||||
|
|
|
@ -30,80 +30,6 @@
|
||||||
|
|
||||||
namespace mamba
|
namespace mamba
|
||||||
{
|
{
|
||||||
|
|
||||||
/**************************************
|
|
||||||
* Implementation of DependencyInfo *
|
|
||||||
**************************************/
|
|
||||||
|
|
||||||
DependencyInfo::DependencyInfo(const std::string& dep)
|
|
||||||
{
|
|
||||||
static std::regex const regexp("\\s*(\\w[\\w-]*)\\s*([^\\s]*)(?:\\s+([^\\s]+))?\\s*");
|
|
||||||
std::smatch matches;
|
|
||||||
const bool matched = std::regex_match(dep, matches, regexp);
|
|
||||||
// First match is the whole regex match
|
|
||||||
if (!matched || matches.size() != 4)
|
|
||||||
{
|
|
||||||
throw std::runtime_error("Invalid dependency info: " + dep);
|
|
||||||
}
|
|
||||||
m_name = matches.str(1);
|
|
||||||
m_version_range = matches.str(2);
|
|
||||||
if (m_version_range.empty())
|
|
||||||
{
|
|
||||||
m_version_range = "*";
|
|
||||||
}
|
|
||||||
m_build_range = matches.str(3);
|
|
||||||
if (m_build_range.empty())
|
|
||||||
{
|
|
||||||
m_build_range = "*";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::string& DependencyInfo::name() const
|
|
||||||
{
|
|
||||||
return m_name;
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::string& DependencyInfo::version() const
|
|
||||||
{
|
|
||||||
return m_version_range;
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::string& DependencyInfo::build_string() const
|
|
||||||
{
|
|
||||||
return m_build_range;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string DependencyInfo::str() const
|
|
||||||
{
|
|
||||||
std::string out(m_name);
|
|
||||||
out.reserve(
|
|
||||||
m_name.size() + (m_version_range.empty() ? 0 : 1) + m_version_range.size()
|
|
||||||
+ (m_build_range.empty() ? 0 : 1) + m_version_range.size()
|
|
||||||
);
|
|
||||||
if (!m_version_range.empty())
|
|
||||||
{
|
|
||||||
out += ' ';
|
|
||||||
out += m_version_range;
|
|
||||||
}
|
|
||||||
if (!m_build_range.empty())
|
|
||||||
{
|
|
||||||
out += ' ';
|
|
||||||
out += m_build_range;
|
|
||||||
}
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DependencyInfo::operator==(const DependencyInfo& other) const
|
|
||||||
{
|
|
||||||
auto attrs = [](const DependencyInfo& x)
|
|
||||||
{ return std::tie(x.name(), x.version(), x.build_string()); };
|
|
||||||
return attrs(*this) == attrs(other);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*************************************
|
|
||||||
* Implementation of ProblemsGraph *
|
|
||||||
*************************************/
|
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -238,7 +164,7 @@ namespace mamba
|
||||||
PackageNode{ std::move(target).value(), { type } }
|
PackageNode{ std::move(target).value(), { type } }
|
||||||
);
|
);
|
||||||
node_id cons_id = add_solvable(problem.dep_id, ConstraintNode{ dep.value() });
|
node_id cons_id = add_solvable(problem.dep_id, ConstraintNode{ dep.value() });
|
||||||
DependencyInfo edge(dep.value());
|
MatchSpec edge(dep.value());
|
||||||
m_graph.add_edge(src_id, cons_id, std::move(edge));
|
m_graph.add_edge(src_id, cons_id, std::move(edge));
|
||||||
add_conflict(cons_id, tgt_id);
|
add_conflict(cons_id, tgt_id);
|
||||||
break;
|
break;
|
||||||
|
@ -258,7 +184,7 @@ namespace mamba
|
||||||
problem.source_id,
|
problem.source_id,
|
||||||
PackageNode{ std::move(source).value(), std::nullopt }
|
PackageNode{ std::move(source).value(), std::nullopt }
|
||||||
);
|
);
|
||||||
DependencyInfo edge(dep.value());
|
MatchSpec edge(dep.value());
|
||||||
bool added = add_expanded_deps_edges(src_id, problem.dep_id, edge);
|
bool added = add_expanded_deps_edges(src_id, problem.dep_id, edge);
|
||||||
if (!added)
|
if (!added)
|
||||||
{
|
{
|
||||||
|
@ -277,7 +203,7 @@ namespace mamba
|
||||||
warn_unexpected_problem(problem);
|
warn_unexpected_problem(problem);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
DependencyInfo edge(dep.value());
|
MatchSpec edge(dep.value());
|
||||||
bool added = add_expanded_deps_edges(m_root_node, problem.dep_id, edge);
|
bool added = add_expanded_deps_edges(m_root_node, problem.dep_id, edge);
|
||||||
if (!added)
|
if (!added)
|
||||||
{
|
{
|
||||||
|
@ -296,7 +222,7 @@ namespace mamba
|
||||||
warn_unexpected_problem(problem);
|
warn_unexpected_problem(problem);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
DependencyInfo edge(dep.value());
|
MatchSpec edge(dep.value());
|
||||||
node_id dep_id = add_solvable(
|
node_id dep_id = add_solvable(
|
||||||
problem.dep_id,
|
problem.dep_id,
|
||||||
UnresolvedDependencyNode{ std::move(dep).value(), type }
|
UnresolvedDependencyNode{ std::move(dep).value(), type }
|
||||||
|
@ -315,7 +241,7 @@ namespace mamba
|
||||||
warn_unexpected_problem(problem);
|
warn_unexpected_problem(problem);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
DependencyInfo edge(dep.value());
|
MatchSpec edge(dep.value());
|
||||||
node_id src_id = add_solvable(
|
node_id src_id = add_solvable(
|
||||||
problem.source_id,
|
problem.source_id,
|
||||||
PackageNode{ std::move(source).value(), std::nullopt }
|
PackageNode{ std::move(source).value(), std::nullopt }
|
||||||
|
@ -728,9 +654,6 @@ namespace mamba
|
||||||
const node_id_mapping& old_to_new
|
const node_id_mapping& old_to_new
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
// Check nothrow move for efficient push_back
|
|
||||||
static_assert(std::is_nothrow_move_constructible_v<ProblemsGraph::edge_t>);
|
|
||||||
|
|
||||||
auto add_new_edge = [&](ProblemsGraph::node_id old_from, ProblemsGraph::node_id old_to)
|
auto add_new_edge = [&](ProblemsGraph::node_id old_from, ProblemsGraph::node_id old_to)
|
||||||
{
|
{
|
||||||
auto const new_from = old_to_new[old_from];
|
auto const new_from = old_to_new[old_from];
|
||||||
|
@ -820,29 +743,25 @@ namespace mamba
|
||||||
* Implementation of CompressedProblemsGraph::RoughCompare *
|
* Implementation of CompressedProblemsGraph::RoughCompare *
|
||||||
*************************************************************/
|
*************************************************************/
|
||||||
|
|
||||||
template <>
|
|
||||||
bool CompressedProblemsGraph::RoughCompare<ProblemsGraph::PackageNode>::operator()(
|
|
||||||
const ProblemsGraph::PackageNode& a,
|
|
||||||
const ProblemsGraph::PackageNode& b
|
|
||||||
)
|
|
||||||
{
|
|
||||||
auto attrs = [](const ProblemsGraph::PackageNode& x)
|
|
||||||
{ return std::tie(x.name, x.version, x.build_number, x.build_string); };
|
|
||||||
return attrs(a) < attrs(b);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
bool CompressedProblemsGraph::RoughCompare<T>::operator()(const T& a, const T& b)
|
bool CompressedProblemsGraph::RoughCompare<T>::operator()(const T& a, const T& b) const
|
||||||
{
|
{
|
||||||
auto attrs = [](const DependencyInfo& x)
|
auto attrs = [](const auto& x)
|
||||||
{ return std::tie(x.name(), x.version(), x.build_string()); };
|
{
|
||||||
|
return std::tie(
|
||||||
|
std::invoke(&T::name, x),
|
||||||
|
std::invoke(&T::version, x),
|
||||||
|
std::invoke(&T::build_number, x),
|
||||||
|
std::invoke(&T::build_string, x)
|
||||||
|
);
|
||||||
|
};
|
||||||
return attrs(a) < attrs(b);
|
return attrs(a) < attrs(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
template struct CompressedProblemsGraph::RoughCompare<ProblemsGraph::PackageNode>;
|
template struct CompressedProblemsGraph::RoughCompare<ProblemsGraph::PackageNode>;
|
||||||
template struct CompressedProblemsGraph::RoughCompare<ProblemsGraph::UnresolvedDependencyNode>;
|
template struct CompressedProblemsGraph::RoughCompare<ProblemsGraph::UnresolvedDependencyNode>;
|
||||||
template struct CompressedProblemsGraph::RoughCompare<ProblemsGraph::ConstraintNode>;
|
template struct CompressedProblemsGraph::RoughCompare<ProblemsGraph::ConstraintNode>;
|
||||||
template struct CompressedProblemsGraph::RoughCompare<DependencyInfo>;
|
template struct CompressedProblemsGraph::RoughCompare<MatchSpec>;
|
||||||
|
|
||||||
/**********************************************************
|
/**********************************************************
|
||||||
* Implementation of CompressedProblemsGraph::NamedList *
|
* Implementation of CompressedProblemsGraph::NamedList *
|
||||||
|
@ -1032,7 +951,7 @@ namespace mamba
|
||||||
template class CompressedProblemsGraph::NamedList<ProblemsGraph::PackageNode>;
|
template class CompressedProblemsGraph::NamedList<ProblemsGraph::PackageNode>;
|
||||||
template class CompressedProblemsGraph::NamedList<ProblemsGraph::UnresolvedDependencyNode>;
|
template class CompressedProblemsGraph::NamedList<ProblemsGraph::UnresolvedDependencyNode>;
|
||||||
template class CompressedProblemsGraph::NamedList<ProblemsGraph::ConstraintNode>;
|
template class CompressedProblemsGraph::NamedList<ProblemsGraph::ConstraintNode>;
|
||||||
template class CompressedProblemsGraph::NamedList<DependencyInfo>;
|
template class CompressedProblemsGraph::NamedList<MatchSpec>;
|
||||||
|
|
||||||
/***********************************
|
/***********************************
|
||||||
* Implementation of summary_msg *
|
* Implementation of summary_msg *
|
||||||
|
|
|
@ -326,19 +326,21 @@ namespace mamba
|
||||||
selected_channel = make_channel(selected_channel).name();
|
selected_channel = make_channel(selected_channel).name();
|
||||||
|
|
||||||
MatchSpec modified_spec(ms);
|
MatchSpec modified_spec(ms);
|
||||||
if (!ms.channel.empty() || !ms.version.empty() || !ms.build.empty())
|
if (!ms.channel.empty() || !ms.version.empty() || !ms.build_string.empty())
|
||||||
{
|
{
|
||||||
Console::stream() << ms.conda_build_form()
|
Console::stream() << ms.conda_build_form()
|
||||||
<< ": overriding channel, version and build from "
|
<< ": overriding channel, version and build from "
|
||||||
"installed packages due to --force-reinstall.";
|
"installed packages due to --force-reinstall.";
|
||||||
ms.channel = "";
|
ms.channel = "";
|
||||||
ms.version = "";
|
ms.version = "";
|
||||||
ms.build = "";
|
ms.build_string = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
modified_spec.channel = selected_channel;
|
modified_spec.channel = selected_channel;
|
||||||
modified_spec.version = check_char(pool_id2str(pool, s->evr));
|
modified_spec.version = check_char(pool_id2str(pool, s->evr));
|
||||||
modified_spec.build = check_char(solvable_lookup_str(s, SOLVABLE_BUILDFLAVOR));
|
modified_spec.build_string = check_char(
|
||||||
|
solvable_lookup_str(s, SOLVABLE_BUILDFLAVOR)
|
||||||
|
);
|
||||||
LOG_INFO << "Reinstall " << modified_spec.conda_build_form() << " from channel "
|
LOG_INFO << "Reinstall " << modified_spec.conda_build_form() << " from channel "
|
||||||
<< selected_channel;
|
<< selected_channel;
|
||||||
return add_channel_specific_job(modified_spec, job_flag);
|
return add_channel_specific_job(modified_spec, job_flag);
|
||||||
|
|
|
@ -478,7 +478,7 @@ namespace mamba
|
||||||
{
|
{
|
||||||
PackageInfo p(ms.name);
|
PackageInfo p(ms.name);
|
||||||
p.url = ms.url;
|
p.url = ms.url;
|
||||||
p.build_string = ms.build;
|
p.build_string = ms.build_string;
|
||||||
p.version = ms.version;
|
p.version = ms.version;
|
||||||
p.channel = ms.channel;
|
p.channel = ms.channel;
|
||||||
p.fn = ms.fn;
|
p.fn = ms.fn;
|
||||||
|
|
|
@ -141,7 +141,7 @@ namespace mamba
|
||||||
);
|
);
|
||||||
EXPECT_EQ(ms.name, "_libgcc_mutex");
|
EXPECT_EQ(ms.name, "_libgcc_mutex");
|
||||||
EXPECT_EQ(ms.version, "0.1");
|
EXPECT_EQ(ms.version, "0.1");
|
||||||
EXPECT_EQ(ms.build, "conda_forge");
|
EXPECT_EQ(ms.build_string, "conda_forge");
|
||||||
EXPECT_EQ(
|
EXPECT_EQ(
|
||||||
ms.url,
|
ms.url,
|
||||||
"https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2"
|
"https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2"
|
||||||
|
@ -152,7 +152,7 @@ namespace mamba
|
||||||
MatchSpec ms("/home/randomguy/Downloads/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2");
|
MatchSpec ms("/home/randomguy/Downloads/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2");
|
||||||
EXPECT_EQ(ms.name, "_libgcc_mutex");
|
EXPECT_EQ(ms.name, "_libgcc_mutex");
|
||||||
EXPECT_EQ(ms.version, "0.1");
|
EXPECT_EQ(ms.version, "0.1");
|
||||||
EXPECT_EQ(ms.build, "conda_forge");
|
EXPECT_EQ(ms.build_string, "conda_forge");
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
std::string driveletter = fs::absolute(fs::u8path("/")).string().substr(0, 1);
|
std::string driveletter = fs::absolute(fs::u8path("/")).string().substr(0, 1);
|
||||||
EXPECT_EQ(
|
EXPECT_EQ(
|
||||||
|
|
|
@ -28,48 +28,6 @@
|
||||||
|
|
||||||
namespace mamba
|
namespace mamba
|
||||||
{
|
{
|
||||||
|
|
||||||
TEST(dependency_info, unconstrained)
|
|
||||||
{
|
|
||||||
const auto d = DependencyInfo("foo7 ");
|
|
||||||
EXPECT_EQ(d.name(), "foo7");
|
|
||||||
EXPECT_EQ(d.version(), "*");
|
|
||||||
EXPECT_EQ(d.build_string(), "*");
|
|
||||||
EXPECT_EQ(d.str(), "foo7 * *");
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(dependency_info, version_range)
|
|
||||||
{
|
|
||||||
const auto d = DependencyInfo(" foo_bar >=4.3.0,<5.0 ");
|
|
||||||
EXPECT_EQ(d.name(), "foo_bar");
|
|
||||||
EXPECT_EQ(d.version(), ">=4.3.0,<5.0");
|
|
||||||
EXPECT_EQ(d.build_string(), "*");
|
|
||||||
EXPECT_EQ(d.str(), "foo_bar >=4.3.0,<5.0 *");
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(dependency_info, version_equality)
|
|
||||||
{
|
|
||||||
const auto d = DependencyInfo("foo-bar==4.3.0");
|
|
||||||
EXPECT_EQ(d.name(), "foo-bar");
|
|
||||||
EXPECT_EQ(d.version(), "==4.3.0");
|
|
||||||
EXPECT_EQ(d.build_string(), "*");
|
|
||||||
EXPECT_EQ(d.str(), "foo-bar ==4.3.0 *");
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(dependency_info, build_range)
|
|
||||||
{
|
|
||||||
const auto d = DependencyInfo(" python_abi 3.10.* *_cp310 ");
|
|
||||||
EXPECT_EQ(d.name(), "python_abi");
|
|
||||||
EXPECT_EQ(d.version(), "3.10.*");
|
|
||||||
EXPECT_EQ(d.build_string(), "*_cp310");
|
|
||||||
EXPECT_EQ(d.str(), "python_abi 3.10.* *_cp310");
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(dependency_info, fail)
|
|
||||||
{
|
|
||||||
EXPECT_ANY_THROW(DependencyInfo("<foo"));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(conflict_map, symetric)
|
TEST(conflict_map, symetric)
|
||||||
{
|
{
|
||||||
auto c = conflict_map<std::size_t>();
|
auto c = conflict_map<std::size_t>();
|
||||||
|
|
|
@ -32,6 +32,8 @@ namespace mamba
|
||||||
EXPECT_EQ(vector_set<int>({ 1, 2 }), vector_set<int>({ 1, 2 }));
|
EXPECT_EQ(vector_set<int>({ 1, 2 }), vector_set<int>({ 1, 2 }));
|
||||||
EXPECT_EQ(vector_set<int>({ 1, 2 }), vector_set<int>({ 2, 1 }));
|
EXPECT_EQ(vector_set<int>({ 1, 2 }), vector_set<int>({ 2, 1 }));
|
||||||
EXPECT_EQ(vector_set<int>({ 1, 2, 1 }), vector_set<int>({ 2, 2, 1 }));
|
EXPECT_EQ(vector_set<int>({ 1, 2, 1 }), vector_set<int>({ 2, 2, 1 }));
|
||||||
|
EXPECT_NE(vector_set<int>({ 1, 2 }), vector_set<int>({ 1, 2, 3 }));
|
||||||
|
EXPECT_NE(vector_set<int>({ 2 }), vector_set<int>({}));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(vector_set, insertion)
|
TEST(vector_set, insertion)
|
||||||
|
|
|
@ -8,7 +8,6 @@ __all__ = [
|
||||||
"CompressedProblemsGraph",
|
"CompressedProblemsGraph",
|
||||||
"Configuration",
|
"Configuration",
|
||||||
"Context",
|
"Context",
|
||||||
"DependencyInfo",
|
|
||||||
"DownloadTargetList",
|
"DownloadTargetList",
|
||||||
"ExtraPkgInfo",
|
"ExtraPkgInfo",
|
||||||
"History",
|
"History",
|
||||||
|
@ -263,7 +262,7 @@ class CompressedProblemsGraph:
|
||||||
def __init__(self) -> None: ...
|
def __init__(self) -> None: ...
|
||||||
def __iter__(self) -> typing.Iterator: ...
|
def __iter__(self) -> typing.Iterator: ...
|
||||||
def __len__(self) -> int: ...
|
def __len__(self) -> int: ...
|
||||||
def add(self, arg0: DependencyInfo) -> None: ...
|
def add(self, arg0: MatchSpec) -> None: ...
|
||||||
def build_strings_trunc(
|
def build_strings_trunc(
|
||||||
self,
|
self,
|
||||||
sep: str = "|",
|
sep: str = "|",
|
||||||
|
@ -671,28 +670,6 @@ class Context:
|
||||||
pass
|
pass
|
||||||
pass
|
pass
|
||||||
|
|
||||||
class DependencyInfo:
|
|
||||||
def __eq__(self, arg0: DependencyInfo) -> bool: ...
|
|
||||||
def __init__(self, arg0: str) -> None: ...
|
|
||||||
def __str__(self) -> str: ...
|
|
||||||
@property
|
|
||||||
def build_string(self) -> str:
|
|
||||||
"""
|
|
||||||
:type: str
|
|
||||||
"""
|
|
||||||
@property
|
|
||||||
def name(self) -> str:
|
|
||||||
"""
|
|
||||||
:type: str
|
|
||||||
"""
|
|
||||||
@property
|
|
||||||
def version(self) -> str:
|
|
||||||
"""
|
|
||||||
:type: str
|
|
||||||
"""
|
|
||||||
__hash__ = None
|
|
||||||
pass
|
|
||||||
|
|
||||||
class DownloadTargetList:
|
class DownloadTargetList:
|
||||||
def __init__(self) -> None: ...
|
def __init__(self) -> None: ...
|
||||||
def add(self, arg0: SubdirData) -> None: ...
|
def add(self, arg0: SubdirData) -> None: ...
|
||||||
|
@ -721,7 +698,7 @@ class ExtraPkgInfo:
|
||||||
|
|
||||||
class History:
|
class History:
|
||||||
def __init__(self, arg0: Path) -> None: ...
|
def __init__(self, arg0: Path) -> None: ...
|
||||||
def get_requested_specs_map(self) -> typing.Dict[str, mamba::MatchSpec]: ...
|
def get_requested_specs_map(self) -> typing.Dict[str, MatchSpec]: ...
|
||||||
pass
|
pass
|
||||||
|
|
||||||
class Key:
|
class Key:
|
||||||
|
@ -1065,7 +1042,7 @@ class ProblemsGraph:
|
||||||
class ConflictMap:
|
class ConflictMap:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
class ConstraintNode(DependencyInfo):
|
class ConstraintNode(MatchSpec):
|
||||||
problem_type: libmambapy.bindings.SolverRuleinfo # value = <SolverRuleinfo.SOLVER_RULE_PKG_CONSTRAINS: 267>
|
problem_type: libmambapy.bindings.SolverRuleinfo # value = <SolverRuleinfo.SOLVER_RULE_PKG_CONSTRAINS: 267>
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -1075,7 +1052,7 @@ class ProblemsGraph:
|
||||||
class RootNode:
|
class RootNode:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
class UnresolvedDependencyNode(DependencyInfo):
|
class UnresolvedDependencyNode(MatchSpec):
|
||||||
@property
|
@property
|
||||||
def problem_type(self) -> SolverRuleinfo:
|
def problem_type(self) -> SolverRuleinfo:
|
||||||
"""
|
"""
|
||||||
|
@ -1099,7 +1076,7 @@ class ProblemsGraph:
|
||||||
ProblemsGraph.ConstraintNode,
|
ProblemsGraph.ConstraintNode,
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
typing.Dict[typing.Tuple[int, int], DependencyInfo],
|
typing.Dict[typing.Tuple[int, int], MatchSpec],
|
||||||
]: ...
|
]: ...
|
||||||
def root_node(self) -> int: ...
|
def root_node(self) -> int: ...
|
||||||
pass
|
pass
|
||||||
|
|
|
@ -253,22 +253,19 @@ PYBIND11_MODULE(bindings, m)
|
||||||
.def_readwrite("description", &MSolverProblem::description)
|
.def_readwrite("description", &MSolverProblem::description)
|
||||||
.def("__str__", [](const MSolverProblem& self) { return self.description; });
|
.def("__str__", [](const MSolverProblem& self) { return self.description; });
|
||||||
|
|
||||||
py::class_<DependencyInfo>(m, "DependencyInfo")
|
py::class_<MatchSpec>(m, "MatchSpec")
|
||||||
|
.def(py::init<>())
|
||||||
.def(py::init<const std::string&>())
|
.def(py::init<const std::string&>())
|
||||||
.def_property_readonly("name", &DependencyInfo::name)
|
.def("conda_build_form", &MatchSpec::conda_build_form);
|
||||||
.def_property_readonly("version", &DependencyInfo::version)
|
|
||||||
.def_property_readonly("build_string", &DependencyInfo::build_string)
|
|
||||||
.def("__str__", &DependencyInfo::str)
|
|
||||||
.def(py::self == py::self);
|
|
||||||
|
|
||||||
using PbGraph = ProblemsGraph;
|
using PbGraph = ProblemsGraph;
|
||||||
auto pyPbGraph = py::class_<PbGraph>(m, "ProblemsGraph");
|
auto pyPbGraph = py::class_<PbGraph>(m, "ProblemsGraph");
|
||||||
|
|
||||||
py::class_<PbGraph::RootNode>(pyPbGraph, "RootNode").def(py::init<>());
|
py::class_<PbGraph::RootNode>(pyPbGraph, "RootNode").def(py::init<>());
|
||||||
py::class_<PbGraph::PackageNode, PackageInfo>(pyPbGraph, "PackageNode");
|
py::class_<PbGraph::PackageNode, PackageInfo>(pyPbGraph, "PackageNode");
|
||||||
py::class_<PbGraph::UnresolvedDependencyNode, DependencyInfo>(pyPbGraph, "UnresolvedDependencyNode")
|
py::class_<PbGraph::UnresolvedDependencyNode, MatchSpec>(pyPbGraph, "UnresolvedDependencyNode")
|
||||||
.def_readwrite("problem_type", &PbGraph::UnresolvedDependencyNode::problem_type);
|
.def_readwrite("problem_type", &PbGraph::UnresolvedDependencyNode::problem_type);
|
||||||
py::class_<PbGraph::ConstraintNode, DependencyInfo>(pyPbGraph, "ConstraintNode")
|
py::class_<PbGraph::ConstraintNode, MatchSpec>(pyPbGraph, "ConstraintNode")
|
||||||
.def_readonly_static("problem_type", &PbGraph::ConstraintNode::problem_type);
|
.def_readonly_static("problem_type", &PbGraph::ConstraintNode::problem_type);
|
||||||
|
|
||||||
py::class_<PbGraph::conflicts_t>(pyPbGraph, "ConflictMap")
|
py::class_<PbGraph::conflicts_t>(pyPbGraph, "ConflictMap")
|
||||||
|
@ -340,11 +337,6 @@ PYBIND11_MODULE(bindings, m)
|
||||||
.def(py::init<const fs::u8path&>())
|
.def(py::init<const fs::u8path&>())
|
||||||
.def("get_requested_specs_map", &History::get_requested_specs_map);
|
.def("get_requested_specs_map", &History::get_requested_specs_map);
|
||||||
|
|
||||||
py::class_<MatchSpec>(m, "MatchSpec")
|
|
||||||
.def(py::init<>())
|
|
||||||
.def(py::init<const std::string&>())
|
|
||||||
.def("conda_build_form", &MatchSpec::conda_build_form);
|
|
||||||
|
|
||||||
/*py::class_<Query>(m, "Query")
|
/*py::class_<Query>(m, "Query")
|
||||||
.def(py::init<MPool&>())
|
.def(py::init<MPool&>())
|
||||||
.def("find", &Query::find)
|
.def("find", &Query::find)
|
||||||
|
|
Loading…
Reference in New Issue