From a757149f99df14c8f728a3d5e416b7d3a0fce437 Mon Sep 17 00:00:00 2001 From: Amadey Vorontsov Date: Wed, 13 May 2026 23:59:06 +0000 Subject: [PATCH] [M6] cmd_build: resolve dev_dependencies + thread into lockfile/codegen --- src/cli/cmd_build.cpp | 53 +++++++++++++++++++++++++++---------------- 1 file changed, 33 insertions(+), 20 deletions(-) diff --git a/src/cli/cmd_build.cpp b/src/cli/cmd_build.cpp index e85871e..0ba4399 100644 --- a/src/cli/cmd_build.cpp +++ b/src/cli/cmd_build.cpp @@ -44,6 +44,7 @@ auto write_text(const fs::path& path, std::string_view content) -> util::Result< // repopulates it. auto merge_lockfile(const manifest::Manifest& m, const std::vector& recipes, + const std::vector& dev_recipes, const lockfile::Lockfile& prior) -> lockfile::Lockfile { auto find_prior = [&](const std::string& name, const std::string& version) -> std::optional { @@ -69,17 +70,13 @@ auto merge_lockfile(const manifest::Manifest& m, for (const auto& dep : m.dependencies) { root.dependencies.push_back(std::format("{} {}", dep.name, dep.version_spec)); } + for (const auto& dep : m.dev_dependencies) { + root.dependencies.push_back(std::format("{} {}", dep.name, dep.version_spec)); + } lock.packages.push_back(std::move(root)); - for (std::size_t i = 0; i < m.dependencies.size(); ++i) { - const auto& dep = m.dependencies[i]; - const auto& rec = recipes[i]; + auto emit_dep = [&](const manifest::Dependency& dep, const linkdb::Recipe& rec) { std::optional rev; - // The recipe's nixpkgs_attr is correct for unpinned deps (it's - // curated against nixos-unstable). When the prior lockfile - // already carries an attr — written by `cargoxx add @` - // from devbox's authoritative attr_paths for the pinned rev — - // that one wins. std::string attr = rec.nixpkgs_attr; if (auto p = find_prior(dep.name, dep.version_spec); p) { rev = p->nixpkgs_rev; @@ -95,6 +92,12 @@ auto merge_lockfile(const manifest::Manifest& m, .nixpkgs_rev = std::move(rev), .linkdb_source = rec.source, }); + }; + for (std::size_t i = 0; i < m.dependencies.size(); ++i) { + emit_dep(m.dependencies[i], recipes[i]); + } + for (std::size_t i = 0; i < m.dev_dependencies.size(); ++i) { + emit_dep(m.dev_dependencies[i], dev_recipes[i]); } return lock; } @@ -148,14 +151,26 @@ auto cmd_build(const fs::path& project_root, bool no_build, bool release, return std::unexpected(db.error()); } - std::vector recipes; - recipes.reserve(m->dependencies.size()); - for (const auto& dep : m->dependencies) { - auto r = db->resolve(dep.name, dep.version_spec, dep.components); - if (!r) { - return std::unexpected(r.error()); + 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) { + return std::unexpected(r.error()); + } + out.push_back(std::move(*r)); } - recipes.push_back(std::move(*r)); + return out; + }; + auto recipes = resolve_list(m->dependencies); + if (!recipes) { + return std::unexpected(recipes.error()); + } + auto dev_recipes = resolve_list(m->dev_dependencies); + if (!dev_recipes) { + return std::unexpected(dev_recipes.error()); } lockfile::Lockfile prior; @@ -163,17 +178,15 @@ auto cmd_build(const fs::path& project_root, bool no_build, bool release, if (auto r = lockfile::parse(project_root / "Cargoxx.lock"); r) { prior = std::move(*r); } - // A malformed prior lockfile is non-fatal — we just rebuild from - // scratch. The user can re-pin by running `cargoxx add` again. } - auto lock = merge_lockfile(*m, recipes, prior); + auto lock = merge_lockfile(*m, *recipes, *dev_recipes, prior); codegen::GenerateInputs in{ .manifest = *m, .layout = *layout_result, .lock = lock, - .recipes = recipes, - .dev_recipes = {}, + .recipes = *recipes, + .dev_recipes = *dev_recipes, .project_root = project_root, }; auto flake_text = codegen::flake_nix(in);