diff options
-rw-r--r-- | tvix/cli/src/known_paths.rs | 1 | ||||
-rw-r--r-- | tvix/cli/src/main.rs | 7 | ||||
-rw-r--r-- | tvix/cli/src/nix_compat.rs | 64 |
3 files changed, 45 insertions, 27 deletions
diff --git a/tvix/cli/src/known_paths.rs b/tvix/cli/src/known_paths.rs index 63372c9caaa9..569fb41ba318 100644 --- a/tvix/cli/src/known_paths.rs +++ b/tvix/cli/src/known_paths.rs @@ -29,6 +29,7 @@ pub enum PathType { Plain, } +#[derive(Debug, Default)] pub struct KnownPaths { /// All known paths, and their associated [`PathType`]. paths: HashMap<String, PathType>, diff --git a/tvix/cli/src/main.rs b/tvix/cli/src/main.rs index 42297d365bbf..242cece9ecd2 100644 --- a/tvix/cli/src/main.rs +++ b/tvix/cli/src/main.rs @@ -2,9 +2,12 @@ mod known_paths; mod nix_compat; mod refscan; +use std::cell::RefCell; +use std::rc::Rc; use std::{fs, path::PathBuf}; use clap::Parser; +use known_paths::KnownPaths; use rustyline::{error::ReadlineError, Editor}; use tvix_eval::observer::{DisassemblingObserver, TracingObserver}; use tvix_eval::Value; @@ -48,7 +51,9 @@ struct Args { /// evaluation succeeded. fn interpret(code: &str, path: Option<PathBuf>, args: &Args, explain: bool) -> bool { let mut eval = tvix_eval::Evaluation::new_impure(code, path); - eval.io_handle = Box::new(nix_compat::NixCompatIO::new()); + let known_paths: Rc<RefCell<KnownPaths>> = Default::default(); + + eval.io_handle = Box::new(nix_compat::NixCompatIO::new(known_paths)); eval.nix_path = args.nix_search_path.clone(); let source_map = eval.source_map(); diff --git a/tvix/cli/src/nix_compat.rs b/tvix/cli/src/nix_compat.rs index 75281d90e85b..c3b28c53f6c8 100644 --- a/tvix/cli/src/nix_compat.rs +++ b/tvix/cli/src/nix_compat.rs @@ -5,10 +5,13 @@ //! by piggybacking off functionality that already exists in Nix and //! is still being implemented in Tvix. +use std::cell::RefCell; use std::path::Path; use std::process::Command; +use std::rc::Rc; use std::{io, path::PathBuf}; +use crate::known_paths::KnownPaths; use smol_str::SmolStr; use tvix_eval::{ErrorKind, EvalIO, FileType, StdIO}; @@ -18,12 +21,10 @@ pub struct NixCompatIO { /// Most IO requests are tunneled through to [`tvix_eval::StdIO`] /// instead. underlying: StdIO, -} -impl NixCompatIO { - pub fn new() -> Self { - NixCompatIO { underlying: StdIO } - } + /// Ingested paths must be reported to this known paths tracker + /// for accurate build reference scanning. + known_paths: Rc<RefCell<KnownPaths>>, } impl EvalIO for NixCompatIO { @@ -33,7 +34,7 @@ impl EvalIO for NixCompatIO { // Pass path imports through to `nix-store --add` fn import_path(&self, path: &Path) -> Result<PathBuf, ErrorKind> { - add_to_store(path).map_err(|error| ErrorKind::IO { + self.add_to_store(path).map_err(|error| ErrorKind::IO { error: std::rc::Rc::new(error), path: Some(path.to_path_buf()), }) @@ -53,30 +54,41 @@ impl EvalIO for NixCompatIO { } } -/// Add a path to the Nix store using the `nix-store --add` -/// functionality from C++ Nix. -fn add_to_store(path: &Path) -> Result<PathBuf, io::Error> { - if !path.try_exists()? { - return Err(io::Error::from(io::ErrorKind::NotFound)); +impl NixCompatIO { + pub fn new(known_paths: Rc<RefCell<KnownPaths>>) -> Self { + NixCompatIO { + underlying: StdIO, + known_paths, + } } - let mut cmd = Command::new("nix-store"); - cmd.arg("--add"); - cmd.arg(path); + /// Add a path to the Nix store using the `nix-store --add` + /// functionality from C++ Nix. + fn add_to_store(&self, path: &Path) -> Result<PathBuf, io::Error> { + if !path.try_exists()? { + return Err(io::Error::from(io::ErrorKind::NotFound)); + } - let out = cmd.output()?; + let mut cmd = Command::new("nix-store"); + cmd.arg("--add"); + cmd.arg(path); - if !out.status.success() { - return Err(io::Error::new( - io::ErrorKind::Other, - String::from_utf8_lossy(&out.stderr), - )); - } + let out = cmd.output()?; + + if !out.status.success() { + return Err(io::Error::new( + io::ErrorKind::Other, + String::from_utf8_lossy(&out.stderr), + )); + } - let out_path_str = String::from_utf8(out.stdout) - .map_err(|err| io::Error::new(io::ErrorKind::InvalidData, err))?; + let out_path_str = String::from_utf8(out.stdout) + .map_err(|err| io::Error::new(io::ErrorKind::InvalidData, err))?; - let mut out_path = PathBuf::new(); - out_path.push(out_path_str.trim()); - Ok(out_path) + self.known_paths.borrow_mut().plain(&out_path_str); + + let mut out_path = PathBuf::new(); + out_path.push(out_path_str.trim()); + Ok(out_path) + } } |