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. and passed explicitly to a few functions.
- ``Channel`` has been redesigned an moved to a new ``libmambapy.specs``. - ``Channel`` has been redesigned an moved to a new ``libmambapy.specs``.
A featureful ``libmambapy.specs.CondaURL`` is used to describe channel URLs. 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``. - ``MatchSpec`` has been redesigned and moved to ``libmambapy.specs``.
The module also includes a platform enumeration, an implementation of ordered ``Version``, and a The module also includes a platform enumeration, an implementation of ordered ``Version``, and a
``VersionSpec`` to match versions. ``VersionSpec`` to match versions.
@ -82,7 +82,7 @@ The main changes are:
- Creation of the ``specs::`` with: - Creation of the ``specs::`` with:
- Implementations of ``Version`` and ``VersionSpec`` for matching versions, - Implementations of ``Version`` and ``VersionSpec`` for matching versions,
- A refactoring of a purely funcitonal ``Channel`` class, - 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 refactored implementation of ``MatchSpec`` using the components above.
- A cleanup of ``ChannelContext`` for be a light proxy and parameter holder wrapping the - A cleanup of ``ChannelContext`` for be a light proxy and parameter holder wrapping the
``specs::Channel``. ``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. 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 A :cpp:type:`UnresolvedChannel <mamba::specs::UnresolvedChannel>` is a lightweight object to represent
channel string, as in passed in the CLI or configuration. 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) It does minimal parsing and can detect the type of ressource (an unresolved name, a URL, a file)
and the platform filters. and the platform filters.
@ -103,11 +105,11 @@ and the platform filters.
import libmambapy.specs as specs 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 uc.location == "https://conda.anaconda.org/conda-forge"
assert cs.platform_filters == {"linux-64"} assert uc.platform_filters == {"linux-64"}
assert cs.type == specs.ChannelSpec.Type.URL assert uc.type == specs.UnresolvedChannel.Type.URL
Dynamic platforms (as in not known by Mamba) can only be detected with the ``[]`` syntax. 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 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 uc.location == "conda-forge"
assert cs.platform_filters == {"prius-avx42"} assert uc.platform_filters == {"prius-avx42"}
assert cs.type == specs.ChannelSpec.Type.Name assert uc.type == specs.UnresolvedChannel.Type.Name
Channel 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. 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 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. 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 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( chan, *_ = specs.Channel.resolve(
spec=cs, uc,
channel_alias="https://repo.mamba.pm" channel_alias="https://repo.mamba.pm"
# ... # ...
) )
assert chan.url.str() == "https://repo.mamba.pm/conda-forge" 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]" assert chan.display_name == "conda-forge[prius-avx42]"
There are no hard-coded names: There are no hard-coded names:
@ -155,9 +157,9 @@ There are no hard-coded names:
import libmambapy.specs as specs import libmambapy.specs as specs
cs = specs.ChannelSpec.parse("defaults") uc = specs.UnresolvedChannel.parse("defaults")
chan, *_ = specs.Channel.resolve( chan, *_ = specs.Channel.resolve(
spec=cs, uc,
channel_alias="https://repo.mamba.pm" 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 import libmambapy.specs as specs
chan_main, *_ = specs.Channel.resolve( chan_main, *_ = specs.Channel.resolve(
spec=specs.ChannelSpec.parse("pkgs/main"), specs.UnresolvedChannel.parse("pkgs/main"),
# ... # ...
) )
chan_r, *_ = specs.Channel.resolve( chan_r, *_ = specs.Channel.resolve(
spec=specs.ChannelSpec.parse("pkgs/r"), specs.UnresolvedChannel.parse("pkgs/r"),
# ... # ...
) )
defaults = specs.Channel.resolve( defaults = specs.Channel.resolve(
spec=specs.ChannelSpec.parse("defaults"), specs.UnresolvedChannel.parse("defaults"),
custom_multichannels=specs.Channel.MultiChannelMap( custom_multichannels=specs.Channel.MultiChannelMap(
{"defaults": [chan_main, chan_r]} {"defaults": [chan_main, chan_r]}
), ),

View File

@ -172,13 +172,13 @@ set(
${LIBMAMBA_SOURCE_DIR}/specs/authentication_info.cpp ${LIBMAMBA_SOURCE_DIR}/specs/authentication_info.cpp
${LIBMAMBA_SOURCE_DIR}/specs/build_number_spec.cpp ${LIBMAMBA_SOURCE_DIR}/specs/build_number_spec.cpp
${LIBMAMBA_SOURCE_DIR}/specs/channel.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/conda_url.cpp
${LIBMAMBA_SOURCE_DIR}/specs/glob_spec.cpp ${LIBMAMBA_SOURCE_DIR}/specs/glob_spec.cpp
${LIBMAMBA_SOURCE_DIR}/specs/match_spec.cpp ${LIBMAMBA_SOURCE_DIR}/specs/match_spec.cpp
${LIBMAMBA_SOURCE_DIR}/specs/package_info.cpp ${LIBMAMBA_SOURCE_DIR}/specs/package_info.cpp
${LIBMAMBA_SOURCE_DIR}/specs/platform.cpp ${LIBMAMBA_SOURCE_DIR}/specs/platform.cpp
${LIBMAMBA_SOURCE_DIR}/specs/repo_data.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.cpp
${LIBMAMBA_SOURCE_DIR}/specs/version_spec.cpp ${LIBMAMBA_SOURCE_DIR}/specs/version_spec.cpp
# Artifacts validation # Artifacts validation
@ -289,13 +289,13 @@ set(
${LIBMAMBA_INCLUDE_DIR}/mamba/specs/authentication_info.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/specs/authentication_info.hpp
${LIBMAMBA_INCLUDE_DIR}/mamba/specs/build_number_spec.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/specs/build_number_spec.hpp
${LIBMAMBA_INCLUDE_DIR}/mamba/specs/channel.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/conda_url.hpp
${LIBMAMBA_INCLUDE_DIR}/mamba/specs/glob_spec.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/specs/glob_spec.hpp
${LIBMAMBA_INCLUDE_DIR}/mamba/specs/match_spec.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/specs/match_spec.hpp
${LIBMAMBA_INCLUDE_DIR}/mamba/specs/package_info.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/specs/package_info.hpp
${LIBMAMBA_INCLUDE_DIR}/mamba/specs/platform.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/specs/platform.hpp
${LIBMAMBA_INCLUDE_DIR}/mamba/specs/repo_data.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.hpp
${LIBMAMBA_INCLUDE_DIR}/mamba/specs/version_spec.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/specs/version_spec.hpp
# Artifacts validation # Artifacts validation

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -105,7 +105,7 @@ namespace mamba
} }
auto ms_modified = ms; 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_version(specs::VersionSpec::parse(solvable->version()));
ms_modified.set_build_string(specs::GlobSpec(std::string(solvable->build_string()))); 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()); 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 display_name = resolve_path_name(uri, params);
auto platforms = ChannelResolveParams::platform_list{}; 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) }; 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); 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_has_scheme(uc.location()));
assert(util::url_get_scheme(spec.location()) != "file"); 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); auto display_name = resolve_url_name(url, params);
set_fallback_credential_from_db(url, params.authentication_db); set_fallback_credential_from_db(url, params.authentication_db);
auto platforms = ChannelResolveParams::platform_list{}; 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) }; return { std::move(url), std::move(display_name), std::move(platforms) };
} }
auto resolve_name_in_custom_channel( auto resolve_name_in_custom_channel(
ChannelSpec&& spec, UnresolvedChannel&& uc,
ChannelResolveParamsView params, ChannelResolveParamsView params,
std::string_view match_name, std::string_view match_name,
const Channel& match_chan const Channel& match_chan
@ -321,17 +321,17 @@ namespace mamba::specs
) -> Channel ) -> Channel
{ {
auto url = match_chan.url(); 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); set_fallback_credential_from_db(url, params.authentication_db);
return { return {
/* url= */ std::move(url), /* url= */ std::move(url),
/* display_name= */ spec.clear_location(), /* display_name= */ uc.clear_location(),
/* platforms= */ make_platforms(spec.clear_platform_filters(), params.platforms), /* platforms= */ make_platforms(uc.clear_platform_filters(), params.platforms),
}; };
} }
auto resolve_name_in_custom_mulitchannels( auto resolve_name_in_custom_mulitchannels(
const ChannelSpec& spec, const UnresolvedChannel& uc,
ChannelResolveParamsView params, ChannelResolveParamsView params,
const Channel::channel_list& matches const Channel::channel_list& matches
) -> Channel::channel_list ) -> Channel::channel_list
@ -346,74 +346,74 @@ namespace mamba::specs
out.emplace_back( out.emplace_back(
/* url= */ std::move(url), /* url= */ std::move(url),
/* display_name= */ chan.display_name(), // Not using multi_channel name /* 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; 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; auto url = params.channel_alias;
url.append_path(spec.location()); url.append_path(uc.location());
set_fallback_credential_from_db(url, params.authentication_db); set_fallback_credential_from_db(url, params.authentication_db);
return { return {
/* url= */ std::move(url), /* url= */ std::move(url),
/* display_name= */ spec.clear_location(), /* display_name= */ uc.clear_location(),
/* platforms= */ make_platforms(spec.clear_platform_filters(), params.platforms), /* 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()) it != params.custom_channels.cend())
{ {
return { return { resolve_name_in_custom_channel(std::move(uc), params, it->first, it->second) };
resolve_name_in_custom_channel(std::move(spec), 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()) 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 UnresolvedChannel::Type::PackagePath:
case ChannelSpec::Type::Path: case UnresolvedChannel::Type::Path:
{ {
return { resolve_path(std::move(spec), params) }; return { resolve_path(std::move(uc), params) };
} }
case ChannelSpec::Type::PackageURL: case UnresolvedChannel::Type::PackageURL:
case ChannelSpec::Type::URL: 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( return resolve(
std::move(spec), std::move(uc),
ChannelResolveParamsView{ ChannelResolveParamsView{
/* .platforms= */ params.platforms, /* .platforms= */ params.platforms,
/* .channel_alias= */ params.channel_alias, /* .channel_alias= */ params.channel_alias,

View File

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

View File

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

View File

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

View File

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

View File

@ -11,11 +11,11 @@
#include "mamba/specs/archive.hpp" #include "mamba/specs/archive.hpp"
#include "mamba/specs/authentication_info.hpp" #include "mamba/specs/authentication_info.hpp"
#include "mamba/specs/channel.hpp" #include "mamba/specs/channel.hpp"
#include "mamba/specs/channel_spec.hpp"
#include "mamba/specs/conda_url.hpp" #include "mamba/specs/conda_url.hpp"
#include "mamba/specs/match_spec.hpp" #include "mamba/specs/match_spec.hpp"
#include "mamba/specs/package_info.hpp" #include "mamba/specs/package_info.hpp"
#include "mamba/specs/platform.hpp" #include "mamba/specs/platform.hpp"
#include "mamba/specs/unresolved_channel.hpp"
#include "mamba/specs/version.hpp" #include "mamba/specs/version.hpp"
#include "mamba/specs/version_spec.hpp" #include "mamba/specs/version_spec.hpp"
@ -301,31 +301,32 @@ namespace mambapy
py::arg("credentials") = CondaURL::Credentials::Hide 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") py::enum_<UnresolvedChannel::Type>(py_channel_spec, "Type")
.value("URL", ChannelSpec::Type::URL) .value("URL", UnresolvedChannel::Type::URL)
.value("PackageURL", ChannelSpec::Type::PackageURL) .value("PackageURL", UnresolvedChannel::Type::PackageURL)
.value("Path", ChannelSpec::Type::Path) .value("Path", UnresolvedChannel::Type::Path)
.value("PackagePath", ChannelSpec::Type::PackagePath) .value("PackagePath", UnresolvedChannel::Type::PackagePath)
.value("Name", ChannelSpec::Type::Name) .value("Name", UnresolvedChannel::Type::Name)
.value("Unknown", ChannelSpec::Type::Unknown) .value("Unknown", UnresolvedChannel::Type::Unknown)
.def(py::init(&enum_from_str<ChannelSpec::Type>)); .def(py::init(&enum_from_str<UnresolvedChannel::Type>));
py::implicitly_convertible<py::str, ChannelSpec::Type>(); py::implicitly_convertible<py::str, UnresolvedChannel::Type>();
py_channel_spec // py_channel_spec //
.def_static("parse", ChannelSpec::parse) .def_static("parse", UnresolvedChannel::parse)
.def( .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("location"),
py::arg("platform_filters"), py::arg("platform_filters"),
py::arg("type") = ChannelSpec::Type::Unknown py::arg("type") = UnresolvedChannel::Type::Unknown
) )
.def("__copy__", &copy<ChannelSpec>) .def("__copy__", &copy<UnresolvedChannel>)
.def("__deepcopy__", &deepcopy<ChannelSpec>, py::arg("memo")) .def("__deepcopy__", &deepcopy<UnresolvedChannel>, py::arg("memo"))
.def_property_readonly("type", &ChannelSpec::type) .def_property_readonly("type", &UnresolvedChannel::type)
.def_property_readonly("location", &ChannelSpec::location) .def_property_readonly("location", &UnresolvedChannel::location)
.def_property_readonly("platform_filters", &ChannelSpec::platform_filters); .def_property_readonly("platform_filters", &UnresolvedChannel::platform_filters);
py::class_<BasicHTTPAuthentication>(m, "BasicHTTPAuthentication") py::class_<BasicHTTPAuthentication>(m, "BasicHTTPAuthentication")
.def( .def(
@ -440,13 +441,13 @@ namespace mambapy
) )
.def_static( .def_static(
"resolve", "resolve",
py::overload_cast<ChannelSpec, const ChannelResolveParams&>(&Channel::resolve), py::overload_cast<UnresolvedChannel, const ChannelResolveParams&>(&Channel::resolve),
py::arg("spec"), py::arg("what"),
py::arg("params") py::arg("params")
) )
.def_static( .def_static(
"resolve", "resolve",
[](const ChannelSpec& spec, [](const UnresolvedChannel& what,
const ChannelResolveParams::platform_list& platforms, const ChannelResolveParams::platform_list& platforms,
const CondaURL& channel_alias, const CondaURL& channel_alias,
const ChannelResolveParams::channel_map& custom_channels, const ChannelResolveParams::channel_map& custom_channels,
@ -457,7 +458,7 @@ namespace mambapy
) )
{ {
return Channel::resolve( return Channel::resolve(
spec, what,
ChannelResolveParamsView{ ChannelResolveParamsView{
/* .platforms= */ platforms, /* .platforms= */ platforms,
/* .channel_alias= */ channel_alias, /* .channel_alias= */ channel_alias,
@ -470,7 +471,7 @@ namespace mambapy
); );
}, },
// Not really meant to provide sensible defaults, the ChannelContext does that. // 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("platforms") = ChannelResolveParams::platform_list{},
py::arg("channel_alias") = CondaURL{}, py::arg("channel_alias") = CondaURL{},
py::arg("custom_channels") = ChannelResolveParams::channel_map{}, 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" assert (url / "file.txt").path() == "/folder/file.txt"
def test_ChannelSpec_Type(): def test_UnresolvedChannel_Type():
Type = libmambapy.specs.ChannelSpec.Type Type = libmambapy.specs.UnresolvedChannel.Type
assert Type.URL.name == "URL" assert Type.URL.name == "URL"
assert Type.PackageURL.name == "PackageURL" assert Type.PackageURL.name == "PackageURL"
@ -245,33 +245,33 @@ def test_ChannelSpec_Type():
assert Type("Name").name == "Name" assert Type("Name").name == "Name"
def test_ChannelSpec(): def test_UnresolvedChannel():
ChannelSpec = libmambapy.specs.ChannelSpec UnresolvedChannel = libmambapy.specs.UnresolvedChannel
# Constructor # Constructor
spec = ChannelSpec( uc = UnresolvedChannel(
location="<unknown>", location="<unknown>",
platform_filters=set(), platform_filters=set(),
type=ChannelSpec.Type.Unknown, type=UnresolvedChannel.Type.Unknown,
) )
assert spec.location == "<unknown>" assert uc.location == "<unknown>"
assert spec.platform_filters == set() assert uc.platform_filters == set()
assert spec.type == ChannelSpec.Type.Unknown assert uc.type == UnresolvedChannel.Type.Unknown
# Enum cast # Enum cast
spec = ChannelSpec(location="conda-forge", platform_filters=set(), type="Name") uc = UnresolvedChannel(location="conda-forge", platform_filters=set(), type="Name")
assert spec.type == ChannelSpec.Type.Name assert uc.type == UnresolvedChannel.Type.Name
# Parser # Parser
spec = ChannelSpec.parse("conda-forge[linux-64]") uc = UnresolvedChannel.parse("conda-forge[linux-64]")
assert spec.location == "conda-forge" assert uc.location == "conda-forge"
assert spec.platform_filters == {"linux-64"} assert uc.platform_filters == {"linux-64"}
assert spec.type == ChannelSpec.Type.Name assert uc.type == UnresolvedChannel.Type.Name
# Copy # Copy
other = copy.deepcopy(spec) other = copy.deepcopy(uc)
assert other.location == spec.location assert other.location == uc.location
assert other is not spec assert other is not uc
def test_BasicHTTPAuthentication(): def test_BasicHTTPAuthentication():
@ -489,7 +489,7 @@ def test_Channel():
def test_Channel_resolve(): def test_Channel_resolve():
Channel = libmambapy.specs.Channel Channel = libmambapy.specs.Channel
ChannelSpec = libmambapy.specs.ChannelSpec UnresolvedChannel = libmambapy.specs.UnresolvedChannel
CondaURL = libmambapy.specs.CondaURL CondaURL = libmambapy.specs.CondaURL
AuthenticationDataBase = libmambapy.specs.AuthenticationDataBase AuthenticationDataBase = libmambapy.specs.AuthenticationDataBase
BearerToken = libmambapy.specs.BearerToken BearerToken = libmambapy.specs.BearerToken
@ -501,7 +501,7 @@ def test_Channel_resolve():
cwd = "/tmp/workspace" cwd = "/tmp/workspace"
chans = Channel.resolve( chans = Channel.resolve(
spec=ChannelSpec.parse("conda-forge"), what=UnresolvedChannel.parse("conda-forge"),
platforms=platforms, platforms=platforms,
channel_alias=channel_alias, channel_alias=channel_alias,
authentication_db=auth_db, authentication_db=auth_db,
@ -518,7 +518,7 @@ def test_Channel_resolve():
# Custom channel match # Custom channel match
custom_channels = Channel.ChannelMap({"best-forge": chan_1}) custom_channels = Channel.ChannelMap({"best-forge": chan_1})
chans = Channel.resolve( chans = Channel.resolve(
spec=ChannelSpec.parse("best-forge"), what=UnresolvedChannel.parse("best-forge"),
platforms=platforms, platforms=platforms,
channel_alias=channel_alias, channel_alias=channel_alias,
custom_channels=custom_channels, custom_channels=custom_channels,
@ -533,7 +533,7 @@ def test_Channel_resolve():
# Custom multi channel match # Custom multi channel match
custom_multichannels = Channel.MultiChannelMap({"known-forges": [chan_1, chan_2]}) custom_multichannels = Channel.MultiChannelMap({"known-forges": [chan_1, chan_2]})
chans = Channel.resolve( chans = Channel.resolve(
spec=ChannelSpec.parse("known-forges"), what=UnresolvedChannel.parse("known-forges"),
platforms=platforms, platforms=platforms,
channel_alias=channel_alias, channel_alias=channel_alias,
custom_channels=custom_channels, custom_channels=custom_channels,