meta: collapse hyperhive's nixpkgs into meta's via follows (#317)

This commit is contained in:
damocles 2026-05-23 14:44:57 +02:00 committed by Mara
parent 0e2319d206
commit 09c51c87aa

View file

@ -242,7 +242,21 @@ fn render_flake(
use std::fmt::Write as _; use std::fmt::Write as _;
let mut out = String::new(); let mut out = String::new();
out.push_str("{\n description = \"hyperhive deployed agents\";\n inputs = {\n"); out.push_str("{\n description = \"hyperhive deployed agents\";\n inputs = {\n");
// Pin canonical nixpkgs revisions at the meta level so every input
// that pulls a nixpkgs sub-input can `follows = "nixpkgs"` and
// collapse to one shared node (closes #317). hyperhive's own
// flake.nix picks `nixos-25.11`; we mirror that here so meta and
// hyperhive don't diverge into two stable channels by default.
// Operator can override these at the meta layer to slide every
// dependent agent onto a different channel in one move.
out.push_str(" nixpkgs.url = \"github:NixOS/nixpkgs/nixos-25.11\";\n");
out.push_str(" nixpkgs-unstable.url = \"github:NixOS/nixpkgs/nixpkgs-unstable\";\n");
let _ = writeln!(out, " hyperhive.url = \"{hyperhive_flake}\";"); let _ = writeln!(out, " hyperhive.url = \"{hyperhive_flake}\";");
// Collapse hyperhive's own `nixpkgs` + `nixpkgs-unstable` inputs
// into meta's. Without this, hyperhive's flake.nix declarations
// become independent `nixpkgs_N` nodes in meta/flake.lock.
out.push_str(" hyperhive.inputs.nixpkgs.follows = \"nixpkgs\";\n");
out.push_str(" hyperhive.inputs.nixpkgs-unstable.follows = \"nixpkgs-unstable\";\n");
for spec in agents { for spec in agents {
let _ = writeln!( let _ = writeln!(
out, out,
@ -329,6 +343,52 @@ fn render_flake(
out out
} }
#[cfg(test)]
mod tests {
use super::*;
fn sample_spec(name: &str, is_manager: bool, port: u16) -> AgentSpec {
AgentSpec {
name: name.to_owned(),
is_manager,
port,
}
}
#[test]
fn render_flake_declares_canonical_nixpkgs() {
let out = render_flake(
"github:example/hyperhive",
8000,
"she/her",
&std::collections::HashMap::new(),
&[sample_spec("alice", false, 9001)],
);
// Top-level nixpkgs inputs pinned by meta — every nested
// nixpkgs input can follow these instead of resolving its own
// (closes #317).
assert!(out.contains("nixpkgs.url = \"github:NixOS/nixpkgs/nixos-25.11\""));
assert!(out.contains("nixpkgs-unstable.url = \"github:NixOS/nixpkgs/nixpkgs-unstable\""));
}
#[test]
fn render_flake_collapses_hyperhive_nixpkgs_via_follows() {
let out = render_flake(
"github:example/hyperhive",
8000,
"she/her",
&std::collections::HashMap::new(),
&[],
);
// hyperhive's own `nixpkgs` + `nixpkgs-unstable` declarations
// get redirected at meta's. Without these, meta/flake.lock
// ends up with separate `nixpkgs_N` nodes for hyperhive's
// copy (the pre-#317 status quo).
assert!(out.contains("hyperhive.inputs.nixpkgs.follows = \"nixpkgs\""));
assert!(out.contains("hyperhive.inputs.nixpkgs-unstable.follows = \"nixpkgs-unstable\""));
}
}
async fn git_is_clean(dir: &Path) -> Result<bool> { async fn git_is_clean(dir: &Path) -> Result<bool> {
let out = lifecycle::git_command() let out = lifecycle::git_command()
.current_dir(dir) .current_dir(dir)