git.delta.rocks / jrsonnet / refs/commits / 42a0a06b84b1

difftreelog

fix workaround ugly generate command

Yaroslav Bolyukin2022-06-05parent: #0acb02b.patch.diff
in: master

1 file changed

modifiedcmds/jrsonnet/src/main.rsdiffbeforeafterboth
before · cmds/jrsonnet/src/main.rs
1use std::{2	fs::{create_dir_all, File},3	io::{Read, Write},4	path::PathBuf,5};67use clap::{AppSettings, IntoApp, Parser};8use clap_complete::Shell;9use jrsonnet_cli::{ConfigureState, GcOpts, GeneralOpts, InputOpts, ManifestOpts, OutputOpts};10use jrsonnet_evaluator::{error::LocError, State};1112#[cfg(feature = "mimalloc")]13#[global_allocator]14static GLOBAL: mimallocator::Mimalloc = mimallocator::Mimalloc;1516#[derive(Parser)]17enum SubOpts {18	/// Generate completions for specified shell19	Generate {20		/// Target shell name21		shell: Shell,22	},23}2425#[derive(Parser)]26#[clap(next_help_heading = "DEBUG")]27struct DebugOpts {28	/// Required OS stack size.29	/// This shouldn't be changed unless jrsonnet is failing with stack overflow error.30	#[clap(long, name = "size")]31	pub os_stack: Option<usize>,32}3334#[derive(Parser)]35#[clap(36	global_setting = AppSettings::DeriveDisplayOrder,37	// args_conflicts_with_subcommands = true,38)]39struct Opts {40	#[clap(subcommand)]41	sub: Option<SubOpts>,4243	#[clap(flatten)]44	input: InputOpts,45	#[clap(flatten)]46	general: GeneralOpts,47	#[clap(flatten)]48	manifest: ManifestOpts,49	#[clap(flatten)]50	output: OutputOpts,51	#[clap(flatten)]52	debug: DebugOpts,53	#[clap(flatten)]54	gc: GcOpts,55}5657fn main() {58	let opts: Opts = Opts::parse();5960	if let Some(sub) = opts.sub {61		match sub {62			SubOpts::Generate { shell } => {63				use clap_complete::generate;64				let app = &mut Opts::command();65				let buf = &mut std::io::stdout();66				generate(shell, app, "jrsonnet", buf);67				std::process::exit(0)68			}69		}70	}7172	let success = if let Some(size) = opts.debug.os_stack {73		std::thread::Builder::new()74			.stack_size(size * 1024 * 1024)75			.spawn(|| main_catch(opts))76			.expect("new thread spawned")77			.join()78			.expect("thread finished successfully")79	} else {80		main_catch(opts)81	};82	if !success {83		std::process::exit(1);84	}85}8687#[derive(thiserror::Error, Debug)]88enum Error {89	// Handled differently90	#[error("evaluation error")]91	Evaluation(jrsonnet_evaluator::error::LocError),92	#[error("io error")]93	Io(#[from] std::io::Error),94	#[error("input is not utf8 encoded")]95	Utf8(#[from] std::str::Utf8Error),96}97impl From<LocError> for Error {98	fn from(e: LocError) -> Self {99		Self::Evaluation(e)100	}101}102103fn main_catch(opts: Opts) -> bool {104	let _printer = opts.gc.stats_printer();105	let s = State::default();106	if let Err(e) = main_real(&s, opts) {107		if let Error::Evaluation(e) = e {108			eprintln!("{}", s.stringify_err(&e));109		} else {110			eprintln!("{}", e);111		}112		return false;113	}114	true115}116117fn main_real(s: &State, opts: Opts) -> Result<(), Error> {118	opts.general.configure(s)?;119	opts.manifest.configure(s)?;120121	let val = if opts.input.exec {122		s.evaluate_snippet("<cmdline>".to_owned(), (&opts.input.input as &str).into())?123	} else if opts.input.input == "-" {124		let mut input = Vec::new();125		std::io::stdin().read_to_end(&mut input)?;126		let input_str = std::str::from_utf8(&input)?.into();127		s.evaluate_snippet("<stdin>".to_owned(), input_str)?128	} else {129		s.import(s.resolve_file(&PathBuf::new(), &opts.input.input)?)?130	};131132	let val = s.with_tla(val)?;133134	if let Some(multi) = opts.output.multi {135		if opts.output.create_output_dirs {136			let mut dir = multi.clone();137			dir.pop();138			create_dir_all(dir)?;139		}140		for (file, data) in s.manifest_multi(val)?.iter() {141			let mut path = multi.clone();142			path.push(file as &str);143			if opts.output.create_output_dirs {144				let mut dir = path.clone();145				dir.pop();146				create_dir_all(dir)?;147			}148			println!("{}", path.to_str().expect("path"));149			let mut file = File::create(path)?;150			writeln!(file, "{}", data)?;151		}152	} else if let Some(path) = opts.output.output_file {153		if opts.output.create_output_dirs {154			let mut dir = path.clone();155			dir.pop();156			create_dir_all(dir)?;157		}158		let mut file = File::create(path)?;159		writeln!(file, "{}", s.manifest(val)?)?;160	} else {161		let output = s.manifest(val)?;162		if !output.is_empty() {163			println!("{}", output);164		}165	}166167	Ok(())168}