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

difftreelog

refactor(cli) move to split stdlib

Yaroslav Bolyukin2022-07-23parent: #06fa714.patch.diff
in: master

5 files changed

modifiedcmds/jrsonnet/Cargo.tomldiffbeforeafterboth
--- a/cmds/jrsonnet/Cargo.toml
+++ b/cmds/jrsonnet/Cargo.toml
@@ -15,6 +15,7 @@
     "jrsonnet-evaluator/exp-preserve-order",
     "jrsonnet-evaluator/exp-serde-preserve-order",
     "jrsonnet-cli/exp-preserve-order",
+    "jrsonnet-cli/exp-serde-preserve-order",
 ]
 # Destructuring of locals
 exp-destruct = ["jrsonnet-evaluator/exp-destruct"]
@@ -27,5 +28,5 @@
 
 mimallocator = { version = "0.1.3", optional = true }
 thiserror = "1.0"
-clap = { version = "3.1", features = ["derive"] }
-clap_complete = { version = "3.1" }
+clap = { version = "3.2", features = ["derive"] }
+clap_complete = { version = "3.2" }
modifiedcrates/jrsonnet-cli/Cargo.tomldiffbeforeafterboth
--- a/crates/jrsonnet-cli/Cargo.toml
+++ b/crates/jrsonnet-cli/Cargo.toml
@@ -7,7 +7,14 @@
 edition = "2021"
 
 [features]
-exp-preserve-order = ["jrsonnet-evaluator/exp-preserve-order"]
+exp-preserve-order = [
+    "jrsonnet-evaluator/exp-preserve-order",
+    "jrsonnet-stdlib/exp-preserve-order",
+]
+exp-serde-preserve-order = [
+    "jrsonnet-evaluator/exp-serde-preserve-order",
+    "jrsonnet-stdlib/exp-serde-preserve-order",
+]
 
 [dependencies]
 jrsonnet-evaluator = { path = "../../crates/jrsonnet-evaluator", version = "0.4.2", features = [
@@ -15,5 +22,6 @@
 ] }
 jrsonnet-parser = { path = "../../crates/jrsonnet-parser", version = "0.4.2" }
 jrsonnet-gcmodule = { version = "0.3.4" }
+jrsonnet-stdlib = { path = "../../crates/jrsonnet-stdlib", version = "0.4.2" }
 
