Skip to content

Commit

Permalink
Migrate Channel::make_channel to resolve multi channels (#2986)
Browse files Browse the repository at this point in the history
* Add one to many get_channels

* Refactor ChannelContext params

* ChannelContext::make_channel migration 1

* ChannelContext::make_channel migration 2

* ChannelContext::make_channel migration 3

* ChannelContext::make_channel migration 4

* ChannelContext::make_channel migration 5

* ChannelContext::make_channel migration 6

* ChannelContext::make_channel migration 7

* Remove Channel bindings

* Remove ChannelContext::make_channel

* ChannelContext::get_channels migration 1

* ChannelContext::get_channels migration 2

* ChannelContext::get_channels migration 3

* Remove get_channels bindings

* Remove ChannelContext::get_channels

* Channel::resolve return a list

* Resolve multi_channel in Channel::resolve

* Use weakening map for multi_channels

* Split Channel resolve_name

* Cleanup signatures

* Add Channel::clear_xxx

* Force removal of trailing '/' in Channel

* Add weak channel comparison

* Use better channel comparisons

* Remove Channel::base_url

* Rename Channel::make_chan > make_channel

* Add doc

* Resolve Channel paths from params

* Review from JohanMabille

* Fix absolute path
  • Loading branch information
AntoinePrv committed Nov 21, 2023
1 parent 0177c44 commit e874e7e
Show file tree
Hide file tree
Showing 17 changed files with 543 additions and 400 deletions.
63 changes: 40 additions & 23 deletions libmamba/include/mamba/core/channel.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,40 +55,55 @@ namespace mamba
-> std::optional<std::string_view>;
};

template <typename Key, typename Value>
using name_map = util::weakening_map<std::unordered_map<Key, Value>, NameWeakener>;

using platform_list = util::flat_set<std::string>;
using channel_list = std::vector<Channel>;
using channel_map = util::weakening_map<std::unordered_map<std::string, Channel>, NameWeakener>;
using multichannel_map = std::unordered_map<std::string, channel_list>;
using channel_map = name_map<std::string, Channel>;
using multichannel_map = name_map<std::string, channel_list>;

const platform_list& platforms;
const specs::CondaURL& channel_alias;
const channel_map& custom_channels;
const specs::AuthenticationDataBase& auth_db;

// TODO add CWD and home
const multichannel_map& custom_multichannels;
const specs::AuthenticationDataBase& authentication_db;
std::string_view home_dir;
std::string_view current_working_dir;
};

using platform_list = util::flat_set<std::string>;
using platform_list = ResolveParams::platform_list;
using channel_list = ResolveParams::channel_list;

[[nodiscard]] static auto resolve(specs::ChannelSpec spec, ResolveParams params) -> Channel;
[[nodiscard]] static auto resolve(specs::ChannelSpec spec, ResolveParams params)
-> channel_list;

Channel(specs::CondaURL url, std::string display_name, util::flat_set<std::string> platforms = {});

[[nodiscard]] auto url() const -> const specs::CondaURL&;
auto clear_url() -> const specs::CondaURL;
void set_url(specs::CondaURL url);

[[nodiscard]] auto platforms() const -> const platform_list&;
auto clear_platforms() -> platform_list;
void set_platforms(platform_list platforms);

[[nodiscard]] auto display_name() const -> const std::string&;
auto clear_display_name() -> std::string;
void set_display_name(std::string display_name);

std::string base_url() const;
std::string platform_url(std::string_view platform, bool with_credential = true) const;
[[nodiscard]] auto url_equivalent_with(const Channel& other) const -> bool;

[[nodiscard]] auto is_equivalent_to(const Channel& other) const -> bool;

[[nodiscard]] auto contains_equivalent(const Channel& other) const -> bool;

[[nodiscard]] auto
platform_url(std::string_view platform, bool with_credential = true) const -> std::string;
// The pairs consist of (platform,url)
util::flat_set<std::pair<std::string, std::string>>
platform_urls(bool with_credential = true) const;
util::flat_set<std::string> urls(bool with_credential = true) const;
[[nodiscard]] auto platform_urls(bool with_credential = true) const
-> util::flat_set<std::pair<std::string, std::string>>;
[[nodiscard]] auto urls(bool with_credential = true) const -> util::flat_set<std::string>;

private:

Expand Down Expand Up @@ -118,40 +133,42 @@ namespace mamba

using channel_map = Channel::ResolveParams::channel_map;
using channel_list = Channel::ResolveParams::channel_list;
using multichannel_map = Channel::ResolveParams::multichannel_map;
using platform_list = Channel::ResolveParams::platform_list;
using multichannel_map = std::unordered_map<std::string, channel_list>;

ChannelContext(Context& context);
~ChannelContext();

ChannelContext(const ChannelContext&) = delete;
ChannelContext& operator=(const ChannelContext&) = delete;
auto operator=(const ChannelContext&) -> ChannelContext& = delete;
ChannelContext(ChannelContext&&) = delete;
ChannelContext& operator=(ChannelContext&&) = delete;
auto operator=(ChannelContext&&) -> ChannelContext& = delete;

const Channel& make_channel(const std::string& value);
auto get_channels(const std::vector<std::string>& channel_names) -> channel_list;
auto make_channel(std::string_view name) -> channel_list;

const specs::CondaURL& get_channel_alias() const;
const channel_map& get_custom_channels() const;
const multichannel_map& get_custom_multichannels() const;
auto get_channel_alias() const -> const specs::CondaURL&;
auto get_custom_channels() const -> const channel_map&;
auto get_custom_multichannels() const -> const multichannel_map&;

Context& context() const
auto context() const -> Context&
{
return m_context;
}

