[M5+] add resolver::conan_probe

This commit is contained in:
2026-05-10 10:14:38 +00:00
parent e63ac69239
commit e5c173b466
8 changed files with 352 additions and 2 deletions

View File

@@ -0,0 +1,81 @@
#include <catch2/catch_test_macros.hpp>
import cargoxx.resolver;
import cargoxx.util;
import std;
using cargoxx::resolver::parse_conanfile;
using cargoxx::util::ErrorCode;
TEST_CASE("parse_conanfile picks up modern set_property form", "[resolver][conan]") {
constexpr std::string_view text = R"PY(
from conan import ConanFile
class FmtConan(ConanFile):
name = "fmt"
def package_info(self):
self.cpp_info.set_property("cmake_file_name", "fmt")
self.cpp_info.set_property("cmake_target_name", "fmt::fmt")
)PY";
auto r = parse_conanfile(text, "fmt");
REQUIRE(r.has_value());
REQUIRE(r->find_package == "fmt CONFIG REQUIRED");
REQUIRE(r->targets == std::vector<std::string>{"fmt::fmt"});
}
TEST_CASE("parse_conanfile picks up legacy names[] form", "[resolver][conan]") {
constexpr std::string_view text = R"PY(
class SpdlogConan(ConanFile):
def package_info(self):
self.cpp_info.names["cmake_find_package"] = "spdlog"
)PY";
auto r = parse_conanfile(text, "spdlog");
REQUIRE(r.has_value());
REQUIRE(r->find_package == "spdlog CONFIG REQUIRED");
// Derived target heuristic: spdlog::spdlog
REQUIRE(r->targets == std::vector<std::string>{"spdlog::spdlog"});
}
TEST_CASE("parse_conanfile derives cmake_file_name from a colon-namespaced target",
"[resolver][conan]") {
constexpr std::string_view text = R"PY(
self.cpp_info.set_property("cmake_target_name", "Boost::filesystem")
)PY";
auto r = parse_conanfile(text, "boost");
REQUIRE(r.has_value());
REQUIRE(r->find_package == "Boost CONFIG REQUIRED");
REQUIRE(r->targets == std::vector<std::string>{"Boost::filesystem"});
}
TEST_CASE("parse_conanfile falls back to the package name when nothing matches",
"[resolver][conan]") {
constexpr std::string_view text = R"PY(
# This recipe gives us nothing useful at the cpp_info level.
class OpaqueConan(ConanFile):
name = "opaque"
)PY";
auto r = parse_conanfile(text, "opaque");
REQUIRE(r.has_value());
REQUIRE(r->find_package == "opaque CONFIG REQUIRED");
REQUIRE(r->targets == std::vector<std::string>{"opaque::opaque"});
}
TEST_CASE("parse_conanfile errors when no information AND no fallback",
"[resolver][conan]") {
auto r = parse_conanfile("# nothing here", "");
REQUIRE_FALSE(r.has_value());
REQUIRE(r.error().code == ErrorCode::ResolutionUnknownPackage);
}
TEST_CASE("parse_conanfile accepts single-quoted strings", "[resolver][conan]") {
constexpr std::string_view text = R"PY(
self.cpp_info.set_property('cmake_target_name', 'absl::strings')
self.cpp_info.set_property('cmake_file_name', 'absl')
)PY";
auto r = parse_conanfile(text, "abseil");
REQUIRE(r.has_value());
REQUIRE(r->find_package == "absl CONFIG REQUIRED");
REQUIRE(r->targets == std::vector<std::string>{"absl::strings"});
}