mirror of https://github.com/mamba-org/mamba.git
Change MatchSpec::parse to named constructor (#3048)
This commit is contained in:
parent
96e9be052b
commit
f36c3f222e
|
@ -14,6 +14,7 @@
|
|||
#include <solv/solver.h>
|
||||
#include <yaml-cpp/yaml.h>
|
||||
|
||||
#include "mamba/core/match_spec.hpp"
|
||||
#include "mamba/core/package_cache.hpp"
|
||||
#include "mamba/core/package_info.hpp"
|
||||
#include "mamba/core/pool.hpp"
|
||||
|
@ -87,11 +88,8 @@ namespace mamba
|
|||
|
||||
yaml_file_contents read_yaml_file(fs::u8path yaml_file, const std::string platform);
|
||||
|
||||
std::tuple<std::vector<PackageInfo>, std::vector<MatchSpec>> parse_urls_to_package_info(
|
||||
const std::vector<std::string>& urls,
|
||||
Context& ctx,
|
||||
ChannelContext& channel_context
|
||||
);
|
||||
std::tuple<std::vector<PackageInfo>, std::vector<MatchSpec>>
|
||||
parse_urls_to_package_info(const std::vector<std::string>& urls);
|
||||
|
||||
inline void to_json(nlohmann::json&, const other_pkg_mgr_spec&)
|
||||
{
|
||||
|
|
|
@ -113,11 +113,8 @@ namespace mamba
|
|||
|
||||
/// Read an environment lock YAML file and returns it's structured content or an error if
|
||||
/// failed.
|
||||
tl::expected<EnvironmentLockFile, mamba_error> read_environment_lockfile(
|
||||
const Context& ctx,
|
||||
ChannelContext& channel_context,
|
||||
const mamba::fs::u8path& lockfile_location
|
||||
);
|
||||
tl::expected<EnvironmentLockFile, mamba_error>
|
||||
read_environment_lockfile(const mamba::fs::u8path& lockfile_location);
|
||||
|
||||
|
||||
/// Returns `true` if the filename matches names of files which should be interpreted as conda
|
||||
|
|
|
@ -52,7 +52,7 @@ namespace mamba
|
|||
std::vector<ParseResult> parse();
|
||||
bool parse_comment_line(const std::string& line, UserRequest& req);
|
||||
std::vector<UserRequest> get_user_requests();
|
||||
std::unordered_map<std::string, MatchSpec> get_requested_specs_map(const Context& ctx);
|
||||
std::unordered_map<std::string, MatchSpec> get_requested_specs_map();
|
||||
void add_entry(const History::UserRequest& entry);
|
||||
|
||||
fs::u8path m_prefix;
|
||||
|
|
|
@ -17,25 +17,18 @@
|
|||
|
||||
namespace mamba
|
||||
{
|
||||
class Context;
|
||||
class ChannelContext;
|
||||
|
||||
class MatchSpec
|
||||
{
|
||||
public:
|
||||
|
||||
MatchSpec() = default;
|
||||
[[nodiscard]] static auto parse_version_and_build(std::string_view s)
|
||||
-> std::tuple<std::string, std::string>;
|
||||
[[nodiscard]] static auto parse(std::string_view spec) -> MatchSpec;
|
||||
|
||||
MatchSpec(std::string_view i_spec);
|
||||
[[nodiscard]] auto conda_build_form() const -> std::string;
|
||||
[[nodiscard]] auto str() const -> std::string;
|
||||
|
||||
void parse();
|
||||
std::string conda_build_form() const;
|
||||
std::string str() const;
|
||||
|
||||
bool is_simple() const;
|
||||
|
||||
static std::tuple<std::string, std::string> parse_version_and_build(std::string_view s);
|
||||
std::string spec;
|
||||
[[nodiscard]] auto is_simple() const -> bool;
|
||||
|
||||
std::optional<specs::ChannelSpec> channel;
|
||||
std::string name;
|
||||
|
@ -51,6 +44,5 @@ namespace mamba
|
|||
std::unordered_map<std::string, std::string> brackets;
|
||||
std::unordered_map<std::string, std::string> parens;
|
||||
};
|
||||
} // namespace mamba
|
||||
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -20,12 +20,7 @@ namespace mamba
|
|||
class u8path;
|
||||
}
|
||||
|
||||
std::string python_pin(
|
||||
const Context& ctx,
|
||||
ChannelContext& chc,
|
||||
PrefixData& prefix_data,
|
||||
const std::vector<std::string>& specs
|
||||
);
|
||||
std::string python_pin(PrefixData& prefix_data, const std::vector<std::string>& specs);
|
||||
|
||||
std::vector<std::string> file_pins(const fs::u8path& file);
|
||||
}
|
||||
|
|
|
@ -342,11 +342,8 @@ namespace mamba
|
|||
return result;
|
||||
}
|
||||
|
||||
std::tuple<std::vector<PackageInfo>, std::vector<MatchSpec>> parse_urls_to_package_info(
|
||||
const std::vector<std::string>& urls,
|
||||
Context& ctx,
|
||||
ChannelContext& channel_context
|
||||
)
|
||||
std::tuple<std::vector<PackageInfo>, std::vector<MatchSpec>>
|
||||
parse_urls_to_package_info(const std::vector<std::string>& urls)
|
||||
{
|
||||
std::vector<PackageInfo> pi_result;
|
||||
std::vector<MatchSpec> ms_result;
|
||||
|
@ -357,7 +354,7 @@ namespace mamba
|
|||
continue;
|
||||
}
|
||||
std::size_t hash = u.find_first_of('#');
|
||||
MatchSpec ms(u.substr(0, hash));
|
||||
auto ms = MatchSpec::parse(u.substr(0, hash));
|
||||
PackageInfo p(ms.name);
|
||||
p.url = ms.url;
|
||||
p.build_string = ms.build_string;
|
||||
|
@ -479,9 +476,9 @@ namespace mamba
|
|||
// add channels from specs
|
||||
for (const auto& s : specs)
|
||||
{
|
||||
if (auto m = MatchSpec{ s }; m.channel.has_value())
|
||||
if (auto ms = MatchSpec::parse(s); ms.channel.has_value())
|
||||
{
|
||||
ctx.channels.push_back(m.channel->str());
|
||||
ctx.channels.push_back(ms.channel->str());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -553,7 +550,7 @@ namespace mamba
|
|||
|
||||
if (!no_py_pin)
|
||||
{
|
||||
auto py_pin = python_pin(ctx, channel_context, prefix_data, specs);
|
||||
auto py_pin = python_pin(prefix_data, specs);
|
||||
if (!py_pin.empty())
|
||||
{
|
||||
solver.add_pin(py_pin);
|
||||
|
|
|
@ -95,7 +95,7 @@ namespace mamba
|
|||
formatted_pkg formatted_pkgs;
|
||||
|
||||
std::vector<formatted_pkg> packages;
|
||||
auto requested_specs = prefix_data.history().get_requested_specs_map(ctx);
|
||||
auto requested_specs = prefix_data.history().get_requested_specs_map();
|
||||
|
||||
// order list of packages from prefix_data by alphabetical order
|
||||
for (const auto& package : prefix_data.records())
|
||||
|
|
|
@ -113,7 +113,7 @@ namespace mamba
|
|||
specs.begin(),
|
||||
specs.end(),
|
||||
std::back_inserter(mspecs),
|
||||
[&](const auto& spec_str) { return MatchSpec{ spec_str }; }
|
||||
[&](const auto& spec_str) { return MatchSpec::parse(spec_str); }
|
||||
);
|
||||
auto transaction = MTransaction(pool, mspecs, {}, package_caches);
|
||||
execute_transaction(transaction);
|
||||
|
@ -131,7 +131,7 @@ namespace mamba
|
|||
);
|
||||
|
||||
History history(ctx.prefix_params.target_prefix, channel_context);
|
||||
auto hist_map = history.get_requested_specs_map(ctx);
|
||||
auto hist_map = history.get_requested_specs_map();
|
||||
std::vector<std::string> keep_specs;
|
||||
for (auto& it : hist_map)
|
||||
{
|
||||
|
|
|
@ -38,7 +38,7 @@ namespace mamba
|
|||
// add channels from specs
|
||||
for (const auto& s : update_specs)
|
||||
{
|
||||
if (auto m = MatchSpec{ s }; m.channel.has_value())
|
||||
if (auto m = MatchSpec::parse(s); m.channel.has_value())
|
||||
{
|
||||
ctx.channels.push_back(m.channel->str());
|
||||
}
|
||||
|
@ -93,7 +93,7 @@ namespace mamba
|
|||
|
||||
if (!no_py_pin)
|
||||
{
|
||||
auto py_pin = python_pin(ctx, channel_context, prefix_data, update_specs);
|
||||
auto py_pin = python_pin(prefix_data, update_specs);
|
||||
if (!py_pin.empty())
|
||||
{
|
||||
solver.add_pin(py_pin);
|
||||
|
@ -114,7 +114,7 @@ namespace mamba
|
|||
|
||||
if (update_all)
|
||||
{
|
||||
auto hist_map = prefix_data.history().get_requested_specs_map(ctx);
|
||||
auto hist_map = prefix_data.history().get_requested_specs_map();
|
||||
std::vector<std::string> keep_specs;
|
||||
for (auto& it : hist_map)
|
||||
{
|
||||
|
@ -132,7 +132,7 @@ namespace mamba
|
|||
{
|
||||
if (remove_not_specified)
|
||||
{
|
||||
auto hist_map = prefix_data.history().get_requested_specs_map(ctx);
|
||||
auto hist_map = prefix_data.history().get_requested_specs_map();
|
||||
std::vector<std::string> remove_specs;
|
||||
for (auto& it : hist_map)
|
||||
{
|
||||
|
|
|
@ -18,8 +18,7 @@ namespace mamba
|
|||
{
|
||||
using Package = EnvironmentLockFile::Package;
|
||||
|
||||
tl::expected<Package, mamba_error>
|
||||
read_package_info(const Context& ctx, ChannelContext& channel_context, const YAML::Node& package_node)
|
||||
tl::expected<Package, mamba_error> read_package_info(const YAML::Node& package_node)
|
||||
{
|
||||
Package package{
|
||||
/* .info = */ mamba::PackageInfo{ package_node["name"].as<std::string>() },
|
||||
|
@ -57,7 +56,7 @@ namespace mamba
|
|||
}
|
||||
|
||||
package.info.url = package_node["url"].as<std::string>();
|
||||
const MatchSpec spec{ package.info.url };
|
||||
const auto spec = MatchSpec::parse(package.info.url);
|
||||
package.info.fn = spec.fn;
|
||||
package.info.build_string = spec.build_string;
|
||||
if (spec.channel.has_value())
|
||||
|
@ -152,11 +151,8 @@ namespace mamba
|
|||
return metadata;
|
||||
}
|
||||
|
||||
tl::expected<EnvironmentLockFile, mamba_error> read_environment_lockfile(
|
||||
const Context& ctx,
|
||||
ChannelContext& channel_context,
|
||||
const YAML::Node& lockfile_yaml
|
||||
)
|
||||
tl::expected<EnvironmentLockFile, mamba_error>
|
||||
read_environment_lockfile(const YAML::Node& lockfile_yaml)
|
||||
{
|
||||
const auto& maybe_metadata = read_metadata(lockfile_yaml["metadata"]);
|
||||
if (!maybe_metadata)
|
||||
|
@ -169,7 +165,7 @@ namespace mamba
|
|||
std::vector<Package> packages;
|
||||
for (const auto& package_node : lockfile_yaml["package"])
|
||||
{
|
||||
if (auto maybe_package = read_package_info(ctx, channel_context, package_node))
|
||||
if (auto maybe_package = read_package_info(package_node))
|
||||
{
|
||||
packages.push_back(maybe_package.value());
|
||||
}
|
||||
|
@ -183,11 +179,8 @@ namespace mamba
|
|||
}
|
||||
}
|
||||
|
||||
tl::expected<EnvironmentLockFile, mamba_error> read_environment_lockfile(
|
||||
const Context& ctx,
|
||||
ChannelContext& channel_context,
|
||||
const fs::u8path& lockfile_location
|
||||
)
|
||||
tl::expected<EnvironmentLockFile, mamba_error>
|
||||
read_environment_lockfile(const fs::u8path& lockfile_location)
|
||||
{
|
||||
const auto file_path = fs::absolute(lockfile_location); // Having the complete path helps
|
||||
// with logging and error reports.
|
||||
|
@ -199,11 +192,7 @@ namespace mamba
|
|||
switch (lockfile_version)
|
||||
{
|
||||
case 1:
|
||||
return env_lockfile_v1::read_environment_lockfile(
|
||||
ctx,
|
||||
channel_context,
|
||||
lockfile_content
|
||||
);
|
||||
return env_lockfile_v1::read_environment_lockfile(lockfile_content);
|
||||
|
||||
default:
|
||||
{
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
#include <regex>
|
||||
|
||||
#include "mamba/core/channel_context.hpp"
|
||||
#include "mamba/core/context.hpp"
|
||||
#include "mamba/core/fsutil.hpp"
|
||||
#include "mamba/core/history.hpp"
|
||||
|
@ -190,7 +191,7 @@ namespace mamba
|
|||
return res;
|
||||
}
|
||||
|
||||
std::unordered_map<std::string, MatchSpec> History::get_requested_specs_map(const Context& ctx)
|
||||
std::unordered_map<std::string, MatchSpec> History::get_requested_specs_map()
|
||||
{
|
||||
std::unordered_map<std::string, MatchSpec> map;
|
||||
|
||||
|
@ -200,7 +201,7 @@ namespace mamba
|
|||
v.reserve(sv.size());
|
||||
for (const auto& el : sv)
|
||||
{
|
||||
v.emplace_back(el);
|
||||
v.emplace_back(MatchSpec::parse(el));
|
||||
}
|
||||
return v;
|
||||
};
|
||||
|
|
|
@ -10,8 +10,6 @@
|
|||
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include "mamba/core/channel_context.hpp"
|
||||
#include "mamba/core/context.hpp"
|
||||
#include "mamba/core/match_spec.hpp"
|
||||
#include "mamba/core/output.hpp"
|
||||
#include "mamba/specs/archive.hpp"
|
||||
|
@ -23,7 +21,7 @@ namespace mamba
|
|||
{
|
||||
namespace
|
||||
{
|
||||
std::vector<std::string> parse_legacy_dist(std::string_view dist)
|
||||
auto parse_legacy_dist(std::string_view dist) -> std::vector<std::string>
|
||||
{
|
||||
auto dist_str = std::string(specs::strip_archive_extension(dist));
|
||||
auto split_str = util::rsplit(dist_str, "-", 2);
|
||||
|
@ -36,13 +34,8 @@ namespace mamba
|
|||
}
|
||||
}
|
||||
|
||||
MatchSpec::MatchSpec(std::string_view i_spec)
|
||||
: spec(i_spec)
|
||||
{
|
||||
parse();
|
||||
}
|
||||
|
||||
std::tuple<std::string, std::string> MatchSpec::parse_version_and_build(std::string_view s)
|
||||
auto MatchSpec::parse_version_and_build(std::string_view s)
|
||||
-> std::tuple<std::string, std::string>
|
||||
{
|
||||
const std::size_t pos = s.find_last_of(" =");
|
||||
if (pos == s.npos || pos == 0)
|
||||
|
@ -75,16 +68,16 @@ namespace mamba
|
|||
}
|
||||
}
|
||||
|
||||
void MatchSpec::parse()
|
||||
auto MatchSpec::parse(std::string_view spec) -> MatchSpec
|
||||
{
|
||||
std::string spec_str = spec;
|
||||
auto spec_str = std::string(spec);
|
||||
auto out = MatchSpec();
|
||||
if (spec_str.empty())
|
||||
{
|
||||
return;
|
||||
return out;
|
||||
}
|
||||
LOG_INFO << "Parsing MatchSpec " << spec;
|
||||
std::size_t idx = spec_str.find('#');
|
||||
if (idx != std::string::npos)
|
||||
|
||||
if (std::size_t idx = spec_str.find('#'); idx != std::string::npos)
|
||||
{
|
||||
spec_str = spec_str.substr(0, idx);
|
||||
}
|
||||
|
@ -92,16 +85,16 @@ namespace mamba
|
|||
|
||||
if (specs::has_archive_extension(spec_str))
|
||||
{
|
||||
channel = specs::ChannelSpec::parse(spec_str);
|
||||
auto [path, pkg] = util::rsplit_once(channel->location(), '/');
|
||||
out.channel = specs::ChannelSpec::parse(spec_str);
|
||||
auto [path, pkg] = util::rsplit_once(out.channel->location(), '/');
|
||||
auto dist = parse_legacy_dist(pkg);
|
||||
name = dist[0];
|
||||
version = dist[1];
|
||||
build_string = dist[2];
|
||||
fn = std::string(pkg);
|
||||
url = util::path_or_url_to_url(spec_str);
|
||||
is_file = true;
|
||||
return;
|
||||
out.name = dist[0];
|
||||
out.version = dist[1];
|
||||
out.build_string = dist[2];
|
||||
out.fn = std::string(pkg);
|
||||
out.url = util::path_or_url_to_url(spec_str);
|
||||
out.is_file = true;
|
||||
return out;
|
||||
}
|
||||
|
||||
auto extract_kv = [&spec_str](const std::string& kv_string, auto& map)
|
||||
|
@ -116,7 +109,9 @@ namespace mamba
|
|||
auto value = kv_match[3].str();
|
||||
if (key.size() == 0 || value.size() == 0)
|
||||
{
|
||||
throw std::runtime_error("key-value mismatch in brackets " + spec_str);
|
||||
throw std::runtime_error(
|
||||
util::concat(R"(key-value mismatch in brackets ")", spec_str, '"')
|
||||
);
|
||||
}
|
||||
text_iter += kv_match.position() + kv_match.length();
|
||||
map[key] = value;
|
||||
|
@ -131,7 +126,7 @@ namespace mamba
|
|||
{
|
||||
auto brackets_str = match[1].str();
|
||||
brackets_str = brackets_str.substr(1, brackets_str.size() - 2);
|
||||
extract_kv(brackets_str, brackets);
|
||||
extract_kv(brackets_str, out.brackets);
|
||||
spec_str.erase(
|
||||
static_cast<std::size_t>(match.position(1)),
|
||||
static_cast<std::size_t>(match.length(1))
|
||||
|
@ -144,10 +139,10 @@ namespace mamba
|
|||
{
|
||||
auto parens_str = match[1].str();
|
||||
parens_str = parens_str.substr(1, parens_str.size() - 2);
|
||||
extract_kv(parens_str, this->parens);
|
||||
extract_kv(parens_str, out.parens);
|
||||
if (parens_str.find("optional") != parens_str.npos)
|
||||
{
|
||||
optional = true;
|
||||
out.optional = true;
|
||||
}
|
||||
spec_str.erase(
|
||||
static_cast<std::size_t>(match.position(1)),
|
||||
|
@ -160,13 +155,13 @@ namespace mamba
|
|||
std::string channel_str;
|
||||
if (m5_len == 3)
|
||||
{
|
||||
channel = specs::ChannelSpec::parse(m5[0]);
|
||||
ns = m5[1];
|
||||
out.channel = specs::ChannelSpec::parse(m5[0]);
|
||||
out.ns = m5[1];
|
||||
spec_str = m5[2];
|
||||
}
|
||||
else if (m5_len == 2)
|
||||
{
|
||||
ns = m5[0];
|
||||
out.ns = m5[0];
|
||||
spec_str = m5[1];
|
||||
}
|
||||
else if (m5_len == 1)
|
||||
|
@ -195,9 +190,9 @@ namespace mamba
|
|||
std::smatch vb_match;
|
||||
if (std::regex_match(spec_str, vb_match, version_build_re))
|
||||
{
|
||||
name = vb_match[1].str();
|
||||
version = util::strip(vb_match[2].str());
|
||||
if (name.size() == 0)
|
||||
out.name = vb_match[1].str();
|
||||
out.version = util::strip(vb_match[2].str());
|
||||
if (out.name.size() == 0)
|
||||
{
|
||||
throw std::runtime_error("Invalid spec, no package name found: " + spec_str);
|
||||
}
|
||||
|
@ -209,113 +204,120 @@ namespace mamba
|
|||
|
||||
// # Step 7. otherwise sort out version + build
|
||||
// spec_str = spec_str and spec_str.strip()
|
||||
if (!version.empty())
|
||||
if (!out.version.empty())
|
||||
{
|
||||
if (version.find("[") != version.npos)
|
||||
if (out.version.find('[') != out.version.npos)
|
||||
{
|
||||
throw std::runtime_error(
|
||||
"Invalid match spec: multiple bracket sections not allowed " + spec
|
||||
);
|
||||
throw std::runtime_error(util::concat(
|
||||
R"(Invalid match spec: multiple bracket sections not allowed ")",
|
||||
spec,
|
||||
'"'
|
||||
));
|
||||
}
|
||||
|
||||
version = std::string(util::strip(version));
|
||||
auto [pv, pb] = parse_version_and_build(std::string(util::strip(version)));
|
||||
out.version = std::string(util::strip(out.version));
|
||||
auto [pv, pb] = parse_version_and_build(std::string(util::strip(out.version)));
|
||||
|
||||
version = pv;
|
||||
build_string = pb;
|
||||
out.version = pv;
|
||||
out.build_string = pb;
|
||||
|
||||
// translate version '=1.2.3' to '1.2.3*'
|
||||
// is it a simple version starting with '='? i.e. '=1.2.3'
|
||||
if (version.size() >= 2 && version[0] == '=')
|
||||
if (out.version.size() >= 2 && out.version[0] == '=')
|
||||
{
|
||||
auto rest = version.substr(1);
|
||||
if (version[1] == '=' && build_string.empty())
|
||||
auto rest = out.version.substr(1);
|
||||
if (out.version[1] == '=' && out.build_string.empty())
|
||||
{
|
||||
version = version.substr(2);
|
||||
out.version = out.version.substr(2);
|
||||
}
|
||||
else if (rest.find_first_of("=,|") == rest.npos)
|
||||
{
|
||||
if (build_string.empty() && version.back() != '*')
|
||||
if (out.build_string.empty() && out.version.back() != '*')
|
||||
{
|
||||
version = util::concat(version, "*");
|
||||
out.version = util::concat(out.version, "*");
|
||||
}
|
||||
else
|
||||
{
|
||||
version = rest;
|
||||
out.version = rest;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
version = "";
|
||||
build_string = "";
|
||||
out.version = "";
|
||||
out.build_string = "";
|
||||
}
|
||||
|
||||
// TODO think about using a hash function here, (and elsewhere), like:
|
||||
// https://hbfs.wordpress.com/2017/01/10/strings-in-c-switchcase-statements/
|
||||
|
||||
for (auto& [k, v] : brackets)
|
||||
for (auto& [k, v] : out.brackets)
|
||||
{
|
||||
if (k == "build_number")
|
||||
{
|
||||
build_number = v;
|
||||
out.build_number = v;
|
||||
}
|
||||
else if (k == "build")
|
||||
{
|
||||
build_string = v;
|
||||
out.build_string = v;
|
||||
}
|
||||
else if (k == "version")
|
||||
{
|
||||
version = v;
|
||||
out.version = v;
|
||||
}
|
||||
else if (k == "channel")
|
||||
{
|
||||
if (!channel.has_value())
|
||||
if (!out.channel.has_value())
|
||||
{
|
||||
channel = specs::ChannelSpec::parse(v);
|
||||
out.channel = specs::ChannelSpec::parse(v);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Subdirs might have been set with a previous subdir key
|
||||
auto subdirs = channel->clear_platform_filters();
|
||||
channel = specs::ChannelSpec::parse(v);
|
||||
auto subdirs = out.channel->clear_platform_filters();
|
||||
out.channel = specs::ChannelSpec::parse(v);
|
||||
if (!subdirs.empty())
|
||||
{
|
||||
channel = specs::ChannelSpec(
|
||||
channel->clear_location(),
|
||||
out.channel = specs::ChannelSpec(
|
||||
out.channel->clear_location(),
|
||||
std::move(subdirs),
|
||||
channel->type()
|
||||
out.channel->type()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (k == "subdir")
|
||||
{
|
||||
if (!channel.has_value())
|
||||
if (!out.channel.has_value())
|
||||
{
|
||||
channel = specs::ChannelSpec("", { v }, specs::ChannelSpec::Type::Unknown);
|
||||
out.channel = specs::ChannelSpec("", { v }, specs::ChannelSpec::Type::Unknown);
|
||||
}
|
||||
// Subdirs specified in the channel part have higher precedence
|
||||
else if (channel->platform_filters().empty())
|
||||
else if (out.channel->platform_filters().empty())
|
||||
{
|
||||
channel = specs::ChannelSpec(channel->clear_location(), { v }, channel->type());
|
||||
out.channel = specs::ChannelSpec(
|
||||
out.channel->clear_location(),
|
||||
{ v },
|
||||
out.channel->type()
|
||||
);
|
||||
}
|
||||
}
|
||||
else if (k == "url")
|
||||
{
|
||||
is_file = true;
|
||||
url = v;
|
||||
out.is_file = true;
|
||||
out.url = v;
|
||||
}
|
||||
else if (k == "fn")
|
||||
{
|
||||
is_file = true;
|
||||
fn = v;
|
||||
out.is_file = true;
|
||||
out.fn = v;
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
std::string MatchSpec::conda_build_form() const
|
||||
auto MatchSpec::conda_build_form() const -> std::string
|
||||
{
|
||||
std::stringstream res;
|
||||
res << name;
|
||||
|
@ -331,7 +333,7 @@ namespace mamba
|
|||
return res.str();
|
||||
}
|
||||
|
||||
std::string MatchSpec::str() const
|
||||
auto MatchSpec::str() const -> std::string
|
||||
{
|
||||
std::stringstream res;
|
||||
// builder = []
|
||||
|
@ -478,7 +480,7 @@ namespace mamba
|
|||
return res.str();
|
||||
}
|
||||
|
||||
bool MatchSpec::is_simple() const
|
||||
auto MatchSpec::is_simple() const -> bool
|
||||
{
|
||||
return version.empty() && build_string.empty() && build_number.empty();
|
||||
}
|
||||
|
|
|
@ -14,12 +14,7 @@
|
|||
|
||||
namespace mamba
|
||||
{
|
||||
std::string python_pin(
|
||||
const Context& ctx,
|
||||
ChannelContext& channel_context,
|
||||
PrefixData& prefix_data,
|
||||
const std::vector<std::string>& specs
|
||||
)
|
||||
std::string python_pin(PrefixData& prefix_data, const std::vector<std::string>& specs)
|
||||
{
|
||||
std::string pin = "";
|
||||
std::string py_version;
|
||||
|
@ -36,8 +31,7 @@ namespace mamba
|
|||
|
||||
for (const auto& spec : specs)
|
||||
{
|
||||
MatchSpec ms{ spec };
|
||||
if (ms.name == "python")
|
||||
if (MatchSpec::parse(spec).name == "python")
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
|
|
@ -241,7 +241,7 @@ namespace mamba
|
|||
throw std::runtime_error(fmt::format(
|
||||
R"(The package "{}" is not available for the specified platform{} ({}))"
|
||||
R"( but is available on {}.)",
|
||||
ms.spec,
|
||||
ms.str(),
|
||||
filters.size() > 1 ? "s" : "",
|
||||
fmt::join(filters, ", "),
|
||||
other_subdir_match
|
||||
|
@ -252,7 +252,7 @@ namespace mamba
|
|||
throw std::runtime_error(fmt::format(
|
||||
R"(The package "{}" is not found in any loaded channels.)"
|
||||
R"( Try adding more channels or subdirs.)",
|
||||
ms.spec
|
||||
ms.str()
|
||||
));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -101,7 +101,7 @@ namespace mamba
|
|||
for (const auto& dep : record->depends)
|
||||
{
|
||||
// Creating a matchspec to parse the name (there may be a channel)
|
||||
auto ms = MatchSpec{ dep };
|
||||
auto ms = MatchSpec::parse(dep);
|
||||
// Ignoring unmatched dependencies, the environment could be broken
|
||||
// or it could be a matchspec
|
||||
const auto from_iter = name_to_node_id.find(ms.name);
|
||||
|
|
|
@ -123,7 +123,7 @@ namespace mamba
|
|||
{
|
||||
for (const auto& job : jobs)
|
||||
{
|
||||
MatchSpec ms{ job };
|
||||
auto ms = MatchSpec::parse(job);
|
||||
int job_type = job_flag & SOLVER_JOBMASK;
|
||||
|
||||
if (ms.conda_build_form().empty())
|
||||
|
@ -133,15 +133,15 @@ namespace mamba
|
|||
|
||||
if (job_type & SOLVER_INSTALL)
|
||||
{
|
||||
m_install_specs.emplace_back(job);
|
||||
m_install_specs.emplace_back(MatchSpec::parse(job));
|
||||
}
|
||||
else if (job_type == SOLVER_ERASE)
|
||||
{
|
||||
m_remove_specs.emplace_back(job);
|
||||
m_remove_specs.emplace_back(MatchSpec::parse(job));
|
||||
}
|
||||
else if (job_type == SOLVER_LOCK)
|
||||
{
|
||||
m_neuter_specs.emplace_back(job); // not used for the moment
|
||||
m_neuter_specs.emplace_back(MatchSpec::parse(job)); // not used for the moment
|
||||
}
|
||||
|
||||
const ::Id job_id = m_pool.matchspec2id(ms);
|
||||
|
@ -171,7 +171,10 @@ namespace mamba
|
|||
|
||||
void MSolver::add_constraint(const std::string& job)
|
||||
{
|
||||
m_jobs->push_back(SOLVER_INSTALL | SOLVER_SOLVABLE_PROVIDES, m_pool.matchspec2id({ job }));
|
||||
m_jobs->push_back(
|
||||
SOLVER_INSTALL | SOLVER_SOLVABLE_PROVIDES,
|
||||
m_pool.matchspec2id(MatchSpec::parse(job))
|
||||
);
|
||||
}
|
||||
|
||||
void MSolver::add_pin(const std::string& pin)
|
||||
|
@ -202,7 +205,7 @@ namespace mamba
|
|||
// as one of its constrains.
|
||||
// Then we lock this solvable and force the re-checking of its dependencies.
|
||||
|
||||
const auto pin_ms = MatchSpec{ pin };
|
||||
const auto pin_ms = MatchSpec::parse(pin);
|
||||
m_pinned_specs.push_back(pin_ms);
|
||||
|
||||
auto& pool = m_pool.pool();
|
||||
|
@ -613,9 +616,9 @@ namespace mamba
|
|||
);
|
||||
node_id cons_id = add_solvable(
|
||||
problem.dep_id,
|
||||
ConstraintNode{ { dep.value() } }
|
||||
ConstraintNode{ MatchSpec::parse(dep.value()) }
|
||||
);
|
||||
MatchSpec edge(dep.value());
|
||||
MatchSpec edge(MatchSpec::parse(dep.value()));
|
||||
m_graph.add_edge(src_id, cons_id, std::move(edge));
|
||||
add_conflict(cons_id, tgt_id);
|
||||
break;
|
||||
|
@ -635,7 +638,7 @@ namespace mamba
|
|||
problem.source_id,
|
||||
PackageNode{ std::move(source).value() }
|
||||
);
|
||||
MatchSpec edge(dep.value());
|
||||
MatchSpec edge(MatchSpec::parse(dep.value()));
|
||||
bool added = add_expanded_deps_edges(src_id, problem.dep_id, edge);
|
||||
if (!added)
|
||||
{
|
||||
|
@ -654,7 +657,7 @@ namespace mamba
|
|||
warn_unexpected_problem(problem);
|
||||
break;
|
||||
}
|
||||
MatchSpec edge(dep.value());
|
||||
MatchSpec edge(MatchSpec::parse(dep.value()));
|
||||
bool added = add_expanded_deps_edges(m_root_node, problem.dep_id, edge);
|
||||
if (!added)
|
||||
{
|
||||
|
@ -673,10 +676,10 @@ namespace mamba
|
|||
warn_unexpected_problem(problem);
|
||||
break;
|
||||
}
|
||||
MatchSpec edge(dep.value());
|
||||
MatchSpec edge(MatchSpec::parse(dep.value()));
|
||||
node_id dep_id = add_solvable(
|
||||
problem.dep_id,
|
||||
UnresolvedDependencyNode{ { std::move(dep).value() } }
|
||||
UnresolvedDependencyNode{ MatchSpec::parse(dep.value()) }
|
||||
);
|
||||
m_graph.add_edge(m_root_node, dep_id, std::move(edge));
|
||||
break;
|
||||
|
@ -692,14 +695,14 @@ namespace mamba
|
|||
warn_unexpected_problem(problem);
|
||||
break;
|
||||
}
|
||||
MatchSpec edge(dep.value());
|
||||
MatchSpec edge(MatchSpec::parse(dep.value()));
|
||||
node_id src_id = add_solvable(
|
||||
problem.source_id,
|
||||
PackageNode{ std::move(source).value() }
|
||||
);
|
||||
node_id dep_id = add_solvable(
|
||||
problem.dep_id,
|
||||
UnresolvedDependencyNode{ { std::move(dep).value() } }
|
||||
UnresolvedDependencyNode{ MatchSpec::parse(dep.value()) }
|
||||
);
|
||||
m_graph.add_edge(src_id, dep_id, std::move(edge));
|
||||
break;
|
||||
|
@ -742,7 +745,7 @@ namespace mamba
|
|||
// how the solver is handling this package, as this is resolved in term of
|
||||
// installed packages and solver flags (allow downgrade...) rather than a
|
||||
// dependency.
|
||||
MatchSpec edge(source.value().name);
|
||||
MatchSpec edge(MatchSpec::parse(source.value().name));
|
||||
// The package cannot exist without its name in the pool
|
||||
assert(m_pool.pool().find_string(edge.name).has_value());
|
||||
const auto dep_id = m_pool.pool().find_string(edge.name).value();
|
||||
|
|
|
@ -582,7 +582,7 @@ namespace mamba
|
|||
std::vector<MatchSpec> specs_to_install;
|
||||
for (const auto& pkginfo : packages)
|
||||
{
|
||||
specs_to_install.push_back(MatchSpec(
|
||||
specs_to_install.push_back(MatchSpec::parse(
|
||||
fmt::format("{}=={}={}", pkginfo.name, pkginfo.version, pkginfo.build_string)
|
||||
));
|
||||
}
|
||||
|
@ -1380,7 +1380,7 @@ namespace mamba
|
|||
}
|
||||
|
||||
const auto hash_idx = url.find_first_of('#');
|
||||
specs_to_install.emplace_back(url.substr(0, hash_idx));
|
||||
specs_to_install.emplace_back(MatchSpec::parse(url.substr(0, hash_idx)));
|
||||
MatchSpec& ms = specs_to_install.back();
|
||||
|
||||
if (hash_idx != std::string::npos)
|
||||
|
@ -1407,11 +1407,7 @@ namespace mamba
|
|||
std::vector<detail::other_pkg_mgr_spec>& other_specs
|
||||
)
|
||||
{
|
||||
const auto maybe_lockfile = read_environment_lockfile(
|
||||
pool.context(),
|
||||
pool.channel_context(),
|
||||
env_lockfile_path
|
||||
);
|
||||
const auto maybe_lockfile = read_environment_lockfile(env_lockfile_path);
|
||||
if (!maybe_lockfile)
|
||||
{
|
||||
throw maybe_lockfile.error(); // NOTE: we cannot return an `un/expected` because
|
||||
|
|
|
@ -20,13 +20,7 @@ namespace mamba
|
|||
{
|
||||
TEST_CASE("absent_file_fails")
|
||||
{
|
||||
auto& ctx = mambatests::context();
|
||||
auto channel_context = ChannelContext::make_conda_compatible(ctx);
|
||||
const auto maybe_lockfile = read_environment_lockfile(
|
||||
ctx,
|
||||
channel_context,
|
||||
"this/file/does/not/exists"
|
||||
);
|
||||
const auto maybe_lockfile = read_environment_lockfile("this/file/does/not/exists");
|
||||
REQUIRE_FALSE(maybe_lockfile);
|
||||
const auto error = maybe_lockfile.error();
|
||||
REQUIRE_EQ(mamba_error_code::env_lockfile_parsing_failed, error.error_code());
|
||||
|
@ -45,15 +39,9 @@ namespace mamba
|
|||
|
||||
TEST_CASE("invalid_version_fails")
|
||||
{
|
||||
auto& ctx = mambatests::context();
|
||||
auto channel_context = ChannelContext::make_conda_compatible(ctx);
|
||||
const fs::u8path invalid_version_lockfile_path{ mambatests::test_data_dir
|
||||
/ "env_lockfile/bad_version-lock.yaml" };
|
||||
const auto maybe_lockfile = read_environment_lockfile(
|
||||
ctx,
|
||||
channel_context,
|
||||
invalid_version_lockfile_path
|
||||
);
|
||||
const auto maybe_lockfile = read_environment_lockfile(invalid_version_lockfile_path);
|
||||
REQUIRE_FALSE(maybe_lockfile);
|
||||
const auto error = maybe_lockfile.error();
|
||||
REQUIRE_EQ(mamba_error_code::env_lockfile_parsing_failed, error.error_code());
|
||||
|
@ -63,11 +51,9 @@ namespace mamba
|
|||
|
||||
TEST_CASE("valid_no_package_succeed")
|
||||
{
|
||||
auto& ctx = mambatests::context();
|
||||
auto channel_context = ChannelContext::make_conda_compatible(ctx);
|
||||
const fs::u8path lockfile_path{ mambatests::test_data_dir
|
||||
/ "env_lockfile/good_no_package-lock.yaml" };
|
||||
const auto maybe_lockfile = read_environment_lockfile(ctx, channel_context, lockfile_path);
|
||||
const auto maybe_lockfile = read_environment_lockfile(lockfile_path);
|
||||
REQUIRE_MESSAGE(maybe_lockfile, maybe_lockfile.error().what());
|
||||
const auto lockfile = maybe_lockfile.value();
|
||||
CHECK(lockfile.get_all_packages().empty());
|
||||
|
@ -75,11 +61,9 @@ namespace mamba
|
|||
|
||||
TEST_CASE("invalid_package_fails")
|
||||
{
|
||||
auto& ctx = mambatests::context();
|
||||
auto channel_context = ChannelContext::make_conda_compatible(ctx);
|
||||
const fs::u8path lockfile_path{ mambatests::test_data_dir
|
||||
/ "env_lockfile/bad_package-lock.yaml" };
|
||||
const auto maybe_lockfile = read_environment_lockfile(ctx, channel_context, lockfile_path);
|
||||
const auto maybe_lockfile = read_environment_lockfile(lockfile_path);
|
||||
REQUIRE_FALSE(maybe_lockfile);
|
||||
const auto error = maybe_lockfile.error();
|
||||
REQUIRE_EQ(mamba_error_code::env_lockfile_parsing_failed, error.error_code());
|
||||
|
@ -89,11 +73,9 @@ namespace mamba
|
|||
|
||||
TEST_CASE("valid_one_package_succeed")
|
||||
{
|
||||
auto& ctx = mambatests::context();
|
||||
auto channel_context = ChannelContext::make_conda_compatible(ctx);
|
||||
const fs::u8path lockfile_path{ mambatests::test_data_dir
|
||||
/ "env_lockfile/good_one_package-lock.yaml" };
|
||||
const auto maybe_lockfile = read_environment_lockfile(ctx, channel_context, lockfile_path);
|
||||
const auto maybe_lockfile = read_environment_lockfile(lockfile_path);
|
||||
REQUIRE_MESSAGE(maybe_lockfile, maybe_lockfile.error().what());
|
||||
const auto lockfile = maybe_lockfile.value();
|
||||
CHECK_EQ(lockfile.get_all_packages().size(), 1);
|
||||
|
@ -101,12 +83,10 @@ namespace mamba
|
|||
|
||||
TEST_CASE("valid_one_package_implicit_category")
|
||||
{
|
||||
auto& ctx = mambatests::context();
|
||||
auto channel_context = ChannelContext::make_conda_compatible(ctx);
|
||||
const fs::u8path lockfile_path{
|
||||
mambatests::test_data_dir / "env_lockfile/good_one_package_missing_category-lock.yaml"
|
||||
};
|
||||
const auto maybe_lockfile = read_environment_lockfile(ctx, channel_context, lockfile_path);
|
||||
const auto maybe_lockfile = read_environment_lockfile(lockfile_path);
|
||||
REQUIRE_MESSAGE(maybe_lockfile, maybe_lockfile.error().what());
|
||||
const auto lockfile = maybe_lockfile.value();
|
||||
CHECK_EQ(lockfile.get_all_packages().size(), 1);
|
||||
|
@ -114,11 +94,9 @@ namespace mamba
|
|||
|
||||
TEST_CASE("valid_multiple_packages_succeed")
|
||||
{
|
||||
auto& ctx = mambatests::context();
|
||||
auto channel_context = ChannelContext::make_conda_compatible(ctx);
|
||||
const fs::u8path lockfile_path{ mambatests::test_data_dir
|
||||
/ "env_lockfile/good_multiple_packages-lock.yaml" };
|
||||
const auto maybe_lockfile = read_environment_lockfile(ctx, channel_context, lockfile_path);
|
||||
const auto maybe_lockfile = read_environment_lockfile(lockfile_path);
|
||||
REQUIRE_MESSAGE(maybe_lockfile, maybe_lockfile.error().what());
|
||||
const auto lockfile = maybe_lockfile.value();
|
||||
CHECK_GT(lockfile.get_all_packages().size(), 1);
|
||||
|
@ -126,11 +104,9 @@ namespace mamba
|
|||
|
||||
TEST_CASE("get_specific_packages")
|
||||
{
|
||||
auto& ctx = mambatests::context();
|
||||
auto channel_context = ChannelContext::make_conda_compatible(ctx);
|
||||
const fs::u8path lockfile_path{ mambatests::test_data_dir
|
||||
/ "env_lockfile/good_multiple_packages-lock.yaml" };
|
||||
const auto lockfile = read_environment_lockfile(ctx, channel_context, lockfile_path).value();
|
||||
const auto lockfile = read_environment_lockfile(lockfile_path).value();
|
||||
CHECK(lockfile.get_packages_for("", "", "").empty());
|
||||
{
|
||||
const auto packages = lockfile.get_packages_for("main", "linux-64", "conda");
|
||||
|
|
|
@ -65,34 +65,34 @@ TEST_SUITE("MatchSpec")
|
|||
TEST_CASE("parse")
|
||||
{
|
||||
{
|
||||
MatchSpec ms("xtensor==0.12.3");
|
||||
auto ms = MatchSpec::parse("xtensor==0.12.3");
|
||||
CHECK_EQ(ms.version, "0.12.3");
|
||||
CHECK_EQ(ms.name, "xtensor");
|
||||
}
|
||||
{
|
||||
MatchSpec ms("");
|
||||
auto ms = MatchSpec::parse("");
|
||||
CHECK_EQ(ms.version, "");
|
||||
CHECK_EQ(ms.name, "");
|
||||
}
|
||||
{
|
||||
MatchSpec ms("ipykernel");
|
||||
auto ms = MatchSpec::parse("ipykernel");
|
||||
CHECK_EQ(ms.version, "");
|
||||
CHECK_EQ(ms.name, "ipykernel");
|
||||
}
|
||||
{
|
||||
MatchSpec ms("ipykernel ");
|
||||
auto ms = MatchSpec::parse("ipykernel ");
|
||||
CHECK_EQ(ms.version, "");
|
||||
CHECK_EQ(ms.name, "ipykernel");
|
||||
}
|
||||
{
|
||||
MatchSpec ms("numpy 1.7*");
|
||||
auto ms = MatchSpec::parse("numpy 1.7*");
|
||||
CHECK_EQ(ms.version, "1.7*");
|
||||
CHECK_EQ(ms.name, "numpy");
|
||||
CHECK_EQ(ms.conda_build_form(), "numpy 1.7*");
|
||||
CHECK_EQ(ms.str(), "numpy=1.7");
|
||||
}
|
||||
{
|
||||
MatchSpec ms("numpy[version='1.7|1.8']");
|
||||
auto ms = MatchSpec::parse("numpy[version='1.7|1.8']");
|
||||
// TODO!
|
||||
// CHECK_EQ(ms.version, "1.7|1.8");
|
||||
CHECK_EQ(ms.name, "numpy");
|
||||
|
@ -100,7 +100,7 @@ TEST_SUITE("MatchSpec")
|
|||
CHECK_EQ(ms.str(), "numpy[version='1.7|1.8']");
|
||||
}
|
||||
{
|
||||
MatchSpec ms("conda-forge/linux-64::xtensor==0.12.3");
|
||||
auto ms = MatchSpec::parse("conda-forge/linux-64::xtensor==0.12.3");
|
||||
CHECK_EQ(ms.version, "0.12.3");
|
||||
CHECK_EQ(ms.name, "xtensor");
|
||||
REQUIRE(ms.channel.has_value());
|
||||
|
@ -109,7 +109,7 @@ TEST_SUITE("MatchSpec")
|
|||
CHECK_EQ(ms.optional, false);
|
||||
}
|
||||
{
|
||||
MatchSpec ms("conda-forge::foo[build=3](target=blarg,optional)");
|
||||
auto ms = MatchSpec::parse("conda-forge::foo[build=3](target=blarg,optional)");
|
||||
CHECK_EQ(ms.version, "");
|
||||
CHECK_EQ(ms.name, "foo");
|
||||
REQUIRE(ms.channel.has_value());
|
||||
|
@ -119,19 +119,19 @@ TEST_SUITE("MatchSpec")
|
|||
CHECK_EQ(ms.optional, true);
|
||||
}
|
||||
{
|
||||
MatchSpec ms("python[build_number=3]");
|
||||
auto ms = MatchSpec::parse("python[build_number=3]");
|
||||
CHECK_EQ(ms.name, "python");
|
||||
CHECK_EQ(ms.brackets["build_number"], "3");
|
||||
CHECK_EQ(ms.build_number, "3");
|
||||
}
|
||||
{
|
||||
MatchSpec ms("python[build_number='<=3']");
|
||||
auto ms = MatchSpec::parse("python[build_number='<=3']");
|
||||
CHECK_EQ(ms.name, "python");
|
||||
CHECK_EQ(ms.brackets["build_number"], "<=3");
|
||||
CHECK_EQ(ms.build_number, "<=3");
|
||||
}
|
||||
{
|
||||
MatchSpec ms(
|
||||
auto ms = MatchSpec::parse(
|
||||
"https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2"
|
||||
);
|
||||
CHECK_EQ(ms.name, "_libgcc_mutex");
|
||||
|
@ -144,7 +144,9 @@ TEST_SUITE("MatchSpec")
|
|||
CHECK_EQ(ms.fn, "_libgcc_mutex-0.1-conda_forge.tar.bz2");
|
||||
}
|
||||
{
|
||||
MatchSpec ms("/home/randomguy/Downloads/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2");
|
||||
auto ms = MatchSpec::parse(
|
||||
"/home/randomguy/Downloads/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2"
|
||||
);
|
||||
CHECK_EQ(ms.name, "_libgcc_mutex");
|
||||
CHECK_EQ(ms.version, "0.1");
|
||||
CHECK_EQ(ms.build_string, "conda_forge");
|
||||
|
@ -171,7 +173,8 @@ TEST_SUITE("MatchSpec")
|
|||
CHECK_EQ(ms.fn, "_libgcc_mutex-0.1-conda_forge.tar.bz2");
|
||||
}
|
||||
{
|
||||
MatchSpec ms("xtensor[url=file:///home/wolfv/Downloads/xtensor-0.21.4-hc9558a2_0.tar.bz2]"
|
||||
auto ms = MatchSpec::parse(
|
||||
"xtensor[url=file:///home/wolfv/Downloads/xtensor-0.21.4-hc9558a2_0.tar.bz2]"
|
||||
);
|
||||
CHECK_EQ(ms.name, "xtensor");
|
||||
CHECK_EQ(
|
||||
|
@ -181,62 +184,64 @@ TEST_SUITE("MatchSpec")
|
|||
CHECK_EQ(ms.url, "file:///home/wolfv/Downloads/xtensor-0.21.4-hc9558a2_0.tar.bz2");
|
||||
}
|
||||
{
|
||||
MatchSpec ms("foo=1.0=2");
|
||||
auto ms = MatchSpec::parse("foo=1.0=2");
|
||||
CHECK_EQ(ms.conda_build_form(), "foo 1.0 2");
|
||||
CHECK_EQ(ms.str(), "foo==1.0=2");
|
||||
}
|
||||
{
|
||||
MatchSpec ms("foo=1.0=2[md5=123123123, license=BSD-3, fn='test 123.tar.bz2']");
|
||||
auto ms = MatchSpec::parse("foo=1.0=2[md5=123123123, license=BSD-3, fn='test 123.tar.bz2']"
|
||||
);
|
||||
CHECK_EQ(ms.conda_build_form(), "foo 1.0 2");
|
||||
CHECK_EQ(ms.str(), "foo==1.0=2[md5=123123123,license=BSD-3,fn='test 123.tar.bz2']");
|
||||
}
|
||||
{
|
||||
MatchSpec ms("foo=1.0=2[md5=123123123, license=BSD-3, fn='test 123.tar.bz2', url='abcdef']"
|
||||
auto ms = MatchSpec::parse(
|
||||
"foo=1.0=2[md5=123123123, license=BSD-3, fn='test 123.tar.bz2', url='abcdef']"
|
||||
);
|
||||
CHECK_EQ(ms.conda_build_form(), "foo 1.0 2");
|
||||
CHECK_EQ(ms.str(), "foo==1.0=2[url=abcdef,md5=123123123,license=BSD-3]");
|
||||
}
|
||||
{
|
||||
MatchSpec ms("libblas=*=*mkl");
|
||||
auto ms = MatchSpec::parse("libblas=*=*mkl");
|
||||
CHECK_EQ(ms.conda_build_form(), "libblas * *mkl");
|
||||
// CHECK_EQ(ms.str(), "foo==1.0=2");
|
||||
}
|
||||
{
|
||||
MatchSpec ms("libblas=0.15*");
|
||||
auto ms = MatchSpec::parse("libblas=0.15*");
|
||||
CHECK_EQ(ms.conda_build_form(), "libblas 0.15*");
|
||||
}
|
||||
{
|
||||
MatchSpec ms("xtensor =0.15*");
|
||||
auto ms = MatchSpec::parse("xtensor =0.15*");
|
||||
CHECK_EQ(ms.conda_build_form(), "xtensor 0.15*");
|
||||
CHECK_EQ(ms.str(), "xtensor=0.15");
|
||||
}
|
||||
{
|
||||
MatchSpec ms("numpy=1.20");
|
||||
auto ms = MatchSpec::parse("numpy=1.20");
|
||||
CHECK_EQ(ms.str(), "numpy=1.20");
|
||||
}
|
||||
|
||||
{
|
||||
MatchSpec ms("conda-forge::tzdata");
|
||||
auto ms = MatchSpec::parse("conda-forge::tzdata");
|
||||
CHECK_EQ(ms.str(), "conda-forge::tzdata");
|
||||
}
|
||||
{
|
||||
MatchSpec ms("conda-forge::noarch/tzdata");
|
||||
auto ms = MatchSpec::parse("conda-forge::noarch/tzdata");
|
||||
CHECK_EQ(ms.str(), "conda-forge::noarch/tzdata");
|
||||
}
|
||||
{
|
||||
MatchSpec ms("pkgs/main::tzdata");
|
||||
auto ms = MatchSpec::parse("pkgs/main::tzdata");
|
||||
CHECK_EQ(ms.str(), "pkgs/main::tzdata");
|
||||
}
|
||||
{
|
||||
MatchSpec ms("pkgs/main/noarch::tzdata");
|
||||
auto ms = MatchSpec::parse("pkgs/main/noarch::tzdata");
|
||||
CHECK_EQ(ms.str(), "pkgs/main[noarch]::tzdata");
|
||||
}
|
||||
{
|
||||
MatchSpec ms("conda-forge[noarch]::tzdata[subdir=linux64]");
|
||||
auto ms = MatchSpec::parse("conda-forge[noarch]::tzdata[subdir=linux64]");
|
||||
CHECK_EQ(ms.str(), "conda-forge[noarch]::tzdata");
|
||||
}
|
||||
{
|
||||
MatchSpec ms("conda-forge::tzdata[subdir=mamba-37]");
|
||||
auto ms = MatchSpec::parse("conda-forge::tzdata[subdir=mamba-37]");
|
||||
CHECK_EQ(ms.str(), "conda-forge[mamba-37]::tzdata");
|
||||
}
|
||||
}
|
||||
|
@ -244,23 +249,23 @@ TEST_SUITE("MatchSpec")
|
|||
TEST_CASE("is_simple")
|
||||
{
|
||||
{
|
||||
MatchSpec ms("libblas");
|
||||
auto ms = MatchSpec::parse("libblas");
|
||||
CHECK(ms.is_simple());
|
||||
}
|
||||
{
|
||||
MatchSpec ms("libblas=12.9=abcdef");
|
||||
auto ms = MatchSpec::parse("libblas=12.9=abcdef");
|
||||
CHECK_FALSE(ms.is_simple());
|
||||
}
|
||||
{
|
||||
MatchSpec ms("libblas=0.15*");
|
||||
auto ms = MatchSpec::parse("libblas=0.15*");
|
||||
CHECK_FALSE(ms.is_simple());
|
||||
}
|
||||
{
|
||||
MatchSpec ms("libblas[version=12.2]");
|
||||
auto ms = MatchSpec::parse("libblas[version=12.2]");
|
||||
CHECK_FALSE(ms.is_simple());
|
||||
}
|
||||
{
|
||||
MatchSpec ms("xtensor =0.15*");
|
||||
auto ms = MatchSpec::parse("xtensor =0.15*");
|
||||
CHECK_FALSE(ms.is_simple());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
#include <doctest/doctest.h>
|
||||
|
||||
#include "mamba/core/channel_context.hpp"
|
||||
#include "mamba/core/context.hpp"
|
||||
#include "mamba/core/pinning.hpp"
|
||||
#include "mamba/core/prefix_data.hpp"
|
||||
#include "mamba/core/util.hpp"
|
||||
|
@ -25,7 +24,6 @@ namespace mamba
|
|||
std::vector<std::string> specs;
|
||||
std::string pin;
|
||||
|
||||
const auto& ctx = mambatests::context();
|
||||
auto channel_context = ChannelContext::make_conda_compatible(mambatests::context());
|
||||
auto sprefix_data = PrefixData::create("", channel_context);
|
||||
if (!sprefix_data)
|
||||
|
@ -37,27 +35,27 @@ namespace mamba
|
|||
REQUIRE_EQ(prefix_data.records().size(), 0);
|
||||
|
||||
specs = { "python" };
|
||||
pin = python_pin(ctx, channel_context, prefix_data, specs);
|
||||
pin = python_pin(prefix_data, specs);
|
||||
CHECK_EQ(pin, "");
|
||||
|
||||
specs = { "python-test" };
|
||||
pin = python_pin(ctx, channel_context, prefix_data, specs);
|
||||
pin = python_pin(prefix_data, specs);
|
||||
CHECK_EQ(pin, "");
|
||||
|
||||
specs = { "python=3" };
|
||||
pin = python_pin(ctx, channel_context, prefix_data, specs);
|
||||
pin = python_pin(prefix_data, specs);
|
||||
CHECK_EQ(pin, "");
|
||||
|
||||
specs = { "python==3.8" };
|
||||
pin = python_pin(ctx, channel_context, prefix_data, specs);
|
||||
pin = python_pin(prefix_data, specs);
|
||||
CHECK_EQ(pin, "");
|
||||
|
||||
specs = { "python==3.8.3" };
|
||||
pin = python_pin(ctx, channel_context, prefix_data, specs);
|
||||
pin = python_pin(prefix_data, specs);
|
||||
CHECK_EQ(pin, "");
|
||||
|
||||
specs = { "numpy" };
|
||||
pin = python_pin(ctx, channel_context, prefix_data, specs);
|
||||
pin = python_pin(prefix_data, specs);
|
||||
CHECK_EQ(pin, "");
|
||||
|
||||
PackageInfo pkg_info("python", "3.7.10", "abcde", 0);
|
||||
|
@ -65,35 +63,35 @@ namespace mamba
|
|||
REQUIRE_EQ(prefix_data.records().size(), 1);
|
||||
|
||||
specs = { "python" };
|
||||
pin = python_pin(ctx, channel_context, prefix_data, specs);
|
||||
pin = python_pin(prefix_data, specs);
|
||||
CHECK_EQ(pin, "");
|
||||
|
||||
specs = { "numpy" };
|
||||
pin = python_pin(ctx, channel_context, prefix_data, specs);
|
||||
pin = python_pin(prefix_data, specs);
|
||||
CHECK_EQ(pin, "python 3.7.*");
|
||||
|
||||
specs = { "python-test" };
|
||||
pin = python_pin(ctx, channel_context, prefix_data, specs);
|
||||
pin = python_pin(prefix_data, specs);
|
||||
CHECK_EQ(pin, "python 3.7.*");
|
||||
|
||||
specs = { "python==3" };
|
||||
pin = python_pin(ctx, channel_context, prefix_data, specs);
|
||||
pin = python_pin(prefix_data, specs);
|
||||
CHECK_EQ(pin, "");
|
||||
|
||||
specs = { "python=3.*" };
|
||||
pin = python_pin(ctx, channel_context, prefix_data, specs);
|
||||
pin = python_pin(prefix_data, specs);
|
||||
CHECK_EQ(pin, "");
|
||||
|
||||
specs = { "python=3.8" };
|
||||
pin = python_pin(ctx, channel_context, prefix_data, specs);
|
||||
pin = python_pin(prefix_data, specs);
|
||||
CHECK_EQ(pin, "");
|
||||
|
||||
specs = { "python=3.8.3" };
|
||||
pin = python_pin(ctx, channel_context, prefix_data, specs);
|
||||
pin = python_pin(prefix_data, specs);
|
||||
CHECK_EQ(pin, "");
|
||||
|
||||
specs = { "numpy", "python" };
|
||||
pin = python_pin(ctx, channel_context, prefix_data, specs);
|
||||
pin = python_pin(prefix_data, specs);
|
||||
CHECK_EQ(pin, "");
|
||||
}
|
||||
|
||||
|
|
|
@ -291,8 +291,19 @@ bind_submodule_impl(pybind11::module_ m)
|
|||
py::add_ostream_redirect(m, "ostream_redirect");
|
||||
|
||||
py::class_<MatchSpec>(m, "MatchSpec")
|
||||
.def_static("parse", &MatchSpec::parse)
|
||||
.def(py::init<>())
|
||||
.def(py::init<std::string_view>(), py::arg("spec"))
|
||||
.def(
|
||||
// Deprecating would lead to confusing error. Better to make sure people stop using it.
|
||||
py::init(
|
||||
[](std::string_view) -> MatchSpec {
|
||||
throw std::invalid_argument(
|
||||
"Use 'MatchSpec.parse' to create a new object from a string"
|
||||
);
|
||||
}
|
||||
),
|
||||
py::arg("spec")
|
||||
)
|
||||
.def("conda_build_form", &MatchSpec::conda_build_form);
|
||||
|
||||
py::class_<MPool>(m, "Pool")
|
||||
|
@ -307,12 +318,7 @@ bind_submodule_impl(pybind11::module_ m)
|
|||
.def("set_debuglevel", &MPool::set_debuglevel)
|
||||
.def("create_whatprovides", &MPool::create_whatprovides)
|
||||
.def("select_solvables", &MPool::select_solvables, py::arg("id"), py::arg("sorted") = false)
|
||||
.def("matchspec2id", &MPool::matchspec2id, py::arg("ms"))
|
||||
.def(
|
||||
"matchspec2id",
|
||||
[](MPool& self, std::string_view spec) { return self.matchspec2id({ spec }); },
|
||||
py::arg("spec")
|
||||
)
|
||||
.def("matchspec2id", &MPool::matchspec2id, py::arg("spec"))
|
||||
.def("id2pkginfo", &MPool::id2pkginfo, py::arg("id"));
|
||||
|
||||
py::class_<MultiPackageCache>(m, "MultiPackageCache")
|
||||
|
@ -490,10 +496,7 @@ bind_submodule_impl(pybind11::module_ m)
|
|||
py::arg("path"),
|
||||
py::arg("channel_context")
|
||||
)
|
||||
.def(
|
||||
"get_requested_specs_map",
|
||||
[](History& self) { return self.get_requested_specs_map(mambapy::singletons.context()); }
|
||||
);
|
||||
.def("get_requested_specs_map", &History::get_requested_specs_map);
|
||||
|
||||
/*py::class_<Query>(m, "Query")
|
||||
.def(py::init<MPool&>())
|
||||
|
|
|
@ -9,8 +9,6 @@
|
|||
#include "constructor.hpp"
|
||||
#include "mamba/api/configuration.hpp"
|
||||
#include "mamba/api/install.hpp"
|
||||
#include "mamba/core/channel_context.hpp"
|
||||
#include "mamba/core/match_spec.hpp"
|
||||
#include "mamba/core/package_handling.hpp"
|
||||
#include "mamba/core/package_info.hpp"
|
||||
#include "mamba/core/subdirdata.hpp"
|
||||
|
@ -80,8 +78,6 @@ construct(Configuration& config, const fs::u8path& prefix, bool extract_conda_pk
|
|||
|
||||
std::map<std::string, nlohmann::json> repodatas;
|
||||
|
||||
auto channel_context = ChannelContext::make_conda_compatible(config.context());
|
||||
|
||||
if (extract_conda_pkgs)
|
||||
{
|
||||
auto find_package = [](nlohmann::json& j, const std::string& fn) -> nlohmann::json
|
||||
|
@ -106,11 +102,7 @@ construct(Configuration& config, const fs::u8path& prefix, bool extract_conda_pk
|
|||
fs::u8path pkgs_dir = prefix / "pkgs";
|
||||
fs::u8path urls_file = pkgs_dir / "urls";
|
||||
|
||||
auto [package_details, _] = detail::parse_urls_to_package_info(
|
||||
read_lines(urls_file),
|
||||
config.context(),
|
||||
channel_context
|
||||
);
|
||||
auto [package_details, _] = detail::parse_urls_to_package_info(read_lines(urls_file));
|
||||
|
||||
for (const auto& pkg_info : package_details)
|
||||
{
|
||||
|
|
|
@ -163,7 +163,7 @@ set_env_command(CLI::App* com, Configuration& config)
|
|||
std::cout << "name: " << get_env_name(ctx, ctx.prefix_params.target_prefix) << "\n";
|
||||
std::cout << "channels:\n";
|
||||
|
||||
auto requested_specs_map = hist.get_requested_specs_map(ctx);
|
||||
auto requested_specs_map = hist.get_requested_specs_map();
|
||||
std::stringstream dependencies;
|
||||
std::set<std::string> channels;
|
||||
for (const auto& [k, v] : versions_map)
|
||||
|
|
|
@ -75,7 +75,7 @@ handle_solve_request(
|
|||
|
||||
for (const auto& s : specs)
|
||||
{
|
||||
if (auto m = MatchSpec{ s }; m.channel.has_value())
|
||||
if (auto m = MatchSpec::parse(s); m.channel.has_value())
|
||||
{
|
||||
channels.push_back(m.channel->str());
|
||||
}
|
||||
|
|
|
@ -51,11 +51,11 @@ update_self(Configuration& config, const std::optional<std::string>& version)
|
|||
std::string matchspec = version ? fmt::format("micromamba={}", version.value())
|
||||
: fmt::format("micromamba>{}", umamba::version());
|
||||
|
||||
auto solvable_ids = pool.select_solvables(pool.matchspec2id({ matchspec }), true);
|
||||
auto solvable_ids = pool.select_solvables(pool.matchspec2id(MatchSpec::parse(matchspec)), true);
|
||||
|
||||
if (solvable_ids.empty())
|
||||
{
|
||||
if (pool.select_solvables(pool.matchspec2id({ "micromamba" })).empty())
|
||||
if (pool.select_solvables(pool.matchspec2id(MatchSpec::parse("micromamba"))).empty())
|
||||
{
|
||||
throw mamba::mamba_error(
|
||||
"No micromamba found in the loaded channels. Add 'conda-forge' to your config file.",
|
||||
|
|
|
@ -632,7 +632,7 @@ def test_spec_with_channel_and_subdir():
|
|||
helpers.create("-n", env_name, "conda-forge/noarch::xtensor", "--dry-run")
|
||||
except subprocess.CalledProcessError as e:
|
||||
assert (
|
||||
'critical libmamba The package "conda-forge/noarch::xtensor" is '
|
||||
'critical libmamba The package "conda-forge[noarch]::xtensor" is '
|
||||
"not available for the specified platform (noarch) but is available on"
|
||||
) in e.stderr.decode()
|
||||
|
||||
|
@ -648,7 +648,7 @@ def test_spec_with_slash_in_channel(tmp_home, tmp_root_prefix):
|
|||
helpers.create("-n", "env1", "pkgs/main/noarch::python", "--dry-run")
|
||||
|
||||
assert info.value.stderr.decode() == (
|
||||
'critical libmamba The package "pkgs/main/noarch::python" is '
|
||||
'critical libmamba The package "pkgs/main[noarch]::python" is '
|
||||
"not found in any loaded channels. Try adding more channels or subdirs.\n"
|
||||
)
|
||||
|
||||
|
|
Loading…
Reference in New Issue