difftreelog
refactor remove GeneralOpts/ConfigureState
in: master
Because many options were removed from global state, everything should be configured manually now
6 files changed
cmds/jrsonnet/src/main.rsdiffbeforeafterboth--- a/cmds/jrsonnet/src/main.rs
+++ b/cmds/jrsonnet/src/main.rs
@@ -5,7 +5,7 @@
use clap::{CommandFactory, Parser};
use clap_complete::Shell;
-use jrsonnet_cli::{ConfigureState, GeneralOpts, ManifestOpts, OutputOpts, TraceOpts};
+use jrsonnet_cli::{ManifestOpts, OutputOpts, TraceOpts, MiscOpts, TlaOpts, StdOpts, GcOpts};
use jrsonnet_evaluator::{
apply_tla,
error::{Error as JrError, ErrorKind},
@@ -60,7 +60,13 @@
#[clap(flatten)]
input: InputOpts,
#[clap(flatten)]
- general: GeneralOpts,
+ misc: MiscOpts,
+ #[clap(flatten)]
+ tla: TlaOpts,
+ #[clap(flatten)]
+ std: StdOpts,
+ #[clap(flatten)]
+ gc: GcOpts,
#[clap(flatten)]
trace: TraceOpts,
@@ -129,8 +135,7 @@
let s = State::default();
let trace = opts
.trace
- .configure(&s)
- .expect("this configurator doesn't fail");
+ .trace_format();
if let Err(e) = main_real(&s, opts) {
if let Error::Evaluation(e) = e {
let mut out = String::new();
@@ -145,8 +150,17 @@
}
fn main_real(s: &State, opts: Opts) -> Result<(), Error> {
- let (tla, _gc_guard) = opts.general.configure(s)?;
- let manifest_format = opts.manifest.configure(s)?;
+ let _gc_leak_guard= opts.gc.leak_on_exit();
+ let _gc_print_stats = opts.gc.stats_printer();
+ let _stack_depth_override = opts.misc.stack_size_override();
+
+ let import_resolver = opts.misc.import_resolver();
+ s.set_import_resolver(import_resolver);
+
+ let std = opts.std.context_initializer(s)?;
+ if let Some(std) = std {
+ s.set_context_initializer(std);
+ }
let input = opts.input.input.ok_or(Error::MissingInputArgument)?;
let val = if opts.input.exec {
@@ -160,8 +174,10 @@
s.import(&input)?
};
+ let tla = opts.tla.tla_opts()?;
let val = apply_tla(s.clone(), &tla, val)?;
+ let manifest_format = opts.manifest.manifest_format();
if let Some(multi) = opts.output.multi {
if opts.output.create_output_dirs {
let mut dir = multi.clone();
crates/jrsonnet-cli/src/lib.rsdiffbeforeafterboth--- a/crates/jrsonnet-cli/src/lib.rs
+++ b/crates/jrsonnet-cli/src/lib.rs
@@ -6,19 +6,13 @@
use std::{env, marker::PhantomData, path::PathBuf};
use clap::Parser;
-use jrsonnet_evaluator::{error::Result, stack::set_stack_depth_limit, FileImportResolver, State};
+use jrsonnet_evaluator::{error::Result, stack::{set_stack_depth_limit, StackDepthLimitOverrideGuard, limit_stack_depth}, FileImportResolver, State, ImportResolver};
use jrsonnet_gcmodule::with_thread_object_space;
pub use manifest::*;
pub use stdlib::*;
pub use tla::*;
pub use trace::*;
-
-pub trait ConfigureState {
- type Guards;
- fn configure(&self, s: &State) -> Result<Self::Guards>;
-}
-
#[derive(Parser)]
#[clap(next_help_heading = "INPUT")]
pub struct InputOpts {
@@ -45,50 +39,18 @@
#[clap(long, short = 'J')]
jpath: Vec<PathBuf>,
}
-impl ConfigureState for MiscOpts {
- type Guards = ();
- fn configure(&self, s: &State) -> Result<Self::Guards> {
+impl MiscOpts {
+ pub fn import_resolver(&self) -> FileImportResolver {
let mut library_paths = self.jpath.clone();
library_paths.reverse();
if let Some(path) = env::var_os("JSONNET_PATH") {
library_paths.extend(env::split_paths(path.as_os_str()));
}
- s.set_import_resolver(FileImportResolver::new(library_paths));
-
- set_stack_depth_limit(self.max_stack);
- Ok(())
+ FileImportResolver::new(library_paths)
}
-}
-
-/// General configuration of jsonnet
-#[derive(Parser)]
-#[clap(name = "jrsonnet", version, author)]
-pub struct GeneralOpts {
- #[clap(flatten)]
- misc: MiscOpts,
-
- #[clap(flatten)]
- tla: TlaOpts,
- #[clap(flatten)]
- std: StdOpts,
-
- #[clap(flatten)]
- gc: GcOpts,
-}
-
-impl ConfigureState for GeneralOpts {
- type Guards = (
- <TlaOpts as ConfigureState>::Guards,
- <GcOpts as ConfigureState>::Guards,
- );
- fn configure(&self, s: &State) -> Result<Self::Guards> {
- // Configure trace first, because tla-code/ext-code can throw
- self.misc.configure(s)?;
- let tla_guards = self.tla.configure(s)?;
- self.std.configure(s)?;
- let gc_guards = self.gc.configure(s)?;
- Ok((tla_guards, gc_guards))
+ pub fn stack_size_override(&self) -> StackDepthLimitOverrideGuard {
+ limit_stack_depth(self.max_stack)
}
}
@@ -107,18 +69,14 @@
#[clap(long)]
gc_collect_before_printing_stats: bool,
}
-impl ConfigureState for GcOpts {
- type Guards = (Option<GcStatsPrinter>, Option<LeakSpace>);
-
- fn configure(&self, _s: &State) -> Result<Self::Guards> {
- // Constructed structs have side-effects in Drop impl
- #[allow(clippy::unnecessary_lazy_evaluations)]
- Ok((
- self.gc_print_stats.then(|| GcStatsPrinter {
- collect_before_printing_stats: self.gc_collect_before_printing_stats,
- }),
- (!self.gc_collect_on_exit).then(|| LeakSpace(PhantomData)),
- ))
+impl GcOpts {
+ pub fn stats_printer(&self) -> Option<GcStatsPrinter> {
+ self.gc_print_stats.then(|| GcStatsPrinter {
+ collect_before_printing_stats: self.gc_collect_before_printing_stats,
+ })
+ }
+ pub fn leak_on_exit(&self) -> Option<LeakSpace> {
+ (!self.gc_collect_on_exit).then(|| LeakSpace(PhantomData))
}
}
crates/jrsonnet-cli/src/manifest.rsdiffbeforeafterboth--- a/crates/jrsonnet-cli/src/manifest.rs
+++ b/crates/jrsonnet-cli/src/manifest.rs
@@ -8,8 +8,6 @@
};
use jrsonnet_stdlib::{TomlFormat, YamlFormat};
-use crate::ConfigureState;
-
#[derive(Clone, ValueEnum)]
pub enum ManifestFormatName {
/// Expect string as output, and write them directly
@@ -41,9 +39,8 @@
#[clap(long)]
pub preserve_order: bool,
}
-impl ConfigureState for ManifestOpts {
- type Guards = Box<dyn ManifestFormat>;
- fn configure(&self, _s: &State) -> Result<Self::Guards> {
+impl ManifestOpts {
+ pub fn manifest_format(&self) -> Box<dyn ManifestFormat> {
let format: Box<dyn ManifestFormat> = if self.string {
Box::new(StringFormat)
} else {
@@ -68,11 +65,11 @@
)),
}
};
- Ok(if self.yaml_stream {
+ if self.yaml_stream {
Box::new(YamlStreamFormat(format))
} else {
format
- })
+ }
}
}
crates/jrsonnet-cli/src/stdlib.rsdiffbeforeafterboth1use std::{fs::read_to_string, str::FromStr};23use clap::Parser;4use jrsonnet_evaluator::{error::Result, tb, trace::PathResolver, 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 = "STANDARD LIBRARY")]60pub struct StdOpts {61 /// Disable standard library.62 /// By default standard library will be available via global `std` variable.63 #[clap(long)]64 no_stdlib: bool,65 /// Add string external variable.66 /// External variables are globally available so it is preferred67 /// to use top level arguments whenever it's possible.68 /// If [=data] is not set then it will be read from `name` env variable.69 /// Can be accessed from code via `std.extVar("name")`.70 #[clap(long, short = 'V', name = "name[=var data]", number_of_values = 1)]71 ext_str: Vec<ExtStr>,72 /// Read string external variable from file.73 /// See also `--ext-str`74 #[clap(long, name = "name=var path", number_of_values = 1)]75 ext_str_file: Vec<ExtFile>,76 /// Add external variable from code.77 /// See also `--ext-str`78 #[clap(long, name = "name[=var source]", number_of_values = 1)]79 ext_code: Vec<ExtStr>,80 /// Read string external variable from file.81 /// See also `--ext-str`82 #[clap(long, name = "name=var code path", number_of_values = 1)]83 ext_code_file: Vec<ExtFile>,84}85impl ConfigureState for StdOpts {86 type Guards = ();87 fn configure(&self, s: &State) -> Result<()> {88 if self.no_stdlib {89 return Ok(());90 }91 let ctx =92 jrsonnet_stdlib::ContextInitializer::new(s.clone(), PathResolver::new_cwd_fallback());93 for ext in self.ext_str.iter() {94 ctx.add_ext_str((&ext.name as &str).into(), (&ext.value as &str).into());95 }96 for ext in self.ext_str_file.iter() {97 ctx.add_ext_str((&ext.name as &str).into(), (&ext.value as &str).into());98 }99 for ext in self.ext_code.iter() {100 ctx.add_ext_code(&ext.name as &str, &ext.value as &str)?;101 }102 for ext in self.ext_code_file.iter() {103 ctx.add_ext_code(&ext.name as &str, &ext.value as &str)?;104 }105 s.settings_mut().context_initializer = tb!(ctx);106 Ok(())107 }108}1use std::{fs::read_to_string, str::FromStr};23use clap::Parser;4use jrsonnet_evaluator::{error::Result, tb, trace::PathResolver, State};5use jrsonnet_stdlib::ContextInitializer;67#[derive(Clone)]8pub struct ExtStr {9 pub name: String,10 pub value: String,11}1213impl FromStr for ExtStr {14 type Err = &'static str;15 fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {16 let out: Vec<_> = s.split('=').collect();17 match out.len() {18 1 => Ok(ExtStr {19 name: out[0].to_owned(),20 value: std::env::var(out[0]).or(Err("missing env var"))?,21 }),22 2 => Ok(ExtStr {23 name: out[0].to_owned(),24 value: out[1].to_owned(),25 }),2627 _ => Err("bad ext-str syntax"),28 }29 }30}3132#[derive(Clone)]33pub struct ExtFile {34 pub name: String,35 pub value: String,36}3738impl FromStr for ExtFile {39 type Err = String;4041 fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {42 let out: Vec<&str> = s.split('=').collect();43 if out.len() != 2 {44 return Err("bad ext-file syntax".to_owned());45 }46 let file = read_to_string(out[1]);47 match file {48 Ok(content) => Ok(Self {49 name: out[0].into(),50 value: content,51 }),52 Err(e) => Err(format!("{}", e)),53 }54 }55}5657#[derive(Parser)]58#[clap(next_help_heading = "STANDARD LIBRARY")]59pub struct StdOpts {60 /// Disable standard library.61 /// By default standard library will be available via global `std` variable.62 #[clap(long)]63 no_stdlib: bool,64 /// Add string external variable.65 /// External variables are globally available so it is preferred66 /// to use top level arguments whenever it's possible.67 /// If [=data] is not set then it will be read from `name` env variable.68 /// Can be accessed from code via `std.extVar("name")`.69 #[clap(long, short = 'V', name = "name[=var data]", number_of_values = 1)]70 ext_str: Vec<ExtStr>,71 /// Read string external variable from file.72 /// See also `--ext-str`73 #[clap(long, name = "name=var path", number_of_values = 1)]74 ext_str_file: Vec<ExtFile>,75 /// Add external variable from code.76 /// See also `--ext-str`77 #[clap(long, name = "name[=var source]", number_of_values = 1)]78 ext_code: Vec<ExtStr>,79 /// Read string external variable from file.80 /// See also `--ext-str`81 #[clap(long, name = "name=var code path", number_of_values = 1)]82 ext_code_file: Vec<ExtFile>,83}84impl StdOpts {85 pub fn context_initializer(&self, s: &State) -> Result<Option<ContextInitializer>> {86 if self.no_stdlib {87 return Ok(None);88 }89 let ctx =90 ContextInitializer::new(s.clone(), PathResolver::new_cwd_fallback());91 for ext in self.ext_str.iter() {92 ctx.add_ext_str((&ext.name as &str).into(), (&ext.value as &str).into());93 }94 for ext in self.ext_str_file.iter() {95 ctx.add_ext_str((&ext.name as &str).into(), (&ext.value as &str).into());96 }97 for ext in self.ext_code.iter() {98 ctx.add_ext_code(&ext.name as &str, &ext.value as &str)?;99 }100 for ext in self.ext_code_file.iter() {101 ctx.add_ext_code(&ext.name as &str, &ext.value as &str)?;102 }103 Ok(Some(ctx))104 }105}crates/jrsonnet-cli/src/tla.rsdiffbeforeafterboth--- a/crates/jrsonnet-cli/src/tla.rs
+++ b/crates/jrsonnet-cli/src/tla.rs
@@ -7,7 +7,7 @@
};
use jrsonnet_parser::{ParserSettings, Source};
-use crate::{ConfigureState, ExtFile, ExtStr};
+use crate::{ExtFile, ExtStr};
#[derive(Parser)]
#[clap(next_help_heading = "TOP LEVEL ARGUMENTS")]
@@ -31,9 +31,8 @@
#[clap(long, name = "name=tla code path", number_of_values = 1)]
tla_code_file: Vec<ExtFile>,
}
-impl ConfigureState for TlaOpts {
- type Guards = GcHashMap<IStr, TlaArg>;
- fn configure(&self, _s: &State) -> Result<Self::Guards> {
+impl TlaOpts {
+ pub fn tla_opts(&self) -> Result<GcHashMap<IStr, TlaArg>> {
let mut out = GcHashMap::new();
for (name, value) in self
.tla_str
crates/jrsonnet-cli/src/trace.rsdiffbeforeafterboth--- a/crates/jrsonnet-cli/src/trace.rs
+++ b/crates/jrsonnet-cli/src/trace.rs
@@ -5,8 +5,6 @@
State,
};
-use crate::ConfigureState;
-
#[derive(PartialEq, Eq, ValueEnum, Clone)]
pub enum TraceFormatName {
/// Only show `filename:line:column`
@@ -26,9 +24,8 @@
#[clap(long, short = 't', default_value = "20")]
max_trace: usize,
}
-impl ConfigureState for TraceOpts {
- type Guards = Box<dyn TraceFormat>;
- fn configure(&self, _s: &State) -> Result<Self::Guards> {
+impl TraceOpts {
+ pub fn trace_format(&self) -> Box<dyn TraceFormat> {
let resolver = PathResolver::new_cwd_fallback();
let max_trace = self.max_trace;
let format: Box<dyn TraceFormat> = match self
@@ -46,6 +43,6 @@
max_trace,
}),
};
- Ok(format)
+ format
}
}