From: Ian Jackson Date: Mon, 3 May 2021 12:38:53 +0000 (+0100) Subject: apitest: Capture and return the output from otter(1) X-Git-Tag: otter-0.6.0~446 X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=commitdiff_plain;h=77efb8f45367c8c6e28a542fd039bf31ec0d140a;p=otter.git apitest: Capture and return the output from otter(1) Signed-off-by: Ian Jackson --- diff --git a/apitest/apitest.rs b/apitest/apitest.rs index 187a87e4..421ce708 100644 --- a/apitest/apitest.rs +++ b/apitest/apitest.rs @@ -632,13 +632,42 @@ _ = "error" # rocket #[error("wait status: {0}")] pub struct ExitStatusError(pub std::process::ExitStatus); +pub struct OtterOutput { + output: Option, +} +impl Deref for OtterOutput { + type Target = fs::File; + fn deref(&self) -> &fs::File { self.output.as_ref().unwrap().as_file() } +} +impl DerefMut for OtterOutput { + fn deref_mut(&mut self) -> &mut fs::File { + self.output.as_mut().unwrap().as_file_mut() + } +} +impl From for String { + fn from(mut oo: OtterOutput) -> String { + let mut s = String::new(); + let mut o = oo.output.take().unwrap(); + o.rewind().unwrap(); + o.read_to_string(&mut s).unwrap(); + s + } +} +impl Drop for OtterOutput { + fn drop(&mut self) { + if let Some(mut o) = self.output.take() { + io::copy(&mut o, &mut io::stdout()).expect("copy otter stdout"); + } + } +} + impl DirSubst { pub fn specs_dir(&self) -> String { format!("{}/specs" , &self.src) } #[throws(AE)] - pub fn otter<'s,S>(&self, xargs: &'s [S]) + pub fn otter<'s,S>(&self, xargs: &'s [S]) -> OtterOutput where &'s S: Into { self.otter_prctx(&default(), xargs)? @@ -646,6 +675,7 @@ impl DirSubst { #[throws(AE)] pub fn otter_prctx<'s,S>(&self, prctx: &PathResolveContext, xargs: &'s [S]) + -> OtterOutput where &'s S: Into { let ds = self; @@ -656,10 +686,14 @@ impl DirSubst { args.push("--spec-dir".to_owned()); args.push(prctx.resolve(&specs) ); args.extend(xargs.iter().map(|s| s.into())); let dbg = format!("running {} {:?}", &exe, &args); + let mut output = NamedTempFile::new_in( + ds.subst("@abstmp@").unwrap() + ).unwrap(); debug!("{}", &dbg); (||{ let mut cmd = Command::new(&exe); cmd.args(&args); + cmd.stdout(output.as_file().try_clone().unwrap()); let st = cmd .spawn().context("spawn")? .wait().context("wait")?; @@ -670,6 +704,9 @@ impl DirSubst { })() .context(dbg) .context("run otter client")?; + + output.rewind().unwrap(); + OtterOutput { output: Some(output) } } #[throws(AE)] diff --git a/src/prelude.rs b/src/prelude.rs index 223f6c88..177220af 100644 --- a/src/prelude.rs +++ b/src/prelude.rs @@ -95,6 +95,7 @@ pub use sha2::{Sha512, Sha512Trunc256}; pub use slotmap::{dense::DenseSlotMap, SparseSecondaryMap, Key as _}; pub use strum::{EnumString, EnumIter, EnumProperty}; pub use strum::{IntoEnumIterator, IntoStaticStr}; +pub use tempfile::NamedTempFile; pub use thiserror::Error; pub use url::Url; pub use vecdeque_stableix::Deque as StableIndexVecDeque;