diff --git a/src/git.rs b/src/git.rs index 80821fb..9c20de1 100644 --- a/src/git.rs +++ b/src/git.rs @@ -8,7 +8,6 @@ use ::std::{ clone::Clone, collections::{BTreeSet, HashMap}, convert::{AsRef, Into}, - format, iter::{IntoIterator, Iterator}, option::Option::{self, Some}, result::Result::{Err, Ok}, @@ -37,15 +36,7 @@ pub struct ExecStatus { } impl ExecStatus { - pub fn new(exitcode: i32, stdout: String, stderr: String) -> Self { - ExecStatus { - exitcode, - stdout, - stderr, - } - } - - pub fn from(exitcode: i32, stdout: Vec, stderr: Vec) -> Self { + pub fn new(exitcode: i32, stdout: Vec, stderr: Vec) -> Self { // TODO: use OsString. ExecStatus { exitcode, @@ -53,18 +44,28 @@ impl ExecStatus { stderr: String::from_utf8_lossy(stderr.as_slice()).to_string(), } } - - pub fn result(self) -> Result<()> { - match self.exitcode { - 0 => Ok(()), - _ => Err(self.into()), - } - } } pub trait Git { fn exec(&self, args: &[&str]) -> Result; + fn exec_log(&self, args: &[&str]) -> Result<()> { + match self.exec(args) { + Ok(_) => { + ::std::eprintln!("[OK] git {:?}", args); + Ok(()) + } + Err(err) => match err.downcast::() { + Ok(status) => { + ::std::assert_ne!(status.exitcode, 0); + ::std::eprintln!("[ERR {:?}] git {:?}", status.exitcode, args); + Err(status.into()) + } + Err(err) => Err(err), + }, + } + } + fn snapshot(&self) -> Result { let status = self.exec(&["for-each-ref", "--format", FIELD_FORMATS.join(",").as_str()])?; let refs = parse_ref(status.stdout.as_bytes())?; @@ -81,26 +82,27 @@ pub trait Git { } fn create_branch(&self, name: &BranchName, base: &BranchName) -> Result<()> { - self.exec(&["branch", "--create-reflog", name.as_str(), base.as_str()]) + self.exec_log(&["branch", "--create-reflog", name.as_str(), base.as_str()]) .map(|_| {}) } fn switch_branch(&self, b: &BranchName) -> Result<()> { - self.exec(&["switch", "--no-guess", b.as_str()]).map(|_| {}) + self.exec_log(&["switch", "--no-guess", b.as_str()]) + .map(|_| {}) } fn create_symref(&self, name: &RefName, target: &RefName, reason: &'static str) -> Result<()> { - self.exec(&["symbolic-ref", "-m", reason, name.as_str(), target.as_str()]) + self.exec_log(&["symbolic-ref", "-m", reason, name.as_str(), target.as_str()]) .map(|_| {}) } fn delete_symref(&self, name: &RefName) -> Result<()> { - self.exec(&["symbolic-ref", "--delete", name.as_str()]) + self.exec_log(&["symbolic-ref", "--delete", name.as_str()]) .map(|_| {}) } fn create_ref(&self, name: &RefName, commit: &ObjectName) -> Result<()> { - self.exec(&[ + self.exec_log(&[ "update-ref", "--no-deref", "--create-reflog", @@ -117,7 +119,7 @@ pub trait Git { new_commit: &ObjectName, cur_commit: &ObjectName, ) -> Result<()> { - self.exec(&[ + self.exec_log(&[ "update-ref", "--no-deref", "--create-reflog", @@ -129,7 +131,7 @@ pub trait Git { } fn delete_ref(&self, name: &RefName, cur_commit: &ObjectName) -> Result<()> { - self.exec(&[ + self.exec_log(&[ "update-ref", "--no-deref", "-d", @@ -140,7 +142,7 @@ pub trait Git { } fn rebase_onto(&self, name: &BranchName) -> Result<()> { - self.exec(&[ + self.exec_log(&[ "rebase", "--committer-date-is-author-date", "--onto", @@ -152,27 +154,28 @@ pub trait Git { } fn push(&self, name: &BranchName, remote: &RemoteName, expect: &ObjectName) -> Result<()> { - self.exec(&[ + self.exec_log(&[ "push", "--set-upstream", - format!("--force-with-lease={}:{}", name.as_str(), expect.as_str()).as_str(), + ::std::format!("--force-with-lease={}:{}", name.as_str(), expect.as_str()).as_str(), remote.as_str(), - format!("{}:{}", name.as_str(), name.as_str()).as_str(), + ::std::format!("{}:{}", name.as_str(), name.as_str()).as_str(), ]) .map(|_| {}) } fn config_set(&self, key: &str, value: &str) -> Result<()> { - self.exec(&["config", "--local", key, value]).map(|_| {}) + self.exec_log(&["config", "--local", key, value]) + .map(|_| {}) } fn config_add(&self, key: &str, value: &str) -> Result<()> { - self.exec(&["config", "--local", "--add", key, value]) + self.exec_log(&["config", "--local", "--add", key, value]) .map(|_| {}) } fn config_unset_pattern(&self, key: &str, pattern: &str) -> Result<()> { - match self.exec(&[ + match self.exec_log(&[ "config", "--local", "--fixed-value", @@ -190,7 +193,7 @@ pub trait Git { } fn fetch_all_prune(&self) -> Result<()> { - self.exec(&["fetch", "--all", "--prune"]).map(|_| {}) + self.exec_log(&["fetch", "--all", "--prune"]).map(|_| {}) } fn forkpoint(&self, base: &RefName, branch: &RefName) -> Result { diff --git a/src/runner.rs b/src/runner.rs index 5b369ad..ec41ca7 100644 --- a/src/runner.rs +++ b/src/runner.rs @@ -1,7 +1,6 @@ use crate::git; use ::anyhow::Result; use ::std::{ - assert_ne, collections::HashMap, convert::Into, option::Option::Some, @@ -28,26 +27,22 @@ impl<'a> Runner<'a> { impl<'a> git::Git for Runner<'a> { fn exec(&self, args: &[&str]) -> Result { - let cmd = Command::new(self.gitpath) + let output = Command::new(self.gitpath) .args(args) .current_dir(&self.workdir) .envs(self.env.iter()) .stdin(Stdio::null()) .stdout(Stdio::piped()) .stderr(Stdio::piped()) - .spawn()?; + .output()?; - let output = cmd.wait_with_output()?; if output.status.success() { - ::std::eprintln!("[OK] git {:?}", args); - Ok(git::ExecStatus::from(0, output.stdout, output.stderr)) + Ok(git::ExecStatus::new(0, output.stdout, output.stderr)) } else if let Some(code) = output.status.code() { - assert_ne!(code, 0); - ::std::eprintln!("[ERR {:?}] git {:?}", code, args); - Err(git::ExecStatus::from(code, output.stdout, output.stderr).into()) + ::std::assert_ne!(code, 0); + Err(git::ExecStatus::new(code, output.stdout, output.stderr).into()) } else { - ::std::eprintln!("[ERR] git {:?}", args); - Err(git::ExecStatus::from(1, output.stdout, output.stderr).into()) + Err(git::ExecStatus::new(1, output.stdout, output.stderr).into()) } } }