From a17fa92c78a6355adb70c9645627d9f42dc1a7c4 Mon Sep 17 00:00:00 2001 From: cy Date: Thu, 17 Apr 2025 22:25:36 -0400 Subject: [PATCH] some progress at an attempt --- src/bindings/mod.rs | 7 +++++++ src/bindings/nix.cpp | 11 +++++++++++ src/bindings/nix.hpp | 1 + src/store.rs | 20 +++++++++++++++++++- src/uploader.rs | 10 ---------- 5 files changed, 38 insertions(+), 11 deletions(-) diff --git a/src/bindings/mod.rs b/src/bindings/mod.rs index 61a32af..701a15e 100644 --- a/src/bindings/mod.rs +++ b/src/bindings/mod.rs @@ -211,6 +211,13 @@ mod ffi { /// Obtains a handle to the Nix store. fn open_nix_store() -> Result>; + /// Creates a NAR dump from a path. + fn nar_from_path( + self: Pin<&mut CNixStore>, + base_name: Vec, + sender: Box, + ) -> Result<()>; + // ========= // CPathInfo // ========= diff --git a/src/bindings/nix.cpp b/src/bindings/nix.cpp index 3914de1..326e878 100644 --- a/src/bindings/nix.cpp +++ b/src/bindings/nix.cpp @@ -108,6 +108,17 @@ std::unique_ptr> CNixStore::compute_fs_closure(RBasePat return std::make_unique>(result); } +void CNixStore::nar_from_path(RVec base_name, RBox sender) { + RustSink sink(std::move(sender)); + + std::string_view sv((const char *)base_name.data(), base_name.size()); + nix::StorePath store_path(sv); + + // exceptions will be thrown into Rust + this->store->narFromPath(store_path, sink); + sink.eof(); +} + std::unique_ptr open_nix_store() { return std::make_unique(); } diff --git a/src/bindings/nix.hpp b/src/bindings/nix.hpp index 9f4964a..5c79a33 100644 --- a/src/bindings/nix.hpp +++ b/src/bindings/nix.hpp @@ -79,6 +79,7 @@ public: bool flip_direction, bool include_outputs, bool include_derivers); + void nar_from_path(RVec base_name, RBox sender); }; std::unique_ptr open_nix_store(); diff --git a/src/store.rs b/src/store.rs index 4499243..9aa5b44 100644 --- a/src/store.rs +++ b/src/store.rs @@ -4,7 +4,10 @@ use anyhow::{Context, Result}; use nix_compat::store_path::StorePath; use tokio::task; -use crate::{bindings, path_info::PathInfo}; +use crate::{ + bindings::{self, AsyncWriteAdapter}, + path_info::PathInfo, +}; pub struct Store { inner: Arc, @@ -75,4 +78,19 @@ impl Store { .await .unwrap() } + + pub fn make_nar(&self, path: StorePath) -> AsyncWriteAdapter { + let inner = self.inner.clone(); + let (adapter, mut sender) = AsyncWriteAdapter::new(); + + task::spawn_blocking(move || { + if let Err(e) = inner + .store() + .nar_from_path(path.to_string().as_bytes().to_vec(), sender.clone()) + { + let _ = sender.rust_error(e); + } + }); + adapter + } } diff --git a/src/uploader.rs b/src/uploader.rs index eb955a2..f77a3d3 100644 --- a/src/uploader.rs +++ b/src/uploader.rs @@ -139,16 +139,6 @@ impl<'a> Uploader<'a> { Ok(()) } - async fn make_nar(&self) -> Result> { - Ok(Command::new("nix") - .arg("nar") - .arg("dump-path") - .arg(self.path.absolute_path()) - .output() - .await? - .stdout) - } - fn narinfo_from_nar(&self, nar: &[u8]) -> Result { let mut hasher = Sha256::new(); hasher.update(nar);