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

difftreelog

fix drop empty line on empty output

Yaroslav Bolyukin2021-01-12parent: #5ffc4ed.patch.diff
in: master

1 file changed

modifiedcmds/jrsonnet/src/main.rsdiffbeforeafterboth
before · cmds/jrsonnet/src/main.rs
1use clap::AppSettings;2use clap::Clap;3use jrsonnet_cli::{ConfigureState, GeneralOpts, InputOpts, ManifestOpts, OutputOpts};4use jrsonnet_evaluator::{error::LocError, EvaluationState, ManifestFormat};5use std::{6	fs::{create_dir_all, File},7	io::Read,8	io::Write,9	path::PathBuf,10	rc::Rc,11};1213#[cfg(feature = "mimalloc")]14#[global_allocator]15static GLOBAL: mimallocator::Mimalloc = mimallocator::Mimalloc;1617#[derive(Clap)]18#[clap(help_heading = "DEBUG")]19struct DebugOpts {20	/// Required OS stack size.21	/// This shouldn't be changed unless jrsonnet is failing with stack overflow error.22	#[clap(long, name = "size")]23	pub os_stack: Option<usize>,24}2526#[derive(Clap)]27#[clap(28	global_setting = AppSettings::ColoredHelp,29	global_setting = AppSettings::DeriveDisplayOrder,30)]31struct Opts {32	#[clap(flatten)]33	input: InputOpts,34	#[clap(flatten)]35	general: GeneralOpts,36	#[clap(flatten)]37	manifest: ManifestOpts,38	#[clap(flatten)]39	output: OutputOpts,40	#[clap(flatten)]41	debug: DebugOpts,42}4344fn main() {45	let opts: Opts = Opts::parse();46	let success;47	if let Some(size) = opts.debug.os_stack {48		success = std::thread::Builder::new()49			.stack_size(size * 1024 * 1024)50			.spawn(|| main_catch(opts))51			.expect("new thread spawned")52			.join()53			.expect("thread finished successfully");54	} else {55		success = main_catch(opts)56	}57	if !success {58		std::process::exit(1);59	}60}6162#[derive(thiserror::Error, Debug)]63enum Error {64	// Handled differently65	#[error("evaluation error")]66	Evaluation(jrsonnet_evaluator::error::LocError),67	#[error("io error")]68	Io(#[from] std::io::Error),69	#[error("input is not utf8 encoded")]70	Utf8(#[from] std::str::Utf8Error),71}72impl From<LocError> for Error {73	fn from(e: LocError) -> Self {74		Self::Evaluation(e)75	}76}7778fn main_catch(opts: Opts) -> bool {79	let state = EvaluationState::default();80	if let Err(e) = main_real(&state, opts) {81		if let Error::Evaluation(e) = e {82			eprintln!("{}", state.stringify_err(&e));83		} else {84			eprintln!("{}", e);85		}86		return false;87	}88	true89}9091fn main_real(state: &EvaluationState, opts: Opts) -> Result<(), Error> {92	opts.general.configure(&state)?;93	opts.manifest.configure(&state)?;9495	let val = if opts.input.exec {96		state.set_manifest_format(ManifestFormat::ToString);97		state.evaluate_snippet_raw(98			Rc::new(PathBuf::from("args")),99			(&opts.input.input as &str).into(),100		)?101	} else if opts.input.input == "-" {102		let mut input = Vec::new();103		std::io::stdin().read_to_end(&mut input)?;104		let input_str = std::str::from_utf8(&input)?.into();105		state.evaluate_snippet_raw(Rc::new(PathBuf::from("<stdin>")), input_str)?106	} else {107		state.evaluate_file_raw(&PathBuf::from(opts.input.input))?108	};109110	let val = state.with_tla(val)?;111112	if let Some(multi) = opts.output.multi {113		if opts.output.create_output_dirs {114			let mut dir = multi.clone();115			dir.pop();116			create_dir_all(dir)?;117		}118		for (file, data) in state.manifest_multi(val)?.iter() {119			let mut path = multi.clone();120			path.push(&file as &str);121			if opts.output.create_output_dirs {122				let mut dir = path.clone();123				dir.pop();124				create_dir_all(dir)?;125			}126			println!("{}", path.to_str().expect("path"));127			let mut file = File::create(path)?;128			writeln!(file, "{}", data)?;129		}130	} else if let Some(path) = opts.output.output_file {131		if opts.output.create_output_dirs {132			let mut dir = path.clone();133			dir.pop();134			create_dir_all(dir)?;135		}136		let mut file = File::create(path)?;137		writeln!(file, "{}", state.manifest(val)?)?;138	} else {139		println!("{}", state.manifest(val)?);140	}141142	Ok(())143}
after · cmds/jrsonnet/src/main.rs
1use clap::AppSettings;2use clap::Clap;3use jrsonnet_cli::{ConfigureState, GeneralOpts, InputOpts, ManifestOpts, OutputOpts};4use jrsonnet_evaluator::{error::LocError, EvaluationState, ManifestFormat};5use std::{6	fs::{create_dir_all, File},7	io::Read,8	io::Write,9	path::PathBuf,10	rc::Rc,11};1213#[cfg(feature = "mimalloc")]14#[global_allocator]15static GLOBAL: mimallocator::Mimalloc = mimallocator::Mimalloc;1617#[derive(Clap)]18#[clap(help_heading = "DEBUG")]19struct DebugOpts {20	/// Required OS stack size.21	/// This shouldn't be changed unless jrsonnet is failing with stack overflow error.22	#[clap(long, name = "size")]23	pub os_stack: Option<usize>,24}2526#[derive(Clap)]27#[clap(28	global_setting = AppSettings::ColoredHelp,29	global_setting = AppSettings::DeriveDisplayOrder,30)]31struct Opts {32	#[clap(flatten)]33	input: InputOpts,34	#[clap(flatten)]35	general: GeneralOpts,36	#[clap(flatten)]37	manifest: ManifestOpts,38	#[clap(flatten)]39	output: OutputOpts,40	#[clap(flatten)]41	debug: DebugOpts,42}4344fn main() {45	let opts: Opts = Opts::parse();46	let success;47	if let Some(size) = opts.debug.os_stack {48		success = std::thread::Builder::new()49			.stack_size(size * 1024 * 1024)50			.spawn(|| main_catch(opts))51			.expect("new thread spawned")52			.join()53			.expect("thread finished successfully");54	} else {55		success = main_catch(opts)56	}57	if !success {58		std::process::exit(1);59	}60}6162#[derive(thiserror::Error, Debug)]63enum Error {64	// Handled differently65	#[error("evaluation error")]66	Evaluation(jrsonnet_evaluator::error::LocError),67	#[error("io error")]68	Io(#[from] std::io::Error),69	#[error("input is not utf8 encoded")]70	Utf8(#[from] std::str::Utf8Error),71}72impl From<LocError> for Error {73	fn from(e: LocError) -> Self {74		Self::Evaluation(e)75	}76}7778fn main_catch(opts: Opts) -> bool {79	let state = EvaluationState::default();80	if let Err(e) = main_real(&state, opts) {81		if let Error::Evaluation(e) = e {82			eprintln!("{}", state.stringify_err(&e));83		} else {84			eprintln!("{}", e);85		}86		return false;87	}88	true89}9091fn main_real(state: &EvaluationState, opts: Opts) -> Result<(), Error> {92	opts.general.configure(&state)?;93	opts.manifest.configure(&state)?;9495	let val = if opts.input.exec {96		state.set_manifest_format(ManifestFormat::ToString);97		state.evaluate_snippet_raw(98			Rc::new(PathBuf::from("args")),99			(&opts.input.input as &str).into(),100		)?101	} else if opts.input.input == "-" {102		let mut input = Vec::new();103		std::io::stdin().read_to_end(&mut input)?;104		let input_str = std::str::from_utf8(&input)?.into();105		state.evaluate_snippet_raw(Rc::new(PathBuf::from("<stdin>")), input_str)?106	} else {107		state.evaluate_file_raw(&PathBuf::from(opts.input.input))?108	};109110	let val = state.with_tla(val)?;111112	if let Some(multi) = opts.output.multi {113		if opts.output.create_output_dirs {114			let mut dir = multi.clone();115			dir.pop();116			create_dir_all(dir)?;117		}118		for (file, data) in state.manifest_multi(val)?.iter() {119			let mut path = multi.clone();120			path.push(&file as &str);121			if opts.output.create_output_dirs {122				let mut dir = path.clone();123				dir.pop();124				create_dir_all(dir)?;125			}126			println!("{}", path.to_str().expect("path"));127			let mut file = File::create(path)?;128			writeln!(file, "{}", data)?;129		}130	} else if let Some(path) = opts.output.output_file {131		if opts.output.create_output_dirs {132			let mut dir = path.clone();133			dir.pop();134			create_dir_all(dir)?;135		}136		let mut file = File::create(path)?;137		writeln!(file, "{}", state.manifest(val)?)?;138	} else {139		let output = state.manifest(val)?;140		if !output.is_empty() {141			println!("{}", output);142		}143	}144145	Ok(())146}