-
Notifications
You must be signed in to change notification settings - Fork 363
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
9c07a0e
commit 686ee86
Showing
5 changed files
with
194 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
// Copyright (c) 2024, 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 <fmt/format.h> | ||
|
||
#include "solver/libsolv/matcher.hpp" | ||
|
||
namespace mamba::solver::libsolv | ||
{ | ||
|
||
auto Matcher::get_matching_packages( // | ||
solv::ObjPoolView pool, | ||
const specs::MatchSpec& ms | ||
) -> solv::OffsetId | ||
{ | ||
m_packages.clear(); // Reuse the buffer | ||
|
||
auto add_pkg_if_matching = [&](solv::ObjSolvableViewConst s) | ||
{ | ||
if (pkg_match(pool, s, ms)) | ||
{ | ||
m_packages.push_back(s.id()); | ||
} | ||
}; | ||
|
||
if (ms.name().is_exact()) | ||
{ | ||
// Name does not have glob so we can use it as index into packages with exact name. | ||
auto name_id = pool.add_string(ms.name().str()); | ||
pool.for_each_whatprovides(name_id, add_pkg_if_matching); | ||
} | ||
else | ||
{ | ||
// Name is a Glob (e.g. ``py*``) so we have to loop through all packages. | ||
pool.for_each_solvable(add_pkg_if_matching); | ||
} | ||
return pool.add_to_whatprovides_data(m_packages); | ||
} | ||
|
||
auto Matcher::get_matching_packages( // | ||
solv::ObjPoolView pool, | ||
solv::StringId dep | ||
) -> solv::OffsetId | ||
{ | ||
return specs::MatchSpec::parse(pool.get_string(dep)) | ||
.transform([&](const specs::MatchSpec& ms) { return get_matching_packages(pool, ms); }) | ||
.or_else( | ||
[&](const auto& error) -> specs::expected_parse_t<solv::OffsetId> | ||
{ | ||
pool.set_current_error(error.what()); | ||
return pool.add_to_whatprovides_data({}); | ||
} | ||
) | ||
.value(); | ||
} | ||
|
||
auto Matcher::get_pkg_attributes(solv::ObjPoolView pool, solv::ObjSolvableViewConst solv) | ||
-> expected_t<Pkg> | ||
{ | ||
auto version = specs::Version::parse(solv.version()); | ||
if (!version.has_value()) | ||
{ | ||
return make_unexpected(version.error().what(), mamba_error_code::invalid_spec); | ||
} | ||
|
||
auto track_features = specs::MatchSpec::string_set(); | ||
for (solv::StringId id : solv.track_features()) | ||
{ | ||
track_features.insert(std::string(pool.get_string(id))); | ||
} | ||
|
||
return { Pkg{ | ||
/* .name= */ solv.name(), | ||
/* .version= */ std::move(version).value(), | ||
/* .build_string= */ solv.build_string(), | ||
/* .build_number= */ solv.build_number(), | ||
/* .md5= */ solv.md5(), | ||
/* .sha256= */ solv.sha256(), | ||
/* .license= */ solv.license(), | ||
/* .platform= */ std::string(solv.platform()), | ||
/* .track_features= */ std::move(track_features), | ||
} }; | ||
} | ||
|
||
auto Matcher::pkg_match( // | ||
solv::ObjPoolView pool, | ||
solv::ObjSolvableViewConst solv, | ||
const specs::MatchSpec& ms | ||
) -> bool | ||
{ | ||
return get_pkg_attributes(pool, solv) | ||
.transform([&](const Pkg& pkg) -> bool { return ms.contains_except_channel(pkg); }) | ||
.or_else([](const auto&) -> expected_t<bool> { return false; }) | ||
.value(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
// Copyright (c) 2024, 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_SOLVER_LIBSOLV_MATCHER | ||
#define MAMBA_SOLVER_LIBSOLV_MATCHER | ||
|
||
#include <functional> | ||
#include <string> | ||
#include <string_view> | ||
|
||
#include "mamba/core/error_handling.hpp" | ||
#include "mamba/specs/match_spec.hpp" | ||
#include "mamba/specs/version.hpp" | ||
#include "solv-cpp/pool.hpp" | ||
#include "solv-cpp/solvable.hpp" | ||
|
||
namespace mamba::solver::libsolv | ||
{ | ||
class Matcher | ||
{ | ||
public: | ||
|
||
auto get_matching_packages( // | ||
solv::ObjPoolView pool, | ||
const specs::MatchSpec& ms | ||
) -> solv::OffsetId; | ||
|
||
auto get_matching_packages( // | ||
solv::ObjPoolView pool, | ||
solv::StringId dep | ||
) -> solv::OffsetId; | ||
|
||
private: | ||
|
||
struct Pkg | ||
{ | ||
std::string_view name; | ||
specs::Version version; | ||
std::string_view build_string; | ||
std::size_t build_number; | ||
std::string_view md5; | ||
std::string_view sha256; | ||
std::string_view license; | ||
std::string platform; | ||
specs::MatchSpec::string_set track_features; | ||
}; | ||
|
||
auto get_pkg_attributes( // | ||
solv::ObjPoolView pool, | ||
solv::ObjSolvableViewConst solv | ||
) -> expected_t<Pkg>; | ||
|
||
auto pkg_match( // | ||
solv::ObjPoolView pool, | ||
solv::ObjSolvableViewConst solv, | ||
const specs::MatchSpec& ms | ||
) -> bool; | ||
|
||
solv::ObjQueue m_packages = {}; | ||
// TODO use matchspec cache? Or not since they would have the same string in libdolv... | ||
// TODO use version cache | ||
// TODO handle channels | ||
}; | ||
} | ||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters