feat(tvix/eval): add configuration of Nix search path to public API

This is required for passing through NIX_PATH from the CLI.

Change-Id: If129df79ef9c3ffab31408adb85679909276c4f0
Reviewed-on: https://cl.tvl.fyi/c/depot/+/7544
Reviewed-by: grfn <grfn@gws.fyi>
Autosubmit: tazjin <tazjin@tvl.su>
Tested-by: BuildkiteCI
This commit is contained in:
Vincent Ambo 2022-12-09 12:47:54 +03:00 committed by tazjin
parent 9d6ee5b6a6
commit 9bc1e6ef05
2 changed files with 33 additions and 2 deletions

View file

@ -37,6 +37,7 @@ mod tests;
use std::path::PathBuf;
use std::rc::Rc;
use std::str::FromStr;
use std::sync::Arc;
// Re-export the public interface used by other crates.
@ -47,7 +48,7 @@ pub use crate::pretty_ast::pretty_print_expr;
pub use crate::source::SourceCode;
pub use crate::value::Value;
pub use crate::vm::run_lambda;
pub use crate::warnings::EvalWarning;
pub use crate::warnings::{EvalWarning, WarningKind};
/// Internal-only parts of `tvix-eval`, exported for use in macros, but not part of the public
/// interface of the crate.
@ -65,6 +66,9 @@ pub(crate) fn unwrap_or_clone_rc<T: Clone>(rc: Rc<T>) -> T {
/// An `Evaluation` represents how a piece of Nix code is evaluated. It can be
/// instantiated and configured directly, or it can be accessed through the
/// various simplified helper methods available below.
///
/// Public fields are intended to be set by the caller. Setting all
/// fields is optional.
#[derive(Clone)]
pub struct Evaluation<'a> {
/// The Nix source code to be evaluated.
@ -83,6 +87,10 @@ pub struct Evaluation<'a> {
/// Root expression of the Nix code after parsing.
expr: Option<rnix::ast::Expr>,
/// (optional) Nix search path, e.g. the value of `NIX_PATH` used
/// for resolving items on the search path (such as `<nixpkgs>`).
pub nix_path: Option<String>,
}
/// Result of evaluating a piece of Nix code. If evaluation succeeded, a value
@ -121,6 +129,7 @@ impl<'a> Evaluation<'a> {
source_map,
file,
expr: None,
nix_path: None,
}
}
@ -177,8 +186,24 @@ impl<'a> Evaluation<'a> {
// If there were no errors during compilation, the resulting bytecode is
// safe to execute.
let nix_path = self
.nix_path
.as_ref()
.and_then(|s| match nix_search_path::NixSearchPath::from_str(s) {
Ok(path) => Some(path),
Err(err) => {
result.warnings.push(EvalWarning {
kind: WarningKind::InvalidNixPath(err.to_string()),
span: self.file.span,
});
None
}
})
.unwrap_or_else(|| Default::default());
let vm_result = run_lambda(
Default::default(), // TODO: add nix search path to `Evaluation`
nix_path,
&mut observer::NoOpObserver::default(), // TODO: runtime observer
compiler_result.lambda,
);

View file

@ -12,6 +12,7 @@ pub enum WarningKind {
UnusedBinding,
ShadowedGlobal(&'static str),
DeprecatedLegacyLet,
InvalidNixPath(String),
/// Tvix internal warning for features triggered by users that are
/// not actually implemented yet, but do not cause runtime failures.
@ -80,6 +81,10 @@ impl EvalWarning {
"legacy `let` syntax used, please rewrite this as `let .. in ...`".to_string()
}
WarningKind::InvalidNixPath(ref err) => {
format!("invalid NIX_PATH resulted in a parse error: {}", err)
}
WarningKind::NotImplemented(what) => {
format!("feature not yet implemented in tvix: {}", what)
}
@ -95,6 +100,7 @@ impl EvalWarning {
WarningKind::UnusedBinding => "W003",
WarningKind::ShadowedGlobal(_) => "W004",
WarningKind::DeprecatedLegacyLet => "W005",
WarningKind::InvalidNixPath(_) => "W006",
WarningKind::NotImplemented(_) => "W999",
}
}