-clap = { version = "3.1", features = ["derive"] }
+clap = { version = "3.2", features = ["derive"] }
deletedcrates/jrsonnet-cli/src/ext.rsdiffbeforeafterboth
before · crates/jrsonnet-cli/src/ext.rs
1use std::{fs::read_to_string, str::FromStr};23use clap::Parser;4use jrsonnet_evaluator::{error::Result, State};56use crate::ConfigureState;78#[derive(Clone)]9pub struct ExtStr {10	pub name: String,11	pub value: String,12}1314impl FromStr for ExtStr {15	type Err = &'static str;16	fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {17		let out: Vec<_> = s.split('=').collect();18		match out.len() {19			1 => Ok(ExtStr {20				name: out[0].to_owned(),21				value: std::env::var(out[0]).or(Err("missing env var"))?,22			}),23			2 => Ok(ExtStr {24				name: out[0].to_owned(),25				value: out[1].to_owned(),26			}),2728			_ => Err("bad ext-str syntax"),29		}30	}31}3233#[derive(Clone)]34pub struct ExtFile {35	pub name: String,36	pub value: String,37}3839impl FromStr for ExtFile {40	type Err = String;4142	fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {43		let out: Vec<&str> = s.split('=').collect();44		if out.len() != 2 {45			return Err("bad ext-file syntax".to_owned());46		}47		let file = read_to_string(&out[1]);48		match file {49			Ok(content) => Ok(Self {50				name: out[0].into(),51				value: content,52			}),53			Err(e) => Err(format!("{}", e)),54		}55	}56}5758#[derive(Parser)]59#[clap(next_help_heading = "EXTERNAL VARIABLES")]60pub struct ExtVarOpts {61	/// Add string external variable.62	/// External variables are globally available so it is preferred63	/// to use top level arguments whenever it's possible.64	/// If [=data] is not set then it will be read from `name` env variable.65	/// Can be accessed from code via `std.extVar("name")`.66	#[clap(67		long,68		short = 'V',69		name = "name[=var data]",70		number_of_values = 1,71		multiple_occurrences = true72	)]73	ext_str: Vec<ExtStr>,74	/// Read string external variable from file.75	/// See also `--ext-str`76	#[clap(77		long,78		name = "name=var path",79		number_of_values = 1,80		multiple_occurrences = true81	)]82	ext_str_file: Vec<ExtFile>,83	/// Add external variable from code.84	/// See also `--ext-str`85	#[clap(86		long,87		name = "name[=var source]",88		number_of_values = 1,89		multiple_occurrences = true90	)]91	ext_code: Vec<ExtStr>,92	/// Read string external variable from file.93	/// See also `--ext-str`94	#[clap(95		long,96		name = "name=var code path",97		number_of_values = 1,98		multiple_occurrences = true99	)]100	ext_code_file: Vec<ExtFile>,101}102impl ConfigureState for ExtVarOpts {103	fn configure(&self, s: &State) -> Result<()> {104		for ext in self.ext_str.iter() {105			s.add_ext_str((&ext.name as &str).into(), (&ext.value as &str).into());106		}107		for ext in self.ext_str_file.iter() {108			s.add_ext_str((&ext.name as &str).into(), (&ext.value as &str).into());109		}110		for ext in self.ext_code.iter() {111			s.add_ext_code(&ext.name as &str, (&ext.value as &str).into())?;112		}113		for ext in self.ext_code_file.iter() {114			s.add_ext_code(&ext.name as &str, (&ext.value as &str).into())?;115		}116		Ok(())117	}118}
modifiedcrates/jrsonnet-cli/src/lib.rsdiffbeforeafterboth
--- a/crates/jrsonnet-cli/src/lib.rs
+++ b/crates/jrsonnet-cli/src/lib.rs
@@ -1,15 +1,15 @@
-mod ext;
 mod manifest;
+mod stdlib;
 mod tla;
 mod trace;
 
 use std::{env, path::PathBuf};
 
 use clap::Parser;
-pub use ext::*;
 use jrsonnet_evaluator::{error::Result, FileImportResolver, State};
 use jrsonnet_gcmodule::with_thread_object_space;
 pub use manifest::*;
+pub use stdlib::*;
 pub use tla::*;
 pub use trace::*;
 
