From 85e5ecabb1d6f1776c1747884dd892ec43f8108a Mon Sep 17 00:00:00 2001 From: Alyssa Ross Date: Sat, 11 Apr 2020 11:30:15 +0000 Subject: Include command in child process error messages --- src/main.rs | 103 +++++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 63 insertions(+), 40 deletions(-) diff --git a/src/main.rs b/src/main.rs index ab3e918..e45a4cb 100644 --- a/src/main.rs +++ b/src/main.rs @@ -8,7 +8,7 @@ use std::io::{self, stderr, stdin, BufRead, BufReader, ErrorKind, Read, Write}; use std::mem::MaybeUninit; use std::os::unix::prelude::*; use std::path::Path; -use std::process::{exit, Command, Stdio}; +use std::process::{exit, Command, ExitStatus, Stdio}; use libc::{ gethostname, posix_spawn_file_actions_adddup2, posix_spawn_file_actions_init, posix_spawnp, @@ -293,11 +293,13 @@ impl<'a> Run<'a> { .arg("--end-of-options") .arg(self.cursor_ref()) .arg(commit) - .status()? - .success() + .status() + .as_ref() + .map(ExitStatus::success) { - true => Ok(()), - false => Err(err_msg("git branch -f failed")), + Ok(true) => Ok(()), + Ok(false) => Err(err_msg("git branch -f failed")), + Err(e) => Err(format_err!("git branch: {}", e)), } } @@ -320,7 +322,7 @@ impl<'a> Run<'a> { message_id_hdr.push(hostname()); message_id_hdr.push(">"); - let mut format_patch = self + let mut format_patch = match self .git("format-patch") .stdout(Stdio::piped()) .arg("--stdout") @@ -329,12 +331,20 @@ impl<'a> Run<'a> { .args(to) .arg("--end-of-options") .arg(format!("{0}~..{0}", commit)) - .spawn()?; + .spawn() + { + Ok(proc) => proc, + Err(e) => return Err(format_err!("git format-patch: {}", e)), + }; - let mut sendmail = Command::new("sendmail") + let mut sendmail = match Command::new("sendmail") .stdin(Stdio::piped()) .args(self.config.recipients) - .spawn()?; + .spawn() + { + Ok(proc) => proc, + Err(e) => return Err(format_err!("sendmail: {}", e)), + }; let sendmail_in = sendmail.stdin.as_mut().unwrap(); @@ -384,14 +394,18 @@ impl<'a> Run<'a> { state = new_state; } - if !format_patch.wait()?.success() { - return Err(err_msg("git format-patch failed")); + match format_patch.wait().as_ref().map(ExitStatus::success) { + Ok(true) => {} + Ok(false) => return Err(err_msg("git format-patch failed")), + Err(e) => return Err(format_err!("git format-patch: {}", e)), } drop(sendmail_in); - if !sendmail.wait()?.success() { - return Err(err_msg("sendmail failed")); + match sendmail.wait().as_ref().map(ExitStatus::success) { + Ok(true) => {} + Ok(false) => return Err(err_msg("sendmail failed")), + Err(e) => return Err(format_err!("sendmail: {}", e)), } Ok(()) @@ -460,7 +474,7 @@ impl<'a> Run<'a> { eprintln!("Checking {}", range.to_string_lossy()); } - let mut log = self + let mut log = match self .git("log") .stdout(Stdio::piped()) .stderr(Stdio::piped()) @@ -469,7 +483,11 @@ impl<'a> Run<'a> { .arg("--format=%H") .arg("--end-of-options") .arg(range) - .spawn()?; + .spawn() + { + Ok(proc) => proc, + Err(e) => return Err(format_err!("git log: {}", e)), + }; let log_out = log.stdout.as_mut().expect("git log stdout missing"); let commits = BufReader::new(log_out).split(b'\n'); @@ -493,33 +511,38 @@ impl<'a> Run<'a> { self.send_email(&commit)?; } - if !log.wait()?.success() { - // If it failed due to the ref not existing, this is the first time we're running. - // So all we need to do is create that ref and exit, and then next run we'll start - // from there.p - let mut arg = self.cursor_ref().to_os_string(); - arg.push("^{commit}"); - if !self - .git("rev-parse") - .arg("--verify") - .arg("-q") - .arg(arg) - .status()? - .success() - { - self.update_cursor("FETCH_HEAD", false)?; - eprintln!("Set FETCH_HEAD as the starting point. Any direct pushes from this point on will"); - eprintln!("generate mail in subsequent pushmail runs."); - return Ok(()); - } + match log.wait().as_ref().map(ExitStatus::success) { + Ok(true) => {} + Err(e) => return Err(format_err!("git log: {}", e)), + + Ok(false) => { + // If it failed due to the ref not existing, this is the first time we're running. + // So all we need to do is create that ref and exit, and then next run we'll start + // from there.p + let mut arg = self.cursor_ref().to_os_string(); + arg.push("^{commit}"); + if !self + .git("rev-parse") + .arg("--verify") + .arg("-q") + .arg(arg) + .status()? + .success() + { + self.update_cursor("FETCH_HEAD", false)?; + eprintln!("Set FETCH_HEAD as the starting point. Any direct pushes from this point on will"); + eprintln!("generate mail in subsequent pushmail runs."); + return Ok(()); + } - // Even if stderr is missing, it's probably more appropriate to fail because of the - // failed command at this point. - if let Some(mut log_stderr) = log.stderr { - let _ = copy_stream(&mut log_stderr, &mut stderr()); // Already crashing. - } + // Even if stderr is missing, it's probably more appropriate to fail because of the + // failed command at this point. + if let Some(mut log_stderr) = log.stderr { + let _ = copy_stream(&mut log_stderr, &mut stderr()); // Already crashing. + } - return Err(err_msg("git log failed")); + return Err(err_msg("git log failed")); + } } Ok(()) -- cgit 1.4.1