diff options
| author | tv <tv@krebsco.de> | 2026-11-13 17:03:25 +0000 |
|---|---|---|
| committer | tv <tv@krebsco.de> | 2026-11-13 18:21:08 +0100 |
| commit | 0e0880fc606e9277c1a52e637cebe7dd3438410d (patch) | |
| tree | 74383c8c11b0999c665da1ba66add2220b4ae685 /pkgs/populate/src/run.rs | |
| parent | 96f5ecf73dba5762de4148ce2e9a0fdd3e13270f (diff) | |
populate: deliver flake and flake-input sources natively in Rust
src/flake_input.rs reads what nix flake metadata and nix flake archive
print as JSON itself: it selects the flake or input, decides what the
target fetches or gets copied, and computes the store paths to root,
which are what selected.jq, selfIsRemote.jq, selfLocked.jq, and the Nix
expressions of the shell implementation do there. On the target, fixed
snippets in sh::flake run Nix, getting values as positional parameters,
and send JSON or store paths back. The jq test's cases are unit tests of
the Rust equivalents.
Diffstat (limited to 'pkgs/populate/src/run.rs')
| -rw-r--r-- | pkgs/populate/src/run.rs | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/pkgs/populate/src/run.rs b/pkgs/populate/src/run.rs index 7525cc0..528977c 100644 --- a/pkgs/populate/src/run.rs +++ b/pkgs/populate/src/run.rs @@ -102,6 +102,9 @@ pub struct Context { /// because Nix waits for its LocalCommand, which may not run over a /// multiplexed connection. pub ssh_nix: PathBuf, + /// What nix flake metadata prints for flakes, by reference, so it's + /// obtained only once, even if several sources use the same flake. + metadata: std::cell::RefCell<std::collections::BTreeMap<String, serde_json::Value>>, } impl Context { @@ -127,6 +130,7 @@ impl Context { tmpdir, ssh, ssh_nix, + metadata: Default::default(), }; context.write_ssh(&context.ssh, &context.ssh_options(true))?; context.write_ssh(&context.ssh_nix, &context.ssh_options(false))?; @@ -231,6 +235,25 @@ impl Context { status(&mut command) } + /// What nix flake metadata prints for the flake url, as get gets it, + /// once. + pub fn flake_metadata( + &self, + url: &str, + get: impl FnOnce() -> Result<String>, + ) -> Result<serde_json::Value> { + if let Some(metadata) = self.metadata.borrow().get(url) { + return Ok(metadata.clone()); + } + let metadata: serde_json::Value = serde_json::from_str(&get()?).map_err(|e| { + Failure::Message(format!("error: can't read flake metadata of {url}: {e}")) + })?; + self.metadata + .borrow_mut() + .insert(url.to_string(), metadata.clone()); + Ok(metadata) + } + /// Runs shell code on the target, returning its output. pub fn output(&self, script: &str, args: &[&str]) -> Result<String> { output(&mut self.shell(script, args)) |
