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}
after · cmds/jrsonnet/src/main.rs
1use std::{2	env::current_dir,3	fs::{create_dir_all, File},4	io::{Read, Write},5};67use clap::{AppSettings, IntoApp, Parser};8use clap_complete::Shell;9use jrsonnet_cli::{ConfigureState, GcOpts, GeneralOpts, 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(next_help_heading = "INPUT")]36struct InputOpts {37	/// Treat input as code, evaluate them instead of reading file38	#[clap(long, short = 'e')]39	pub exec: bool,4041	/// Path to the file to be compiled if `--evaluate` is unset, otherwise code itself42	pub input: Option<String>,43}4445#[derive(Parser)]46#[clap(47	global_setting = AppSettings::DeriveDisplayOrder,48	args_conflicts_with_subcommands = true,49)]50struct Opts {51	#[clap(subcommand)]52	sub: Option<SubOpts>,5354	#[clap(flatten)]55	input: InputOpts,56	#[clap(flatten)]57	general: GeneralOpts,58	#[clap(flatten)]59	manifest: ManifestOpts,60	#[clap(flatten)]61	output: OutputOpts,62	#[clap(flatten)]63	debug: DebugOpts,64	#[clap(flatten)]65	gc: GcOpts,66}6768fn main() {69	let opts: Opts = Opts::parse();7071	if let Some(sub) = opts.sub {72		match sub {73			SubOpts::Generate { shell } => {74				use clap_complete::generate;75				let app = &mut Opts::command();76				let buf = &mut std::io::stdout();77				generate(shell, app, "jrsonnet", buf);78				std::process::exit(0)79			}80		}81	}8283	let success = if let Some(size) = opts.debug.os_stack {84		std::thread::Builder::new()85			.stack_size(size * 1024 * 1024)86			.spawn(|| main_catch(opts))87			.expect("new thread spawned")88			.join()89			.expect("thread finished successfully")90	} else {91		main_catch(opts)92	};93	if !success {94		std::process::exit(1);95	}96}9798#[derive(thiserror::Error, Debug)]99enum Error {100	// Handled differently101	#[error("evaluation error")]102	Evaluation(jrsonnet_evaluator::error::LocError),103	#[error("io error")]104	Io(#[from] std::io::Error),105	#[error("input is not utf8 encoded")]106	Utf8(#[from] std::str::Utf8Error),107	#[error("missing input argument")]108	MissingInputArgument,109}110impl From<LocError> for Error {111	fn from(e: LocError) -> Self {112		Self::Evaluation(e)113	}114}115116fn main_catch(opts: Opts) -> bool {117	let _printer = opts.gc.stats_printer();118	let s = State::default();119	if let Err(e) = main_real(&s, opts) {120		if let Error::Evaluation(e) = e {121			eprintln!("{}", s.stringify_err(&e));122		} else {123			eprintln!("{}", e);124		}125		return false;126	}127	true128}129130fn main_real(s: &State, opts: Opts) -> Result<(), Error> {131	opts.general.configure(s)?;132	opts.manifest.configure(s)?;133134	let input = opts.input.input.ok_or(Error::MissingInputArgument)?;135	let val = if opts.input.exec {136		s.evaluate_snippet("<cmdline>".to_owned(), (&input as &str).into())?137	} else if input == "-" {138		let mut input = Vec::new();139		std::io::stdin().read_to_end(&mut input)?;140		let input_str = std::str::from_utf8(&input)?.into();141		s.evaluate_snippet("<stdin>".to_owned(), input_str)?142	} else {143		s.import(s.resolve_file(&current_dir().expect("cwd"), &input)?)?144	};145146	let val = s.with_tla(val)?;147148	if let Some(multi) = opts.output.multi {149		if opts.output.create_output_dirs {150			let mut dir = multi.clone();151			dir.pop();152			create_dir_all(dir)?;153		}154		for (file, data) in s.manifest_multi(val)?.iter() {155			let mut path = multi.clone();156			path.push(file as &str);157			if opts.output.create_output_dirs {158				let mut dir = path.clone();159				dir.pop();160				create_dir_all(dir)?;161			}162			println!("{}", path.to_str().expect("path"));163			let mut file = File::create(path)?;164			writeln!(file, "{}", data)?;165		}166	} else if let Some(path) = opts.output.output_file {167		if opts.output.create_output_dirs {168			let mut dir = path.clone();169			dir.pop();170			create_dir_all(dir)?;171		}172		let mut file = File::create(path)?;173		writeln!(file, "{}", s.manifest(val)?)?;174	} else {175		let output = s.manifest(val)?;176		if !output.is_empty() {177			println!("{}", output);178		}179	}180181	Ok(())182}