Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GlobSpec #3094

Merged
merged 4 commits into from
Jan 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions libmamba/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -173,11 +173,12 @@ set(
${LIBMAMBA_SOURCE_DIR}/specs/channel.cpp
${LIBMAMBA_SOURCE_DIR}/specs/channel_spec.cpp
${LIBMAMBA_SOURCE_DIR}/specs/conda_url.cpp
${LIBMAMBA_SOURCE_DIR}/specs/glob_spec.cpp
${LIBMAMBA_SOURCE_DIR}/specs/match_spec.cpp
${LIBMAMBA_SOURCE_DIR}/specs/platform.cpp
${LIBMAMBA_SOURCE_DIR}/specs/repo_data.cpp
${LIBMAMBA_SOURCE_DIR}/specs/version.cpp
${LIBMAMBA_SOURCE_DIR}/specs/version_spec.cpp
${LIBMAMBA_SOURCE_DIR}/specs/match_spec.cpp
# Artifacts validation
${LIBMAMBA_SOURCE_DIR}/validation/tools.cpp
${LIBMAMBA_SOURCE_DIR}/validation/errors.cpp
Expand Down Expand Up @@ -287,11 +288,12 @@ set(
${LIBMAMBA_INCLUDE_DIR}/mamba/specs/channel.hpp
${LIBMAMBA_INCLUDE_DIR}/mamba/specs/channel_spec.hpp
${LIBMAMBA_INCLUDE_DIR}/mamba/specs/conda_url.hpp
${LIBMAMBA_INCLUDE_DIR}/mamba/specs/glob_spec.hpp
${LIBMAMBA_INCLUDE_DIR}/mamba/specs/match_spec.hpp
${LIBMAMBA_INCLUDE_DIR}/mamba/specs/platform.hpp
${LIBMAMBA_INCLUDE_DIR}/mamba/specs/repo_data.hpp
${LIBMAMBA_INCLUDE_DIR}/mamba/specs/version.hpp
${LIBMAMBA_INCLUDE_DIR}/mamba/specs/version_spec.hpp
${LIBMAMBA_INCLUDE_DIR}/mamba/specs/match_spec.hpp
# Artifacts validation
${LIBMAMBA_INCLUDE_DIR}/mamba/validation/tools.hpp
${LIBMAMBA_INCLUDE_DIR}/mamba/validation/errors.hpp
Expand Down
59 changes: 59 additions & 0 deletions libmamba/include/mamba/specs/glob_spec.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// 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.

#ifndef MAMBA_SPECS_GLOB_SPEC
#define MAMBA_SPECS_GLOB_SPEC

#include <string>
#include <string_view>

#include <fmt/core.h>

namespace mamba::specs
{
/**
* A matcher for glob expression.
*
* Currently only support "*" wildcard for matching zero or more characters.
*/
class GlobSpec
{
public:

inline static constexpr std::string_view free_pattern = "*";

GlobSpec() = default;
explicit GlobSpec(std::string pattern);

[[nodiscard]] auto contains(std::string_view str) const -> bool;

/**
* Return true if the spec will match true on any input.
*/
[[nodiscard]] auto is_free() const -> bool;

/**
* Return true if the spec will match exaclty one input.
*/
[[nodiscard]] auto is_exact() const -> bool;

[[nodiscard]] auto str() const -> const std::string&;

private:

std::string m_pattern = std::string(free_pattern);
};
}

template <>
struct fmt::formatter<mamba::specs::GlobSpec>
{
auto parse(format_parse_context& ctx) -> decltype(ctx.begin());

auto format(const ::mamba::specs::GlobSpec& spec, format_context& ctx) -> decltype(ctx.out());
};

#endif
20 changes: 12 additions & 8 deletions libmamba/include/mamba/specs/match_spec.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
//
// The full license is in the file LICENSE, distributed with this software.

#ifndef MAMBA_CORE_MATCH_SPEC
#define MAMBA_CORE_MATCH_SPEC
#ifndef MAMBA_SPECS_MATCH_SPEC
#define MAMBA_SPECS_MATCH_SPEC

#include <optional>
#include <string>
Expand All @@ -14,6 +14,7 @@
#include <unordered_map>

#include "mamba/specs/channel_spec.hpp"
#include "mamba/specs/glob_spec.hpp"
#include "mamba/specs/version_spec.hpp"

namespace mamba::specs
Expand All @@ -22,6 +23,9 @@ namespace mamba::specs
{
public:

using NameSpec = GlobSpec;
using BuildStringSpec = GlobSpec;

[[nodiscard]] static auto parse_version_and_build(std::string_view s)
-> std::tuple<std::string, std::string>;

Expand All @@ -35,17 +39,17 @@ namespace mamba::specs
[[nodiscard]] auto name_space() const -> const std::string&;
void set_name_space(std::string ns);

[[nodiscard]] auto name() const -> const std::string&;
void set_name(std::string name);
[[nodiscard]] auto name() const -> const NameSpec&;
void set_name(NameSpec name);

[[nodiscard]] auto version() const -> const VersionSpec&;
void set_version(VersionSpec ver);

[[nodiscard]] auto build_number() const -> const std::string&;
void set_build_number(std::string num);

[[nodiscard]] auto build_string() const -> const std::string&;
void set_build_string(std::string bs);
[[nodiscard]] auto build_string() const -> const BuildStringSpec&;
void set_build_string(BuildStringSpec bs);

[[nodiscard]] auto optional() const -> bool;
void set_optional(bool opt);
Expand All @@ -69,10 +73,10 @@ namespace mamba::specs

std::optional<ChannelSpec> m_channel;
VersionSpec m_version;
NameSpec m_name;
BuildStringSpec m_build_string;
std::string m_name_space;
std::string m_name;
std::string m_build_number;
std::string m_build_string;
// TODO can put inside channel spec
std::string m_filename;
std::string m_url;
Expand Down
4 changes: 2 additions & 2 deletions libmamba/src/api/install.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -355,9 +355,9 @@ namespace mamba
}
std::size_t hash = u.find_first_of('#');
auto ms = specs::MatchSpec::parse(u.substr(0, hash));
PackageInfo p(ms.name());
PackageInfo p(ms.name().str());
p.url = ms.url();
p.build_string = ms.build_string();
p.build_string = ms.build_string().str();
p.version = ms.version().str();
if (ms.channel().has_value())
{
Expand Down
6 changes: 3 additions & 3 deletions libmamba/src/api/update.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ namespace mamba
std::vector<std::string> keep_specs;
for (auto& it : hist_map)
{
keep_specs.push_back(it.second.name());
keep_specs.push_back(it.second.name().str());
}
solver_flag |= SOLVER_SOLVABLE_ALL;
if (prune_deps)
Expand All @@ -136,10 +136,10 @@ namespace mamba
std::vector<std::string> remove_specs;
for (auto& it : hist_map)
{
if (std::find(update_specs.begin(), update_specs.end(), it.second.name())
if (std::find(update_specs.begin(), update_specs.end(), it.second.name().str())
== update_specs.end())
{
remove_specs.push_back(it.second.name());
remove_specs.push_back(it.second.name().str());
}
}
solver.add_jobs(remove_specs, SOLVER_ERASE | SOLVER_CLEANDEPS);
Expand Down
2 changes: 1 addition & 1 deletion libmamba/src/core/env_lockfile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ namespace mamba
package.info.url = package_node["url"].as<std::string>();
const auto spec = specs::MatchSpec::parse(package.info.url);
package.info.fn = spec.filename();
package.info.build_string = spec.build_string();
package.info.build_string = spec.build_string().str();
if (spec.channel().has_value())
{
package.info.channel = spec.channel()->location();
Expand Down
6 changes: 3 additions & 3 deletions libmamba/src/core/history.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -211,17 +211,17 @@ namespace mamba
auto remove_specs = to_specs(request.remove);
for (auto& spec : remove_specs)
{
map.erase(spec.name());
map.erase(spec.name().str());
}
auto update_specs = to_specs(request.update);
for (auto& spec : update_specs)
{
map[spec.name()] = spec;
map[spec.name().str()] = spec;
}
auto neutered_specs = to_specs(request.neutered);
for (auto& spec : neutered_specs)
{
map[spec.name()] = spec;
map[spec.name().str()] = spec;
}
}

Expand Down
2 changes: 1 addition & 1 deletion libmamba/src/core/link.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -996,7 +996,7 @@ namespace mamba
specs::MatchSpec* requested_spec = nullptr;
for (auto& ms : m_context->requested_specs)
{
if (ms.name() == m_pkg_info.name)
if (ms.name().contains(m_pkg_info.name))
{
requested_spec = &ms;
}
Expand Down
2 changes: 1 addition & 1 deletion libmamba/src/core/pinning.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ namespace mamba

for (const auto& spec : specs)
{
if (specs::MatchSpec::parse(spec).name() == "python")
if (specs::MatchSpec::parse(spec).name().contains("python"))
{
return "";
}
Expand Down
2 changes: 1 addition & 1 deletion libmamba/src/core/prefix_data.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ namespace mamba
auto ms = specs::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());
const auto from_iter = name_to_node_id.find(ms.name().str());
if (from_iter != name_to_node_id.cend())
{
dep_graph.add_edge(from_iter->second, to_id);
Expand Down
101 changes: 58 additions & 43 deletions libmamba/src/core/satisfiability_error.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,54 @@ namespace mamba
return CompressedProblemsGraph::NamedList<O>(tmp.begin(), tmp.end());
}

template <typename T>
auto invoke_version(T&& e) -> decltype(auto)
{
using TT = std::remove_cv_t<std::remove_reference_t<T>>;
using Ver = decltype(std::invoke(&TT::version, std::forward<T>(e)));
Ver v = std::invoke(&TT::version, std::forward<T>(e));
if constexpr (std::is_same_v<std::decay_t<decltype(v)>, specs::VersionSpec>)
{
return std::forward<Ver>(v).str();
}
else
{
return v;
}
}

template <typename T>
auto invoke_build_string(T&& e) -> decltype(auto)
{
using TT = std::remove_cv_t<std::remove_reference_t<T>>;
using Build = decltype(std::invoke(&TT::build_string, std::forward<T>(e)));
Build bld = std::invoke(&TT::build_string, std::forward<T>(e));
if constexpr (std::is_same_v<std::decay_t<decltype(bld)>, specs::GlobSpec>)
{
return std::forward<Build>(bld).str();
}
else
{
return bld;
}
}

template <typename T>
auto invoke_name(T&& e) -> decltype(auto)
{
using TT = std::remove_cv_t<std::remove_reference_t<T>>;
using Name = decltype(std::invoke(&TT::name, std::forward<T>(e)));
Name name = std::invoke(&TT::name, std::forward<T>(e));
if constexpr (std::is_same_v<std::decay_t<decltype(name)>, specs::GlobSpec>)
{
return std::forward<Name>(name).str();
}
else
{
return name;
}
}

/**
* Detect if a type has a ``name`` member (function).
*/
Expand All @@ -287,7 +335,7 @@ namespace mamba
{
if constexpr (has_name_v<T>)
{
return std::invoke(&T::name, obj);
return invoke_name(obj);
}
else
{
Expand Down Expand Up @@ -538,32 +586,6 @@ namespace mamba
* Implementation of CompressedProblemsGraph::RoughCompare *
*************************************************************/

namespace
{
template <typename T>
auto invoke_name(T&& e) -> decltype(auto)
{
using TT = std::remove_cv_t<std::remove_reference_t<T>>;
return std::invoke(&TT::name, std::forward<T>(e));
}

template <typename T>
auto invoke_version(T&& e) -> decltype(auto)
{
using TT = std::remove_cv_t<std::remove_reference_t<T>>;
using Ver = decltype(std::invoke(&TT::version, std::forward<T>(e)));
Ver v = std::invoke(&TT::version, std::forward<T>(e));
if constexpr (std::is_same_v<std::decay_t<decltype(v)>, specs::VersionSpec>)
{
return std::forward<Ver>(v).str();
}
else
{
return v;
}
}
}

template <typename T>
auto CompressedProblemsGraph::RoughCompare<T>::operator()(const T& a, const T& b) const -> bool
{
Expand All @@ -573,12 +595,12 @@ namespace mamba
decltype(invoke_name(x)),
decltype(invoke_version(x)),
decltype(std::invoke(&T::build_number, x)),
decltype(std::invoke(&T::build_string, x))>;
decltype(invoke_build_string(x))>;
return Attrs(
invoke_name(x),
invoke_version(x),
std::invoke(&T::build_number, x),
std::invoke(&T::build_string, x)
invoke_build_string(x)
);
};
return attrs(a) < attrs(b);
Expand Down Expand Up @@ -694,13 +716,13 @@ namespace mamba
) const -> std::pair<std::string, std::size_t>
{
auto builds = std::vector<std::string>(size());
auto invoke_build_string = [](auto&& v) -> decltype(auto)
{
using TT = std::remove_cv_t<std::remove_reference_t<decltype(v)>>;
return std::invoke(&TT::build_string, std::forward<decltype(v)>(v));
};
// TODO(C++20) *this | std::ranges::transform(invoke_buid_string) | ranges::unique
std::transform(begin(), end(), builds.begin(), invoke_build_string);
std::transform(
begin(),
end(),
builds.begin(),
[](const auto& p) { return invoke_build_string(p); }
);
if (remove_duplicates)
{
builds.erase(std::unique(builds.begin(), builds.end()), builds.end());
Expand All @@ -718,14 +740,7 @@ namespace mamba
{
auto versions_builds = std::vector<std::string>(size());
auto invoke_version_builds = [](auto&& v) -> decltype(auto)
{
using TT = std::remove_cv_t<std::remove_reference_t<decltype(v)>>;
return fmt::format(
"{} {}",
std::invoke(&TT::version, std::forward<decltype(v)>(v)),
std::invoke(&TT::build_string, std::forward<decltype(v)>(v))
);
};
{ return fmt::format("{} {}", invoke_version(v), invoke_build_string(v)); };
// TODO(C++20) *this | std::ranges::transform(invoke_version) | ranges::unique
std::transform(begin(), end(), versions_builds.begin(), invoke_version_builds);
if (remove_duplicates)
Expand Down
Loading
Loading