Rename ChannelSpec > UndefinedChannel (#3117)

* Rename ChannelSpec > UndefinedChannel

* Rename UndefinedChannel > UnresolvedChannel
This commit is contained in:
Antoine Prouvost 2024-01-09 13:52:23 +01:00 committed by GitHub
parent 328457276a
commit 13d034147f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 496 additions and 475 deletions

View File

@ -63,7 +63,7 @@ Changes inlcude:
and passed explicitly to a few functions.
- ``Channel`` has been redesigned an moved to a new ``libmambapy.specs``.
A featureful ``libmambapy.specs.CondaURL`` is used to describe channel URLs.
This module also includes ``ChannelSpec`` used to match channels.
This module also includes ``UnresolvedChannel`` used to describe unresolved channel strings.
- ``MatchSpec`` has been redesigned and moved to ``libmambapy.specs``.
The module also includes a platform enumeration, an implementation of ordered ``Version``, and a
``VersionSpec`` to match versions.
@ -82,7 +82,7 @@ The main changes are:
- Creation of the ``specs::`` with:
- Implementations of ``Version`` and ``VersionSpec`` for matching versions,
- A refactoring of a purely funcitonal ``Channel`` class,
- Implementaiton of a ``ChannelSpec`` to match ``Channels``,
- Implementaiton of a ``UnresolvedChannel`` to describe unresolved ``Channels``,
- A refactored implementation of ``MatchSpec`` using the components above.
- A cleanup of ``ChannelContext`` for be a light proxy and parameter holder wrapping the
``specs::Channel``.

View File

@ -91,11 +91,13 @@ Similarily the :cpp:func:`CondaURL.pretty_str <mamba::specs::CondaURL::pretty_st
user-friendly string, but that may not be parsed back.
ChannelSpec
-----------
UnresolvedChannel
----------------
A :cpp:type:`ChannelSpec <mamba::specs::ChannelSpec>` is a lightweight object to represent a
channel string, as in passed in the CLI or configuration.
A :cpp:type:`UnresolvedChannel <mamba::specs::UnresolvedChannel>` is a lightweight object to represent
a channel string, as in passed in the CLI or configuration.
Since channels rely heavily on configuration options, this type can be used as a placeholder for a
channel that has not been fully "resolved" to a specific location.
It does minimal parsing and can detect the type of ressource (an unresolved name, a URL, a file)
and the platform filters.
@ -103,11 +105,11 @@ and the platform filters.
import libmambapy.specs as specs
cs = specs.ChannelSpec.parse("https://conda.anaconda.org/conda-forge/linux-64")
uc = specs.UnresolvedChannel.parse("https://conda.anaconda.org/conda-forge/linux-64")
assert cs.location == "https://conda.anaconda.org/conda-forge"
assert cs.platform_filters == {"linux-64"}
assert cs.type == specs.ChannelSpec.Type.URL
assert uc.location == "https://conda.anaconda.org/conda-forge"
assert uc.platform_filters == {"linux-64"}
assert uc.type == specs.UnresolvedChannel.Type.URL
Dynamic platforms (as in not known by Mamba) can only be detected with the ``[]`` syntax.
@ -115,11 +117,11 @@ Dynamic platforms (as in not known by Mamba) can only be detected with the ``[]`
import libmambapy.specs as specs
cs = specs.ChannelSpec.parse("conda-forge[prius-avx42]")
uc = specs.UnresolvedChannel.parse("conda-forge[prius-avx42]")
assert cs.location == "conda-forge"
assert cs.platform_filters == {"prius-avx42"}
assert cs.type == specs.ChannelSpec.Type.Name
assert uc.location == "conda-forge"
assert uc.platform_filters == {"prius-avx42"}
assert uc.type == specs.UnresolvedChannel.Type.Name
Channel
@ -130,7 +132,7 @@ A display name is also available, but is not considered a stable identifiaction
channel, since it depends on the many configuration parameters, such as the channel alias.
We construct a :cpp:type:`Channel <mamba::specs::Channel>` by *resolving* a
:cpp:type:`ChannelSpec <mamba::specs::ChannelSpec>`.
:cpp:type:`UnresolvedChannel <mamba::specs::UnresolvedChannel>`.
All parameters that influence this resolution must be provided explicitly.
@ -138,15 +140,15 @@ All parameters that influence this resolution must be provided explicitly.
import libmambapy.specs as specs
cs = specs.ChannelSpec.parse("conda-forge[prius-avx42]")
uc = specs.UnresolvedChannel.parse("conda-forge[prius-avx42]")
chan, *_ = specs.Channel.resolve(
spec=cs,
uc,
channel_alias="https://repo.mamba.pm"
# ...
)
assert chan.url.str() == "https://repo.mamba.pm/conda-forge"
assert cs.platforms == {"prius-avx42"}
assert chan.platforms == {"prius-avx42"}
assert chan.display_name == "conda-forge[prius-avx42]"
There are no hard-coded names:
@ -155,9 +157,9 @@ There are no hard-coded names:
import libmambapy.specs as specs
cs = specs.ChannelSpec.parse("defaults")
uc = specs.UnresolvedChannel.parse("defaults")
chan, *_ = specs.Channel.resolve(
spec=cs,
uc,
channel_alias="https://repo.mamba.pm"
# ...
)
@ -174,16 +176,16 @@ This is because of custom multichannel, a single name can return mutliple channe
import libmambapy.specs as specs
chan_main, *_ = specs.Channel.resolve(
spec=specs.ChannelSpec.parse("pkgs/main"),
specs.UnresolvedChannel.parse("pkgs/main"),
# ...
)
chan_r, *_ = specs.Channel.resolve(
spec=specs.ChannelSpec.parse("pkgs/r"),
specs.UnresolvedChannel.parse("pkgs/r"),
# ...
)
defaults = specs.Channel.resolve(
spec=specs.ChannelSpec.parse("defaults"),
specs.UnresolvedChannel.parse("defaults"),
custom_multichannels=specs.Channel.MultiChannelMap(
{"defaults": [chan_main, chan_r]}
),

View File

@ -172,13 +172,13 @@ set(
${LIBMAMBA_SOURCE_DIR}/specs/authentication_info.cpp
${LIBMAMBA_SOURCE_DIR}/specs/build_number_spec.cpp
${LIBMAMBA_SOURCE_DIR}/specs/channel.cpp
${LIBMAMBA_SOURCE_DIR}/specs/channel_spec.cpp
${LIBMAMBA_SOURCE_DIR}/specs/conda_url.cpp
${LIBMAMBA_SOURCE_DIR}/specs/glob_spec.cpp
${LIBMAMBA_SOURCE_DIR}/specs/match_spec.cpp
${LIBMAMBA_SOURCE_DIR}/specs/package_info.cpp
${LIBMAMBA_SOURCE_DIR}/specs/platform.cpp
${LIBMAMBA_SOURCE_DIR}/specs/repo_data.cpp
${LIBMAMBA_SOURCE_DIR}/specs/unresolved_channel.cpp
${LIBMAMBA_SOURCE_DIR}/specs/version.cpp
${LIBMAMBA_SOURCE_DIR}/specs/version_spec.cpp
# Artifacts validation
@ -289,13 +289,13 @@ set(
${LIBMAMBA_INCLUDE_DIR}/mamba/specs/authentication_info.hpp
${LIBMAMBA_INCLUDE_DIR}/mamba/specs/build_number_spec.hpp
${LIBMAMBA_INCLUDE_DIR}/mamba/specs/channel.hpp
${LIBMAMBA_INCLUDE_DIR}/mamba/specs/channel_spec.hpp
${LIBMAMBA_INCLUDE_DIR}/mamba/specs/conda_url.hpp
${LIBMAMBA_INCLUDE_DIR}/mamba/specs/glob_spec.hpp
${LIBMAMBA_INCLUDE_DIR}/mamba/specs/match_spec.hpp
${LIBMAMBA_INCLUDE_DIR}/mamba/specs/package_info.hpp
${LIBMAMBA_INCLUDE_DIR}/mamba/specs/platform.hpp
${LIBMAMBA_INCLUDE_DIR}/mamba/specs/repo_data.hpp
${LIBMAMBA_INCLUDE_DIR}/mamba/specs/unresolved_channel.hpp
${LIBMAMBA_INCLUDE_DIR}/mamba/specs/version.hpp
${LIBMAMBA_INCLUDE_DIR}/mamba/specs/version_spec.hpp
# Artifacts validation

View File

@ -51,7 +51,7 @@ namespace mamba
*/
ChannelContext(ChannelResolveParams params, std::vector<Channel> has_zst);
[[nodiscard]] auto make_channel(specs::ChannelSpec spec) -> const channel_list&;
[[nodiscard]] auto make_channel(specs::UnresolvedChannel uc) -> const channel_list&;
[[nodiscard]] auto make_channel(std::string_view name) -> const channel_list&;
[[nodiscard]] auto params() const -> const specs::ChannelResolveParams&;

View File

@ -11,8 +11,8 @@
#include <vector>
#include "mamba/specs/authentication_info.hpp"
#include "mamba/specs/channel_spec.hpp"
#include "mamba/specs/conda_url.hpp"
#include "mamba/specs/unresolved_channel.hpp"
#include "mamba/util/flat_set.hpp"
#include "mamba/util/weakening_map.hpp"
@ -78,12 +78,12 @@ namespace mamba::specs
using channel_list = ChannelResolveParams::channel_list;
[[nodiscard]] static auto resolve( //
ChannelSpec spec,
UnresolvedChannel uc,
const ChannelResolveParams& params
) -> channel_list;
[[nodiscard]] static auto resolve( //
ChannelSpec spec,
UnresolvedChannel uc,
ChannelResolveParamsView params
) -> channel_list;

View File

@ -12,8 +12,8 @@
#include <string_view>
#include "mamba/specs/build_number_spec.hpp"
#include "mamba/specs/channel_spec.hpp"
#include "mamba/specs/glob_spec.hpp"
#include "mamba/specs/unresolved_channel.hpp"
#include "mamba/specs/version_spec.hpp"
#include "mamba/util/heap_optional.hpp"
@ -30,8 +30,8 @@ namespace mamba::specs
[[nodiscard]] static auto parse_url(std::string_view spec) -> MatchSpec;
[[nodiscard]] auto channel() const -> const std::optional<ChannelSpec>&;
void set_channel(std::optional<ChannelSpec> chan);
[[nodiscard]] auto channel() const -> const std::optional<UnresolvedChannel>&;
void set_channel(std::optional<UnresolvedChannel> chan);
[[nodiscard]] auto name_space() const -> const std::string&;
void set_name_space(std::string ns);
@ -93,14 +93,14 @@ namespace mamba::specs
bool optional = false;
};
std::optional<ChannelSpec> m_channel;
std::optional<UnresolvedChannel> m_channel;
VersionSpec m_version;
NameSpec m_name;
BuildStringSpec m_build_string;
std::string m_name_space;
BuildNumberSpec m_build_number;
util::heap_optional<ExtraMembers> m_extra = {}; // unlikely data
// TODO can put inside channel spec
// TODO can put inside channel
std::string m_filename;
std::string m_url;

View File

@ -4,8 +4,8 @@
//
// The full license is in the file LICENSE, distributed with this software.
#ifndef MAMBA_SPECS_CHANNEL_SPEC_HPP
#define MAMBA_SPECS_CHANNEL_SPEC_HPP
#ifndef MAMBA_SPECS_UNRESOLVED_CHANNEL_HPP
#define MAMBA_SPECS_UNRESOLVED_CHANNEL_HPP
#include <array>
#include <string>
@ -19,18 +19,20 @@
namespace mamba::specs
{
/**
* Channel specification.
* Unresolved Channel specification.
*
* This represent the string that is passed by the user to select a channel.
* It needs to be resolved in order to get a final URL/path.
* This is even true when a full URL or path is given, as some authentification information
* This represent an unverified channel string passed by the user, or written through files.
* Due the the heavy reliance of channels on configuration options, this placeholder type
* can be used to represent channel inputs that have not been "resolved" to s specific
* location.
* This can even be true when a full URL or path is given, as some authentification information
* may come from login database.
*
* Note that for a string to be considered a URL, it must have an explicit scheme.
* So "repo.anaconda.com" is considered a name, similarily to "conda-forge" and not a URL.
* This is because otherwise it is not possible to tell names and URL appart.
*/
class ChannelSpec
class UnresolvedChannel
{
public:
@ -86,10 +88,10 @@ namespace mamba::specs
using dynamic_platform_set = util::flat_set<std::string>;
[[nodiscard]] static auto parse(std::string_view str) -> ChannelSpec;
[[nodiscard]] static auto parse(std::string_view str) -> UnresolvedChannel;
ChannelSpec() = default;
ChannelSpec(std::string location, dynamic_platform_set filters, Type type);
UnresolvedChannel() = default;
UnresolvedChannel(std::string location, dynamic_platform_set filters, Type type);
[[nodiscard]] auto type() const -> Type;
@ -112,9 +114,9 @@ namespace mamba::specs
}
template <>
struct fmt::formatter<mamba::specs::ChannelSpec>
struct fmt::formatter<mamba::specs::UnresolvedChannel>
{
using ChannelSpec = ::mamba::specs::ChannelSpec;
using UnresolvedChannel = ::mamba::specs::UnresolvedChannel;
constexpr auto parse(format_parse_context& ctx) -> format_parse_context::iterator
{
@ -126,7 +128,7 @@ struct fmt::formatter<mamba::specs::ChannelSpec>
return ctx.begin();
}
auto format(const ChannelSpec& spec, format_context& ctx) const -> format_context::iterator;
auto format(const UnresolvedChannel& uc, format_context& ctx) const -> format_context::iterator;
};
#endif

View File

@ -12,8 +12,8 @@
#include "mamba/core/channel_context.hpp"
#include "mamba/core/context.hpp"
#include "mamba/specs/channel_spec.hpp"
#include "mamba/specs/conda_url.hpp"
#include "mamba/specs/unresolved_channel.hpp"
#include "mamba/util/environment.hpp"
#include "mamba/util/string.hpp"
#include "mamba/util/url_manip.hpp"
@ -36,8 +36,8 @@ namespace mamba
template <typename Param>
auto make_unique_chan(std::string_view loc, const Param& params) -> specs::Channel
{
auto spec = specs::ChannelSpec::parse(loc);
auto channels = specs::Channel::resolve(std::move(spec), params);
auto uc = specs::UnresolvedChannel::parse(loc);
auto channels = specs::Channel::resolve(std::move(uc), params);
assert(channels.size() == 1);
return std::move(channels.front());
};
@ -178,8 +178,8 @@ namespace mamba
out.reserve(ctx.repodata_has_zst.size());
for (const auto& loc : ctx.repodata_has_zst)
{
auto spec = specs::ChannelSpec::parse(loc);
auto channels = specs::Channel::resolve(std::move(spec), params);
auto uc = specs::UnresolvedChannel::parse(loc);
auto channels = specs::Channel::resolve(std::move(uc), params);
for (auto& chan : channels)
{
out.push_back(std::move(chan));
@ -214,9 +214,9 @@ namespace mamba
return { std::move(params), has_zst };
}
auto ChannelContext::make_channel(specs::ChannelSpec spec) -> const channel_list&
auto ChannelContext::make_channel(specs::UnresolvedChannel uc) -> const channel_list&
{
auto str = spec.str();
auto str = uc.str();
if (const auto it = m_channel_cache.find(str); it != m_channel_cache.end())
{
return it->second;
@ -224,7 +224,7 @@ namespace mamba
auto [it, inserted] = m_channel_cache.emplace(
std::move(str),
Channel::resolve(std::move(spec), params())
Channel::resolve(std::move(uc), params())
);
assert(inserted);
return it->second;
@ -239,7 +239,7 @@ namespace mamba
auto [it, inserted] = m_channel_cache.emplace(
name,
Channel::resolve(specs::ChannelSpec::parse(name), params())
Channel::resolve(specs::UnresolvedChannel::parse(name), params())
);
assert(inserted);
return it->second;

View File

@ -105,7 +105,7 @@ namespace mamba
}
auto ms_modified = ms;
ms_modified.set_channel(specs::ChannelSpec::parse(solvable->channel()));
ms_modified.set_channel(specs::UnresolvedChannel::parse(solvable->channel()));
ms_modified.set_version(specs::VersionSpec::parse(solvable->version()));
ms_modified.set_build_string(specs::GlobSpec(std::string(solvable->build_string())));

View File

@ -258,14 +258,14 @@ namespace mamba::specs
return util::abs_path_to_url(std::move(path).string());
}
auto resolve_path(ChannelSpec&& spec, ChannelResolveParamsView params) -> Channel
auto resolve_path(UnresolvedChannel&& uc, ChannelResolveParamsView params) -> Channel
{
auto uri = CondaURL::parse(resolve_path_location(spec.clear_location(), params));
auto uri = CondaURL::parse(resolve_path_location(uc.clear_location(), params));
auto display_name = resolve_path_name(uri, params);
auto platforms = ChannelResolveParams::platform_list{};
if (spec.type() == ChannelSpec::Type::Path)
if (uc.type() == UnresolvedChannel::Type::Path)
{
platforms = make_platforms(spec.clear_platform_filters(), params.platforms);
platforms = make_platforms(uc.clear_platform_filters(), params.platforms);
}
return { std::move(uri), std::move(display_name), std::move(platforms) };
@ -295,25 +295,25 @@ namespace mamba::specs
return url.pretty_str(StripScheme::no, '/', Credentials::Remove);
}
auto resolve_url(ChannelSpec&& spec, ChannelResolveParamsView params) -> Channel
auto resolve_url(UnresolvedChannel&& uc, ChannelResolveParamsView params) -> Channel
{
assert(util::url_has_scheme(spec.location()));
assert(util::url_get_scheme(spec.location()) != "file");
assert(util::url_has_scheme(uc.location()));
assert(util::url_get_scheme(uc.location()) != "file");
auto url = CondaURL::parse(spec.location());
auto url = CondaURL::parse(uc.location());
auto display_name = resolve_url_name(url, params);
set_fallback_credential_from_db(url, params.authentication_db);
auto platforms = ChannelResolveParams::platform_list{};
if (spec.type() == ChannelSpec::Type::URL)
if (uc.type() == UnresolvedChannel::Type::URL)
{
platforms = make_platforms(spec.clear_platform_filters(), params.platforms);
platforms = make_platforms(uc.clear_platform_filters(), params.platforms);
}
return { std::move(url), std::move(display_name), std::move(platforms) };
}
auto resolve_name_in_custom_channel(
ChannelSpec&& spec,
UnresolvedChannel&& uc,
ChannelResolveParamsView params,
std::string_view match_name,
const Channel& match_chan
@ -321,17 +321,17 @@ namespace mamba::specs
) -> Channel
{
auto url = match_chan.url();
url.append_path(util::remove_prefix(spec.location(), match_name));
url.append_path(util::remove_prefix(uc.location(), match_name));
set_fallback_credential_from_db(url, params.authentication_db);
return {
/* url= */ std::move(url),
/* display_name= */ spec.clear_location(),
/* platforms= */ make_platforms(spec.clear_platform_filters(), params.platforms),
/* display_name= */ uc.clear_location(),
/* platforms= */ make_platforms(uc.clear_platform_filters(), params.platforms),
};
}
auto resolve_name_in_custom_mulitchannels(
const ChannelSpec& spec,
const UnresolvedChannel& uc,
ChannelResolveParamsView params,
const Channel::channel_list& matches
) -> Channel::channel_list
@ -346,74 +346,74 @@ namespace mamba::specs
out.emplace_back(
/* url= */ std::move(url),
/* display_name= */ chan.display_name(), // Not using multi_channel name
/* platforms= */ make_platforms(spec.platform_filters(), params.platforms)
/* platforms= */ make_platforms(uc.platform_filters(), params.platforms)
);
}
return out;
}
auto resolve_name_from_alias(ChannelSpec&& spec, ChannelResolveParamsView params) -> Channel
auto resolve_name_from_alias(UnresolvedChannel&& uc, ChannelResolveParamsView params)
-> Channel
{
auto url = params.channel_alias;
url.append_path(spec.location());
url.append_path(uc.location());
set_fallback_credential_from_db(url, params.authentication_db);
return {
/* url= */ std::move(url),
/* display_name= */ spec.clear_location(),
/* platforms= */ make_platforms(spec.clear_platform_filters(), params.platforms),
/* display_name= */ uc.clear_location(),
/* platforms= */ make_platforms(uc.clear_platform_filters(), params.platforms),
};
}
auto resolve_name(ChannelSpec&& spec, ChannelResolveParamsView params) -> Channel::channel_list
auto resolve_name(UnresolvedChannel&& uc, ChannelResolveParamsView params)
-> Channel::channel_list
{
if (auto it = params.custom_channels.find_weaken(spec.location());
if (auto it = params.custom_channels.find_weaken(uc.location());
it != params.custom_channels.cend())
{
return {
resolve_name_in_custom_channel(std::move(spec), params, it->first, it->second)
};
return { resolve_name_in_custom_channel(std::move(uc), params, it->first, it->second) };
}
if (auto it = params.custom_multichannels.find(spec.location());
if (auto it = params.custom_multichannels.find(uc.location());
it != params.custom_multichannels.end())
{
return resolve_name_in_custom_mulitchannels(spec, params, it->second);
return resolve_name_in_custom_mulitchannels(uc, params, it->second);
}
return { resolve_name_from_alias(std::move(spec), params) };
return { resolve_name_from_alias(std::move(uc), params) };
}
}
auto Channel::resolve(ChannelSpec spec, ChannelResolveParamsView params) -> channel_list
auto Channel::resolve(UnresolvedChannel uc, ChannelResolveParamsView params) -> channel_list
{
switch (spec.type())
switch (uc.type())
{
case ChannelSpec::Type::PackagePath:
case ChannelSpec::Type::Path:
case UnresolvedChannel::Type::PackagePath:
case UnresolvedChannel::Type::Path:
{
return { resolve_path(std::move(spec), params) };
return { resolve_path(std::move(uc), params) };
}
case ChannelSpec::Type::PackageURL:
case ChannelSpec::Type::URL:
case UnresolvedChannel::Type::PackageURL:
case UnresolvedChannel::Type::URL:
{
return { resolve_url(std::move(spec), params) };
return { resolve_url(std::move(uc), params) };
}
case ChannelSpec::Type::Name:
case UnresolvedChannel::Type::Name:
{
return resolve_name(std::move(spec), params);
return resolve_name(std::move(uc), params);
}
case ChannelSpec::Type::Unknown:
case UnresolvedChannel::Type::Unknown:
{
return { { CondaURL{}, spec.clear_location() } };
return { { CondaURL{}, uc.clear_location() } };
}
}
throw std::invalid_argument("Invalid ChannelSpec::Type");
throw std::invalid_argument("Invalid UnresolvedChannel::Type");
}
auto Channel::resolve(ChannelSpec spec, const ChannelResolveParams& params) -> channel_list
auto Channel::resolve(UnresolvedChannel uc, const ChannelResolveParams& params) -> channel_list
{
return resolve(
std::move(spec),
std::move(uc),
ChannelResolveParamsView{
/* .platforms= */ params.platforms,
/* .channel_alias= */ params.channel_alias,

View File

@ -29,7 +29,7 @@ namespace mamba::specs
};
auto out = MatchSpec();
out.m_channel = ChannelSpec::parse(spec);
out.m_channel = UnresolvedChannel::parse(spec);
auto [_, pkg] = util::rsplit_once(out.m_channel->location(), '/');
out.m_filename = std::string(pkg);
out.m_url = util::path_or_url_to_url(spec);
@ -170,7 +170,7 @@ namespace mamba::specs
std::string channel_str;
if (m5_len == 3)
{
out.m_channel = ChannelSpec::parse(m5[0]);
out.m_channel = UnresolvedChannel::parse(m5[0]);
out.m_name_space = m5[1];
spec_str = m5[2];
}
@ -257,18 +257,18 @@ namespace mamba::specs
}
if (const auto& val = at_or(extra, "channel", ""); !val.empty())
{
out.set_channel(ChannelSpec::parse(val));
out.set_channel(UnresolvedChannel::parse(val));
}
if (const auto& val = at_or(extra, "subdir", ""); !val.empty())
{
if (!out.m_channel.has_value())
{
out.m_channel = ChannelSpec("", { val }, ChannelSpec::Type::Unknown);
out.m_channel = UnresolvedChannel("", { val }, UnresolvedChannel::Type::Unknown);
}
// Subdirs specified in the channel part have higher precedence
else if (out.m_channel->platform_filters().empty())
{
out.m_channel = ChannelSpec(
out.m_channel = UnresolvedChannel(
out.m_channel->clear_location(),
{ val },
out.m_channel->type()
@ -311,12 +311,12 @@ namespace mamba::specs
return out;
}
auto MatchSpec::channel() const -> const std::optional<ChannelSpec>&
auto MatchSpec::channel() const -> const std::optional<UnresolvedChannel>&
{
return m_channel;
}
void MatchSpec::set_channel(std::optional<ChannelSpec> chan)
void MatchSpec::set_channel(std::optional<UnresolvedChannel> chan)
{
m_channel = std::move(chan);
}

View File

@ -16,8 +16,8 @@
#include "mamba/fs/filesystem.hpp"
#include "mamba/specs/archive.hpp"
#include "mamba/specs/channel_spec.hpp"
#include "mamba/specs/platform.hpp"
#include "mamba/specs/unresolved_channel.hpp"
#include "mamba/util/path_manip.hpp"
#include "mamba/util/string.hpp"
#include "mamba/util/url_manip.hpp"
@ -30,12 +30,12 @@ namespace mamba::specs
namespace
{
using dynamic_platform_set = ChannelSpec::dynamic_platform_set;
using dynamic_platform_set = UnresolvedChannel::dynamic_platform_set;
auto parse_platform_list(std::string_view plats) -> dynamic_platform_set
{
static constexpr auto is_not_sep = [](char c) -> bool
{ return !util::contains(ChannelSpec::platform_separators, c); };
{ return !util::contains(UnresolvedChannel::platform_separators, c); };
auto out = dynamic_platform_set{};
auto head_rest = util::lstrip_if_parts(plats, is_not_sep);
@ -44,7 +44,7 @@ namespace mamba::specs
// Accepting all strings, so that user can dynamically register new platforms
out.insert(util::to_lower(util::strip(head_rest.front())));
head_rest = util::lstrip_if_parts(
util::lstrip(head_rest.back(), ChannelSpec::platform_separators),
util::lstrip(head_rest.back(), UnresolvedChannel::platform_separators),
is_not_sep
);
}
@ -114,15 +114,15 @@ namespace mamba::specs
auto is_unknown_channel(std::string_view str) -> bool
{
auto it = std::find(
ChannelSpec::invalid_channels_lower.cbegin(),
ChannelSpec::invalid_channels_lower.cend(),
UnresolvedChannel::invalid_channels_lower.cbegin(),
UnresolvedChannel::invalid_channels_lower.cend(),
util::to_lower(str)
);
return str.empty() || (it != ChannelSpec::invalid_channels_lower.cend());
return str.empty() || (it != UnresolvedChannel::invalid_channels_lower.cend());
}
}
auto ChannelSpec::parse(std::string_view str) -> ChannelSpec
auto UnresolvedChannel::parse(std::string_view str) -> UnresolvedChannel
{
str = util::strip(str);
if (is_unknown_channel(str))
@ -155,7 +155,7 @@ namespace mamba::specs
return { std::move(location), std::move(filters), type };
}
ChannelSpec::ChannelSpec(std::string location, dynamic_platform_set filters, Type type)
UnresolvedChannel::UnresolvedChannel(std::string location, dynamic_platform_set filters, Type type)
: m_location(std::move(location))
, m_platform_filters(std::move(filters))
, m_type(type)
@ -174,55 +174,55 @@ namespace mamba::specs
}
}
auto ChannelSpec::type() const -> Type
auto UnresolvedChannel::type() const -> Type
{
return m_type;
}
auto ChannelSpec::location() const& -> const std::string&
auto UnresolvedChannel::location() const& -> const std::string&
{
return m_location;
}
auto ChannelSpec::location() && -> std::string
auto UnresolvedChannel::location() && -> std::string
{
return std::move(m_location);
}
auto ChannelSpec::clear_location() -> std::string
auto UnresolvedChannel::clear_location() -> std::string
{
return std::exchange(m_location, "");
}
auto ChannelSpec::platform_filters() const& -> const dynamic_platform_set&
auto UnresolvedChannel::platform_filters() const& -> const dynamic_platform_set&
{
return m_platform_filters;
}
auto ChannelSpec::platform_filters() && -> dynamic_platform_set
auto UnresolvedChannel::platform_filters() && -> dynamic_platform_set
{
return std::move(m_platform_filters);
}
auto ChannelSpec::clear_platform_filters() -> dynamic_platform_set
auto UnresolvedChannel::clear_platform_filters() -> dynamic_platform_set
{
return std::exchange(m_platform_filters, {});
}
auto ChannelSpec::str() const -> std::string
auto UnresolvedChannel::str() const -> std::string
{
return fmt::format("{}", *this);
}
}
auto
fmt::formatter<mamba::specs::ChannelSpec>::format(const ChannelSpec& spec, format_context& ctx) const
fmt::formatter<mamba::specs::UnresolvedChannel>::format(const UnresolvedChannel& uc, format_context& ctx) const
-> format_context::iterator
{
auto out = fmt::format_to(ctx.out(), "{}", spec.location());
if (!spec.platform_filters().empty())
auto out = fmt::format_to(ctx.out(), "{}", uc.location());
if (!uc.platform_filters().empty())
{
out = fmt::format_to(ctx.out(), "[{}]", fmt::join(spec.platform_filters(), ","));
out = fmt::format_to(ctx.out(), "[{}]", fmt::join(uc.platform_filters(), ","));
}
return out;
}

View File

@ -46,13 +46,13 @@ set(
src/specs/test_authentication_info.cpp
src/specs/test_build_number_spec.cpp
src/specs/test_channel.cpp
src/specs/test_channel_spec.cpp
src/specs/test_conda_url.cpp
src/specs/test_glob_spec.cpp
src/specs/test_match_spec.cpp
src/specs/test_package_info.cpp
src/specs/test_platform.cpp
src/specs/test_repo_data.cpp
src/specs/test_unresolved_channel.cpp
src/specs/test_version.cpp
src/specs/test_version_spec.cpp
# Artifacts validation

View File

@ -7,8 +7,8 @@
#include <doctest/doctest.h>
#include "mamba/specs/channel.hpp"
#include "mamba/specs/channel_spec.hpp"
#include "mamba/specs/conda_url.hpp"
#include "mamba/specs/unresolved_channel.hpp"
#include "mamba/util/path_manip.hpp"
#include "mamba/util/string.hpp"
@ -126,7 +126,7 @@ TEST_SUITE("specs::channel")
auto make_typical_params = []() -> ChannelResolveParams
{
auto make_channel = [](std::string_view loc, ChannelResolveParams const& params)
{ return Channel::resolve(ChannelSpec::parse(loc), params).at(0); };
{ return Channel::resolve(UnresolvedChannel::parse(loc), params).at(0); };
auto params = ChannelResolveParams{};
params.platforms = { "linux-64", "noarch" };
@ -157,12 +157,12 @@ TEST_SUITE("specs::channel")
SUBCASE("/path/to/libmamba-1.4.2-hcea66bb_0.conda")
{
const auto path = "/path/to/libmamba-1.4.2-hcea66bb_0.conda"sv;
auto specs = ChannelSpec(std::string(path), {}, ChannelSpec::Type::PackagePath);
auto uc = UnresolvedChannel(std::string(path), {}, UnresolvedChannel::Type::PackagePath);
SUBCASE("Typical parameters")
{
auto params = make_typical_params();
auto channels = Channel::resolve(specs, params);
auto channels = Channel::resolve(uc, params);
REQUIRE_EQ(channels.size(), 1);
const auto& chan = channels.front();
const auto url = "file:///path/to/libmamba-1.4.2-hcea66bb_0.conda"sv;
@ -175,12 +175,12 @@ TEST_SUITE("specs::channel")
SUBCASE("~/conda-bld/win-64/libmamba-1.4.2-hcea66bb_0.conda")
{
const auto path = "~/conda-bld/win-64/libmamba-1.4.2-hcea66bb_0.conda"sv;
auto specs = ChannelSpec(std::string(path), {}, ChannelSpec::Type::PackagePath);
auto uc = UnresolvedChannel(std::string(path), {}, UnresolvedChannel::Type::PackagePath);
SUBCASE("Typical parameters")
{
auto params = make_typical_params();
auto channels = Channel::resolve(specs, params);
auto channels = Channel::resolve(uc, params);
REQUIRE_EQ(channels.size(), 1);
const auto& chan = channels.front();
const auto url = "file:///home/conda-bld/win-64/libmamba-1.4.2-hcea66bb_0.conda"sv;
@ -200,7 +200,7 @@ TEST_SUITE("specs::channel")
/* .home_dir= */ "/home",
};
CHECK_EQ(
Channel::resolve(specs, params).at(0).display_name(),
Channel::resolve(uc, params).at(0).display_name(),
"win-64/libmamba-1.4.2-hcea66bb_0.conda"
);
}
@ -217,21 +217,21 @@ TEST_SUITE("specs::channel")
};
params.custom_channels.emplace(
"mychan",
Channel::resolve(ChannelSpec::parse("file:///home/conda-bld/"), params).at(0)
Channel::resolve(UnresolvedChannel::parse("file:///home/conda-bld/"), params).at(0)
);
CHECK_EQ(Channel::resolve(specs, params).at(0).display_name(), "mychan");
CHECK_EQ(Channel::resolve(uc, params).at(0).display_name(), "mychan");
}
}
SUBCASE("./path/to/libmamba-1.4.2-hcea66bb_0.conda")
{
const auto path = "./path/to/libmamba-1.4.2-hcea66bb_0.conda"sv;
auto specs = ChannelSpec(std::string(path), {}, ChannelSpec::Type::PackagePath);
auto uc = UnresolvedChannel(std::string(path), {}, UnresolvedChannel::Type::PackagePath);
SUBCASE("Typical parameters")
{
auto params = make_typical_params();
auto channels = Channel::resolve(specs, params);
auto channels = Channel::resolve(uc, params);
REQUIRE_EQ(channels.size(), 1);
const auto& chan = channels.front();
const auto url = "file:///cwd/path/to/libmamba-1.4.2-hcea66bb_0.conda"sv;
@ -244,12 +244,12 @@ TEST_SUITE("specs::channel")
SUBCASE("/some/folder")
{
const auto path = "/some/folder"sv;
auto specs = ChannelSpec(std::string(path), {}, ChannelSpec::Type::Path);
auto uc = UnresolvedChannel(std::string(path), {}, UnresolvedChannel::Type::Path);
SUBCASE("Typical parameters")
{
auto params = make_typical_params();
auto channels = Channel::resolve(specs, params);
auto channels = Channel::resolve(uc, params);
REQUIRE_EQ(channels.size(), 1);
const auto& chan = channels.front();
const auto url = "file:///some/folder"sv;
@ -260,7 +260,11 @@ TEST_SUITE("specs::channel")
SUBCASE("With platform filers")
{
auto other_specs = ChannelSpec(std::string(path), { "foo-56" }, ChannelSpec::Type::Path);
auto other_specs = UnresolvedChannel(
std::string(path),
{ "foo-56" },
UnresolvedChannel::Type::Path
);
CHECK_EQ(
Channel::resolve(other_specs, ChannelResolveParams{}).at(0).platforms(),
other_specs.platform_filters()
@ -271,12 +275,12 @@ TEST_SUITE("specs::channel")
SUBCASE("~/folder")
{
const auto path = "~/folder"sv;
auto specs = ChannelSpec(std::string(path), {}, ChannelSpec::Type::Path);
auto uc = UnresolvedChannel(std::string(path), {}, UnresolvedChannel::Type::Path);
SUBCASE("Typical parameters")
{
auto params = make_typical_params();
auto channels = Channel::resolve(specs, params);
auto channels = Channel::resolve(uc, params);
REQUIRE_EQ(channels.size(), 1);
const auto& chan = channels.front();
const auto url = "file:///home/folder"sv;
@ -289,12 +293,12 @@ TEST_SUITE("specs::channel")
SUBCASE("./other/folder")
{
const auto path = "./other/folder"sv;
auto specs = ChannelSpec(std::string(path), {}, ChannelSpec::Type::Path);
auto uc = UnresolvedChannel(std::string(path), {}, UnresolvedChannel::Type::Path);
SUBCASE("Typical parameters")
{
auto params = make_typical_params();
auto channels = Channel::resolve(specs, params);
auto channels = Channel::resolve(uc, params);
REQUIRE_EQ(channels.size(), 1);
const auto& chan = channels.front();
const auto url = "file:///cwd/other/folder"sv;
@ -307,12 +311,12 @@ TEST_SUITE("specs::channel")
SUBCASE("https://repo.mamba.pm/conda-forge/linux-64/libmamba-1.4.2-hcea66bb_0.conda")
{
const auto url = "https://repo.mamba.pm/conda-forge/linux-64/libmamba-1.4.2-hcea66bb_0.conda"sv;
auto specs = ChannelSpec(std::string(url), {}, ChannelSpec::Type::PackageURL);
auto uc = UnresolvedChannel(std::string(url), {}, UnresolvedChannel::Type::PackageURL);
SUBCASE("Typical parameters")
{
auto params = make_typical_params();
auto channels = Channel::resolve(specs, params);
auto channels = Channel::resolve(uc, params);
REQUIRE_EQ(channels.size(), 1);
const auto& chan = channels.front();
CHECK_EQ(chan.url(), CondaURL::parse(url));
@ -324,26 +328,30 @@ TEST_SUITE("specs::channel")
SUBCASE("https://repo.mamba.pm")
{
const auto url = "https://repo.mamba.pm"sv;
auto specs = ChannelSpec(std::string(url), { "linux-64", "noarch" }, ChannelSpec::Type::URL);
auto uc = UnresolvedChannel(
std::string(url),
{ "linux-64", "noarch" },
UnresolvedChannel::Type::URL
);
SUBCASE("Empty params")
{
auto channels = Channel::resolve(specs, ChannelResolveParams{});
auto channels = Channel::resolve(uc, ChannelResolveParams{});
REQUIRE_EQ(channels.size(), 1);
const auto& chan = channels.front();
CHECK_EQ(chan.url(), CondaURL::parse(url));
CHECK_EQ(chan.platforms(), specs.platform_filters());
CHECK_EQ(chan.platforms(), uc.platform_filters());
CHECK_EQ(chan.display_name(), url);
}
SUBCASE("Typical parameters")
{
auto params = make_typical_params();
auto channels = Channel::resolve(specs, params);
auto channels = Channel::resolve(uc, params);
REQUIRE_EQ(channels.size(), 1);
const auto& chan = channels.front();
CHECK_EQ(chan.url(), CondaURL::parse(url));
CHECK_EQ(chan.platforms(), specs.platform_filters());
CHECK_EQ(chan.platforms(), uc.platform_filters());
CHECK_EQ(chan.display_name(), url);
}
}
@ -351,36 +359,40 @@ TEST_SUITE("specs::channel")
SUBCASE("https://repo.mamba.pm/conda-forge")
{
const auto url = "https://repo.mamba.pm/conda-forge"sv;
auto specs = ChannelSpec(std::string(url), { "linux-64", "noarch" }, ChannelSpec::Type::URL);
auto uc = UnresolvedChannel(
std::string(url),
{ "linux-64", "noarch" },
UnresolvedChannel::Type::URL
);
SUBCASE("Empty params")
{
auto channels = Channel::resolve(specs, ChannelResolveParams{});
auto channels = Channel::resolve(uc, ChannelResolveParams{});
REQUIRE_EQ(channels.size(), 1);
const auto& chan = channels.front();
CHECK_EQ(chan.url(), CondaURL::parse(url));
CHECK_EQ(chan.platforms(), specs.platform_filters());
CHECK_EQ(chan.platforms(), uc.platform_filters());
CHECK_EQ(chan.display_name(), url);
}
SUBCASE("Typical parameters")
{
auto params = make_typical_params();
auto channels = Channel::resolve(specs, params);
auto channels = Channel::resolve(uc, params);
REQUIRE_EQ(channels.size(), 1);
const auto& chan = channels.front();
CHECK_EQ(chan.url(), CondaURL::parse(url));
CHECK_EQ(chan.platforms(), specs.platform_filters());
CHECK_EQ(chan.platforms(), uc.platform_filters());
CHECK_EQ(chan.display_name(), url);
}
SUBCASE("Default platforms")
{
auto params = ChannelResolveParams{ /* .platform= */ { "rainbow-37", "noarch" } };
CHECK_EQ(Channel::resolve(specs, params).at(0).platforms(), specs.platform_filters());
CHECK_EQ(Channel::resolve(uc, params).at(0).platforms(), uc.platform_filters());
specs.clear_platform_filters();
CHECK_EQ(Channel::resolve(specs, params).at(0).platforms(), params.platforms);
uc.clear_platform_filters();
CHECK_EQ(Channel::resolve(uc, params).at(0).platforms(), params.platforms);
}
SUBCASE("Matching channel alias")
@ -396,7 +408,7 @@ TEST_SUITE("specs::channel")
/* .platform= */ {},
/* .channel_alias= */ CondaURL::parse(alias),
};
CHECK_EQ(Channel::resolve(specs, params).at(0).display_name(), "conda-forge");
CHECK_EQ(Channel::resolve(uc, params).at(0).display_name(), "conda-forge");
}
}
@ -411,7 +423,7 @@ TEST_SUITE("specs::channel")
/* .platform= */ {},
/* .channel_alias= */ CondaURL::parse(alias),
};
CHECK_EQ(Channel::resolve(specs, params).at(0).display_name(), url);
CHECK_EQ(Channel::resolve(uc, params).at(0).display_name(), url);
}
}
@ -421,9 +433,9 @@ TEST_SUITE("specs::channel")
/* .platform= */ {},
/* .channel_alias= */ CondaURL::parse("https://repo.mamba.pm/"),
/* .custom_channels= */
{ { "mychan", Channel::resolve(specs, ChannelResolveParams{}).at(0) } }
{ { "mychan", Channel::resolve(uc, ChannelResolveParams{}).at(0) } }
};
auto channels = Channel::resolve(specs, params);
auto channels = Channel::resolve(uc, params);
REQUIRE_EQ(channels.size(), 1);
const auto& chan = channels.front();
CHECK_EQ(chan.url(), CondaURL::parse(url));
@ -440,7 +452,7 @@ TEST_SUITE("specs::channel")
/* .authentication_db= */ { { "repo.mamba.pm", CondaToken{ "mytoken" } } },
};
auto channels = Channel::resolve(specs, params);
auto channels = Channel::resolve(uc, params);
REQUIRE_EQ(channels.size(), 1);
const auto& chan = channels.front();
CHECK_EQ(chan.url(), CondaURL::parse("https://repo.mamba.pm/t/mytoken/conda-forge"));
@ -461,7 +473,7 @@ TEST_SUITE("specs::channel")
},
};
auto channels = Channel::resolve(specs, params);
auto channels = Channel::resolve(uc, params);
REQUIRE_EQ(channels.size(), 1);
const auto& chan = channels.front();
CHECK_EQ(chan.url(), CondaURL::parse("https://repo.mamba.pm/t/forge-token/conda-forge"));
@ -472,7 +484,7 @@ TEST_SUITE("specs::channel")
SUBCASE("https://user:pass@repo.mamba.pm/conda-forge")
{
const auto url = "https://user:pass@repo.mamba.pm/conda-forge"sv;
auto specs = ChannelSpec(std::string(url), {}, ChannelSpec::Type::URL);
auto uc = UnresolvedChannel(std::string(url), {}, UnresolvedChannel::Type::URL);
SUBCASE("Authentication info token")
{
@ -484,7 +496,7 @@ TEST_SUITE("specs::channel")
/* .authentication_db= */ { { "repo.mamba.pm", CondaToken{ "mytoken" } } },
};
auto channels = Channel::resolve(specs, params);
auto channels = Channel::resolve(uc, params);
REQUIRE_EQ(channels.size(), 1);
const auto& chan = channels.front();
CHECK_EQ(
@ -505,7 +517,7 @@ TEST_SUITE("specs::channel")
{ { "repo.mamba.pm", BasicHTTPAuthentication{ "foo", "weak" } } },
};
auto channels = Channel::resolve(specs, params);
auto channels = Channel::resolve(uc, params);
REQUIRE_EQ(channels.size(), 1);
const auto& chan = channels.front();
// Higher precedence
@ -517,12 +529,12 @@ TEST_SUITE("specs::channel")
SUBCASE("https://repo.anaconda.com/pkgs/main")
{
const auto url = "https://repo.anaconda.com/pkgs/main"sv;
auto specs = ChannelSpec(std::string(url), {}, ChannelSpec::Type::URL);
auto uc = UnresolvedChannel(std::string(url), {}, UnresolvedChannel::Type::URL);
SUBCASE("Typical parameters")
{
auto params = make_typical_params();
auto channels = Channel::resolve(specs, params);
auto channels = Channel::resolve(uc, params);
REQUIRE_EQ(channels.size(), 1);
const auto& chan = channels.front();
CHECK_EQ(chan.url(), CondaURL::parse(url));
@ -537,7 +549,7 @@ TEST_SUITE("specs::channel")
/* .channel_alias= */ CondaURL::parse("https://repo.anaconda.com"),
};
auto channels = Channel::resolve(specs, params);
auto channels = Channel::resolve(uc, params);
REQUIRE_EQ(channels.size(), 1);
const auto& chan = channels.front();
CHECK_EQ(chan.url(), CondaURL::parse(url));
@ -548,12 +560,12 @@ TEST_SUITE("specs::channel")
SUBCASE("conda-forge")
{
const auto name = "conda-forge"sv;
auto specs = ChannelSpec(std::string(name), {}, ChannelSpec::Type::Name);
auto uc = UnresolvedChannel(std::string(name), {}, UnresolvedChannel::Type::Name);
SUBCASE("Typical parameters")
{
auto params = make_typical_params();
auto channels = Channel::resolve(specs, params);
auto channels = Channel::resolve(uc, params);
REQUIRE_EQ(channels.size(), 1);
const auto& chan = channels.front();
CHECK_EQ(
@ -575,7 +587,7 @@ TEST_SUITE("specs::channel")
{ { "mydomain.com", BasicHTTPAuthentication{ "user", "pass" } } },
};
auto channels = Channel::resolve(specs, params);
auto channels = Channel::resolve(uc, params);
REQUIRE_EQ(channels.size(), 1);
const auto& chan = channels.front();
CHECK_EQ(
@ -591,10 +603,10 @@ TEST_SUITE("specs::channel")
auto params = make_typical_params();
params.custom_channels.emplace(
"conda-forge",
Channel::resolve(ChannelSpec::parse("ftp://mydomain.net/conda"), params).at(0)
Channel::resolve(UnresolvedChannel::parse("ftp://mydomain.net/conda"), params).at(0)
);
auto channels = Channel::resolve(specs, params);
auto channels = Channel::resolve(uc, params);
REQUIRE_EQ(channels.size(), 1);
const auto& chan = channels.front();
// Higher precedence.
@ -607,12 +619,12 @@ TEST_SUITE("specs::channel")
SUBCASE("pkgs/main")
{
const auto name = "pkgs/main"sv;
auto specs = ChannelSpec(std::string(name), {}, ChannelSpec::Type::Name);
auto uc = UnresolvedChannel(std::string(name), {}, UnresolvedChannel::Type::Name);
SUBCASE("Typical parameters")
{
auto params = make_typical_params();
auto channels = Channel::resolve(specs, params);
auto channels = Channel::resolve(uc, params);
REQUIRE_EQ(channels.size(), 1);
const auto& chan = channels.front();
CHECK_EQ(chan.url(), CondaURL::parse("https://repo.anaconda.com/pkgs/main"));
@ -624,7 +636,7 @@ TEST_SUITE("specs::channel")
SUBCASE("pkgs/main/label/dev")
{
const auto name = "pkgs/main/label/dev"sv;
auto specs = ChannelSpec(std::string(name), {}, ChannelSpec::Type::Name);
auto specs = UnresolvedChannel(std::string(name), {}, UnresolvedChannel::Type::Name);
SUBCASE("Typical parameters")
{
@ -641,12 +653,12 @@ TEST_SUITE("specs::channel")
SUBCASE("testchannel/mylabel/xyz")
{
const auto name = "testchannel/mylabel/xyz"sv;
auto specs = ChannelSpec(std::string(name), {}, ChannelSpec::Type::Name);
auto uc = UnresolvedChannel(std::string(name), {}, UnresolvedChannel::Type::Name);
SUBCASE("Typical parameters")
{
auto params = make_typical_params();
auto channels = Channel::resolve(specs, params);
auto channels = Channel::resolve(uc, params);
REQUIRE_EQ(channels.size(), 1);
const auto& chan = channels.front();
CHECK_EQ(
@ -662,11 +674,14 @@ TEST_SUITE("specs::channel")
auto params = make_typical_params();
params.custom_channels.emplace(
"testchannel",
Channel::resolve(ChannelSpec::parse("https://server.com/private/testchannel"), params)
Channel::resolve(
UnresolvedChannel::parse("https://server.com/private/testchannel"),
params
)
.at(0)
);
auto channels = Channel::resolve(specs, params);
auto channels = Channel::resolve(uc, params);
REQUIRE_EQ(channels.size(), 1);
const auto& chan = channels.front();
CHECK_EQ(
@ -681,7 +696,7 @@ TEST_SUITE("specs::channel")
SUBCASE("prefix-and-more")
{
const auto name = "prefix-and-more"sv;
auto specs = ChannelSpec(std::string(name), {}, ChannelSpec::Type::Name);
auto uc = UnresolvedChannel(std::string(name), {}, UnresolvedChannel::Type::Name);
auto params = ChannelResolveParams{
/* .platform= */ {},
@ -689,10 +704,10 @@ TEST_SUITE("specs::channel")
};
params.custom_channels.emplace(
"prefix",
Channel::resolve(ChannelSpec::parse("https://server.com/prefix"), params).at(0)
Channel::resolve(UnresolvedChannel::parse("https://server.com/prefix"), params).at(0)
);
auto channels = Channel::resolve(specs, params);
auto channels = Channel::resolve(uc, params);
REQUIRE_EQ(channels.size(), 1);
const auto& chan = channels.front();
CHECK_EQ(chan.url(), CondaURL::parse("https://ali.as/prefix-and-more"));
@ -703,18 +718,18 @@ TEST_SUITE("specs::channel")
SUBCASE("defaults")
{
const auto name = "defaults"sv;
auto specs = ChannelSpec(std::string(name), { "linux-64" }, ChannelSpec::Type::Name);
auto uc = UnresolvedChannel(std::string(name), { "linux-64" }, UnresolvedChannel::Type::Name);
SUBCASE("Typical parameters")
{
auto params = make_typical_params();
auto channels = Channel::resolve(specs, params);
auto channels = Channel::resolve(uc, params);
REQUIRE_EQ(channels.size(), 3);
auto found_names = util::flat_set<std::string>();
for (const auto& chan : channels)
{
CHECK_EQ(chan.platforms(), specs.platform_filters()); // Overriden
CHECK_EQ(chan.platforms(), uc.platform_filters()); // Overriden
found_names.insert(chan.display_name());
}
CHECK_EQ(found_names, util::flat_set<std::string>{ "pkgs/main", "pkgs/pro", "pkgs/r" });
@ -723,8 +738,8 @@ TEST_SUITE("specs::channel")
SUBCASE("<unknown>")
{
auto specs = ChannelSpec({}, { "linux-64" }, ChannelSpec::Type::Unknown);
auto channels = Channel::resolve(specs, ChannelResolveParams{});
auto uc = UnresolvedChannel({}, { "linux-64" }, UnresolvedChannel::Type::Unknown);
auto channels = Channel::resolve(uc, ChannelResolveParams{});
REQUIRE_EQ(channels.size(), 1);
const auto& chan = channels.front();
CHECK_EQ(chan.url(), CondaURL());
@ -736,12 +751,12 @@ TEST_SUITE("specs::channel")
{
// Version 1!164.3095 is URL encoded
const auto url = "https://conda.anaconda.org/conda-forge/linux-64/x264-1%21164.3095-h166bdaf_2.tar.bz2"sv;
auto specs = ChannelSpec(std::string(url), {}, ChannelSpec::Type::PackageURL);
auto uc = UnresolvedChannel(std::string(url), {}, UnresolvedChannel::Type::PackageURL);
SUBCASE("Typical parameters")
{
auto params = make_typical_params();
auto channels = Channel::resolve(specs, params);
auto channels = Channel::resolve(uc, params);
REQUIRE_EQ(channels.size(), 1);
const auto& chan = channels.front();
CHECK_EQ(chan.url(), CondaURL::parse(url));

View File

@ -1,232 +0,0 @@
// 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.
#include <doctest/doctest.h>
#include "mamba/specs/channel_spec.hpp"
#include "mamba/util/build.hpp"
using namespace mamba;
using namespace mamba::specs;
TEST_SUITE("specs::channel_spec")
{
using PlatformSet = typename util::flat_set<std::string>;
using Type = typename ChannelSpec::Type;
TEST_CASE("Constructor")
{
SUBCASE("Default")
{
const auto spec = ChannelSpec();
CHECK_EQ(spec.type(), ChannelSpec::Type::Unknown);
CHECK_EQ(spec.location(), "<unknown>");
CHECK(spec.platform_filters().empty());
}
SUBCASE("Unknown")
{
const auto spec = ChannelSpec("hello", { "linux-78" }, ChannelSpec::Type::Unknown);
CHECK_EQ(spec.type(), ChannelSpec::Type::Unknown);
CHECK_EQ(spec.location(), "<unknown>");
CHECK_EQ(spec.platform_filters(), PlatformSet{ "linux-78" });
}
}
TEST_CASE("Parsing")
{
SUBCASE("Invalid channels")
{
for (std::string_view str : { "", "<unknown>", ":///<unknown>", "none" })
{
CAPTURE(str);
const auto spec = ChannelSpec::parse(str);
CHECK_EQ(spec.type(), Type::Unknown);
CHECK_EQ(spec.location(), "<unknown>");
CHECK_EQ(spec.platform_filters(), PlatformSet{});
}
}
SUBCASE("https://repo.anaconda.com/conda-forge")
{
const auto spec = ChannelSpec::parse("https://repo.anaconda.com/conda-forge");
CHECK_EQ(spec.type(), Type::URL);
CHECK_EQ(spec.location(), "https://repo.anaconda.com/conda-forge");
CHECK_EQ(spec.platform_filters(), PlatformSet{});
}
SUBCASE("https://repo.anaconda.com/conda-forge/osx-64")
{
const auto spec = ChannelSpec::parse("https://repo.anaconda.com/conda-forge/osx-64");
CHECK_EQ(spec.type(), Type::URL);
CHECK_EQ(spec.location(), "https://repo.anaconda.com/conda-forge");
CHECK_EQ(spec.platform_filters(), PlatformSet{ "osx-64" });
}
SUBCASE("https://repo.anaconda.com/conda-forge[win-64|noarch]")
{
const auto spec = ChannelSpec::parse("https://repo.anaconda.com/conda-forge[win-64|noarch]"
);
CHECK_EQ(spec.type(), Type::URL);
CHECK_EQ(spec.location(), "https://repo.anaconda.com/conda-forge");
CHECK_EQ(spec.platform_filters(), PlatformSet{ "win-64", "noarch" });
}
SUBCASE("https://repo.anaconda.com/conda-forge/linux-64/pkg-0.0-bld.conda")
{
const auto spec = ChannelSpec::parse(
"https://repo.anaconda.com/conda-forge/linux-64/pkg-0.0-bld.conda"
);
CHECK_EQ(spec.type(), Type::PackageURL);
CHECK_EQ(spec.location(), "https://repo.anaconda.com/conda-forge/linux-64/pkg-0.0-bld.conda");
CHECK_EQ(spec.platform_filters(), PlatformSet{});
}
SUBCASE("file:///Users/name/conda")
{
const auto spec = ChannelSpec::parse("file:///Users/name/conda");
CHECK_EQ(spec.type(), Type::Path);
CHECK_EQ(spec.location(), "file:///Users/name/conda");
CHECK_EQ(spec.platform_filters(), PlatformSet{});
}
SUBCASE("file:///Users/name/conda[linux-64]")
{
const auto spec = ChannelSpec::parse("file:///Users/name/conda[linux-64]");
CHECK_EQ(spec.type(), Type::Path);
CHECK_EQ(spec.location(), "file:///Users/name/conda");
CHECK_EQ(spec.platform_filters(), PlatformSet{ "linux-64" });
}
SUBCASE("file://C:/Users/name/conda")
{
if (util::on_win)
{
const auto spec = ChannelSpec::parse("file://C:/Users/name/conda");
CHECK_EQ(spec.type(), Type::Path);
CHECK_EQ(spec.location(), "file://C:/Users/name/conda");
CHECK_EQ(spec.platform_filters(), PlatformSet{});
}
}
SUBCASE("/Users/name/conda")
{
const auto spec = ChannelSpec::parse("/Users/name/conda");
CHECK_EQ(spec.type(), Type::Path);
CHECK_EQ(spec.location(), "/Users/name/conda");
CHECK_EQ(spec.platform_filters(), PlatformSet{});
}
SUBCASE("./folder/../folder/.")
{
const auto spec = ChannelSpec::parse("./folder/../folder/.");
CHECK_EQ(spec.type(), Type::Path);
CHECK_EQ(spec.location(), "folder");
CHECK_EQ(spec.platform_filters(), PlatformSet{});
}
SUBCASE("~/folder/")
{
const auto spec = ChannelSpec::parse("~/folder/");
CHECK_EQ(spec.type(), Type::Path);
CHECK_EQ(spec.location(), "~/folder");
CHECK_EQ(spec.platform_filters(), PlatformSet{});
}
SUBCASE("/tmp/pkg-0.0-bld.tar.bz2")
{
const auto spec = ChannelSpec::parse("/tmp/pkg-0.0-bld.tar.bz2");
CHECK_EQ(spec.type(), Type::PackagePath);
CHECK_EQ(spec.location(), "/tmp/pkg-0.0-bld.tar.bz2");
CHECK_EQ(spec.platform_filters(), PlatformSet{});
}
SUBCASE("C:/tmp//pkg-0.0-bld.tar.bz2")
{
const auto spec = ChannelSpec::parse("C:/tmp//pkg-0.0-bld.tar.bz2");
CHECK_EQ(spec.type(), Type::PackagePath);
CHECK_EQ(spec.location(), "C:/tmp/pkg-0.0-bld.tar.bz2");
CHECK_EQ(spec.platform_filters(), PlatformSet{});
}
SUBCASE(R"(C:\tmp\pkg-0.0-bld.tar.bz2)")
{
if (util::on_win)
{
const auto spec = ChannelSpec::parse(R"(C:\tmp\pkg-0.0-bld.tar.bz2)");
CHECK_EQ(spec.type(), Type::PackagePath);
CHECK_EQ(spec.location(), "C:/tmp/pkg-0.0-bld.tar.bz2");
CHECK_EQ(spec.platform_filters(), PlatformSet{});
}
}
SUBCASE("conda-forge")
{
const auto spec = ChannelSpec::parse("conda-forge");
CHECK_EQ(spec.type(), Type::Name);
CHECK_EQ(spec.location(), "conda-forge");
CHECK_EQ(spec.platform_filters(), PlatformSet{});
}
SUBCASE("repo.anaconda.com")
{
const auto spec = ChannelSpec::parse("repo.anaconda.com");
// Unintuitive but correct type, this is not a URL. Better explicit than clever.
CHECK_EQ(spec.type(), Type::Name);
CHECK_EQ(spec.location(), "repo.anaconda.com");
CHECK_EQ(spec.platform_filters(), PlatformSet{});
}
SUBCASE("conda-forge/linux-64")
{
const auto spec = ChannelSpec::parse("conda-forge/linux-64");
CHECK_EQ(spec.type(), Type::Name);
CHECK_EQ(spec.location(), "conda-forge");
CHECK_EQ(spec.platform_filters(), PlatformSet{ "linux-64" });
}
SUBCASE("conda-forge[linux-avx512]")
{
const auto spec = ChannelSpec::parse("conda-forge[linux-avx512]");
CHECK_EQ(spec.type(), Type::Name);
CHECK_EQ(spec.location(), "conda-forge");
CHECK_EQ(spec.platform_filters(), PlatformSet{ "linux-avx512" });
}
SUBCASE("conda-forge[]")
{
const auto spec = ChannelSpec::parse("conda-forge[linux-64]");
CHECK_EQ(spec.type(), Type::Name);
CHECK_EQ(spec.location(), "conda-forge");
CHECK_EQ(spec.platform_filters(), PlatformSet{ "linux-64" });
}
SUBCASE("conda-forge/linux-64/label/foo_dev")
{
const auto spec = ChannelSpec::parse("conda-forge/linux-64/label/foo_dev");
CHECK_EQ(spec.type(), Type::Name);
CHECK_EQ(spec.location(), "conda-forge/label/foo_dev");
CHECK_EQ(spec.platform_filters(), PlatformSet{ "linux-64" });
}
SUBCASE("conda-forge/label/foo_dev[linux-64]")
{
const auto spec = ChannelSpec::parse("conda-forge/label/foo_dev[linux-64]");
CHECK_EQ(spec.type(), Type::Name);
CHECK_EQ(spec.location(), "conda-forge/label/foo_dev");
CHECK_EQ(spec.platform_filters(), PlatformSet{ "linux-64" });
}
}
TEST_CASE("str")
{
CHECK_EQ(ChannelSpec("location", {}, Type::Name).str(), "location");
CHECK_EQ(
ChannelSpec("location", { "linux-64", "noarch" }, Type::Name).str(),
"location[linux-64,noarch]"
);
}
}

View File

@ -0,0 +1,233 @@
// 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.
#include <doctest/doctest.h>
#include "mamba/specs/unresolved_channel.hpp"
#include "mamba/util/build.hpp"
using namespace mamba;
using namespace mamba::specs;
TEST_SUITE("specs::channel_spec")
{
using PlatformSet = typename util::flat_set<std::string>;
using Type = typename UnresolvedChannel::Type;
TEST_CASE("Constructor")
{
SUBCASE("Default")
{
const auto uc = UnresolvedChannel();
CHECK_EQ(uc.type(), UnresolvedChannel::Type::Unknown);
CHECK_EQ(uc.location(), "<unknown>");
CHECK(uc.platform_filters().empty());
}
SUBCASE("Unknown")
{
const auto uc = UnresolvedChannel("hello", { "linux-78" }, UnresolvedChannel::Type::Unknown);
CHECK_EQ(uc.type(), UnresolvedChannel::Type::Unknown);
CHECK_EQ(uc.location(), "<unknown>");
CHECK_EQ(uc.platform_filters(), PlatformSet{ "linux-78" });
}
}
TEST_CASE("Parsing")
{
SUBCASE("Invalid channels")
{
for (std::string_view str : { "", "<unknown>", ":///<unknown>", "none" })
{
CAPTURE(str);
const auto uc = UnresolvedChannel::parse(str);
CHECK_EQ(uc.type(), Type::Unknown);
CHECK_EQ(uc.location(), "<unknown>");
CHECK_EQ(uc.platform_filters(), PlatformSet{});
}
}
SUBCASE("https://repo.anaconda.com/conda-forge")
{
const auto uc = UnresolvedChannel::parse("https://repo.anaconda.com/conda-forge");
CHECK_EQ(uc.type(), Type::URL);
CHECK_EQ(uc.location(), "https://repo.anaconda.com/conda-forge");
CHECK_EQ(uc.platform_filters(), PlatformSet{});
}
SUBCASE("https://repo.anaconda.com/conda-forge/osx-64")
{
const auto uc = UnresolvedChannel::parse("https://repo.anaconda.com/conda-forge/osx-64");
CHECK_EQ(uc.type(), Type::URL);
CHECK_EQ(uc.location(), "https://repo.anaconda.com/conda-forge");
CHECK_EQ(uc.platform_filters(), PlatformSet{ "osx-64" });
}
SUBCASE("https://repo.anaconda.com/conda-forge[win-64|noarch]")
{
const auto uc = UnresolvedChannel::parse(
"https://repo.anaconda.com/conda-forge[win-64|noarch]"
);
CHECK_EQ(uc.type(), Type::URL);
CHECK_EQ(uc.location(), "https://repo.anaconda.com/conda-forge");
CHECK_EQ(uc.platform_filters(), PlatformSet{ "win-64", "noarch" });
}
SUBCASE("https://repo.anaconda.com/conda-forge/linux-64/pkg-0.0-bld.conda")
{
const auto uc = UnresolvedChannel::parse(
"https://repo.anaconda.com/conda-forge/linux-64/pkg-0.0-bld.conda"
);
CHECK_EQ(uc.type(), Type::PackageURL);
CHECK_EQ(uc.location(), "https://repo.anaconda.com/conda-forge/linux-64/pkg-0.0-bld.conda");
CHECK_EQ(uc.platform_filters(), PlatformSet{});
}
SUBCASE("file:///Users/name/conda")
{
const auto uc = UnresolvedChannel::parse("file:///Users/name/conda");
CHECK_EQ(uc.type(), Type::Path);
CHECK_EQ(uc.location(), "file:///Users/name/conda");
CHECK_EQ(uc.platform_filters(), PlatformSet{});
}
SUBCASE("file:///Users/name/conda[linux-64]")
{
const auto uc = UnresolvedChannel::parse("file:///Users/name/conda[linux-64]");
CHECK_EQ(uc.type(), Type::Path);
CHECK_EQ(uc.location(), "file:///Users/name/conda");
CHECK_EQ(uc.platform_filters(), PlatformSet{ "linux-64" });
}
SUBCASE("file://C:/Users/name/conda")
{
if (util::on_win)
{
const auto uc = UnresolvedChannel::parse("file://C:/Users/name/conda");
CHECK_EQ(uc.type(), Type::Path);
CHECK_EQ(uc.location(), "file://C:/Users/name/conda");
CHECK_EQ(uc.platform_filters(), PlatformSet{});
}
}
SUBCASE("/Users/name/conda")
{
const auto uc = UnresolvedChannel::parse("/Users/name/conda");
CHECK_EQ(uc.type(), Type::Path);
CHECK_EQ(uc.location(), "/Users/name/conda");
CHECK_EQ(uc.platform_filters(), PlatformSet{});
}
SUBCASE("./folder/../folder/.")
{
const auto uc = UnresolvedChannel::parse("./folder/../folder/.");
CHECK_EQ(uc.type(), Type::Path);
CHECK_EQ(uc.location(), "folder");
CHECK_EQ(uc.platform_filters(), PlatformSet{});
}
SUBCASE("~/folder/")
{
const auto uc = UnresolvedChannel::parse("~/folder/");
CHECK_EQ(uc.type(), Type::Path);
CHECK_EQ(uc.location(), "~/folder");
CHECK_EQ(uc.platform_filters(), PlatformSet{});
}
SUBCASE("/tmp/pkg-0.0-bld.tar.bz2")
{
const auto uc = UnresolvedChannel::parse("/tmp/pkg-0.0-bld.tar.bz2");
CHECK_EQ(uc.type(), Type::PackagePath);
CHECK_EQ(uc.location(), "/tmp/pkg-0.0-bld.tar.bz2");
CHECK_EQ(uc.platform_filters(), PlatformSet{});
}
SUBCASE("C:/tmp//pkg-0.0-bld.tar.bz2")
{
const auto uc = UnresolvedChannel::parse("C:/tmp//pkg-0.0-bld.tar.bz2");
CHECK_EQ(uc.type(), Type::PackagePath);
CHECK_EQ(uc.location(), "C:/tmp/pkg-0.0-bld.tar.bz2");
CHECK_EQ(uc.platform_filters(), PlatformSet{});
}
SUBCASE(R"(C:\tmp\pkg-0.0-bld.tar.bz2)")
{
if (util::on_win)
{
const auto uc = UnresolvedChannel::parse(R"(C:\tmp\pkg-0.0-bld.tar.bz2)");
CHECK_EQ(uc.type(), Type::PackagePath);
CHECK_EQ(uc.location(), "C:/tmp/pkg-0.0-bld.tar.bz2");
CHECK_EQ(uc.platform_filters(), PlatformSet{});
}
}
SUBCASE("conda-forge")
{
const auto uc = UnresolvedChannel::parse("conda-forge");
CHECK_EQ(uc.type(), Type::Name);
CHECK_EQ(uc.location(), "conda-forge");
CHECK_EQ(uc.platform_filters(), PlatformSet{});
}
SUBCASE("repo.anaconda.com")
{
const auto uc = UnresolvedChannel::parse("repo.anaconda.com");
// Unintuitive but correct type, this is not a URL. Better explicit than clever.
CHECK_EQ(uc.type(), Type::Name);
CHECK_EQ(uc.location(), "repo.anaconda.com");
CHECK_EQ(uc.platform_filters(), PlatformSet{});
}
SUBCASE("conda-forge/linux-64")
{
const auto uc = UnresolvedChannel::parse("conda-forge/linux-64");
CHECK_EQ(uc.type(), Type::Name);
CHECK_EQ(uc.location(), "conda-forge");
CHECK_EQ(uc.platform_filters(), PlatformSet{ "linux-64" });
}
SUBCASE("conda-forge[linux-avx512]")
{
const auto uc = UnresolvedChannel::parse("conda-forge[linux-avx512]");
CHECK_EQ(uc.type(), Type::Name);
CHECK_EQ(uc.location(), "conda-forge");
CHECK_EQ(uc.platform_filters(), PlatformSet{ "linux-avx512" });
}
SUBCASE("conda-forge[]")
{
const auto uc = UnresolvedChannel::parse("conda-forge[linux-64]");
CHECK_EQ(uc.type(), Type::Name);
CHECK_EQ(uc.location(), "conda-forge");
CHECK_EQ(uc.platform_filters(), PlatformSet{ "linux-64" });
}
SUBCASE("conda-forge/linux-64/label/foo_dev")
{
const auto uc = UnresolvedChannel::parse("conda-forge/linux-64/label/foo_dev");
CHECK_EQ(uc.type(), Type::Name);
CHECK_EQ(uc.location(), "conda-forge/label/foo_dev");
CHECK_EQ(uc.platform_filters(), PlatformSet{ "linux-64" });
}
SUBCASE("conda-forge/label/foo_dev[linux-64]")
{
const auto uc = UnresolvedChannel::parse("conda-forge/label/foo_dev[linux-64]");
CHECK_EQ(uc.type(), Type::Name);
CHECK_EQ(uc.location(), "conda-forge/label/foo_dev");
CHECK_EQ(uc.platform_filters(), PlatformSet{ "linux-64" });
}
}
TEST_CASE("str")
{
CHECK_EQ(UnresolvedChannel("location", {}, Type::Name).str(), "location");
CHECK_EQ(
UnresolvedChannel("location", { "linux-64", "noarch" }, Type::Name).str(),
"location[linux-64,noarch]"
);
}
}

View File

@ -717,7 +717,7 @@ bind_submodule_impl(pybind11::module_ m)
py::arg("has_zst")
)
.def("make_channel", py::overload_cast<std::string_view>(&ChannelContext::make_channel))
.def("make_channel", py::overload_cast<specs::ChannelSpec>(&ChannelContext::make_channel))
.def("make_channel", py::overload_cast<specs::UnresolvedChannel>(&ChannelContext::make_channel))
.def("params", &ChannelContext::params)
.def("has_zst", &ChannelContext::has_zst);

View File

@ -11,11 +11,11 @@
#include "mamba/specs/archive.hpp"
#include "mamba/specs/authentication_info.hpp"
#include "mamba/specs/channel.hpp"
#include "mamba/specs/channel_spec.hpp"
#include "mamba/specs/conda_url.hpp"
#include "mamba/specs/match_spec.hpp"
#include "mamba/specs/package_info.hpp"
#include "mamba/specs/platform.hpp"
#include "mamba/specs/unresolved_channel.hpp"
#include "mamba/specs/version.hpp"
#include "mamba/specs/version_spec.hpp"
@ -301,31 +301,32 @@ namespace mambapy
py::arg("credentials") = CondaURL::Credentials::Hide
);
auto py_channel_spec = py::class_<ChannelSpec>(m, "ChannelSpec");
auto py_channel_spec = py::class_<UnresolvedChannel>(m, "UnresolvedChannel");
py::enum_<ChannelSpec::Type>(py_channel_spec, "Type")
.value("URL", ChannelSpec::Type::URL)
.value("PackageURL", ChannelSpec::Type::PackageURL)
.value("Path", ChannelSpec::Type::Path)
.value("PackagePath", ChannelSpec::Type::PackagePath)
.value("Name", ChannelSpec::Type::Name)
.value("Unknown", ChannelSpec::Type::Unknown)
.def(py::init(&enum_from_str<ChannelSpec::Type>));
py::implicitly_convertible<py::str, ChannelSpec::Type>();
py::enum_<UnresolvedChannel::Type>(py_channel_spec, "Type")
.value("URL", UnresolvedChannel::Type::URL)
.value("PackageURL", UnresolvedChannel::Type::PackageURL)
.value("Path", UnresolvedChannel::Type::Path)
.value("PackagePath", UnresolvedChannel::Type::PackagePath)
.value("Name", UnresolvedChannel::Type::Name)
.value("Unknown", UnresolvedChannel::Type::Unknown)
.def(py::init(&enum_from_str<UnresolvedChannel::Type>));
py::implicitly_convertible<py::str, UnresolvedChannel::Type>();
py_channel_spec //
.def_static("parse", ChannelSpec::parse)
.def_static("parse", UnresolvedChannel::parse)
.def(
py::init<std::string, ChannelSpec::dynamic_platform_set, ChannelSpec::Type>(),
py::init<std::string, UnresolvedChannel::dynamic_platform_set, UnresolvedChannel::Type>(
),
py::arg("location"),
py::arg("platform_filters"),
py::arg("type") = ChannelSpec::Type::Unknown
py::arg("type") = UnresolvedChannel::Type::Unknown
)
.def("__copy__", &copy<ChannelSpec>)
.def("__deepcopy__", &deepcopy<ChannelSpec>, py::arg("memo"))
.def_property_readonly("type", &ChannelSpec::type)
.def_property_readonly("location", &ChannelSpec::location)
.def_property_readonly("platform_filters", &ChannelSpec::platform_filters);
.def("__copy__", &copy<UnresolvedChannel>)
.def("__deepcopy__", &deepcopy<UnresolvedChannel>, py::arg("memo"))
.def_property_readonly("type", &UnresolvedChannel::type)
.def_property_readonly("location", &UnresolvedChannel::location)
.def_property_readonly("platform_filters", &UnresolvedChannel::platform_filters);
py::class_<BasicHTTPAuthentication>(m, "BasicHTTPAuthentication")
.def(
@ -440,13 +441,13 @@ namespace mambapy
)
.def_static(
"resolve",
py::overload_cast<ChannelSpec, const ChannelResolveParams&>(&Channel::resolve),
py::arg("spec"),
py::overload_cast<UnresolvedChannel, const ChannelResolveParams&>(&Channel::resolve),
py::arg("what"),
py::arg("params")
)
.def_static(
"resolve",
[](const ChannelSpec& spec,
[](const UnresolvedChannel& what,
const ChannelResolveParams::platform_list& platforms,
const CondaURL& channel_alias,
const ChannelResolveParams::channel_map& custom_channels,
@ -457,7 +458,7 @@ namespace mambapy
)
{
return Channel::resolve(
spec,
what,
ChannelResolveParamsView{
/* .platforms= */ platforms,
/* .channel_alias= */ channel_alias,
@ -470,7 +471,7 @@ namespace mambapy
);
},
// Not really meant to provide sensible defaults, the ChannelContext does that.
py::arg("spec"),
py::arg("what"),
py::arg("platforms") = ChannelResolveParams::platform_list{},
py::arg("channel_alias") = CondaURL{},
py::arg("custom_channels") = ChannelResolveParams::channel_map{},

View File

@ -233,8 +233,8 @@ def test_CondaURL_op():
assert (url / "file.txt").path() == "/folder/file.txt"
def test_ChannelSpec_Type():
Type = libmambapy.specs.ChannelSpec.Type
def test_UnresolvedChannel_Type():
Type = libmambapy.specs.UnresolvedChannel.Type
assert Type.URL.name == "URL"
assert Type.PackageURL.name == "PackageURL"
@ -245,33 +245,33 @@ def test_ChannelSpec_Type():
assert Type("Name").name == "Name"
def test_ChannelSpec():
ChannelSpec = libmambapy.specs.ChannelSpec
def test_UnresolvedChannel():
UnresolvedChannel = libmambapy.specs.UnresolvedChannel
# Constructor
spec = ChannelSpec(
uc = UnresolvedChannel(
location="<unknown>",
platform_filters=set(),
type=ChannelSpec.Type.Unknown,
type=UnresolvedChannel.Type.Unknown,
)
assert spec.location == "<unknown>"
assert spec.platform_filters == set()
assert spec.type == ChannelSpec.Type.Unknown
assert uc.location == "<unknown>"
assert uc.platform_filters == set()
assert uc.type == UnresolvedChannel.Type.Unknown
# Enum cast
spec = ChannelSpec(location="conda-forge", platform_filters=set(), type="Name")
assert spec.type == ChannelSpec.Type.Name
uc = UnresolvedChannel(location="conda-forge", platform_filters=set(), type="Name")
assert uc.type == UnresolvedChannel.Type.Name
# Parser
spec = ChannelSpec.parse("conda-forge[linux-64]")
assert spec.location == "conda-forge"
assert spec.platform_filters == {"linux-64"}
assert spec.type == ChannelSpec.Type.Name
uc = UnresolvedChannel.parse("conda-forge[linux-64]")
assert uc.location == "conda-forge"
assert uc.platform_filters == {"linux-64"}
assert uc.type == UnresolvedChannel.Type.Name
# Copy
other = copy.deepcopy(spec)
assert other.location == spec.location
assert other is not spec
other = copy.deepcopy(uc)
assert other.location == uc.location
assert other is not uc
def test_BasicHTTPAuthentication():
@ -489,7 +489,7 @@ def test_Channel():
def test_Channel_resolve():
Channel = libmambapy.specs.Channel
ChannelSpec = libmambapy.specs.ChannelSpec
UnresolvedChannel = libmambapy.specs.UnresolvedChannel
CondaURL = libmambapy.specs.CondaURL
AuthenticationDataBase = libmambapy.specs.AuthenticationDataBase
BearerToken = libmambapy.specs.BearerToken
@ -501,7 +501,7 @@ def test_Channel_resolve():
cwd = "/tmp/workspace"
chans = Channel.resolve(
spec=ChannelSpec.parse("conda-forge"),
what=UnresolvedChannel.parse("conda-forge"),
platforms=platforms,
channel_alias=channel_alias,
authentication_db=auth_db,
@ -518,7 +518,7 @@ def test_Channel_resolve():
# Custom channel match
custom_channels = Channel.ChannelMap({"best-forge": chan_1})
chans = Channel.resolve(
spec=ChannelSpec.parse("best-forge"),
what=UnresolvedChannel.parse("best-forge"),
platforms=platforms,
channel_alias=channel_alias,
custom_channels=custom_channels,
@ -533,7 +533,7 @@ def test_Channel_resolve():
# Custom multi channel match
custom_multichannels = Channel.MultiChannelMap({"known-forges": [chan_1, chan_2]})
chans = Channel.resolve(
spec=ChannelSpec.parse("known-forges"),
what=UnresolvedChannel.parse("known-forges"),
platforms=platforms,
channel_alias=channel_alias,
custom_channels=custom_channels,