private:

using ChannelCache = std::map<std::string, Channel>;
using ChannelCache = std::unordered_map<std::string, channel_list>;

Context& m_context;
ChannelCache m_channel_cache;
specs::CondaURL m_channel_alias;
platform_list m_platforms;
channel_map m_custom_channels;
multichannel_map m_custom_multichannels;
platform_list m_platforms;
std::string m_home_dir;
std::string m_current_working_dir;

auto params() -> Channel::ResolveParams;
void init_custom_channels();
};

Expand Down
10 changes: 10 additions & 0 deletions libmamba/include/mamba/util/path_manip.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,16 @@

namespace mamba::util
{
/**
* Lightweight file path manipulation.
*
* The purpose of this file is to provide a lightweight functions for manipulating paths
* for things that manipulate "path-like" objects, such as parsers and URLs.
* In general, users should prefer using the correct abstraction, such as @ref URL
* and @ref u8path.
* However some features provided here, such as @ref expand_home, are not available elsewhere.
*/

inline static constexpr char preferred_path_separator_posix = '/';
inline static constexpr char preferred_path_separator_win = '\\';

Expand Down
61 changes: 31 additions & 30 deletions libmamba/src/api/channel_loader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,50 +51,51 @@ namespace mamba

auto& ctx = pool.context();

std::vector<std::string> channel_urls = ctx.channels;

std::vector<MSubdirData> subdirs;

std::vector<std::pair<int, int>> priorities;
int max_prio = static_cast<int>(channel_urls.size());
int max_prio = static_cast<int>(ctx.channels.size());
auto prev_channel_url = specs::CondaURL();

Console::instance().init_progress_bar_manager(ProgressBarMode::multi);

std::vector<mamba_error> error_list;

for (auto channel : pool.channel_context().get_channels(channel_urls))
for (const auto& location : ctx.channels)
{
for (auto& [platform, url] : channel.platform_urls(true))
for (auto channel : pool.channel_context().make_channel(location))
{
auto sdires = MSubdirData::create(
pool.channel_context(),
channel,
platform,
url,
package_caches,
"repodata.json"
);
if (!sdires.has_value())
{
error_list.push_back(std::move(sdires).error());
continue;
}
auto sdir = std::move(sdires).value();
subdirs.push_back(std::move(sdir));
if (ctx.channel_priority == ChannelPriority::Disabled)
for (auto& [platform, url] : channel.platform_urls(true))
{
priorities.push_back(std::make_pair(0, 0));
}
else
{
// Consider 'flexible' and 'strict' the same way
if (channel.url() != prev_channel_url)
auto sdires = MSubdirData::create(
pool.channel_context(),
channel,
platform,
url,
package_caches,
"repodata.json"
);
if (!sdires.has_value())
{
error_list.push_back(std::move(sdires).error());
continue;
}
auto sdir = std::move(sdires).value();
subdirs.push_back(std::move(sdir));
if (ctx.channel_priority == ChannelPriority::Disabled)
{
priorities.push_back(std::make_pair(0, 0));
}
else
{
max_prio--;
prev_channel_url = channel.url();
// Consider 'flexible' and 'strict' the same way
if (channel.url() != prev_channel_url)
{
max_prio--;
prev_channel_url = channel.url();
}
priorities.push_back(std::make_pair(max_prio, 0));
}
priorities.push_back(std::make_pair(max_prio, 0));
}
}
}
Expand Down
13 changes: 7 additions & 6 deletions libmamba/src/api/info.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -160,16 +160,17 @@ namespace mamba
}
items.push_back({ "virtual packages", virtual_pkgs });

std::vector<std::string> channels = ctx.channels;
// Always append context channels
auto& ctx_channels = ctx.channels;
std::copy(ctx_channels.begin(), ctx_channels.end(), std::back_inserter(channels));
std::vector<std::string> channel_urls;
for (auto channel : channel_context.get_channels(channels))
channel_urls.reserve(ctx.channels.size() * 2); // Lower bound * (platform + noarch)
for (const auto& loc : ctx.channels)
{
for (auto url : channel.urls(true))
for (auto channel : channel_context.make_channel(loc))
{
channel_urls.push_back(url);
for (auto url : channel.urls(true))
{
channel_urls.push_back(url);
}
}
}
items.push_back({ "channels", channel_urls });
Expand Down
13 changes: 8 additions & 5 deletions libmamba/src/api/list.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,13 @@ namespace mamba

if (regex.empty() || std::regex_search(pkg_info.name, spec_pat))
{
auto& channel = channel_context.make_channel(pkg_info.url);
obj["base_url"] = channel.base_url();
auto channels = channel_context.make_channel(pkg_info.url);
assert(channels.size() == 1); // A URL can only resolve to one channel
obj["base_url"] = channels.front().url().str(specs::CondaURL::Credentials::Remove
);
obj["build_number"] = pkg_info.build_number;
obj["build_string"] = pkg_info.build_string;
obj["channel"] = channel.display_name();
obj["channel"] = channels.front().display_name();
obj["dist_name"] = pkg_info.str();
obj["name"] = pkg_info.name;
obj["platform"] = pkg_info.subdir;
Expand Down Expand Up @@ -111,8 +113,9 @@ namespace mamba
}
else
{
const Channel& channel = channel_context.make_channel(package.second.url);
formatted_pkgs.channel = channel.display_name();
auto channels = channel_context.make_channel(package.second.url);
assert(channels.size() == 1); // A URL can only resolve to one channel
formatted_pkgs.channel = channels.front().display_name();
}
packages.push_back(formatted_pkgs);
}
Expand Down
Loading

0 comments on commit e874e7e

Please sign in to comment.