git.delta.rocks / jrsonnet / refs/commits / 2cecfb0ba471

difftreelog

refactor remove GeneralOpts/ConfigureState

Yaroslav Bolyukin2023-01-20parent: #1f5d87f.patch.diff
in: master
Because many options were removed from global state, everything should
be configured manually now

6 files changed

modifiedcmds/jrsonnet/src/main.rsdiffbeforeafterboth
55
6use clap::{CommandFactory, Parser};6use clap::{CommandFactory, Parser};
7use clap_complete::Shell;7use clap_complete::Shell;
8use jrsonnet_cli::{ConfigureState, GeneralOpts, ManifestOpts, OutputOpts, TraceOpts};8use jrsonnet_cli::{ManifestOpts, OutputOpts, TraceOpts, MiscOpts, TlaOpts, StdOpts, GcOpts};
9use jrsonnet_evaluator::{9use jrsonnet_evaluator::{
10 apply_tla,10 apply_tla,
11 error::{Error as JrError, ErrorKind},11 error::{Error as JrError, ErrorKind},
60 #[clap(flatten)]60 #[clap(flatten)]
61 input: InputOpts,61 input: InputOpts,
62 #[clap(flatten)]62 #[clap(flatten)]
63 general: GeneralOpts,63 misc: MiscOpts,
64 #[clap(flatten)]
65 tla: TlaOpts,
66 #[clap(flatten)]
67 std: StdOpts,
68 #[clap(flatten)]
69 gc: GcOpts,
6470
65 #[clap(flatten)]71 #[clap(flatten)]
66 trace: TraceOpts,72 trace: TraceOpts,
129 let s = State::default();135 let s = State::default();
130 let trace = opts136 let trace = opts
131 .trace137 .trace
132 .configure(&s)
133 .expect("this configurator doesn't fail");138 .trace_format();
134 if let Err(e) = main_real(&s, opts) {139 if let Err(e) = main_real(&s, opts) {
135 if let Error::Evaluation(e) = e {140 if let Error::Evaluation(e) = e {
136 let mut out = String::new();141 let mut out = String::new();
145}150}
146151
147fn main_real(s: &State, opts: Opts) -> Result<(), Error> {152fn main_real(s: &State, opts: Opts) -> Result<(), Error> {
148 let (tla, _gc_guard) = opts.general.configure(s)?;153 let _gc_leak_guard= opts.gc.leak_on_exit();
154 let _gc_print_stats = opts.gc.stats_printer();
155 let _stack_depth_override = opts.misc.stack_size_override();
156
157 let import_resolver = opts.misc.import_resolver();
158 s.set_import_resolver(import_resolver);
159
149 let manifest_format = opts.manifest.configure(s)?;160 let std = opts.std.context_initializer(s)?;
161 if let Some(std) = std {
162 s.set_context_initializer(std);
163 }
150164
151 let input = opts.input.input.ok_or(Error::MissingInputArgument)?;165 let input = opts.input.input.ok_or(Error::MissingInputArgument)?;
152 let val = if opts.input.exec {166 let val = if opts.input.exec {
160 s.import(&input)?174 s.import(&input)?
161 };175 };
162176
177 let tla = opts.tla.tla_opts()?;
163 let val = apply_tla(s.clone(), &tla, val)?;178 let val = apply_tla(s.clone(), &tla, val)?;
164179
180 let manifest_format = opts.manifest.manifest_format();
165 if let Some(multi) = opts.output.multi {181 if let Some(multi) = opts.output.multi {
166 if opts.output.create_output_dirs {182 if opts.output.create_output_dirs {
167 let mut dir = multi.clone();183 let mut dir = multi.clone();
modifiedcrates/jrsonnet-cli/src/lib.rsdiffbeforeafterboth
6use std::{env, marker::PhantomData, path::PathBuf};6use std::{env, marker::PhantomData, path::PathBuf};
77
8use clap::Parser;8use clap::Parser;
9use jrsonnet_evaluator::{error::Result, stack::set_stack_depth_limit, FileImportResolver, State};9use jrsonnet_evaluator::{error::Result, stack::{set_stack_depth_limit, StackDepthLimitOverrideGuard, limit_stack_depth}, FileImportResolver, State, ImportResolver};
10use jrsonnet_gcmodule::with_thread_object_space;10use jrsonnet_gcmodule::with_thread_object_space;
11pub use manifest::*;11pub use manifest::*;
12pub use stdlib::*;12pub use stdlib::*;
13pub use tla::*;13pub use tla::*;
14pub use trace::*;14pub use trace::*;
15
16pub trait ConfigureState {
17 type Guards;
18
19 fn configure(&self, s: &State) -> Result<Self::Guards>;
20}
2115
22#[derive(Parser)]16#[derive(Parser)]
23#[clap(next_help_heading = "INPUT")]17#[clap(next_help_heading = "INPUT")]
45 #[clap(long, short = 'J')]39 #[clap(long, short = 'J')]
46 jpath: Vec<PathBuf>,40 jpath: Vec<PathBuf>,
47}41}
48impl ConfigureState for MiscOpts {42impl MiscOpts {
49 type Guards = ();
50 fn configure(&self, s: &State) -> Result<Self::Guards> {43 pub fn import_resolver(&self) -> FileImportResolver {
51 let mut library_paths = self.jpath.clone();44 let mut library_paths = self.jpath.clone();
52 library_paths.reverse();45 library_paths.reverse();
53 if let Some(path) = env::var_os("JSONNET_PATH") {46 if let Some(path) = env::var_os("JSONNET_PATH") {
54 library_paths.extend(env::split_paths(path.as_os_str()));47 library_paths.extend(env::split_paths(path.as_os_str()));
55 }48 }
5649
57 s.set_import_resolver(FileImportResolver::new(library_paths));50 FileImportResolver::new(library_paths)
58
59 set_stack_depth_limit(self.max_stack);
60 Ok(())
61 }51 }
52 pub fn stack_size_override(&self) -> StackDepthLimitOverrideGuard {
53 limit_stack_depth(self.max_stack)
54 }
62}55}
63
64/// General configuration of jsonnet
65#[derive(Parser)]
66#[clap(name = "jrsonnet", version, author)]
67pub struct GeneralOpts {
68 #[clap(flatten)]
69 misc: MiscOpts,
70
71 #[clap(flatten)]
72 tla: TlaOpts,
73 #[clap(flatten)]
74 std: StdOpts,
75
76 #[clap(flatten)]
77 gc: GcOpts,
78}
79
80impl 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 throw
87 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}
9456
95#[derive(Parser)]57#[derive(Parser)]
96#[clap(next_help_heading = "GARBAGE COLLECTION")]58#[clap(next_help_heading = "GARBAGE COLLECTION")]
107 #[clap(long)]69 #[clap(long)]
108 gc_collect_before_printing_stats: bool,70 gc_collect_before_printing_stats: bool,
109}71}
110impl ConfigureState for GcOpts {72impl GcOpts {
111 type Guards = (Option<GcStatsPrinter>, Option<LeakSpace>);73 pub fn stats_printer(&self) -> Option<GcStatsPrinter> {
11274 self.gc_print_stats.then(|| GcStatsPrinter {
75 collect_before_printing_stats: self.gc_collect_before_printing_stats,
76 })
77 }
113 fn configure(&self, _s: &State) -> Result<Self::Guards> {78 pub fn leak_on_exit(&self) -> Option<LeakSpace> {
114 // Constructed structs have side-effects in Drop impl
115 #[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)),79 (!self.gc_collect_on_exit).then(|| LeakSpace(PhantomData))
121 ))
122 }80 }
123}81}
12482
modifiedcrates/jrsonnet-cli/src/manifest.rsdiffbeforeafterboth
8};8};
9use jrsonnet_stdlib::{TomlFormat, YamlFormat};9use jrsonnet_stdlib::{TomlFormat, YamlFormat};
10
11use crate::ConfigureState;
1210
13#[derive(Clone, ValueEnum)]11#[derive(Clone, ValueEnum)]
14pub enum ManifestFormatName {12pub enum ManifestFormatName {
41 #[clap(long)]39 #[clap(long)]
42 pub preserve_order: bool,40 pub preserve_order: bool,
43}41}
44impl ConfigureState for ManifestOpts {42impl ManifestOpts {
45 type Guards = Box<dyn ManifestFormat>;
46 fn configure(&self, _s: &State) -> Result<Self::Guards> {43 pub fn manifest_format(&self) -> Box<dyn ManifestFormat> {
47 let format: Box<dyn ManifestFormat> = if self.string {44 let format: Box<dyn ManifestFormat> = if self.string {
48 Box::new(StringFormat)45 Box::new(StringFormat)
49 } else {46 } else {
68 )),65 )),
69 }66 }
70 };67 };
71 Ok(if self.yaml_stream {68 if self.yaml_stream {
72 Box::new(YamlStreamFormat(format))69 Box::new(YamlStreamFormat(format))
73 } else {70 } else {
74 format71 format
75 })72 }
76 }73 }
77}74}
7875
modifiedcrates/jrsonnet-cli/src/stdlib.rsdiffbeforeafterboth
3use clap::Parser;3use clap::Parser;
4use jrsonnet_evaluator::{error::Result, tb, trace::PathResolver, State};4use jrsonnet_evaluator::{error::Result, tb, trace::PathResolver, State};
5
6use crate::ConfigureState;5use jrsonnet_stdlib::ContextInitializer;
76
8#[derive(Clone)]7#[derive(Clone)]
9pub struct ExtStr {8pub struct ExtStr {
82 #[clap(long, name = "name=var code path", number_of_values = 1)]81 #[clap(long, name = "name=var code path", number_of_values = 1)]
83 ext_code_file: Vec<ExtFile>,82 ext_code_file: Vec<ExtFile>,
84}83}
85impl ConfigureState for StdOpts {84impl StdOpts {
86 type Guards = ();
87 fn configure(&self, s: &State) -> Result<()> {85 pub fn context_initializer(&self, s: &State) -> Result<Option<ContextInitializer>> {
88 if self.no_stdlib {86 if self.no_stdlib {
89 return Ok(());87 return Ok(None);
90 }88 }
91 let ctx =89 let ctx =
92 jrsonnet_stdlib::ContextInitializer::new(s.clone(), PathResolver::new_cwd_fallback());90 ContextInitializer::new(s.clone(), PathResolver::new_cwd_fallback());
93 for ext in self.ext_str.iter() {91 for ext in self.ext_str.iter() {
94 ctx.add_ext_str((&ext.name as &str).into(), (&ext.value as &str).into());92 ctx.add_ext_str((&ext.name as &str).into(), (&ext.value as &str).into());
95 }93 }
102 for ext in self.ext_code_file.iter() {100 for ext in self.ext_code_file.iter() {
103 ctx.add_ext_code(&ext.name as &str, &ext.value as &str)?;101 ctx.add_ext_code(&ext.name as &str, &ext.value as &str)?;
104 }102 }
105 s.settings_mut().context_initializer = tb!(ctx);103 Ok(Some(ctx))
106 Ok(())
107 }104 }
108}105}
109106
modifiedcrates/jrsonnet-cli/src/tla.rsdiffbeforeafterboth
7};7};
8use jrsonnet_parser::{ParserSettings, Source};8use jrsonnet_parser::{ParserSettings, Source};
99
10use crate::{ConfigureState, ExtFile, ExtStr};10use crate::{ExtFile, ExtStr};
1111
12#[derive(Parser)]12#[derive(Parser)]
13#[clap(next_help_heading = "TOP LEVEL ARGUMENTS")]13#[clap(next_help_heading = "TOP LEVEL ARGUMENTS")]
31 #[clap(long, name = "name=tla code path", number_of_values = 1)]31 #[clap(long, name = "name=tla code path", number_of_values = 1)]
32 tla_code_file: Vec<ExtFile>,32 tla_code_file: Vec<ExtFile>,
33}33}
34impl ConfigureState for TlaOpts {34impl TlaOpts {
35 type Guards = GcHashMap<IStr, TlaArg>;
36 fn configure(&self, _s: &State) -> Result<Self::Guards> {35 pub fn tla_opts(&self) -> Result<GcHashMap<IStr, TlaArg>> {
37 let mut out = GcHashMap::new();36 let mut out = GcHashMap::new();
38 for (name, value) in self37 for (name, value) in self
39 .tla_str38 .tla_str
modifiedcrates/jrsonnet-cli/src/trace.rsdiffbeforeafterboth
5 State,5 State,
6};6};
7
8use crate::ConfigureState;
97
10#[derive(PartialEq, Eq, ValueEnum, Clone)]8#[derive(PartialEq, Eq, ValueEnum, Clone)]
11pub enum TraceFormatName {9pub enum TraceFormatName {
26 #[clap(long, short = 't', default_value = "20")]24 #[clap(long, short = 't', default_value = "20")]
27 max_trace: usize,25 max_trace: usize,
28}26}
29impl ConfigureState for TraceOpts {27impl TraceOpts {
30 type Guards = Box<dyn TraceFormat>;
31 fn configure(&self, _s: &State) -> Result<Self::Guards> {28 pub fn trace_format(&self) -> Box<dyn TraceFormat> {
32 let resolver = PathResolver::new_cwd_fallback();29 let resolver = PathResolver::new_cwd_fallback();
33 let max_trace = self.max_trace;30 let max_trace = self.max_trace;
34 let format: Box<dyn TraceFormat> = match self31 let format: Box<dyn TraceFormat> = match self
46 max_trace,43 max_trace,
47 }),44 }),
48 };45 };
49 Ok(format)46 format
50 }47 }
51}48}
5249