diff --git a/hive-meta-flake/src/lib.rs b/hive-meta-flake/src/lib.rs index 4d880481..d2615401 100644 --- a/hive-meta-flake/src/lib.rs +++ b/hive-meta-flake/src/lib.rs @@ -173,19 +173,25 @@ pub fn canonical_inputs_in_lock(raw: &str) -> Vec<&'static str> { /// Render the meta flake. `vars` are the [`FORWARDED_VARS`] pairs with a /// value; `github_disabled` turns the agents' GitHub integration off. Errors /// on a custom agent without an [`AgentPin`]. -#[allow( - clippy::too_many_lines, - reason = "templated string-builder for the meta flake — the length is one \ - contiguous fmt block, splitting it would just hide the shape" -)] pub fn render_flake( hyperhive_url: &str, agents: &[AgentSpec], vars: &[(&'static str, String)], github_disabled: bool, ) -> Result { - use std::fmt::Write as _; let mut out = String::new(); + push_inputs(&mut out, hyperhive_url, agents)?; + push_mk_agent_open(&mut out); + push_agent_service_options(&mut out, vars, github_disabled); + push_agent_environment(&mut out, vars); + push_agent_entries(&mut out, agents); + Ok(out) +} + +/// The flake header and `inputs` block: `hyperhive`, `nixpkgs`, and one input +/// per config-repo agent. +fn push_inputs(out: &mut String, hyperhive_url: &str, agents: &[AgentSpec]) -> Result<()> { + use std::fmt::Write as _; out.push_str("{\n description = \"hyperhive deployed agents\";\n inputs = {\n"); // `hyperhive` is pinned by forge URL and rev, so the flake resolves on // any machine that can reach the forge. `nixpkgs` follows hyperhive's @@ -230,6 +236,12 @@ pub fn render_flake( ); } } + Ok(()) +} + +/// Closes `inputs`, opens `outputs` and the `mkAgent` function up to the +/// start of the per-agent module. +fn push_mk_agent_open(out: &mut String) { out.push_str( " };\n outputs =\n { self, hyperhive, ... }@inputs:\n let\n mkAgent = { name, port, archetype ? null }:\n", ); @@ -254,6 +266,14 @@ pub fn render_flake( { "#, ); +} + +/// Service URL options and the GitHub override inside the per-agent module. +fn push_agent_service_options( + out: &mut String, + vars: &[(&'static str, String)], + github_disabled: bool, +) { // Agent-facing service URLs (`services.hyperhive.agent.forge.url`, `services.hyperhive.agent.matrix.url`): // emit the host's real values as build-time agent config, the same // host-state -> agent-module shape as the CA block above. @@ -279,7 +299,7 @@ pub fn render_flake( // the forge, which a running hive always has, so the caller rejects a // missing `HIVE_FORGE_URL` before it renders. The check is not here because // rendering is a pure string operation the tests exercise directly. - push_forwarded_var_options(&mut out, vars); + push_forwarded_var_options(out, vars); // GitHub integration is on by default in every agent // (`services.hyperhive.agent.github.enable`); the host turns it off swarm-wide via // `services.hyperhive.swarm.github.enable = false`, passed here as @@ -288,6 +308,12 @@ pub fn render_flake( if github_disabled { out.push_str(" services.hyperhive.agent.github.enable = false;\n"); } +} + +/// The rest of the per-agent module: user, hostname, git identity, and the +/// container-wide and harness-service environments. +fn push_agent_environment(out: &mut String, vars: &[(&'static str, String)]) { + use std::fmt::Write as _; out.push_str( r#" # The harness service inside the container runs as a # non-root unix user named after the agent (`damocles`, @@ -374,6 +400,11 @@ pub fn render_flake( nixosConfigurations = { "#, ); +} + +/// One `mkAgent` line per agent, closing `outputs`. +fn push_agent_entries(out: &mut String, agents: &[AgentSpec]) { + use std::fmt::Write as _; for spec in agents { // `source` and `name` are identifiers (`archetypes::store_read`), so // they need no escaping. @@ -390,7 +421,6 @@ pub fn render_flake( ); } out.push_str(" };\n };\n}\n"); - Ok(out) } /// Web UI port range, shared by every agent including the manager.