about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAlyssa Ross <hi@alyssa.is>2020-04-11 11:30:15 +0000
committerAlyssa Ross <hi@alyssa.is>2020-04-11 13:34:36 +0000
commit85e5ecabb1d6f1776c1747884dd892ec43f8108a (patch)
tree200204fd022026b85e12c3f4fbae9f565aae102b
parent03ea0ff5dcee3410d5aa477541c0ef642da4f7ae (diff)
downloadpushmail-85e5ecabb1d6f1776c1747884dd892ec43f8108a.tar
pushmail-85e5ecabb1d6f1776c1747884dd892ec43f8108a.tar.gz
pushmail-85e5ecabb1d6f1776c1747884dd892ec43f8108a.tar.bz2
pushmail-85e5ecabb1d6f1776c1747884dd892ec43f8108a.tar.lz
pushmail-85e5ecabb1d6f1776c1747884dd892ec43f8108a.tar.xz
pushmail-85e5ecabb1d6f1776c1747884dd892ec43f8108a.tar.zst
pushmail-85e5ecabb1d6f1776c1747884dd892ec43f8108a.zip
Include command in child process error messages
-rw-r--r--src/main.rs103
1 files 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(())