difftreelog
refactor(cli) move to split stdlib
in: master
5 files changed
cmds/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" }
crates/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"] }
crates/jrsonnet-cli/src/ext.rsdiffbeforeafterboth1use 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}crates/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 {}),
)
}
}
crates/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(())
+ }
+}