@@ -31,13 +31,6 @@
 #[derive(Parser)]
 #[clap(next_help_heading = "OPTIONS")]
 pub struct MiscOpts {
-	/// Disable standard library.
-	/// By default standard library will be available via global `std` variable.
-	/// Note that standard library will still be loaded
-	/// if chosen manifestification method is not `none`.
-	#[clap(long)]
-	no_stdlib: bool,
-
 	/// Maximal allowed number of stack frames,
 	/// stack overflow error will be raised if this number gets exceeded.
 	#[clap(long, short = 's', default_value = "200")]
@@ -52,10 +45,6 @@
 }
 impl ConfigureState for MiscOpts {
 	fn configure(&self, s: &State) -> Result<()> {
-		if !self.no_stdlib {
-			s.with_stdlib();
-		}
-
 		let mut library_paths = self.jpath.clone();
 		library_paths.reverse();
 		if let Some(path) = env::var_os("JSONNET_PATH") {
@@ -79,7 +68,7 @@
 	#[clap(flatten)]
 	tla: TLAOpts,
 	#[clap(flatten)]
-	ext: ExtVarOpts,
+	std: StdOpts,
 
 	#[clap(flatten)]
 	trace: TraceOpts,
@@ -91,7 +80,7 @@
 		self.trace.configure(s)?;
 		self.misc.configure(s)?;
 		self.tla.configure(s)?;
-		self.ext.configure(s)?;
+		self.std.configure(s)?;
 		Ok(())
 	}
 }
@@ -114,10 +103,10 @@
 impl GcOpts {
 	pub fn stats_printer(&self) -> (Option<GcStatsPrinter>, Option<LeakSpace>) {
 		(
-			self.gc_print_stats.then(|| GcStatsPrinter {
+			self.gc_print_stats.then_some(GcStatsPrinter {
 				collect_before_printing_stats: self.gc_collect_before_printing_stats,
 			}),
-			(!self.gc_collect_on_exit).then(|| LeakSpace {}),
+			(!self.gc_collect_on_exit).then_some(LeakSpace {}),
 		)
 	}
 }
addedcrates/jrsonnet-cli/src/stdlib.rsdiffbeforeafterboth
--- /dev/null
+++ b/crates/jrsonnet-cli/src/stdlib.rs
@@ -0,0 +1,129 @@
+use std::{fs::read_to_string, str::FromStr};
+
+use clap::Parser;
+use jrsonnet_evaluator::{error::Result, State};
+
+use crate::ConfigureState;
+
+#[derive(Clone)]
+pub struct ExtStr {
+	pub name: String,
+	pub value: String,
+}
+
+impl FromStr for ExtStr {
+	type Err = &'static str;
+	fn from_str(s: &str) -> std::result::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(Clone)]
+pub struct ExtFile {
+	pub name: String,
+	pub value: String,
+}
+
+impl FromStr for ExtFile {
+	type Err = String;
+
+	fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
+		let out: Vec<&str> = s.split('=').collect();
+		if out.len() != 2 {
+			return Err("bad ext-file syntax".to_owned());
+		}
+		let file = read_to_string(&out[1]);
+		match file {
+			Ok(content) => Ok(Self {
+				name: out[0].into(),
+				value: content,
+			}),
+			Err(e) => Err(format!("{}", e)),
+		}
+	}
+}
+
+#[derive(Parser)]
+#[clap(next_help_heading = "STANDARD LIBRARY")]
+pub struct StdOpts {
+	/// Disable standard library.
+	/// By default standard library will be available via global `std` variable.
+	/// Note that standard library will still be loaded
+	/// if chosen manifestification method is not `none`.
+	#[clap(long)]
+	no_stdlib: bool,
+	/// Add string external variable.
+	/// External variables are globally available so it is preferred
+	/// to use top level arguments whenever it's possible.
+	/// If [=data] is not set then it will be read from `name` env variable.
+	/// Can be accessed from code via `std.extVar("name")`.
+	#[clap(
+		long,
+		short = 'V',
+		name = "name[=var data]",
+		number_of_values = 1,
+		multiple_occurrences = true
+	)]
+	ext_str: Vec<ExtStr>,
+	/// Read string external variable from file.
+	/// See also `--ext-str`
+	#[clap(
+		long,
+		name = "name=var path",
+		number_of_values = 1,
+		multiple_occurrences = true
+	)]
+	ext_str_file: Vec<ExtFile>,
+	/// Add external variable from code.
+	/// See also `--ext-str`
+	#[clap(
+		long,
+		name = "name[=var source]",
+		number_of_values = 1,
+		multiple_occurrences = true
+	)]
+	ext_code: Vec<ExtStr>,
+	/// Read string external variable from file.
+	/// See also `--ext-str`
+	#[clap(
+		long,
+		name = "name=var code path",
+		number_of_values = 1,
+		multiple_occurrences = true
+	)]
+	ext_code_file: Vec<ExtFile>,
+}
+impl ConfigureState for StdOpts {
+	fn configure(&self, s: &State) -> Result<()> {
+		if self.no_stdlib {
+			return Ok(());
+		}
+		let ctx = jrsonnet_stdlib::ContextInitializer::new(s.clone());
+		for ext in self.ext_str.iter() {
+			ctx.add_ext_str((&ext.name as &str).into(), (&ext.value as &str).into());
+		}
+		for ext in self.ext_str_file.iter() {
+			ctx.add_ext_str((&ext.name as &str).into(), (&ext.value as &str).into());
+		}
+		for ext in self.ext_code.iter() {
+			ctx.add_ext_code(&ext.name as &str, (&ext.value as &str).into())?;
+		}
+		for ext in self.ext_code_file.iter() {
+			ctx.add_ext_code(&ext.name as &str, (&ext.value as &str).into())?;
+		}
+		s.settings_mut().context_initializer = Box::new(ctx);
+		Ok(())
+	}
+}