[M5+] wire resolver::discover into cargoxx add
This commit is contained in:
124
src/resolver/discover.cpp
Normal file
124
src/resolver/discover.cpp
Normal file
@@ -0,0 +1,124 @@
|
||||
module cargoxx.resolver;
|
||||
|
||||
import std;
|
||||
import cargoxx.util;
|
||||
import cargoxx.linkdb;
|
||||
|
||||
namespace cargoxx::resolver {
|
||||
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
namespace {
|
||||
|
||||
auto error(util::ErrorCode code, std::string msg) -> util::Error {
|
||||
return util::Error{code, std::move(msg), "", std::nullopt, std::nullopt};
|
||||
}
|
||||
|
||||
// Build a linkdb::Recipe out of one of the probe outputs. The
|
||||
// nixpkgs_attr is always the package name (the attr we used to query
|
||||
// nixpkgs in step 1); find_package + targets come from the probe.
|
||||
auto recipe_from_conan(const ConanRecipe& c, const std::string& nixpkgs_attr,
|
||||
const std::string& source) -> linkdb::Recipe {
|
||||
return linkdb::Recipe{
|
||||
.nixpkgs_attr = nixpkgs_attr,
|
||||
.find_package = c.find_package,
|
||||
.targets = c.targets,
|
||||
.source = source,
|
||||
};
|
||||
}
|
||||
|
||||
auto recipe_from_vcpkg(const VcpkgRecipe& v, const std::string& nixpkgs_attr,
|
||||
const std::string& source) -> linkdb::Recipe {
|
||||
return linkdb::Recipe{
|
||||
.nixpkgs_attr = nixpkgs_attr,
|
||||
.find_package = v.find_package,
|
||||
.targets = v.targets,
|
||||
.source = source,
|
||||
};
|
||||
}
|
||||
|
||||
auto recipe_from_nix_scan(const NixCmakeCandidate& n,
|
||||
const std::string& nixpkgs_attr,
|
||||
const std::string& source) -> linkdb::Recipe {
|
||||
return linkdb::Recipe{
|
||||
.nixpkgs_attr = nixpkgs_attr,
|
||||
.find_package = n.find_package,
|
||||
.targets = n.targets,
|
||||
.source = source,
|
||||
};
|
||||
}
|
||||
|
||||
struct Candidate {
|
||||
std::string source;
|
||||
linkdb::Recipe recipe;
|
||||
};
|
||||
|
||||
auto try_verify(const Candidate& cand, const std::string& name,
|
||||
const std::string& version_spec,
|
||||
const std::vector<std::string>& components,
|
||||
const fs::path& overlay_path, const fs::path& scratch_root,
|
||||
const BuildFn& build_fn) -> util::Result<void> {
|
||||
VerifyLinkRequest req{
|
||||
.candidate = cand.recipe,
|
||||
.source = cand.source,
|
||||
.package_name = name,
|
||||
.version_spec = version_spec,
|
||||
.components = components,
|
||||
.overlay_path = overlay_path,
|
||||
.scratch_root = scratch_root,
|
||||
};
|
||||
return verify_link(req, build_fn);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
auto discover(const std::string& name, const std::string& version_spec,
|
||||
const std::vector<std::string>& components,
|
||||
const fs::path& overlay_path, const fs::path& scratch_root,
|
||||
const BuildFn& build_fn) -> util::Result<Discovered> {
|
||||
auto info = nixpkgs_probe(name);
|
||||
if (!info) {
|
||||
return std::unexpected(info.error());
|
||||
}
|
||||
|
||||
std::vector<Candidate> candidates;
|
||||
|
||||
if (auto c = conan_probe(name); c) {
|
||||
candidates.push_back({"conan", recipe_from_conan(*c, name, "conan")});
|
||||
}
|
||||
if (auto v = vcpkg_probe(name); v) {
|
||||
candidates.push_back({"vcpkg", recipe_from_vcpkg(*v, name, "vcpkg")});
|
||||
}
|
||||
if (auto n = nix_cmake_scan(info->out_path, name); n) {
|
||||
candidates.push_back(
|
||||
{"nix-probe", recipe_from_nix_scan(*n, name, "nix-probe")});
|
||||
}
|
||||
|
||||
if (candidates.empty()) {
|
||||
return std::unexpected(error(
|
||||
util::ErrorCode::ResolutionUnsatisfiable,
|
||||
std::format("no recipe candidates for '{}' (Conan/vcpkg/nix-scan all empty)",
|
||||
name)));
|
||||
}
|
||||
|
||||
util::Error last_error{
|
||||
util::ErrorCode::ResolutionUnsatisfiable,
|
||||
std::format("no candidate for '{}' verified", name), "",
|
||||
std::nullopt, std::nullopt,
|
||||
};
|
||||
for (auto& cand : candidates) {
|
||||
auto verified = try_verify(cand, name, version_spec, components, overlay_path,
|
||||
scratch_root, build_fn);
|
||||
if (verified) {
|
||||
return Discovered{
|
||||
.recipe = std::move(cand.recipe),
|
||||
.source = std::move(cand.source),
|
||||
};
|
||||
}
|
||||
last_error = verified.error();
|
||||
}
|
||||
|
||||
return std::unexpected(last_error);
|
||||
}
|
||||
|
||||
} // namespace cargoxx::resolver
|
||||
Reference in New Issue
Block a user