mirror of https://github.com/mamba-org/mamba.git
Add Channel::contains_package (#3121)
* Add CondaURL literals * Add Channel::contains_package * Fix test case name * Bind Channel::contains_package
This commit is contained in:
parent
13d034147f
commit
43e24a864d
|
@ -113,6 +113,8 @@ namespace mamba::specs
|
|||
|
||||
[[nodiscard]] auto contains_equivalent(const Channel& other) const -> bool;
|
||||
|
||||
[[nodiscard]] auto contains_package(const CondaURL& pkg) const -> bool;
|
||||
|
||||
private:
|
||||
|
||||
CondaURL m_url;
|
||||
|
|
|
@ -241,6 +241,11 @@ namespace mamba::specs
|
|||
/** A functional equivalent to ``CondaURL::append_path``. */
|
||||
auto operator/(const CondaURL& url, std::string_view subpath) -> CondaURL;
|
||||
auto operator/(CondaURL&& url, std::string_view subpath) -> CondaURL;
|
||||
|
||||
namespace conda_url_literals
|
||||
{
|
||||
auto operator""_cu(const char* str, std::size_t len) -> CondaURL;
|
||||
}
|
||||
}
|
||||
|
||||
template <>
|
||||
|
|
|
@ -121,23 +121,29 @@ namespace mamba::specs
|
|||
m_display_name = std::move(display_name);
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
auto url_equivalent_with_impl(const CondaURL& lhs, const CondaURL& rhs) -> bool
|
||||
{
|
||||
using Decode = typename CondaURL::Decode;
|
||||
|
||||
// Not checking users, passwords, and tokens
|
||||
return
|
||||
// Schemes
|
||||
(lhs.scheme() == rhs.scheme())
|
||||
// Hosts
|
||||
&& (lhs.host(Decode::no) == rhs.host(Decode::no))
|
||||
// Different ports are considered different channels
|
||||
&& (lhs.port() == rhs.port())
|
||||
// Removing potential trailing '/'
|
||||
&& (util::rstrip(lhs.path_without_token(Decode::no), '/')
|
||||
== util::rstrip(rhs.path_without_token(Decode::no), '/'));
|
||||
}
|
||||
}
|
||||
|
||||
auto Channel::url_equivalent_with(const Channel& other) const -> bool
|
||||
{
|
||||
using Decode = typename CondaURL::Decode;
|
||||
|
||||
const auto& this_url = url();
|
||||
const auto& other_url = other.url();
|
||||
// Not checking users, passwords, and tokens
|
||||
return
|
||||
// Schemes
|
||||
(this_url.scheme() == other_url.scheme())
|
||||
// Hosts
|
||||
&& (this_url.host(Decode::no) == other_url.host(Decode::no))
|
||||
// Different ports are considered different channels
|
||||
&& (this_url.port() == other_url.port())
|
||||
// Removing potential trailing '/'
|
||||
&& (util::rstrip(this_url.path_without_token(Decode::no), '/')
|
||||
== util::rstrip(other_url.path_without_token(Decode::no), '/'));
|
||||
return url_equivalent_with_impl(url(), other.url());
|
||||
}
|
||||
|
||||
auto Channel::is_equivalent_to(const Channel& other) const -> bool
|
||||
|
@ -147,9 +153,30 @@ namespace mamba::specs
|
|||
|
||||
auto Channel::contains_equivalent(const Channel& other) const -> bool
|
||||
{
|
||||
if (other.is_package())
|
||||
{
|
||||
return contains_package(other.url());
|
||||
}
|
||||
return url_equivalent_with(other) && util::set_is_superset_of(platforms(), other.platforms());
|
||||
}
|
||||
|
||||
auto Channel::contains_package(const CondaURL& pkg) const -> bool
|
||||
{
|
||||
if (is_package())
|
||||
{
|
||||
return url_equivalent_with_impl(url(), pkg);
|
||||
}
|
||||
if (!platforms().contains(std::string(pkg.platform_name())))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
auto pkg_repo = pkg;
|
||||
pkg_repo.clear_platform();
|
||||
pkg_repo.clear_package();
|
||||
return url_equivalent_with_impl(url(), pkg_repo);
|
||||
}
|
||||
|
||||
/****************************************
|
||||
* Implementation of Channel::resolve *
|
||||
****************************************/
|
||||
|
|
|
@ -524,6 +524,14 @@ namespace mamba::specs
|
|||
url.append_path(subpath);
|
||||
return std::move(url);
|
||||
}
|
||||
|
||||
namespace conda_url_literals
|
||||
{
|
||||
auto operator""_cu(const char* str, std::size_t len) -> CondaURL
|
||||
{
|
||||
return CondaURL::parse({ str, len });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto
|
||||
|
|
|
@ -79,44 +79,138 @@ TEST_SUITE("specs::channel")
|
|||
|
||||
SUBCASE("Equivalence")
|
||||
{
|
||||
for (auto raw_url : {
|
||||
"https://repo.mamba.pm/"sv,
|
||||
"https://repo.mamba.pm/t/mytoken/"sv,
|
||||
"https://user:pass@repo.mamba.pm/conda-forge/win-64/"sv,
|
||||
"file:///some/folder/"sv,
|
||||
"ftp://mamba.org/some/folder"sv,
|
||||
})
|
||||
SUBCASE("Same platforms")
|
||||
{
|
||||
CAPTURE(raw_url);
|
||||
for (auto raw_url : {
|
||||
"https://repo.mamba.pm/"sv,
|
||||
"https://repo.mamba.pm/t/mytoken/"sv,
|
||||
"https://user:pass@repo.mamba.pm/conda-forge/"sv,
|
||||
"file:///some/folder/"sv,
|
||||
"ftp://mamba.org/some/folder"sv,
|
||||
})
|
||||
{
|
||||
CAPTURE(raw_url);
|
||||
|
||||
auto url_a = CondaURL::parse(raw_url);
|
||||
auto url_b = url_a;
|
||||
url_b.clear_user();
|
||||
url_b.clear_password();
|
||||
url_b.clear_token();
|
||||
auto chan_a = Channel(url_a, "somename", { "linux-64" });
|
||||
auto chan_b = Channel(url_b, "somename", { "linux-64" });
|
||||
auto url_a = CondaURL::parse(raw_url);
|
||||
auto url_b = url_a;
|
||||
url_b.clear_user();
|
||||
url_b.clear_password();
|
||||
url_b.clear_token();
|
||||
auto chan_a = Channel(url_a, "somename", { "linux-64" });
|
||||
auto chan_b = Channel(url_b, "somename", { "linux-64" });
|
||||
|
||||
// Channel::url_equivalent_with
|
||||
CHECK(chan_a.url_equivalent_with(chan_a));
|
||||
CHECK(chan_b.url_equivalent_with(chan_b));
|
||||
CHECK(chan_a.url_equivalent_with(chan_b));
|
||||
CHECK(chan_b.url_equivalent_with(chan_a));
|
||||
// Channel::url_equivalent_with
|
||||
CHECK(chan_a.url_equivalent_with(chan_a));
|
||||
CHECK(chan_b.url_equivalent_with(chan_b));
|
||||
CHECK(chan_a.url_equivalent_with(chan_b));
|
||||
CHECK(chan_b.url_equivalent_with(chan_a));
|
||||
|
||||
// Channel::contains_equivalent
|
||||
CHECK(chan_a.contains_equivalent(chan_a));
|
||||
CHECK(chan_b.contains_equivalent(chan_b));
|
||||
CHECK(chan_a.contains_equivalent(chan_b));
|
||||
CHECK(chan_b.contains_equivalent(chan_a));
|
||||
// Channel::contains_equivalent
|
||||
CHECK(chan_a.contains_equivalent(chan_a));
|
||||
CHECK(chan_b.contains_equivalent(chan_b));
|
||||
CHECK(chan_a.contains_equivalent(chan_b));
|
||||
CHECK(chan_b.contains_equivalent(chan_a));
|
||||
}
|
||||
}
|
||||
|
||||
chan_a = Channel(chan_a.url(), chan_a.display_name(), { "noarch", "linux-64" });
|
||||
CHECK(chan_a.contains_equivalent(chan_a));
|
||||
CHECK(chan_a.contains_equivalent(chan_b));
|
||||
CHECK_FALSE(chan_b.contains_equivalent(chan_a));
|
||||
SUBCASE("Platforms superset")
|
||||
{
|
||||
for (auto raw_url : {
|
||||
"https://repo.mamba.pm/"sv,
|
||||
"https://repo.mamba.pm/t/mytoken/"sv,
|
||||
"https://user:pass@repo.mamba.pm/conda-forge/"sv,
|
||||
"file:///some/folder/"sv,
|
||||
"ftp://mamba.org/some/folder"sv,
|
||||
})
|
||||
{
|
||||
CAPTURE(raw_url);
|
||||
|
||||
chan_b = Channel(chan_b.url(), chan_b.display_name(), { "ox-64" });
|
||||
CHECK_FALSE(chan_a.contains_equivalent(chan_b));
|
||||
CHECK_FALSE(chan_b.contains_equivalent(chan_a));
|
||||
auto url_a = CondaURL::parse(raw_url);
|
||||
auto url_b = url_a;
|
||||
url_a.clear_user();
|
||||
url_a.clear_password();
|
||||
url_a.clear_token();
|
||||
auto chan_a = Channel(url_a, "somename", { "noarch", "linux-64" });
|
||||
auto chan_b = Channel(url_b, "somename", { "linux-64" });
|
||||
|
||||
CHECK(chan_a.contains_equivalent(chan_a));
|
||||
CHECK(chan_a.contains_equivalent(chan_b));
|
||||
CHECK_FALSE(chan_b.contains_equivalent(chan_a));
|
||||
}
|
||||
}
|
||||
|
||||
SUBCASE("Different platforms")
|
||||
{
|
||||
for (auto raw_url : {
|
||||
"https://repo.mamba.pm/"sv,
|
||||
"https://repo.mamba.pm/t/mytoken/"sv,
|
||||
"https://user:pass@repo.mamba.pm/conda-forge/"sv,
|
||||
"file:///some/folder/"sv,
|
||||
"ftp://mamba.org/some/folder"sv,
|
||||
})
|
||||
{
|
||||
CAPTURE(raw_url);
|
||||
|
||||
auto url_a = CondaURL::parse(raw_url);
|
||||
auto url_b = url_a;
|
||||
auto chan_a = Channel(url_a, "somename", { "noarch", "linux-64" });
|
||||
auto chan_b = Channel(url_b, "somename", { "osx-64" });
|
||||
|
||||
CHECK_FALSE(chan_a.contains_equivalent(chan_b));
|
||||
CHECK_FALSE(chan_b.contains_equivalent(chan_a));
|
||||
}
|
||||
}
|
||||
|
||||
SUBCASE("Packages")
|
||||
{
|
||||
using namespace conda_url_literals;
|
||||
|
||||
const auto chan = Channel("https://repo.mamba.pm/"_cu, "conda-forge", { "linux-64" });
|
||||
CHECK(chan.contains_equivalent(Channel(chan.url() / "linux-64/pkg.conda", "", {})));
|
||||
CHECK_FALSE(chan.contains_equivalent(Channel(chan.url() / "osx-64/pkg.conda", "", {}))
|
||||
);
|
||||
|
||||
const auto pkg_chan = Channel(chan.url() / "linux-64/foo.tar.bz2", "", {});
|
||||
CHECK(pkg_chan.contains_equivalent(pkg_chan));
|
||||
CHECK_FALSE(pkg_chan.contains_equivalent(chan));
|
||||
CHECK_FALSE(
|
||||
pkg_chan.contains_equivalent(Channel(chan.url() / "osx-64/pkg.conda", "", {}))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
SUBCASE("Contains package")
|
||||
{
|
||||
using namespace conda_url_literals;
|
||||
|
||||
SUBCASE("https://repo.mamba.pm/")
|
||||
{
|
||||
auto chan = Channel("https://repo.mamba.pm/"_cu, "conda-forge", { "linux-64" });
|
||||
CHECK(chan.contains_package("https://repo.mamba.pm/linux-64/pkg.conda"_cu));
|
||||
CHECK_FALSE(chan.contains_package("https://repo.mamba.pm/win-64/pkg.conda"_cu));
|
||||
CHECK_FALSE(chan.contains_package("https://repo.mamba.pm/pkg.conda"_cu));
|
||||
}
|
||||
|
||||
SUBCASE("https://repo.mamba.pm/osx-64/foo.tar.gz")
|
||||
{
|
||||
auto chan = Channel("https://repo.mamba.pm/osx-64/foo.tar.bz2"_cu, "", {});
|
||||
CHECK(chan.contains_package(chan.url()));
|
||||
CHECK_FALSE(chan.contains_package("https://repo.mamba.pm/win-64/pkg.conda"_cu));
|
||||
CHECK_FALSE(chan.contains_package("https://repo.mamba.pm/pkg.conda"_cu));
|
||||
}
|
||||
|
||||
SUBCASE("https://user:pass@repo.mamba.pm/conda-forge/win-64/")
|
||||
{
|
||||
auto chan = Channel(
|
||||
"https://user:pass@repo.mamba.pm/conda-forge/"_cu,
|
||||
"conda-forge",
|
||||
{ "win-64" }
|
||||
);
|
||||
CHECK(chan.contains_package(chan.url() / "win-64/pkg.conda"));
|
||||
CHECK(chan.contains_package("https://repo.mamba.pm/conda-forge/win-64/pkg.conda"_cu));
|
||||
CHECK_FALSE(
|
||||
chan.contains_package("https://repo.mamba.pm/conda-forge/osx-64/pkg.conda"_cu)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
using namespace mamba;
|
||||
using namespace mamba::specs;
|
||||
|
||||
TEST_SUITE("specs::channel_spec")
|
||||
TEST_SUITE("specs::unresolved_channel")
|
||||
{
|
||||
using PlatformSet = typename util::flat_set<std::string>;
|
||||
using Type = typename UnresolvedChannel::Type;
|
||||
|
|
|
@ -489,6 +489,7 @@ namespace mambapy
|
|||
.def("url_equivalent_with", &Channel::url_equivalent_with)
|
||||
.def("is_equivalent_to", &Channel::is_equivalent_to)
|
||||
.def("contains_equivalent", &Channel::contains_equivalent)
|
||||
.def("contains_package", &Channel::contains_package)
|
||||
.def(py::self == py::self)
|
||||
.def(py::self != py::self)
|
||||
.def("__hash__", &hash<Channel>)
|
||||
|
|
|
@ -474,8 +474,10 @@ def test_Channel():
|
|||
assert hash(chan) != 0
|
||||
|
||||
# Weak comparison
|
||||
other.url = chan.url
|
||||
other.platforms = chan.platforms | {"human-67"}
|
||||
chan = Channel(url=url_1, platforms=platforms_1, display_name=display_name_1)
|
||||
other = Channel(
|
||||
url=url_1, platforms=(chan.platforms | {"human-67"}), display_name=display_name_1
|
||||
)
|
||||
assert chan.url_equivalent_with(chan)
|
||||
assert chan.url_equivalent_with(other)
|
||||
assert other.url_equivalent_with(chan)
|
||||
|
@ -485,6 +487,8 @@ def test_Channel():
|
|||
assert chan.contains_equivalent(chan)
|
||||
assert other.contains_equivalent(chan)
|
||||
assert not chan.contains_equivalent(other)
|
||||
assert chan.contains_package(chan.url / "noarch/pkg.conda")
|
||||
assert not chan.contains_package(chan.url / "win-64/pkg.conda")
|
||||
|
||||
|
||||
def test_Channel_resolve():
|
||||
|
|
Loading…
Reference in New Issue