diff options
Diffstat (limited to 'tvix/glue/src/builtins/mod.rs')
-rw-r--r-- | tvix/glue/src/builtins/mod.rs | 89 |
1 files changed, 53 insertions, 36 deletions
diff --git a/tvix/glue/src/builtins/mod.rs b/tvix/glue/src/builtins/mod.rs index 4081489e0ec3..6149423acff0 100644 --- a/tvix/glue/src/builtins/mod.rs +++ b/tvix/glue/src/builtins/mod.rs @@ -18,13 +18,14 @@ pub use errors::{DerivationError, FetcherError, ImportError}; /// /// As they need to interact with `known_paths`, we also need to pass in /// `known_paths`. -pub fn add_derivation_builtins<IO>(eval: &mut tvix_eval::Evaluation<IO>, io: Rc<TvixStoreIO>) { - eval.builtins - .extend(derivation::derivation_builtins::builtins(Rc::clone(&io))); - - // Add the actual `builtins.derivation` from compiled Nix code - eval.src_builtins - .push(("derivation", include_str!("derivation.nix"))); +pub fn add_derivation_builtins<'co, 'ro, 'env, IO>( + eval_builder: tvix_eval::EvaluationBuilder<'co, 'ro, 'env, IO>, + io: Rc<TvixStoreIO>, +) -> tvix_eval::EvaluationBuilder<'co, 'ro, 'env, IO> { + eval_builder + .add_builtins(derivation::derivation_builtins::builtins(Rc::clone(&io))) + // Add the actual `builtins.derivation` from compiled Nix code + .add_src_builtin("derivation", include_str!("derivation.nix")) } /// Adds fetcher builtins to the passed [tvix_eval::Evaluation]: @@ -32,9 +33,11 @@ pub fn add_derivation_builtins<IO>(eval: &mut tvix_eval::Evaluation<IO>, io: Rc< /// * `fetchurl` /// * `fetchTarball` /// * `fetchGit` -pub fn add_fetcher_builtins<IO>(eval: &mut tvix_eval::Evaluation<IO>, io: Rc<TvixStoreIO>) { - eval.builtins - .extend(fetchers::fetcher_builtins::builtins(Rc::clone(&io))); +pub fn add_fetcher_builtins<'co, 'ro, 'env, IO>( + eval_builder: tvix_eval::EvaluationBuilder<'co, 'ro, 'env, IO>, + io: Rc<TvixStoreIO>, +) -> tvix_eval::EvaluationBuilder<'co, 'ro, 'env, IO> { + eval_builder.add_builtins(fetchers::fetcher_builtins::builtins(Rc::clone(&io))) } /// Adds import-related builtins to the passed [tvix_eval::Evaluation]. @@ -42,10 +45,12 @@ pub fn add_fetcher_builtins<IO>(eval: &mut tvix_eval::Evaluation<IO>, io: Rc<Tvi /// These are `filterSource` and `path` /// /// As they need to interact with the store implementation, we pass [`TvixStoreIO`]. -pub fn add_import_builtins<IO>(eval: &mut tvix_eval::Evaluation<IO>, io: Rc<TvixStoreIO>) { - eval.builtins.extend(import::import_builtins(io)); - +pub fn add_import_builtins<'co, 'ro, 'env, IO>( + eval_builder: tvix_eval::EvaluationBuilder<'co, 'ro, 'env, IO>, + io: Rc<TvixStoreIO>, +) -> tvix_eval::EvaluationBuilder<'co, 'ro, 'env, IO> { // TODO(raitobezarius): evaluate expressing filterSource as Nix code using path (b/372) + eval_builder.add_builtins(import::import_builtins(io)) } #[cfg(test)] @@ -55,12 +60,13 @@ mod tests { use crate::tvix_store_io::TvixStoreIO; use super::{add_derivation_builtins, add_fetcher_builtins, add_import_builtins}; + use clap::Parser; use nix_compat::store_path::hash_placeholder; use rstest::rstest; use tempfile::TempDir; use tvix_build::buildservice::DummyBuildService; use tvix_eval::{EvalIO, EvaluationResult}; - use tvix_store::utils::construct_services; + use tvix_store::utils::{construct_services, ServiceUrlsMemory}; /// evaluates a given nix expression and returns the result. /// Takes care of setting up the evaluator so it knows about the @@ -68,23 +74,26 @@ mod tests { fn eval(str: &str) -> EvaluationResult { // We assemble a complete store in memory. let runtime = tokio::runtime::Runtime::new().expect("Failed to build a Tokio runtime"); - let (blob_service, directory_service, path_info_service) = runtime - .block_on(async { construct_services("memory://", "memory://", "memory://").await }) + let (blob_service, directory_service, path_info_service, nar_calculation_service) = runtime + .block_on(async { + construct_services(ServiceUrlsMemory::parse_from(std::iter::empty::<&str>())).await + }) .expect("Failed to construct store services in memory"); let io = Rc::new(TvixStoreIO::new( blob_service, directory_service, - path_info_service.into(), + path_info_service, + nar_calculation_service.into(), Arc::<DummyBuildService>::default(), runtime.handle().clone(), )); - let mut eval = tvix_eval::Evaluation::new(io.clone() as Rc<dyn EvalIO>, false); - - add_derivation_builtins(&mut eval, Rc::clone(&io)); - add_fetcher_builtins(&mut eval, Rc::clone(&io)); - add_import_builtins(&mut eval, io); + let mut eval_builder = tvix_eval::Evaluation::builder(io.clone() as Rc<dyn EvalIO>); + eval_builder = add_derivation_builtins(eval_builder, Rc::clone(&io)); + eval_builder = add_fetcher_builtins(eval_builder, Rc::clone(&io)); + eval_builder = add_import_builtins(eval_builder, io); + let eval = eval_builder.build(); // run the evaluation itself. eval.evaluate(str, None) @@ -528,14 +537,13 @@ mod tests { assert!(eval_result.errors.is_empty(), "errors should be empty"); } - // Space is an illegal character. + /// Space is an illegal character, but if we specify a name without spaces, it's ok. #[rstest] - #[case( + #[case::rename_success( r#"(builtins.path { name = "valid-name"; path = @fixtures + "/te st"; recursive = true; })"#, true )] - // Space is still an illegal character. - #[case( + #[case::rename_with_spaces_fail( r#"(builtins.path { name = "invalid name"; path = @fixtures + "/te st"; recursive = true; })"#, false )] @@ -574,14 +582,13 @@ mod tests { } } - // Space is an illegal character. + /// Space is an illegal character, but if we specify a name without spaces, it's ok. #[rstest] - #[case( + #[case::rename_success( r#"(builtins.path { name = "valid-name"; path = @fixtures + "/te st"; recursive = false; })"#, true )] - // Space is still an illegal character. - #[case( + #[case::rename_with_spaces_fail( r#"(builtins.path { name = "invalid name"; path = @fixtures + "/te st"; recursive = false; })"#, false )] @@ -622,20 +629,20 @@ mod tests { } #[rstest] - #[case( + #[case::flat_success( r#"(builtins.path { name = "valid-name"; path = @fixtures + "/te st"; recursive = false; sha256 = "sha256-47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU="; })"#, true )] - #[case( - r#"(builtins.path { name = "valid-name"; path = @fixtures + "/te st"; recursive = true; sha256 = "sha256-47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU="; })"#, + #[case::flat_fail( + r#"(builtins.path { name = "valid-name"; path = @fixtures + "/te st"; recursive = false; sha256 = "sha256-d6xi4mKdjkX2JFicDIv5niSzpyI0m/Hnm8GGAIU04kY="; })"#, false )] - #[case( + #[case::recursive_success( r#"(builtins.path { name = "valid-name"; path = @fixtures + "/te st"; recursive = true; sha256 = "sha256-d6xi4mKdjkX2JFicDIv5niSzpyI0m/Hnm8GGAIU04kY="; })"#, true )] - #[case( - r#"(builtins.path { name = "valid-name"; path = @fixtures + "/te st"; recursive = false; sha256 = "sha256-d6xi4mKdjkX2JFicDIv5niSzpyI0m/Hnm8GGAIU04kY="; })"#, + #[case::recursive_fail( + r#"(builtins.path { name = "valid-name"; path = @fixtures + "/te st"; recursive = true; sha256 = "sha256-47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU="; })"#, false )] fn builtins_path_fod_locking(#[case] code: &str, #[case] exp_success: bool) { @@ -739,6 +746,7 @@ mod tests { false )] fn builtins_filter_source_unsupported_files(#[case] code: &str, #[case] exp_success: bool) { + use nix::errno::Errno; use nix::sys::stat; use nix::unistd; use std::os::unix::net::UnixListener; @@ -765,6 +773,15 @@ mod tests { stat::Mode::S_IRWXU, 0, ) + .inspect_err(|e| { + if *e == Errno::EPERM { + eprintln!( + "\ +Missing permissions to create a character device node with mknod(2). +Please run this test as root or set CAP_MKNOD." + ); + } + }) .expect("Failed to create a character device node"); let code_replaced = code.replace("@fixtures", &temp.path().to_string_lossy()); |