Skip to content

Commit

Permalink
ChannelContext::make_channel migration 6
Browse files Browse the repository at this point in the history
  • Loading branch information
AntoinePrv committed Nov 17, 2023
1 parent 887ccbb commit 5940c2e
Showing 1 changed file with 59 additions and 58 deletions.
117 changes: 59 additions & 58 deletions libmamba/src/core/pool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -140,63 +140,38 @@ namespace mamba

namespace
{
bool
channel_match(ChannelContext& channel_context, const Channel& chan, const Channel& needle)
enum struct ChannelMatch
{
if (chan.base_url() == needle.base_url())
{
return true;
}

auto& custom_multichannels = channel_context.context().custom_multichannels;
auto x = custom_multichannels.find(needle.display_name());
if (x != custom_multichannels.end())
None,
ChannelOnly,
ChannelAndSubdir,
};

auto channel_match(
const std::vector<Channel>& repo_channels,
const std::vector<Channel>& candidate_channels
) -> ChannelMatch
{
// More than one element means the channel spec was a custom_multi_channel,
// which should never happen for the repo
for (const auto& repo_chan : repo_channels)
{
for (auto el : (x->second))
// More than one element means the channel spec was a custom_multi_channel.
// We need to add any repo that matches.
for (const auto& cand_chan : candidate_channels)
{
const Channel& inner = channel_context.make_channel(el);
if (chan.base_url() == inner.base_url())
// TODO replace with weaker equality: no credentials and rstrip
if (repo_chan.url() == cand_chan.url())
{
return true;
if (util::set_is_subset_of(repo_chan.platforms(), cand_chan.platforms()))
{
return ChannelMatch::ChannelAndSubdir;
}
return ChannelMatch::ChannelOnly;
}
}
}

return false;
}

bool subdir_match(std::string candidate_repo_url, std::string needle_spec)
{
// Example candidate_repo_url: https://.../conda-forge/linux-64
// example needle_spec: conda-forge/osx-64::xtensor

std::string needle_channel = util::split(needle_spec, ":", 1)[0];
if (!util::contains(needle_channel, "/"))
{
// Subdir not specified, so any subdir is fine
return true;
}
std::string needle_subdir = util::rsplit(needle_channel, "/", 1)[1];

auto known_platforms = specs::known_platform_names();
if (std::find(known_platforms.begin(), known_platforms.end(), needle_subdir)
== known_platforms.end())
{
// Not a known subdir. This can happen for specs like pkgs/main.
// so any subdir is fine
return true;
}

std::string candidate_repo_subdir = util::rsplit(candidate_repo_url, "/", 1)[1];

if (candidate_repo_subdir == needle_subdir)
{
return true;
}
throw std::runtime_error(fmt::format(
"The package \"{}\" is not available for the specified platform",
needle_spec
));
return ChannelMatch::None;
}

/**
Expand Down Expand Up @@ -224,28 +199,54 @@ namespace mamba
);

solv::ObjQueue selected_pkgs = {};
bool found_partial_matches = false;
pool.for_each_whatprovides(
match,
[&](solv::ObjSolvableViewConst s)
{
// TODO this does not work with s.url(), we need to proper channel class
// to properly manage this.
auto repo = solv::ObjRepoView(*s.raw()->repo);
// TODO make_channel should disapear avoiding conflict here
auto const url = std::string(repo.url());
for (auto const& c : channel_context.get_channels({ ms.channel }))
// TODO Replace MatchSpec channel and subdir with a ChannelSpec
auto const chan_spec = [&]() -> std::string
{
if (ms.subdir.empty())
{
return ms.channel;
}
return util::concat(ms.channel, '[', ms.subdir, ']');
}();
auto const match = channel_match(
channel_context.get_channels({ std::string(repo.url()) }),
channel_context.get_channels({ chan_spec })
);
switch (match)
{
if (channel_match(channel_context, channel_context.make_channel(url), c))
case (ChannelMatch::ChannelAndSubdir):
{
selected_pkgs.push_back(s.id());
break;
}
case (ChannelMatch::ChannelOnly):
{
found_partial_matches = true;
break;
}
case (ChannelMatch::None):
{
if (subdir_match(url, ms.spec))
{
selected_pkgs.push_back(s.id());
}
}
}
}
);

if (selected_pkgs.empty() && found_partial_matches)
{
throw std::runtime_error(fmt::format(
R"(The package "{}" is not available for the specified platform)",
ms.spec
));
}

const solv::StringId repr_id = pool.add_string(repr);
// FRAGILE This get deleted when calling ``pool_createwhatprovides`` so care
// must be taken to do it before
Expand Down

0 comments on commit 5940c2e

Please sign in to comment.