From ebe0d4f89c93b39f354942bd96f70212ca9c47cf Mon Sep 17 00:00:00 2001 From: Hind-M <70631848+Hind-M@users.noreply.github.com> Date: Thu, 21 Nov 2024 11:38:40 +0100 Subject: [PATCH] Fix build trailing `*` display (#3619) --- libmamba/src/solver/problems_graph.cpp | 40 +++++++++++-------- .../tests/src/solver/libsolv/test_solver.cpp | 28 +++++++++++++ 2 files changed, 51 insertions(+), 17 deletions(-) diff --git a/libmamba/src/solver/problems_graph.cpp b/libmamba/src/solver/problems_graph.cpp index 25cf5ca7f2..e07a036371 100644 --- a/libmamba/src/solver/problems_graph.cpp +++ b/libmamba/src/solver/problems_graph.cpp @@ -1322,18 +1322,28 @@ namespace mamba::solver return arr; } - auto rstrip_excessive_free(std::string_view str) -> std::string_view - { - str = util::rstrip(str); - str = util::remove_suffix(str, specs::GlobSpec::free_pattern); - str = util::rstrip(str); - for (const auto& suffix : sorted_suffix(specs::VersionSpec::all_free_strs)) - { - str = util::remove_suffix(str, suffix); - } - str = util::rstrip(str); - return str; - } + // Single dependency with only name constraint often end up looking like + // ``python =* *`` so `rstrip_excessive_free` was used to strip all this. + // Best would be to handle this with a richer NamedList that contains + // ``VersionSpecs`` to avoid flaky reliance on string modification. + + // As `rstrip_excessive_free` side effect was to strip `*` from a regex, + // (which is not wanted and confusing when trying to understand the + // unsolvability problems), it is not used anymore on `vers_builds_trunc`. + // But we still keep it uncommented for a while (in case we need to + // restore it later). + // auto rstrip_excessive_free(std::string_view str) -> std::string_view + // { + // str = util::rstrip(str); + // str = util::remove_suffix(str, specs::GlobSpec::free_pattern); + // str = util::rstrip(str); + // for (const auto& suffix : sorted_suffix(specs::VersionSpec::all_free_strs)) + // { + // str = util::remove_suffix(str, suffix); + // } + // str = util::rstrip(str); + // return str; + // } void TreeExplainer::write_pkg_dep(const TreeNode& tn) { @@ -1348,11 +1358,7 @@ namespace mamba::solver } else { - // Single dependency with only name constraint often end up looking like - // ``python =* *`` so we strip all this. - // Best would be to handle this with a richer NamedList that contains - // ``VersionSpecs`` to avoid flaky reliance on string modification. - const auto relevant_vers_builds_trunc = rstrip_excessive_free(vers_builds_trunc); + const auto relevant_vers_builds_trunc = vers_builds_trunc; if (relevant_vers_builds_trunc.empty()) { write(fmt::format(style, "{}", edges.name())); diff --git a/libmamba/tests/src/solver/libsolv/test_solver.cpp b/libmamba/tests/src/solver/libsolv/test_solver.cpp index 63b35ce07d..87aa6cb673 100644 --- a/libmamba/tests/src/solver/libsolv/test_solver.cpp +++ b/libmamba/tests/src/solver/libsolv/test_solver.cpp @@ -1097,5 +1097,33 @@ TEST_SUITE("solver::libsolv::solver") CHECK_EQ(std::get(solution.actions.front()).install.build_string, "bld"); CHECK_EQ(std::get(solution.actions.front()).install.build_number, 4); } + + SUBCASE("foo[version='=*,=*', build='pyhd*']") + { + auto pkg = PackageInfo("foo"); + pkg.version = "=*,=*"; + pkg.build_string = "pyhd*"; + + db.add_repo_from_packages(std::array{ pkg }); + + auto request = Request{ + /* .flags= */ {}, + /* .jobs= */ { Request::Install{ "foo[version='=*,=*', build='pyhd*']"_ms } }, + }; + const auto outcome = libsolv::Solver().solve(db, request); + + REQUIRE(outcome.has_value()); + REQUIRE(std::holds_alternative(outcome.value())); + + const auto& unsolvable = std::get(outcome.value()); + const auto problems_explained = unsolvable.explain_problems(db, {}); + // To avoid mismatch due to color formatting, we perform the check by splitting the + // output following the format + CHECK(util::contains(problems_explained, "foo =*,=* pyhd*")); + CHECK(util::contains( + problems_explained, + "does not exist (perhaps a typo or a missing channel)." + )); + } } }