difftreelog
feat library paths
in: master
5 files changed
cmds/jrsonnet/src/main.rsdiffbeforeafterboth--- a/cmds/jrsonnet/src/main.rs
+++ b/cmds/jrsonnet/src/main.rs
@@ -99,6 +99,9 @@
)]
max_trace: usize,
+ #[clap(long, short = "J", about = "Library search dir")]
+ jpath: Vec<PathBuf>,
+
#[clap(
long,
default_value = "3",
@@ -112,10 +115,15 @@
fn main() {
let opts: Opts = Opts::parse();
- let evaluator = jsonnet_evaluator::EvaluationState::new(EvaluationSettings {
- import_resolver: Box::new(|path| String::from_utf8(std::fs::read(path).unwrap()).unwrap()),
- ..Default::default()
- });
+ let evaluator = jsonnet_evaluator::EvaluationState::new(
+ EvaluationSettings {
+ max_stack_trace_size: opts.max_trace,
+ max_stack_frames: opts.max_stack,
+ },
+ Box::new(jsonnet_evaluator::FileImportResolver {
+ library_paths: opts.jpath.clone(),
+ }),
+ );
if !opts.no_stdlib {
evaluator.with_stdlib();
}
crates/jsonnet-evaluator/src/error.rsdiffbeforeafterboth--- a/crates/jsonnet-evaluator/src/error.rs
+++ b/crates/jsonnet-evaluator/src/error.rs
@@ -1,5 +1,6 @@
use crate::ValType;
use jsonnet_parser::LocExpr;
+use std::path::PathBuf;
#[derive(Debug)]
pub enum Error {
@@ -24,6 +25,12 @@
StandaloneSuper,
+ ImportFileNotFound(PathBuf, PathBuf),
+ ResolvedFileNotFound(PathBuf),
+ ImportBadFileUtf8(PathBuf),
+ ImportNotSupported(PathBuf, PathBuf),
+ ImportSyntaxError(jsonnet_parser::ParseError),
+
RuntimeError(String),
StackOverflow,
FractionalIndex,
crates/jsonnet-evaluator/src/evaluate.rsdiffbeforeafterboth--- a/crates/jsonnet-evaluator/src/evaluate.rs
+++ b/crates/jsonnet-evaluator/src/evaluate.rs
@@ -785,24 +785,22 @@
}
}
Import(path) => {
- let mut lib_path = loc
+ let mut import_location = loc
.clone()
.expect("imports can't be used without loc_data")
.0
.clone();
- lib_path.pop();
- lib_path.push(path);
- with_state(|s| s.import_file(&lib_path))?
+ import_location.pop();
+ with_state(|s| s.import_file(&import_location, path))?
}
ImportStr(path) => {
- let mut file_path = loc
+ let mut import_location = loc
.clone()
.expect("imports can't be used without loc_data")
.0
.clone();
- file_path.pop();
- file_path.push(path);
- Val::Str(with_state(|s| s.import_file_str(&file_path))?)
+ import_location.pop();
+ Val::Str(with_state(|s| s.import_file_str(&import_location, path))?)
}
Literal(LiteralType::Super) => return create_error(crate::error::Error::StandaloneSuper),
})
crates/jsonnet-evaluator/src/import.rsdiffbeforeafterbothno changes
crates/jsonnet-evaluator/src/lib.rsdiffbeforeafterboth--- a/crates/jsonnet-evaluator/src/lib.rs
+++ b/crates/jsonnet-evaluator/src/lib.rs
@@ -8,6 +8,7 @@
mod error;
mod evaluate;
mod function;
+mod import;
mod map;
mod obj;
mod val;
@@ -17,6 +18,7 @@
pub use error::*;
pub use evaluate::*;
pub use function::parse_function_call;
+pub use import::*;
use jsonnet_parser::*;
pub use obj::*;
use std::{cell::RefCell, collections::HashMap, fmt::Debug, path::PathBuf, rc::Rc};
@@ -46,16 +48,12 @@
pub struct EvaluationSettings {
pub max_stack_frames: usize,
pub max_stack_trace_size: usize,
- pub import_resolver: Box<dyn Fn(&PathBuf) -> String>,
}
impl Default for EvaluationSettings {
fn default() -> Self {
EvaluationSettings {
max_stack_frames: 200,
max_stack_trace_size: 20,
- import_resolver: Box::new(|path| {
- panic!("default EvaluationSettings have no support for import resolution, can't import {:?}", path)
- }),
}
}
}
@@ -75,6 +73,7 @@
ext_vars: RefCell<HashMap<String, Val>>,
settings: EvaluationSettings,
+ import_resolver: Box<dyn ImportResolver>,
}
thread_local! {
@@ -101,9 +100,10 @@
#[derive(Default, Clone)]
pub struct EvaluationState(Rc<EvaluationStateInternals>);
impl EvaluationState {
- pub fn new(settings: EvaluationSettings) -> Self {
+ pub fn new(settings: EvaluationSettings, import_resolver: Box<dyn ImportResolver>) -> Self {
EvaluationState(Rc::new(EvaluationStateInternals {
settings,
+ import_resolver,
..Default::default()
}))
}
@@ -171,19 +171,29 @@
}
Ok(value)
}
- pub(crate) fn import_file(&self, path: &PathBuf) -> Result<Val> {
- if !self.0.files.borrow().contains_key(path) {
- let file_str = (self.0.settings.import_resolver)(path);
- self.add_file(path.clone(), file_str).unwrap();
+ pub(crate) fn import_file(&self, from: &PathBuf, path: &PathBuf) -> Result<Val> {
+ let file_path = self.0.import_resolver.resolve_file(from, path)?;
+ {
+ let files = self.0.files.borrow();
+ if files.contains_key(&file_path) {
+ return self.evaluate_file(&file_path);
+ }
}
- self.evaluate_file_in_current_state(path)
+ let contents = self.0.import_resolver.load_file_contents(&file_path)?;
+ self.add_file(file_path.clone(), contents).map_err(|e| {
+ create_error::<()>(Error::ImportSyntaxError(e))
+ .err()
+ .unwrap()
+ })?;
+ self.evaluate_file(&file_path)
}
- pub(crate) fn import_file_str(&self, path: &PathBuf) -> Result<String> {
- if !self.0.str_files.borrow().contains_key(path) {
- let file_str = (self.0.settings.import_resolver)(path);
+ pub(crate) fn import_file_str(&self, from: &PathBuf, path: &PathBuf) -> Result<String> {
+ let path = self.0.import_resolver.resolve_file(from, path)?;
+ if !self.0.str_files.borrow().contains_key(&path) {
+ let file_str = self.0.import_resolver.load_file_contents(&path)?;
self.0.str_files.borrow_mut().insert(path.clone(), file_str);
}
- Ok(self.0.str_files.borrow().get(path).cloned().unwrap())
+ Ok(self.0.str_files.borrow().get(&path).cloned().unwrap())
}
pub fn parse_evaluate_raw(&self, code: &str) -> Result<Val> {