diff --git a/src/cli/cmd_build.cpp b/src/cli/cmd_build.cpp index 0ba4399..ad111b4 100644 --- a/src/cli/cmd_build.cpp +++ b/src/cli/cmd_build.cpp @@ -8,6 +8,7 @@ import cargoxx.linkdb; import cargoxx.lockfile; import cargoxx.codegen; import cargoxx.exec; +import cargoxx.resolver; namespace cargoxx::cli { @@ -146,17 +147,46 @@ auto cmd_build(const fs::path& project_root, bool no_build, bool release, return std::unexpected(layout_result.error()); } - auto db = linkdb::Database::open(std::move(overlay_path)); + const auto effective_overlay = overlay_path.value_or(linkdb::default_overlay_path()); + auto db = linkdb::Database::open(effective_overlay); if (!db) { return std::unexpected(db.error()); } + auto auto_resolve = [&](const std::string& name, const std::string& version, + const std::vector& components) + -> util::Result { + auto build_fn = [&](const fs::path& root) { + return cmd_build(root, /*no_build=*/false, /*release=*/false, + /*target=*/std::nullopt, effective_overlay); + }; + const auto scratch_root = + std::filesystem::temp_directory_path() / + std::format("cargoxx-discover-{}", std::random_device{}()); + auto disc = resolver::discover(name, version, components, + effective_overlay, scratch_root, build_fn); + std::error_code ec; + std::filesystem::remove_all(scratch_root, ec); + if (!disc) { + return std::unexpected(disc.error()); + } + return {}; + }; + auto resolve_list = [&](const std::vector& deps) -> util::Result> { std::vector out; out.reserve(deps.size()); for (const auto& dep : deps) { auto r = db->resolve(dep.name, dep.version_spec, dep.components); + if (!r && r.error().code == util::ErrorCode::LinkdbUnknownPackage) { + if (auto resolved = auto_resolve(dep.name, dep.version_spec, + dep.components); + !resolved) { + return std::unexpected(resolved.error()); + } + r = db->resolve(dep.name, dep.version_spec, dep.components); + } if (!r) { return std::unexpected(r.error()); } diff --git a/tests/cmd_build.cpp b/tests/cmd_build.cpp index e7b0b9e..70811e6 100644 --- a/tests/cmd_build.cpp +++ b/tests/cmd_build.cpp @@ -156,7 +156,7 @@ TEST_CASE("cmd_build fails for an unknown dep", "[cli][build]") { auto r = cmd_build(root, true, false, std::nullopt, overlay_path(parent)); REQUIRE_FALSE(r.has_value()); - REQUIRE(r.error().code == ErrorCode::LinkdbUnknownPackage); + REQUIRE(r.error().code == ErrorCode::ResolutionUnknownPackage); } TEST_CASE("cmd_build --release writes a release-typed build/CMakeLists",