git.delta.rocks / jrsonnet / refs/commits / ff03a2a1eb62

difftreelog

feat std.extVar support

Лач2020-06-10parent: #7420435.patch.diff
in: master

4 files changed

modifiedcmds/jrsonnet/src/main.rsdiffbeforeafterboth
--- a/cmds/jrsonnet/src/main.rs
+++ b/cmds/jrsonnet/src/main.rs
@@ -42,19 +42,42 @@
 	}
 }
 
+#[derive(Clone)]
+struct ExtStr {
+	name: String,
+	value: String,
+}
+impl FromStr for ExtStr {
+	type Err = &'static str;
+	fn from_str(s: &str) -> Result<Self, Self::Err> {
+		let out: Vec<_> = s.split('=').collect();
+		match out.len() {
+			1 => Ok(ExtStr {
+				name: out[0].to_owned(),
+				value: std::env::var(out[0]).or(Err("missing env var"))?,
+			}),
+			2 => Ok(ExtStr {
+				name: out[0].to_owned(),
+				value: out[1].to_owned(),
+			}),
+			_ => Err("bad ext-str syntax"),
+		}
+	}
+}
+
 #[derive(Clap)]
 #[clap(version = "0.1.0", author = "Lach <iam@lach.pw>")]
 struct Opts {
 	#[clap(long, about = "Disable global std variable")]
 	no_stdlib: bool,
 	#[clap(long, about = "Add external string")]
-	ext_str: Option<Vec<String>>,
+	ext_str: Vec<ExtStr>,
 	#[clap(long, about = "Add external string from code")]
-	ext_code: Option<Vec<String>>,
+	ext_code: Vec<ExtStr>,
 	#[clap(long, about = "Add TLA")]
-	tla_str: Option<Vec<String>>,
+	tla_str: Vec<ExtStr>,
 	#[clap(long, about = "Add TLA from code")]
-	tla_code: Option<Vec<String>>,
+	tla_code: Vec<ExtStr>,
 	#[clap(long, short = "f", default_value = "json", possible_values = &["none", "json", "yaml"], about = "Output format, wraps resulting value to corresponding std.manifest call")]
 	format: Format,
 	#[clap(long, default_value = "default", possible_values = &["cpp", "go", "default"], about = "Emulated needed stacktrace display")]
@@ -92,6 +115,12 @@
 	if !opts.no_stdlib {
 		evaluator.with_stdlib();
 	}
+	for ExtStr { name, value } in opts.ext_str.iter().cloned() {
+		evaluator.add_ext_var(name, Val::Str(value));
+	}
+	for ExtStr { name, value } in opts.ext_code.iter().cloned() {
+		evaluator.add_ext_var(name, evaluator.parse_evaluate_raw(&value).unwrap());
+	}
 	let mut input = current_dir().unwrap();
 	input.push(opts.input.clone());
 	let code_string = String::from_utf8(std::fs::read(opts.input.clone()).unwrap()).unwrap();
modifiedcrates/jsonnet-evaluator/src/error.rsdiffbeforeafterboth
12 TooManyArgsFunctionHas(usize),12 TooManyArgsFunctionHas(usize),
13 FunctionParameterNotBoundInCall(String),13 FunctionParameterNotBoundInCall(String),
14
15 UndefinedExternalVariable(String),
1416
15 RuntimeError(String),17 RuntimeError(String),
16 StackOverflow,18 StackOverflow,
modifiedcrates/jsonnet-evaluator/src/evaluate.rsdiffbeforeafterboth
--- a/crates/jsonnet-evaluator/src/evaluate.rs
+++ b/crates/jsonnet-evaluator/src/evaluate.rs
@@ -533,6 +533,20 @@
 							panic!("bad pow call");
 						}
 					}
+					("std", "extVar") => {
+						assert_eq!(args.len(), 1);
+						if let Val::Str(a) = evaluate(context, &args[0].1)? {
+							with_state(|s| s.0.ext_vars.borrow().get(&a).cloned()).ok_or_else(
+								|| {
+									create_error::<()>(crate::Error::UndefinedExternalVariable(a))
+										.err()
+										.unwrap()
+								},
+							)?
+						} else {
+							panic!("bad extVar call");
+						}
+					}
 					(ns, name) => panic!("Intristic not found: {}.{}", ns, name),
 				},
 				Val::Func(f) => {
modifiedcrates/jsonnet-evaluator/src/lib.rsdiffbeforeafterboth
--- a/crates/jsonnet-evaluator/src/lib.rs
+++ b/crates/jsonnet-evaluator/src/lib.rs
@@ -72,6 +72,9 @@
 	files: RefCell<HashMap<PathBuf, FileData>>,
 	globals: RefCell<HashMap<String, Val>>,
 
+	/// Values to use with std.extVar
+	ext_vars: RefCell<HashMap<String, Val>>,
+
 	settings: EvaluationSettings,
 }
 
@@ -177,6 +180,9 @@
 	pub fn add_global(&self, name: String, value: Val) {
 		self.0.globals.borrow_mut().insert(name, value);
 	}
+	pub fn add_ext_var(&self, name: String, value: Val) {
+		self.0.ext_vars.borrow_mut().insert(name, value);
+	}
 
 	pub fn with_stdlib(&self) -> &Self {
 		self.begin_state();