From 41ddc37725a59b4af0f7043a7fd66b3fe48f935d Mon Sep 17 00:00:00 2001 From: William Carroll Date: Tue, 6 Sep 2022 13:56:40 -0700 Subject: feat(tvix/eval): Support builtins.readDir Co-authored-by: Griffin Smith Change-Id: I5ff19efbe87d8f571f22ab0480500505afa624c5 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6552 Autosubmit: wpcarro Reviewed-by: tazjin Tested-by: BuildkiteCI --- tvix/eval/src/builtins/impure.rs | 41 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) (limited to 'tvix/eval/src/builtins') diff --git a/tvix/eval/src/builtins/impure.rs b/tvix/eval/src/builtins/impure.rs index 8e23003edb47..32653b665c36 100644 --- a/tvix/eval/src/builtins/impure.rs +++ b/tvix/eval/src/builtins/impure.rs @@ -1,6 +1,7 @@ use std::{ cell::RefCell, collections::{BTreeMap, HashMap}, + io, rc::Rc, time::{SystemTime, UNIX_EPOCH}, }; @@ -8,13 +9,49 @@ use std::{ use crate::{ errors::ErrorKind, observer::NoOpObserver, - value::{Builtin, NixString, Thunk}, + value::{Builtin, NixAttrs, NixString, Thunk}, vm::VM, SourceCode, Value, }; fn impure_builtins() -> Vec { - vec![] + vec![Builtin::new( + "readDir", + &[true], + |args: Vec, vm: &mut VM| { + let path = super::coerce_value_to_path(&args[0], vm)?; + let mk_err = |err: io::Error| ErrorKind::IO { + path: Some(path.clone()), + error: Rc::new(err), + }; + + let mut res = BTreeMap::new(); + for entry in path.read_dir().map_err(mk_err)? { + let entry = entry.map_err(mk_err)?; + let file_type = entry + .metadata() + .map_err(|err| ErrorKind::IO { + path: Some(entry.path()), + error: Rc::new(err), + })? + .file_type(); + let val = if file_type.is_dir() { + "directory" + } else if file_type.is_file() { + "regular" + } else if file_type.is_symlink() { + "symlink" + } else { + "unknown" + }; + res.insert( + entry.file_name().to_string_lossy().as_ref().into(), + val.into(), + ); + } + Ok(Value::attrs(NixAttrs::from_map(res))) + }, + )] } /// Return all impure builtins, that is all builtins which may perform I/O -- cgit 1.4.1