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

difftreelog

source

crates/jrsonnet-cli/src/lib.rs3.5 KiBsourcehistory
1mod ext;2mod manifest;3mod tla;4mod trace;56use std::{env, path::PathBuf};78use clap::Parser;9pub use ext::*;10use jrsonnet_evaluator::{error::Result, FileImportResolver, State};11pub use manifest::*;12pub use tla::*;13pub use trace::*;1415pub trait ConfigureState {16	fn configure(&self, s: &State) -> Result<()>;17}1819#[derive(Parser)]20#[clap(next_help_heading = "INPUT")]21pub struct InputOpts {22	/// Treat input as code, evaluate them instead of reading file23	#[clap(long, short = 'e')]24	pub exec: bool,2526	/// Path to the file to be compiled if `--evaluate` is unset, otherwise code itself27	pub input: String,28}2930#[derive(Parser)]31#[clap(next_help_heading = "OPTIONS")]32pub struct MiscOpts {33	/// Disable standard library.34	/// By default standard library will be available via global `std` variable.35	/// Note that standard library will still be loaded36	/// if chosen manifestification method is not `none`.37	#[clap(long)]38	no_stdlib: bool,3940	/// Maximal allowed number of stack frames,41	/// stack overflow error will be raised if this number gets exceeded.42	#[clap(long, short = 's', default_value = "200")]43	max_stack: usize,4445	/// Library search dirs. (right-most wins)46	/// Any not found `imported` file will be searched in these.47	/// This can also be specified via `JSONNET_PATH` variable,48	/// which should contain a colon-separated (semicolon-separated on Windows) list of directories.49	#[clap(long, short = 'J', multiple_occurrences = true)]50	jpath: Vec<PathBuf>,51}52impl ConfigureState for MiscOpts {53	fn configure(&self, s: &State) -> Result<()> {54		if !self.no_stdlib {55			s.with_stdlib();56		}5758		let mut library_paths = self.jpath.clone();59		library_paths.reverse();60		if let Some(path) = env::var_os("JSONNET_PATH") {61			library_paths.extend(env::split_paths(path.as_os_str()));62		}6364		s.set_import_resolver(Box::new(FileImportResolver { library_paths }));6566		s.set_max_stack(self.max_stack);67		Ok(())68	}69}7071/// General configuration of jsonnet72#[derive(Parser)]73#[clap(name = "jrsonnet", version, author)]74pub struct GeneralOpts {75	#[clap(flatten)]76	misc: MiscOpts,7778	#[clap(flatten)]79	tla: TLAOpts,80	#[clap(flatten)]81	ext: ExtVarOpts,8283	#[clap(flatten)]84	trace: TraceOpts,85}8687impl ConfigureState for GeneralOpts {88	fn configure(&self, s: &State) -> Result<()> {89		// Configure trace first, because tla-code/ext-code can throw90		self.trace.configure(s)?;91		self.misc.configure(s)?;92		self.tla.configure(s)?;93		self.ext.configure(s)?;94		Ok(())95	}96}9798#[derive(Parser)]99#[clap(next_help_heading = "GARBAGE COLLECTION")]100pub struct GcOpts {101	/// Do not skip gc on exit102	#[clap(long)]103	gc_collect_on_exit: bool,104	/// Print gc stats before exit105	#[clap(long)]106	gc_print_stats: bool,107	/// Force garbage collection before printing stats108	/// Useful for checking for memory leaks109	/// Does nothing useless --gc-print-stats is specified110	#[clap(long)]111	gc_collect_before_printing_stats: bool,112}113impl GcOpts {114	pub fn configure_global(&self) {115		if !self.gc_collect_on_exit {116			gcmodule::set_thread_collect_on_drop(false)117		}118	}119	pub fn stats_printer(&self) -> Option<GcStatsPrinter> {120		self.gc_print_stats.then(|| GcStatsPrinter {121			collect_before_printing_stats: self.gc_collect_before_printing_stats,122		})123	}124}125126pub struct GcStatsPrinter {127	collect_before_printing_stats: bool,128}129impl Drop for GcStatsPrinter {130	fn drop(&mut self) {131		eprintln!("=== GC STATS ===");132		if self.collect_before_printing_stats {133			let collected = gcmodule::collect_thread_cycles();134			eprintln!("Collected: {}", collected);135		}136		eprintln!("Tracked: {}", gcmodule::count_thread_tracked())137	}138}