diff options
author | Vincent Ambo <mail@tazj.in> | 2023-05-17T15·33+0300 |
---|---|---|
committer | tazjin <tazjin@tvl.su> | 2023-05-18T19·12+0000 |
commit | ba4807e1de44a234fc9499dad0011440cde113fb (patch) | |
tree | 938107dbb5da42d2146221e63003dc68c89f3b29 /tvix/cli/src/tvix_io.rs | |
parent | 7f99eb44a5c734dba27682025f0dbdc253a7cabd (diff) |
refactor(tvix/cli): split CLI-specific IO logic into TvixIO type r/6159
This adds a wrapper type TvixIO<T: EvalIO>, which can wrap around an arbitrary EvalIO implementation and perform actions needed for the Tvix CLI (marking imported paths as known, and handling __corepkgs__). Change-Id: I5fc1ca199b9f94b21a89103b84575e0f8f58dff9 Reviewed-on: https://cl.tvl.fyi/c/depot/+/8579 Tested-by: BuildkiteCI Reviewed-by: flokli <flokli@flokli.de>
Diffstat (limited to 'tvix/cli/src/tvix_io.rs')
-rw-r--r-- | tvix/cli/src/tvix_io.rs | 78 |
1 files changed, 78 insertions, 0 deletions
diff --git a/tvix/cli/src/tvix_io.rs b/tvix/cli/src/tvix_io.rs new file mode 100644 index 000000000000..401b8a5f48da --- /dev/null +++ b/tvix/cli/src/tvix_io.rs @@ -0,0 +1,78 @@ +//! This module implements a wrapper around tvix-eval's [EvalIO] type, +//! adding functionality which is required by tvix-cli: +//! +//! 1. Marking plain paths known to the reference scanner. +//! 2. Handling the C++ Nix `__corepkgs__`-hack for nixpkgs bootstrapping. +//! +//! All uses of [EvalIO] in tvix-cli must make use of this wrapper, +//! otherwise fundamental features like nixpkgs bootstrapping and hash +//! calculation will not work. + +use crate::KnownPaths; +use smol_str::SmolStr; +use std::cell::RefCell; +use std::path::{Path, PathBuf}; +use std::rc::Rc; +use tvix_eval::{ErrorKind, EvalIO, FileType}; + +pub(crate) struct TvixIO<T: EvalIO> { + /// Ingested paths must be reported to this known paths tracker + /// for accurate build reference scanning. + known_paths: Rc<RefCell<KnownPaths>>, + + // Actual underlying [EvalIO] implementation. + actual: T, +} + +impl<T: EvalIO> TvixIO<T> { + pub(crate) fn new(known_paths: Rc<RefCell<KnownPaths>>, actual: T) -> Self { + Self { + known_paths, + actual, + } + } +} + +impl<T: EvalIO> EvalIO for TvixIO<T> { + fn store_dir(&self) -> Option<String> { + self.actual.store_dir() + } + + fn import_path(&mut self, path: &Path) -> Result<PathBuf, ErrorKind> { + let imported_path = self.actual.import_path(path)?; + self.known_paths + .borrow_mut() + .plain(imported_path.to_string_lossy()); + + Ok(imported_path) + } + + fn path_exists(&mut self, path: PathBuf) -> Result<bool, ErrorKind> { + if path.starts_with("/__corepkgs__") { + return Ok(true); + } + + self.actual.path_exists(path) + } + + fn read_to_string(&mut self, path: PathBuf) -> Result<String, ErrorKind> { + // Bundled version of corepkgs/fetchurl.nix. The counterpart + // of this happens in `main`, where the `nix_path` of the + // evaluation has `nix=/__corepkgs__` added to it. + // + // This workaround is similar to what cppnix does for passing + // the path through. + // + // TODO: this comparison is bad and allocates, we should use + // the sane path library. + if path.starts_with("/__corepkgs__/fetchurl.nix") { + return Ok(include_str!("fetchurl.nix").to_string()); + } + + self.actual.read_to_string(path) + } + + fn read_dir(&mut self, path: PathBuf) -> Result<Vec<(SmolStr, FileType)>, ErrorKind> { + self.actual.read_dir(path) + } +} |