[M5+] cmd_build merges Cargoxx.lock instead of overwriting
This commit is contained in:
@@ -91,6 +91,13 @@ All notable changes to cargoxx will be documented in this file.
|
|||||||
6 cases against fixtures derived from a real fmt 10.2.1 response;
|
6 cases against fixtures derived from a real fmt 10.2.1 response;
|
||||||
`tests/devbox_resolve_live.cpp` (gated by `CARGOXX_NETWORK_TESTS=1`)
|
`tests/devbox_resolve_live.cpp` (gated by `CARGOXX_NETWORK_TESTS=1`)
|
||||||
hits the live API.
|
hits the live API.
|
||||||
|
- `cargoxx build` now **merges** rather than overwrites
|
||||||
|
`Cargoxx.lock`: when an existing entry's `(name, version)` still
|
||||||
|
matches the manifest, its `nixpkgs_rev` is preserved. New deps and
|
||||||
|
version bumps still get a null rev (track `nixos-unstable`). Means
|
||||||
|
pins written by `cargoxx add <pkg>@<ver>` survive arbitrary
|
||||||
|
rebuilds; cmd_build is now idempotent w.r.t. the lockfile.
|
||||||
|
`synthesize_lockfile` was renamed `merge_lockfile`.
|
||||||
- `cargoxx.resolver::resolve_version(name, version)` orchestrator
|
- `cargoxx.resolver::resolve_version(name, version)` orchestrator
|
||||||
chains `devbox_resolve` (HTTP, primary) → `nixpkgs_git_resolve`
|
chains `devbox_resolve` (HTTP, primary) → `nixpkgs_git_resolve`
|
||||||
(offline, fallback). Returns a 40-char nixpkgs SHA. Wildcards
|
(offline, fallback). Returns a 40-char nixpkgs SHA. Wildcards
|
||||||
|
|||||||
@@ -308,8 +308,8 @@ mitigation is to append `-<short-sha>` to the input attr.
|
|||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| 1. devbox_resolve + parser | ✅ | `df2c25b` |
|
| 1. devbox_resolve + parser | ✅ | `df2c25b` |
|
||||||
| 2. nixpkgs_git_resolve fallback | ✅ | `cb82e91` |
|
| 2. nixpkgs_git_resolve fallback | ✅ | `cb82e91` |
|
||||||
| 3. resolve_version + cmd_add wire-up | ✅ | (this commit) |
|
| 3. resolve_version + cmd_add wire-up | ✅ | `6f8e9c4` |
|
||||||
| 4. cmd_build lockfile merge | pending | — |
|
| 4. cmd_build lockfile merge | ✅ | (this commit) |
|
||||||
| 5. flake codegen for per-dep inputs | pending | — |
|
| 5. flake codegen for per-dep inputs | pending | — |
|
||||||
| 6. SPEC §7/§10 amendment + smoke | pending | — |
|
| 6. SPEC §7/§10 amendment + smoke | pending | — |
|
||||||
|
|
||||||
|
|||||||
@@ -34,12 +34,27 @@ auto write_text(const fs::path& path, std::string_view content) -> util::Result<
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Synthesizes a fresh lockfile from the manifest + resolved recipes. Without a
|
// Builds the lockfile from the manifest + resolved recipes, **preserving**
|
||||||
// resolver (M5), `nixpkgs_rev` is left null — flake codegen falls back to the
|
// `nixpkgs_rev` for any (name, version) entry that already exists in
|
||||||
// `nixos-unstable` branch and the user gets a working but non-reproducible
|
// `prior` with a matching key. This is what makes `cargoxx build`
|
||||||
// build. M5 will populate the rev.
|
// idempotent w.r.t. the lockfile — concrete pins written by
|
||||||
auto synthesize_lockfile(const manifest::Manifest& m,
|
// `cargoxx add <pkg>@<ver>` survive subsequent rebuilds. New deps and
|
||||||
const std::vector<linkdb::Recipe>& recipes) -> lockfile::Lockfile {
|
// version bumps get a null rev (today's behaviour); the dep tracks the
|
||||||
|
// shared `nixos-unstable` input until a future `cargoxx update`
|
||||||
|
// repopulates it.
|
||||||
|
auto merge_lockfile(const manifest::Manifest& m,
|
||||||
|
const std::vector<linkdb::Recipe>& recipes,
|
||||||
|
const lockfile::Lockfile& prior) -> lockfile::Lockfile {
|
||||||
|
auto find_prior = [&](const std::string& name, const std::string& version)
|
||||||
|
-> std::optional<lockfile::LockfilePackage> {
|
||||||
|
for (const auto& p : prior.packages) {
|
||||||
|
if (p.name == name && p.version == version) {
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return std::nullopt;
|
||||||
|
};
|
||||||
|
|
||||||
lockfile::Lockfile lock;
|
lockfile::Lockfile lock;
|
||||||
lock.version = 1;
|
lock.version = 1;
|
||||||
|
|
||||||
@@ -59,12 +74,16 @@ auto synthesize_lockfile(const manifest::Manifest& m,
|
|||||||
for (std::size_t i = 0; i < m.dependencies.size(); ++i) {
|
for (std::size_t i = 0; i < m.dependencies.size(); ++i) {
|
||||||
const auto& dep = m.dependencies[i];
|
const auto& dep = m.dependencies[i];
|
||||||
const auto& rec = recipes[i];
|
const auto& rec = recipes[i];
|
||||||
|
std::optional<std::string> rev;
|
||||||
|
if (auto p = find_prior(dep.name, dep.version_spec); p) {
|
||||||
|
rev = p->nixpkgs_rev;
|
||||||
|
}
|
||||||
lock.packages.push_back(lockfile::LockfilePackage{
|
lock.packages.push_back(lockfile::LockfilePackage{
|
||||||
.name = dep.name,
|
.name = dep.name,
|
||||||
.version = dep.version_spec,
|
.version = dep.version_spec,
|
||||||
.dependencies = {},
|
.dependencies = {},
|
||||||
.nixpkgs_attr = rec.nixpkgs_attr,
|
.nixpkgs_attr = rec.nixpkgs_attr,
|
||||||
.nixpkgs_rev = std::nullopt,
|
.nixpkgs_rev = std::move(rev),
|
||||||
.linkdb_source = rec.source,
|
.linkdb_source = rec.source,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -130,7 +149,15 @@ auto cmd_build(const fs::path& project_root, bool no_build, bool release,
|
|||||||
recipes.push_back(std::move(*r));
|
recipes.push_back(std::move(*r));
|
||||||
}
|
}
|
||||||
|
|
||||||
auto lock = synthesize_lockfile(*m, recipes);
|
lockfile::Lockfile prior;
|
||||||
|
if (std::error_code ec; std::filesystem::exists(project_root / "Cargoxx.lock", ec)) {
|
||||||
|
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);
|
||||||
|
|
||||||
codegen::GenerateInputs in{*m, *layout_result, lock, recipes, project_root};
|
codegen::GenerateInputs in{*m, *layout_result, lock, recipes, project_root};
|
||||||
auto flake_text = codegen::flake_nix(in);
|
auto flake_text = codegen::flake_nix(in);
|
||||||
|
|||||||
Reference in New Issue
Block a user