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.rsdiffbeforeafterboth1mod manifest;2mod stdlib;3mod tla;4mod trace;56use std::{env, marker::PhantomData, path::PathBuf};78use clap::Parser;9use jrsonnet_evaluator::{error::Result, stack::set_stack_depth_limit, FileImportResolver, State};10use jrsonnet_gcmodule::with_thread_object_space;11pub use manifest::*;12pub use stdlib::*;13pub use tla::*;14pub use trace::*;1516pub trait ConfigureState {17 type Guards;1819 fn configure(&self, s: &State) -> Result<Self::Guards>;20}2122#[derive(Parser)]23#[clap(next_help_heading = "INPUT")]24pub struct InputOpts {25 /// Treat input as code, evaluate them instead of reading file26 #[clap(long, short = 'e')]27 pub exec: bool,2829 /// Path to the file to be compiled if `--evaluate` is unset, otherwise code itself30 pub input: String,31}3233#[derive(Parser)]34#[clap(next_help_heading = "OPTIONS")]35pub struct MiscOpts {36 /// Maximal allowed number of stack frames,37 /// stack overflow error will be raised if this number gets exceeded.38 #[clap(long, short = 's', default_value = "200")]39 max_stack: usize,4041 /// Library search dirs. (right-most wins)42 /// Any not found `imported` file will be searched in these.43 /// This can also be specified via `JSONNET_PATH` variable,44 /// which should contain a colon-separated (semicolon-separated on Windows) list of directories.45 #[clap(long, short = 'J')]46 jpath: Vec<PathBuf>,47}48impl ConfigureState for MiscOpts {49 type Guards = ();50 fn configure(&self, s: &State) -> Result<Self::Guards> {51 let mut library_paths = self.jpath.clone();52 library_paths.reverse();53 if let Some(path) = env::var_os("JSONNET_PATH") {54 library_paths.extend(env::split_paths(path.as_os_str()));55 }5657 s.set_import_resolver(FileImportResolver::new(library_paths));5859 set_stack_depth_limit(self.max_stack);60 Ok(())61 }62}6364/// General configuration of jsonnet65#[derive(Parser)]66#[clap(name = "jrsonnet", version, author)]67pub struct GeneralOpts {68 #[clap(flatten)]69 misc: MiscOpts,7071 #[clap(flatten)]72 tla: TlaOpts,73 #[clap(flatten)]74 std: StdOpts,7576 #[clap(flatten)]77 gc: GcOpts,78}7980impl ConfigureState for GeneralOpts {81 type Guards = (82 <TlaOpts as ConfigureState>::Guards,83 <GcOpts as ConfigureState>::Guards,84 );85 fn configure(&self, s: &State) -> Result<Self::Guards> {86 // Configure trace first, because tla-code/ext-code can throw87 self.misc.configure(s)?;88 let tla_guards = self.tla.configure(s)?;89 self.std.configure(s)?;90 let gc_guards = self.gc.configure(s)?;91 Ok((tla_guards, gc_guards))92 }93}9495#[derive(Parser)]96#[clap(next_help_heading = "GARBAGE COLLECTION")]97pub struct GcOpts {98 /// Do not skip gc on exit99 #[clap(long)]100 gc_collect_on_exit: bool,101 /// Print gc stats before exit102 #[clap(long)]103 gc_print_stats: bool,104 /// Force garbage collection before printing stats105 /// Useful for checking for memory leaks106 /// Does nothing useless --gc-print-stats is specified107 #[clap(long)]108 gc_collect_before_printing_stats: bool,109}110impl ConfigureState for GcOpts {111 type Guards = (Option<GcStatsPrinter>, Option<LeakSpace>);112113 fn configure(&self, _s: &State) -> Result<Self::Guards> {114 // Constructed structs have side-effects in Drop impl115 #[allow(clippy::unnecessary_lazy_evaluations)]116 Ok((117 self.gc_print_stats.then(|| GcStatsPrinter {118 collect_before_printing_stats: self.gc_collect_before_printing_stats,119 }),120 (!self.gc_collect_on_exit).then(|| LeakSpace(PhantomData)),121 ))122 }123}124125pub struct LeakSpace(PhantomData<()>);126127impl Drop for LeakSpace {128 fn drop(&mut self) {129 with_thread_object_space(|s| s.leak())130 }131}132133pub struct GcStatsPrinter {134 collect_before_printing_stats: bool,135}136impl Drop for GcStatsPrinter {137 fn drop(&mut self) {138 eprintln!("=== GC STATS ===");139 if self.collect_before_printing_stats {140 let collected = jrsonnet_gcmodule::collect_thread_cycles();141 eprintln!("Collected: {}", collected);142 }143 eprintln!("Tracked: {}", jrsonnet_gcmodule::count_thread_tracked())144 }145}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.rsdiffbeforeafterboth--- a/crates/jrsonnet-cli/src/stdlib.rs
+++ b/crates/jrsonnet-cli/src/stdlib.rs
@@ -2,8 +2,7 @@
use clap::Parser;
use jrsonnet_evaluator::{error::Result, tb, trace::PathResolver, State};
-
-use crate::ConfigureState;
+use jrsonnet_stdlib::ContextInitializer;
#[derive(Clone)]
pub struct ExtStr {
@@ -82,14 +81,13 @@
#[clap(long, name = "name=var code path", number_of_values = 1)]
ext_code_file: Vec<ExtFile>,
}
-impl ConfigureState for StdOpts {
- type Guards = ();
- fn configure(&self, s: &State) -> Result<()> {
+impl StdOpts {
+ pub fn context_initializer(&self, s: &State) -> Result<Option<ContextInitializer>> {
if self.no_stdlib {
- return Ok(());
+ return Ok(None);
}
let ctx =
- jrsonnet_stdlib::ContextInitializer::new(s.clone(), PathResolver::new_cwd_fallback());
+ ContextInitializer::new(s.clone(), PathResolver::new_cwd_fallback());
for ext in self.ext_str.iter() {
ctx.add_ext_str((&ext.name as &str).into(), (&ext.value as &str).into());
}
@@ -102,7 +100,6 @@
for ext in self.ext_code_file.iter() {
ctx.add_ext_code(&ext.name as &str, &ext.value as &str)?;
}
- s.settings_mut().context_initializer = tb!(ctx);
- Ok(())
+ Ok(Some(ctx))
}
}
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
}
}