From 1076c26c135172a21ce97d041b860ef7ceb172e2 Mon Sep 17 00:00:00 2001 From: Mehran KORDI Date: Thu, 14 May 2020 14:18:43 +0200 Subject: [PATCH 01/26] adding a custom error type. --- Cargo.lock | 56 +++++++++++++++++++++++++++++++++++++++++++ asyncgit/Cargo.toml | 3 ++- asyncgit/src/error.rs | 22 +++++++++++++++++ asyncgit/src/lib.rs | 1 + 4 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 asyncgit/src/error.rs diff --git a/Cargo.lock b/Cargo.lock index 674688ef6c..cebc6a9f82 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -38,6 +38,7 @@ dependencies = [ "rayon-core", "scopetime", "tempfile", + "thiserror", ] [[package]] @@ -565,6 +566,24 @@ version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74490b50b9fbe561ac330df47c08f3f33073d2d00c150f719147d7c54522fa1b" +[[package]] +name = "proc-macro2" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8872cf6f48eee44265156c111456a700ab3483686b3f96df4cf5481c89157319" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "quote" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42934bc9c8ab0d3b273a16d8551c8f0fcff46be73276ca083ec2414c15c4ba5e" +dependencies = [ + "proc-macro2", +] + [[package]] name = "rand" version = "0.7.3" @@ -719,6 +738,17 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c7cb5678e1615754284ec264d9bb5b4c27d2018577fd90ac0ceb578591ed5ee4" +[[package]] +name = "syn" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4696caa4048ac7ce2bcd2e484b3cef88c1004e41b8e945a277e2c25dc0b72060" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + [[package]] name = "tempfile" version = "3.1.0" @@ -733,6 +763,26 @@ dependencies = [ "winapi 0.3.8", ] +[[package]] +name = "thiserror" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "467e5ff447618a916519a4e0d62772ab14f434897f3d63f05d8700ef1e9b22c1" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e63c1091225b9834089b429bc4a2e01223470e3183e891582909e9d1c4cb55d9" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "time" version = "0.1.43" @@ -788,6 +838,12 @@ version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "caaa9d531767d1ff2150b9332433f32a24622147e5ebb1f26409d5da67afd479" +[[package]] +name = "unicode-xid" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" + [[package]] name = "url" version = "2.1.1" diff --git a/asyncgit/Cargo.toml b/asyncgit/Cargo.toml index cc22f3805d..e84d24f0bd 100644 --- a/asyncgit/Cargo.toml +++ b/asyncgit/Cargo.toml @@ -17,4 +17,5 @@ crossbeam-channel = "0.4" log = "0.4" is_executable = "0.1" scopetime = { path = "../scopetime", version = "0.1" } -tempfile = "3.1" \ No newline at end of file +tempfile = "3.1" +thiserror = "1.0" \ No newline at end of file diff --git a/asyncgit/src/error.rs b/asyncgit/src/error.rs new file mode 100644 index 0000000000..ff7a188a03 --- /dev/null +++ b/asyncgit/src/error.rs @@ -0,0 +1,22 @@ +use thiserror::Error; + +#[derive(Error, Debug)] +pub enum Error { + #[error("`{0}`")] + Generic(String), + + #[error("io error")] + Io { + #[from] + source: std::io::Error, + }, + + #[error("git error")] + Git { + #[from] + source: git2::Error, + }, + + #[error(transparent)] + Other(#[from] Box), +} diff --git a/asyncgit/src/lib.rs b/asyncgit/src/lib.rs index 74eb4199b4..96214f5bc9 100644 --- a/asyncgit/src/lib.rs +++ b/asyncgit/src/lib.rs @@ -5,6 +5,7 @@ #![deny(clippy::all)] mod diff; +mod error; mod revlog; mod status; pub mod sync; From 7158c3dd249e8b3eedeb039f98bf7e2031314cef Mon Sep 17 00:00:00 2001 From: Mehran KORDI Date: Thu, 14 May 2020 14:29:35 +0200 Subject: [PATCH 02/26] hooks.rs updated. --- asyncgit/src/sync/hooks.rs | 21 ++++++++++++--------- src/components/commit.rs | 2 +- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/asyncgit/src/sync/hooks.rs b/asyncgit/src/sync/hooks.rs index 2ec3853092..c184c29ab4 100644 --- a/asyncgit/src/sync/hooks.rs +++ b/asyncgit/src/sync/hooks.rs @@ -1,3 +1,4 @@ +use crate::error::Error; use is_executable::IsExecutable; use scopetime::scope_time; use std::{ @@ -14,26 +15,28 @@ const HOOK_COMMIT_MSG: &str = ".git/hooks/commit-msg"; pub fn hooks_commit_msg( repo_path: &str, msg: &mut String, -) -> HookResult { +) -> Result { scope_time!("hooks_commit_msg"); if hook_runable(repo_path, HOOK_COMMIT_MSG) { - let mut file = NamedTempFile::new().unwrap(); + let mut file = NamedTempFile::new()?; - write!(file, "{}", msg).unwrap(); + write!(file, "{}", msg)?; - let file_path = file.path().to_str().unwrap(); + let file_path = file.path().to_str().ok_or_else(|| { + Error::Generic("can't get temp file's path".to_string()) + })?; let res = run_hook(repo_path, HOOK_COMMIT_MSG, &[&file_path]); // load possibly altered msg - let mut file = file.reopen().unwrap(); + let mut file = file.reopen()?; msg.clear(); - file.read_to_string(msg).unwrap(); + file.read_to_string(msg)?; - res + Ok(res) } else { - HookResult::Ok + Ok(HookResult::Ok) } } @@ -94,7 +97,7 @@ mod tests { let repo_path = root.as_os_str().to_str().unwrap(); let mut msg = String::from("test"); - let res = hooks_commit_msg(repo_path, &mut msg); + let res = hooks_commit_msg(repo_path, &mut msg).unwrap(); assert_eq!(res, HookResult::Ok); diff --git a/src/components/commit.rs b/src/components/commit.rs index 86f5205df6..c47360c1f9 100644 --- a/src/components/commit.rs +++ b/src/components/commit.rs @@ -122,7 +122,7 @@ impl CommitComponent { fn commit(&mut self) { if let HookResult::NotOk(e) = - sync::hooks_commit_msg(CWD, &mut self.msg) + sync::hooks_commit_msg(CWD, &mut self.msg).unwrap() { error!("commit-msg hook error: {}", e); self.queue.borrow_mut().push_back( From f96b86ba79e8d5ac8a02e348a39f135f150dce69 Mon Sep 17 00:00:00 2001 From: Mehran KORDI Date: Thu, 14 May 2020 14:36:32 +0200 Subject: [PATCH 03/26] removed unwrap from commits_infos.rs --- asyncgit/src/sync/commits_info.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/asyncgit/src/sync/commits_info.rs b/asyncgit/src/sync/commits_info.rs index d8f5ea3c11..f601c7960a 100644 --- a/asyncgit/src/sync/commits_info.rs +++ b/asyncgit/src/sync/commits_info.rs @@ -24,7 +24,11 @@ pub fn get_commits_info( let repo = repo(repo_path); - let commits = ids.iter().map(|id| repo.find_commit(*id).unwrap()); + let commits = ids + .iter() + .map(|id| repo.find_commit(*id)) + .collect::, Error>>()? + .into_iter(); let res = commits .map(|c: Commit| { From 3e4d1e9505688f336f06a8ae78834cfb55e6a247 Mon Sep 17 00:00:00 2001 From: Mehran KORDI Date: Thu, 14 May 2020 14:41:40 +0200 Subject: [PATCH 04/26] removed unwrap from diff.rs --- asyncgit/src/diff.rs | 3 +- asyncgit/src/sync/diff.rs | 70 ++++++++++++++++++++++++++------------- 2 files changed, 49 insertions(+), 24 deletions(-) diff --git a/asyncgit/src/diff.rs b/asyncgit/src/diff.rs index aad272b8a1..16fcfdf1c7 100644 --- a/asyncgit/src/diff.rs +++ b/asyncgit/src/diff.rs @@ -92,7 +92,8 @@ impl AsyncDiff { arc_pending.fetch_add(1, Ordering::Relaxed); let res = - sync::diff::get_diff(CWD, params.0.clone(), params.1); + sync::diff::get_diff(CWD, params.0.clone(), params.1) + .unwrap(); let mut notify = false; { let mut current = arc_current.lock().unwrap(); diff --git a/asyncgit/src/sync/diff.rs b/asyncgit/src/sync/diff.rs index 86eac44dee..1a4a82b4ac 100644 --- a/asyncgit/src/sync/diff.rs +++ b/asyncgit/src/sync/diff.rs @@ -1,10 +1,10 @@ //! sync git api for fetching a diff use super::utils; -use crate::hash; +use crate::{error::Error, hash}; use git2::{ - Delta, Diff, DiffDelta, DiffFormat, DiffHunk, DiffOptions, Error, - Patch, Repository, + Delta, Diff, DiffDelta, DiffFormat, DiffHunk, DiffOptions, Patch, + Repository, }; use scopetime::scope_time; use std::{fs, path::Path}; @@ -87,8 +87,15 @@ pub(crate) fn get_diff_raw<'a>( let diff = if stage { // diff against head if let Ok(ref_head) = repo.head() { - let parent = - repo.find_commit(ref_head.target().unwrap())?; + let parent = repo.find_commit( + ref_head.target().ok_or_else(|| { + let name = ref_head.name().unwrap_or("??"); + Error::Generic( + format!("can not find the target of symbolic references: {}", name) + ) + })?, + )?; + let tree = parent.tree()?; repo.diff_tree_to_index( Some(&tree), @@ -113,13 +120,21 @@ pub(crate) fn get_diff_raw<'a>( //TODO: return Option /// -pub fn get_diff(repo_path: &str, p: String, stage: bool) -> FileDiff { +pub fn get_diff( + repo_path: &str, + p: String, + stage: bool, +) -> Result { scope_time!("get_diff"); let repo = utils::repo(repo_path); - let repo_path = repo.path().parent().unwrap(); - - let diff = get_diff_raw(&repo, &p, stage, false).unwrap(); + let repo_path = repo.path().parent().ok_or_else(|| { + Error::Generic( + "repositories located at root are not supported." + .to_string(), + ) + })?; + let diff = get_diff_raw(&repo, &p, stage, false)?; let mut res: FileDiff = FileDiff::default(); let mut current_lines = Vec::new(); @@ -165,11 +180,18 @@ pub fn get_diff(repo_path: &str, p: String, stage: bool) -> FileDiff { }; let new_file_diff = if diff.deltas().len() == 1 { + // it's safe to unwrap here because we check first that diff.deltas has a single element. let delta: DiffDelta = diff.deltas().next().unwrap(); if delta.status() == Delta::Untracked { - let newfile_path = - repo_path.join(delta.new_file().path().unwrap()); + let relative_path = + delta.new_file().path().ok_or_else(|| { + Error::Generic( + "new file path is unspecified.".to_string(), + ) + })?; + + let newfile_path = repo_path.join(relative_path); if let Some(newfile_content) = new_file_content(&newfile_path) @@ -180,15 +202,13 @@ pub fn get_diff(repo_path: &str, p: String, stage: bool) -> FileDiff { newfile_content.as_bytes(), Some(&newfile_path), None, - ) - .unwrap(); + )?; patch .print(&mut |_delta, hunk:Option, line: git2::DiffLine| { put(hunk,line); true - }) - .unwrap(); + })?; true } else { @@ -208,15 +228,14 @@ pub fn get_diff(repo_path: &str, p: String, stage: bool) -> FileDiff { put(hunk, line); true }, - ) - .unwrap(); + )?; } if !current_lines.is_empty() { adder(¤t_hunk.unwrap(), ¤t_lines); } - res + Ok(res) } fn new_file_content(path: &Path) -> Option { @@ -268,7 +287,8 @@ mod tests { assert_eq!(res.len(), 1); let diff = - get_diff(repo_path, "foo/bar.txt".to_string(), false); + get_diff(repo_path, "foo/bar.txt".to_string(), false) + .unwrap(); assert_eq!(diff.hunks.len(), 1); assert_eq!(diff.hunks[0].lines[1].content, "test\n"); @@ -298,7 +318,8 @@ mod tests { repo_path, String::from(file_path.to_str().unwrap()), true, - ); + ) + .unwrap(); assert_eq!(diff.hunks.len(), 1); } @@ -364,7 +385,8 @@ mod tests { assert_eq!(get_statuses(repo_path), (1, 1)); - let res = get_diff(repo_path, "bar.txt".to_string(), false); + let res = get_diff(repo_path, "bar.txt".to_string(), false) + .unwrap(); assert_eq!(res.hunks.len(), 2) } @@ -387,7 +409,8 @@ mod tests { sub_path.to_str().unwrap(), String::from(file_path.to_str().unwrap()), false, - ); + ) + .unwrap(); assert_eq!(diff.hunks[0].lines[1].content, "test"); } @@ -407,7 +430,8 @@ mod tests { repo_path, String::from(file_path.to_str().unwrap()), false, - ); + ) + .unwrap(); assert_eq!(diff.hunks.len(), 0); From edcade6d1c77fa709545809eeeea9fa8490988f6 Mon Sep 17 00:00:00 2001 From: Mehran KORDI Date: Thu, 14 May 2020 15:19:57 +0200 Subject: [PATCH 05/26] fixed broken linux tests. --- asyncgit/src/sync/hooks.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/asyncgit/src/sync/hooks.rs b/asyncgit/src/sync/hooks.rs index c184c29ab4..b682bcfa9e 100644 --- a/asyncgit/src/sync/hooks.rs +++ b/asyncgit/src/sync/hooks.rs @@ -134,7 +134,7 @@ exit 0 create_hook(root, HOOK_COMMIT_MSG, hook); let mut msg = String::from("test"); - let res = hooks_commit_msg(repo_path, &mut msg); + let res = hooks_commit_msg(repo_path, &mut msg).unwrap(); assert_eq!(res, HookResult::Ok); @@ -158,7 +158,7 @@ exit 1 create_hook(root, HOOK_COMMIT_MSG, hook); let mut msg = String::from("test"); - let res = hooks_commit_msg(repo_path, &mut msg); + let res = hooks_commit_msg(repo_path, &mut msg).unwrap(); assert_eq!( res, @@ -184,7 +184,7 @@ exit 0 create_hook(root, HOOK_COMMIT_MSG, hook); let mut msg = String::from("test"); - let res = hooks_commit_msg(repo_path, &mut msg); + let res = hooks_commit_msg(repo_path, &mut msg).unwrap(); assert_eq!(res, HookResult::Ok); assert_eq!(msg, String::from("msg\n")); From befee58f76ce468f7808735660ad8ce99af8d922 Mon Sep 17 00:00:00 2001 From: Mehran KORDI Date: Thu, 14 May 2020 17:11:06 +0200 Subject: [PATCH 06/26] removed an unused Error variant. removed an obsolete comment. --- asyncgit/src/error.rs | 3 --- asyncgit/src/sync/diff.rs | 1 - 2 files changed, 4 deletions(-) diff --git a/asyncgit/src/error.rs b/asyncgit/src/error.rs index ff7a188a03..24e6002b6b 100644 --- a/asyncgit/src/error.rs +++ b/asyncgit/src/error.rs @@ -16,7 +16,4 @@ pub enum Error { #[from] source: git2::Error, }, - - #[error(transparent)] - Other(#[from] Box), } diff --git a/asyncgit/src/sync/diff.rs b/asyncgit/src/sync/diff.rs index 1a4a82b4ac..1e73ac7c15 100644 --- a/asyncgit/src/sync/diff.rs +++ b/asyncgit/src/sync/diff.rs @@ -118,7 +118,6 @@ pub(crate) fn get_diff_raw<'a>( Ok(diff) } -//TODO: return Option /// pub fn get_diff( repo_path: &str, From 0e6a5b35d57a92f20c83536918f192d3adc9c2a1 Mon Sep 17 00:00:00 2001 From: Mehran KORDI Date: Thu, 14 May 2020 17:41:15 +0200 Subject: [PATCH 07/26] changed Error variants from struct to tuples. --- asyncgit/src/error.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/asyncgit/src/error.rs b/asyncgit/src/error.rs index 24e6002b6b..5c8ee3a6c3 100644 --- a/asyncgit/src/error.rs +++ b/asyncgit/src/error.rs @@ -6,14 +6,14 @@ pub enum Error { Generic(String), #[error("io error")] - Io { - #[from] - source: std::io::Error, - }, + Io(#[from] std::io::Error), #[error("git error")] - Git { + Git(#[from] git2::Error), + + #[error("encoding error.")] + Encoding { #[from] - source: git2::Error, + source: std::string::FromUtf8Error, }, } From abdd53e85311132a54d0d2dd40c9e7400bf5fb94 Mon Sep 17 00:00:00 2001 From: Mehran KORDI Date: Thu, 14 May 2020 18:23:43 +0200 Subject: [PATCH 08/26] temperary commit to be modified. --- asyncgit/src/diff.rs | 36 +++++--- asyncgit/src/error.rs | 30 +++++-- asyncgit/src/lib.rs | 11 ++- asyncgit/src/revlog.rs | 16 ++-- asyncgit/src/status.rs | 29 ++++--- asyncgit/src/sync/commits_info.rs | 11 +-- asyncgit/src/sync/diff.rs | 41 +++++---- asyncgit/src/sync/hooks.rs | 29 ++++--- asyncgit/src/sync/hunks.rs | 27 +++--- asyncgit/src/sync/logwalker.rs | 12 +-- asyncgit/src/sync/mod.rs | 76 ++++++++-------- asyncgit/src/sync/reset.rs | 138 +++++++++++++++++------------- asyncgit/src/sync/status.rs | 41 +++++---- asyncgit/src/sync/tags.rs | 6 +- asyncgit/src/sync/utils.rs | 137 +++++++++++++++++------------ src/app.rs | 16 +++- src/components/changes.rs | 9 +- src/components/commit.rs | 4 +- src/tabs/revlog/mod.rs | 7 +- src/tabs/status.rs | 8 +- 20 files changed, 406 insertions(+), 278 deletions(-) diff --git a/asyncgit/src/diff.rs b/asyncgit/src/diff.rs index 16fcfdf1c7..28efbfc19e 100644 --- a/asyncgit/src/diff.rs +++ b/asyncgit/src/diff.rs @@ -1,4 +1,6 @@ -use crate::{hash, sync, AsyncNotification, FileDiff, CWD}; +use crate::{ + error::Error, hash, sync, AsyncNotification, FileDiff, CWD, +}; use crossbeam_channel::Sender; use log::trace; use std::{ @@ -42,18 +44,25 @@ impl AsyncDiff { } /// - pub fn last(&mut self) -> Option<(DiffParams, FileDiff)> { - let last = self.last.lock().unwrap(); - if let Some(res) = last.clone() { - Some((res.params, res.result)) - } else { - None - } + pub fn last( + &mut self, + ) -> Result, Error> { + let last = self.last.lock().or_else(|x| { + Err(Error::Generic(format!( + "failed to get last changes:{}", + x + ))) + })?; + + Ok(match last.clone() { + Some(res) => Some((res.params, res.result)), + None => None, + }) } /// pub fn refresh(&mut self) { - if let Some(param) = self.get_last_param() { + if let Ok(Some(param)) = self.get_last_param() { self.clear_current(); self.request(param); } @@ -124,8 +133,13 @@ impl AsyncDiff { None } - fn get_last_param(&self) -> Option { - self.last.lock().unwrap().clone().map(|e| e.params) + fn get_last_param(&self) -> Result, Error> { + Ok(self + .last + .lock() + .map_err(|_| Error::Generic("".to_string()))? + .clone() + .map(|e| e.params)) } fn clear_current(&mut self) { diff --git a/asyncgit/src/error.rs b/asyncgit/src/error.rs index 5c8ee3a6c3..c9da4bd8a3 100644 --- a/asyncgit/src/error.rs +++ b/asyncgit/src/error.rs @@ -5,15 +5,31 @@ pub enum Error { #[error("`{0}`")] Generic(String), - #[error("io error")] + #[error("io error:{0}")] Io(#[from] std::io::Error), - #[error("git error")] + #[error("git error:{0}")] Git(#[from] git2::Error), - #[error("encoding error.")] - Encoding { - #[from] - source: std::string::FromUtf8Error, - }, + #[error("encoding error:{0}")] + Encoding(#[from] std::string::FromUtf8Error), + + #[error("unspecified error:{0}")] + Unspecified(Box), +} + +pub type Returns = std::result::Result; + +// impl From<&dyn std::error::Error> for Error { +// fn from(error: &dyn std::error::Error) -> Self { +// let e = error.clone().to_owned(); +// let b = Box::new(e); +// Error::Unspecified(b) +// } +// } + +impl From> for Error { + fn from(error: std::sync::PoisonError) -> Self { + Error::Generic(format!("poison error: {}", error)) + } } diff --git a/asyncgit/src/lib.rs b/asyncgit/src/lib.rs index 96214f5bc9..fbb672502c 100644 --- a/asyncgit/src/lib.rs +++ b/asyncgit/src/lib.rs @@ -20,6 +20,7 @@ pub use crate::{ utils::is_repo, }, }; +use error::{Error, Returns}; use std::{ collections::hash_map::DefaultHasher, hash::{Hash, Hasher}, @@ -48,9 +49,11 @@ pub fn hash(v: &T) -> u64 { } /// helper function to return the current tick since unix epoch -pub fn current_tick() -> u64 { - SystemTime::now() +pub fn current_tick() -> Returns { + Ok(SystemTime::now() .duration_since(UNIX_EPOCH) - .unwrap() - .as_millis() as u64 + .map_err(|_| { + Error::Generic("can't get system time".to_string()) + })? + .as_millis() as u64) } diff --git a/asyncgit/src/revlog.rs b/asyncgit/src/revlog.rs index 8df8e451b5..0b1474805d 100644 --- a/asyncgit/src/revlog.rs +++ b/asyncgit/src/revlog.rs @@ -1,3 +1,4 @@ +use crate::error::Returns; use crate::{sync, AsyncNotification, CWD}; use crossbeam_channel::Sender; use git2::Oid; @@ -31,8 +32,8 @@ impl AsyncLog { } /// - pub fn count(&mut self) -> usize { - self.current.lock().unwrap().len() + pub fn count(&mut self) -> Returns { + Ok(self.current.lock()?.len()) } /// @@ -40,13 +41,13 @@ impl AsyncLog { &self, start_index: usize, amount: usize, - ) -> Vec { - let list = self.current.lock().unwrap(); + ) -> Returns> { + let list = self.current.lock()?; let list_len = list.len(); let min = start_index.min(list_len); let max = min + amount; let max = max.min(list_len); - Vec::from_iter(list[min..max].iter().cloned()) + Ok(Vec::from_iter(list[min..max].iter().cloned())) } /// @@ -55,7 +56,7 @@ impl AsyncLog { } /// - pub fn fetch(&mut self) { + pub fn fetch(&mut self) -> Returns<()> { if !self.is_pending() { self.clear(); @@ -68,7 +69,7 @@ impl AsyncLog { scope_time!("async::revlog"); let mut entries = Vec::with_capacity(LIMIT_COUNT); - let r = repo(CWD); + let r = repo(CWD).unwrap(); let mut walker = LogWalker::new(&r); loop { entries.clear(); @@ -93,6 +94,7 @@ impl AsyncLog { Self::notify(&sender); }); } + Ok(()) } fn clear(&mut self) { diff --git a/asyncgit/src/status.rs b/asyncgit/src/status.rs index f29792acf5..270b13276f 100644 --- a/asyncgit/src/status.rs +++ b/asyncgit/src/status.rs @@ -1,4 +1,7 @@ -use crate::{hash, sync, AsyncNotification, StatusItem, CWD}; +use crate::{ + error::{Error, Returns}, + hash, sync, AsyncNotification, StatusItem, CWD, +}; use crossbeam_channel::Sender; use log::trace; use std::{ @@ -38,9 +41,9 @@ impl AsyncStatus { } /// - pub fn last(&mut self) -> Status { - let last = self.last.lock().unwrap(); - last.clone() + pub fn last(&mut self) -> Returns { + let last = self.last.lock()?; + Ok(last.clone()) } /// @@ -49,16 +52,16 @@ impl AsyncStatus { } /// - pub fn fetch(&mut self, request: u64) -> Option { + pub fn fetch(&mut self, request: u64) -> Returns> { let hash_request = hash(&request); trace!("request: {} [hash: {}]", request, hash_request); { - let mut current = self.current.lock().unwrap(); + let mut current = self.current.lock()?; if current.0 == hash_request { - return current.1.clone(); + return Ok(current.1.clone()); } current.0 = hash_request; @@ -72,7 +75,7 @@ impl AsyncStatus { rayon_core::spawn(move || { arc_pending.fetch_add(1, Ordering::Relaxed); - let res = Self::get_status(); + let res = Self::get_status().unwrap(); trace!("status fetched: {}", hash(&res)); { @@ -94,14 +97,14 @@ impl AsyncStatus { .expect("error sending status"); }); - None + Ok(None) } - fn get_status() -> Status { + fn get_status() -> Result { let work_dir = - sync::status::get_status(CWD, StatusType::WorkingDir); - let stage = sync::status::get_status(CWD, StatusType::Stage); + sync::status::get_status(CWD, StatusType::WorkingDir)?; + let stage = sync::status::get_status(CWD, StatusType::Stage)?; - Status { stage, work_dir } + Ok(Status { stage, work_dir }) } } diff --git a/asyncgit/src/sync/commits_info.rs b/asyncgit/src/sync/commits_info.rs index f601c7960a..7d0ebcacc7 100644 --- a/asyncgit/src/sync/commits_info.rs +++ b/asyncgit/src/sync/commits_info.rs @@ -1,4 +1,5 @@ use super::utils::repo; +use crate::error::Returns; use git2::{Commit, Error, Oid}; use scopetime::scope_time; @@ -19,10 +20,10 @@ pub struct CommitInfo { pub fn get_commits_info( repo_path: &str, ids: &[Oid], -) -> Result, Error> { +) -> Returns> { scope_time!("get_commits_info"); - let repo = repo(repo_path); + let repo = repo(repo_path)?; let commits = ids .iter() @@ -82,15 +83,15 @@ mod tests { #[test] fn test_log() -> Result<(), Error> { let file_path = Path::new("foo"); - let (_td, repo) = repo_init_empty(); + let (_td, repo) = repo_init_empty().unwrap(); let root = repo.path().parent().unwrap(); let repo_path = root.as_os_str().to_str().unwrap(); File::create(&root.join(file_path))?.write_all(b"a")?; - stage_add_file(repo_path, file_path); + stage_add_file(repo_path, file_path).unwrap(); let c1 = commit(repo_path, "commit1").unwrap(); File::create(&root.join(file_path))?.write_all(b"a")?; - stage_add_file(repo_path, file_path); + stage_add_file(repo_path, file_path).unwrap(); let c2 = commit(repo_path, "commit2").unwrap(); let res = get_commits_info(repo_path, &vec![c2, c1]).unwrap(); diff --git a/asyncgit/src/sync/diff.rs b/asyncgit/src/sync/diff.rs index 1e73ac7c15..81270b2de7 100644 --- a/asyncgit/src/sync/diff.rs +++ b/asyncgit/src/sync/diff.rs @@ -126,7 +126,7 @@ pub fn get_diff( ) -> Result { scope_time!("get_diff"); - let repo = utils::repo(repo_path); + let repo = utils::repo(repo_path)?; let repo_path = repo.path().parent().ok_or_else(|| { Error::Generic( "repositories located at root are not supported." @@ -269,11 +269,12 @@ mod tests { #[test] fn test_untracked_subfolder() { - let (_td, repo) = repo_init(); + let (_td, repo) = repo_init().unwrap(); let root = repo.path().parent().unwrap(); let repo_path = root.as_os_str().to_str().unwrap(); - let res = get_status(repo_path, StatusType::WorkingDir); + let res = + get_status(repo_path, StatusType::WorkingDir).unwrap(); assert_eq!(res.len(), 0); fs::create_dir(&root.join("foo")).unwrap(); @@ -282,7 +283,8 @@ mod tests { .write_all(b"test\nfoo") .unwrap(); - let res = get_status(repo_path, StatusType::WorkingDir); + let res = + get_status(repo_path, StatusType::WorkingDir).unwrap(); assert_eq!(res.len(), 1); let diff = @@ -296,22 +298,25 @@ mod tests { #[test] fn test_empty_repo() { let file_path = Path::new("foo.txt"); - let (_td, repo) = repo_init_empty(); + let (_td, repo) = repo_init_empty().unwrap(); let root = repo.path().parent().unwrap(); let repo_path = root.as_os_str().to_str().unwrap(); - assert_eq!(get_statuses(repo_path), (0, 0)); + assert_eq!(get_statuses(repo_path).unwrap(), (0, 0)); File::create(&root.join(file_path)) .unwrap() .write_all(b"test\nfoo") .unwrap(); - assert_eq!(get_statuses(repo_path), (1, 0)); + assert_eq!(get_statuses(repo_path).unwrap(), (1, 0)); - assert_eq!(stage_add_file(repo_path, file_path), true); + assert_eq!( + stage_add_file(repo_path, file_path).unwrap(), + true + ); - assert_eq!(get_statuses(repo_path), (0, 1)); + assert_eq!(get_statuses(repo_path).unwrap(), (0, 1)); let diff = get_diff( repo_path, @@ -351,11 +356,11 @@ mod tests { #[test] fn test_hunks() { - let (_td, repo) = repo_init(); + let (_td, repo) = repo_init().unwrap(); let root = repo.path().parent().unwrap(); let repo_path = root.as_os_str().to_str().unwrap(); - assert_eq!(get_statuses(repo_path), (0, 0)); + assert_eq!(get_statuses(repo_path).unwrap(), (0, 0)); let file_path = root.join("bar.txt"); @@ -366,13 +371,15 @@ mod tests { .unwrap(); } - let res = get_status(repo_path, StatusType::WorkingDir); + let res = + get_status(repo_path, StatusType::WorkingDir).unwrap(); assert_eq!(res.len(), 1); assert_eq!(res[0].path, "bar.txt"); - let res = stage_add_file(repo_path, Path::new("bar.txt")); + let res = + stage_add_file(repo_path, Path::new("bar.txt")).unwrap(); assert_eq!(res, true); - assert_eq!(get_statuses(repo_path), (0, 1)); + assert_eq!(get_statuses(repo_path).unwrap(), (0, 1)); // overwrite with next content { @@ -382,7 +389,7 @@ mod tests { .unwrap(); } - assert_eq!(get_statuses(repo_path), (1, 1)); + assert_eq!(get_statuses(repo_path).unwrap(), (1, 1)); let res = get_diff(repo_path, "bar.txt".to_string(), false) .unwrap(); @@ -393,7 +400,7 @@ mod tests { #[test] fn test_diff_newfile_in_sub_dir_current_dir() { let file_path = Path::new("foo/foo.txt"); - let (_td, repo) = repo_init_empty(); + let (_td, repo) = repo_init_empty().unwrap(); let root = repo.path().parent().unwrap(); let sub_path = root.join("foo/"); @@ -418,7 +425,7 @@ mod tests { fn test_diff_new_binary_file_using_invalid_utf8( ) -> Result<(), Error> { let file_path = Path::new("bar"); - let (_td, repo) = repo_init_empty(); + let (_td, repo) = repo_init_empty().unwrap(); let root = repo.path().parent().unwrap(); let repo_path = root.as_os_str().to_str().unwrap(); diff --git a/asyncgit/src/sync/hooks.rs b/asyncgit/src/sync/hooks.rs index b682bcfa9e..2a6775466e 100644 --- a/asyncgit/src/sync/hooks.rs +++ b/asyncgit/src/sync/hooks.rs @@ -1,4 +1,4 @@ -use crate::error::Error; +use crate::error::{Error, Returns}; use is_executable::IsExecutable; use scopetime::scope_time; use std::{ @@ -27,7 +27,8 @@ pub fn hooks_commit_msg( Error::Generic("can't get temp file's path".to_string()) })?; - let res = run_hook(repo_path, HOOK_COMMIT_MSG, &[&file_path]); + let res = + run_hook(repo_path, HOOK_COMMIT_MSG, &[&file_path])?; // load possibly altered msg let mut file = file.reopen()?; @@ -41,13 +42,13 @@ pub fn hooks_commit_msg( } /// -pub fn hooks_post_commit(repo_path: &str) -> HookResult { +pub fn hooks_post_commit(repo_path: &str) -> Returns { scope_time!("hooks_post_commit"); if hook_runable(repo_path, HOOK_POST_COMMIT) { - run_hook(repo_path, HOOK_POST_COMMIT, &[]) + Ok(run_hook(repo_path, HOOK_POST_COMMIT, &[])?) } else { - HookResult::Ok + Ok(HookResult::Ok) } } @@ -67,20 +68,24 @@ pub enum HookResult { NotOk(String), } -fn run_hook(path: &str, cmd: &str, args: &[&str]) -> HookResult { +fn run_hook( + path: &str, + cmd: &str, + args: &[&str], +) -> Returns { let output = Command::new(cmd).args(args).current_dir(path).output(); let output = output.expect("general hook error"); if output.status.success() { - HookResult::Ok + Ok(HookResult::Ok) } else { - let err = String::from_utf8(output.stderr).unwrap(); - let out = String::from_utf8(output.stdout).unwrap(); + let err = String::from_utf8(output.stderr)?; + let out = String::from_utf8(output.stdout)?; let formatted = format!("{}{}", out, err); - HookResult::NotOk(formatted) + Ok(HookResult::NotOk(formatted)) } } @@ -92,7 +97,7 @@ mod tests { #[test] fn test_smoke() { - let (_td, repo) = repo_init(); + let (_td, repo) = repo_init().unwrap(); let root = repo.path().parent().unwrap(); let repo_path = root.as_os_str().to_str().unwrap(); @@ -101,7 +106,7 @@ mod tests { assert_eq!(res, HookResult::Ok); - let res = hooks_post_commit(repo_path); + let res = hooks_post_commit(repo_path).unwrap(); assert_eq!(res, HookResult::Ok); } diff --git a/asyncgit/src/sync/hunks.rs b/asyncgit/src/sync/hunks.rs index 1f72724b4d..2c39e67fc1 100644 --- a/asyncgit/src/sync/hunks.rs +++ b/asyncgit/src/sync/hunks.rs @@ -2,7 +2,7 @@ use super::{ diff::{get_diff_raw, HunkHeader}, utils::repo, }; -use crate::hash; +use crate::{error::Error, hash}; use git2::{ApplyLocation, ApplyOptions, Diff}; use log::error; use scopetime::scope_time; @@ -12,12 +12,12 @@ pub fn stage_hunk( repo_path: &str, file_path: String, hunk_hash: u64, -) -> bool { +) -> Result { scope_time!("stage_hunk"); - let repo = repo(repo_path); + let repo = repo(repo_path)?; - let diff = get_diff_raw(&repo, &file_path, false, false).unwrap(); + let diff = get_diff_raw(&repo, &file_path, false, false)?; let mut opt = ApplyOptions::new(); opt.hunk_callback(|hunk| { @@ -25,8 +25,9 @@ pub fn stage_hunk( hash(&header) == hunk_hash }); - repo.apply(&diff, ApplyLocation::Index, Some(&mut opt)) - .is_ok() + repo.apply(&diff, ApplyLocation::Index, Some(&mut opt))?; + + Ok(true) } fn find_hunk_index(diff: &Diff, hunk_hash: u64) -> Option { @@ -60,22 +61,22 @@ pub fn unstage_hunk( repo_path: &str, file_path: String, hunk_hash: u64, -) -> bool { +) -> Result { scope_time!("revert_hunk"); - let repo = repo(repo_path); + let repo = repo(repo_path)?; - let diff = get_diff_raw(&repo, &file_path, true, false).unwrap(); + let diff = get_diff_raw(&repo, &file_path, true, false)?; let diff_count_positive = diff.deltas().len(); let hunk_index = find_hunk_index(&diff, hunk_hash); if hunk_index.is_none() { error!("hunk not found"); - return false; + return Err(Error::Generic("hunk not found".to_string())); } - let diff = get_diff_raw(&repo, &file_path, true, true).unwrap(); + let diff = get_diff_raw(&repo, &file_path, true, true)?; assert_eq!(diff.deltas().len(), diff_count_positive); @@ -100,9 +101,9 @@ pub fn unstage_hunk( .is_err() { error!("apply failed"); - return false; + return Err(Error::Generic("apply failed".to_string())); } } - count == 1 + Ok(count == 1) } diff --git a/asyncgit/src/sync/logwalker.rs b/asyncgit/src/sync/logwalker.rs index cd7c61b559..6f047f9b22 100644 --- a/asyncgit/src/sync/logwalker.rs +++ b/asyncgit/src/sync/logwalker.rs @@ -62,15 +62,15 @@ mod tests { #[test] fn test_limit() -> Result<(), Error> { let file_path = Path::new("foo"); - let (_td, repo) = repo_init_empty(); + let (_td, repo) = repo_init_empty().unwrap(); let root = repo.path().parent().unwrap(); let repo_path = root.as_os_str().to_str().unwrap(); File::create(&root.join(file_path))?.write_all(b"a")?; - stage_add_file(repo_path, file_path); + stage_add_file(repo_path, file_path).unwrap(); commit(repo_path, "commit1").unwrap(); File::create(&root.join(file_path))?.write_all(b"a")?; - stage_add_file(repo_path, file_path); + stage_add_file(repo_path, file_path).unwrap(); let oid2 = commit(repo_path, "commit2").unwrap(); let mut items = Vec::new(); @@ -86,15 +86,15 @@ mod tests { #[test] fn test_logwalker() -> Result<(), Error> { let file_path = Path::new("foo"); - let (_td, repo) = repo_init_empty(); + let (_td, repo) = repo_init_empty().unwrap(); let root = repo.path().parent().unwrap(); let repo_path = root.as_os_str().to_str().unwrap(); File::create(&root.join(file_path))?.write_all(b"a")?; - stage_add_file(repo_path, file_path); + stage_add_file(repo_path, file_path).unwrap(); commit(repo_path, "commit1").unwrap(); File::create(&root.join(file_path))?.write_all(b"a")?; - stage_add_file(repo_path, file_path); + stage_add_file(repo_path, file_path).unwrap(); let oid2 = commit(repo_path, "commit2").unwrap(); let mut items = Vec::new(); diff --git a/asyncgit/src/sync/mod.rs b/asyncgit/src/sync/mod.rs index ba76509af0..c327c973f7 100644 --- a/asyncgit/src/sync/mod.rs +++ b/asyncgit/src/sync/mod.rs @@ -25,36 +25,37 @@ pub use utils::{ #[cfg(test)] mod tests { use super::status::{get_status, StatusType}; + use crate::error::Error; use git2::Repository; use std::process::Command; use tempfile::TempDir; /// - pub fn repo_init_empty() -> (TempDir, Repository) { - let td = TempDir::new().unwrap(); - let repo = Repository::init(td.path()).unwrap(); + pub fn repo_init_empty() -> Result<(TempDir, Repository), Error> { + let td = TempDir::new()?; + let repo = Repository::init(td.path())?; { - let mut config = repo.config().unwrap(); - config.set_str("user.name", "name").unwrap(); - config.set_str("user.email", "email").unwrap(); + let mut config = repo.config()?; + config.set_str("user.name", "name")?; + config.set_str("user.email", "email")?; } - (td, repo) + Ok((td, repo)) } /// - pub fn repo_init() -> (TempDir, Repository) { - let td = TempDir::new().unwrap(); - let repo = Repository::init(td.path()).unwrap(); + pub fn repo_init() -> Result<(TempDir, Repository), Error> { + let td = TempDir::new()?; + let repo = Repository::init(td.path())?; { - let mut config = repo.config().unwrap(); - config.set_str("user.name", "name").unwrap(); - config.set_str("user.email", "email").unwrap(); + let mut config = repo.config()?; + config.set_str("user.name", "name")?; + config.set_str("user.email", "email")?; - let mut index = repo.index().unwrap(); - let id = index.write_tree().unwrap(); + let mut index = repo.index()?; + let id = index.write_tree()?; - let tree = repo.find_tree(id).unwrap(); - let sig = repo.signature().unwrap(); + let tree = repo.find_tree(id)?; + let sig = repo.signature()?; repo.commit( Some("HEAD"), &sig, @@ -62,43 +63,48 @@ mod tests { "initial", &tree, &[], - ) - .unwrap(); + )?; } - (td, repo) + Ok((td, repo)) } /// helper returning amount of files with changes in the (wd,stage) - pub fn get_statuses(repo_path: &str) -> (usize, usize) { - ( - get_status(repo_path, StatusType::WorkingDir).len(), - get_status(repo_path, StatusType::Stage).len(), - ) + pub fn get_statuses( + repo_path: &str, + ) -> Result<(usize, usize), Error> { + Ok(( + get_status(repo_path, StatusType::WorkingDir)?.len(), + get_status(repo_path, StatusType::Stage)?.len(), + )) } /// - pub fn debug_cmd_print(path: &str, cmd: &str) { - eprintln!("\n----\n{}", debug_cmd(path, cmd)) + pub fn debug_cmd_print( + path: &str, + cmd: &str, + ) -> Result<(), Error> { + let cmd = debug_cmd(path, cmd)?; + eprintln!("\n----\n{}", cmd); + Ok(()) } - fn debug_cmd(path: &str, cmd: &str) -> String { + fn debug_cmd(path: &str, cmd: &str) -> Result { let output = if cfg!(target_os = "windows") { Command::new("cmd") .args(&["/C", cmd]) .current_dir(path) - .output() + .output()? } else { Command::new("sh") .arg("-c") .arg(cmd) .current_dir(path) - .output() + .output()? }; - let output = output.unwrap(); - let stdout = String::from_utf8(output.stdout).unwrap(); - let stderr = String::from_utf8(output.stderr).unwrap(); - format!( + let stdout = String::from_utf8(output.stdout)?; + let stderr = String::from_utf8(output.stderr)?; + Ok(format!( "{}{}", if stdout.is_empty() { String::new() @@ -110,6 +116,6 @@ mod tests { } else { format!("err:\n{}", stderr) } - ) + )) } } diff --git a/asyncgit/src/sync/reset.rs b/asyncgit/src/sync/reset.rs index 11dfcf64b4..8fc8527c8c 100644 --- a/asyncgit/src/sync/reset.rs +++ b/asyncgit/src/sync/reset.rs @@ -1,35 +1,44 @@ use super::utils::repo; +use crate::error::{Error, Returns}; use git2::{build::CheckoutBuilder, ObjectType, Status}; use scopetime::scope_time; use std::{fs, path::Path}; /// -pub fn reset_stage(repo_path: &str, path: &Path) -> bool { +pub fn reset_stage(repo_path: &str, path: &Path) -> Returns { scope_time!("reset_stage"); - let repo = repo(repo_path); + let repo = repo(repo_path)?; let head = repo.head(); if let Ok(reference) = head { - let obj = repo - .find_object( - reference.target().unwrap(), - Some(ObjectType::Commit), - ) - .unwrap(); - - repo.reset_default(Some(&obj), &[path]).is_ok() + let obj = repo.find_object( + reference.target().ok_or_else(|| { + Error::Generic( + "can't get reference to symbolic reference," + .to_string(), + ) + })?, + Some(ObjectType::Commit), + )?; + + repo.reset_default(Some(&obj), &[path])?; } else { - repo.reset_default(None, &[path]).is_ok() + repo.reset_default(None, &[path])?; } + + Ok(true) } /// -pub fn reset_workdir_file(repo_path: &str, path: &str) -> bool { +pub fn reset_workdir_file( + repo_path: &str, + path: &str, +) -> Returns { scope_time!("reset_workdir_file"); - let repo = repo(repo_path); + let repo = repo(repo_path)?; // Note: early out for removing untracked files, due to bug in checkout_head code: // see https://github.com/libgit2/libgit2/issues/5089 @@ -37,9 +46,10 @@ pub fn reset_workdir_file(repo_path: &str, path: &str) -> bool { let removed_file_wd = if status == Status::WT_NEW || (status == Status::WT_MODIFIED | Status::INDEX_NEW) { - fs::remove_file(Path::new(repo_path).join(path)).is_ok() + Ok(fs::remove_file(Path::new(repo_path).join(path)) + .is_ok()) } else { - false + Ok(false) }; if status == Status::WT_NEW { @@ -53,17 +63,22 @@ pub fn reset_workdir_file(repo_path: &str, path: &str) -> bool { .force() .path(path); - repo.checkout_index(None, Some(&mut checkout_opts)).is_ok() + Ok(repo + .checkout_index(None, Some(&mut checkout_opts)) + .is_ok()) } else { - false + Ok(false) } } /// -pub fn reset_workdir_folder(repo_path: &str, path: &str) -> bool { +pub fn reset_workdir_folder( + repo_path: &str, + path: &str, +) -> Returns { scope_time!("reset_workdir_folder"); - let repo = repo(repo_path); + let repo = repo(repo_path)?; let mut checkout_opts = CheckoutBuilder::new(); checkout_opts @@ -73,7 +88,8 @@ pub fn reset_workdir_folder(repo_path: &str, path: &str) -> bool { .force() .path(path); - repo.checkout_index(None, Some(&mut checkout_opts)).is_ok() + repo.checkout_index(None, Some(&mut checkout_opts))?; + Ok(true) } #[cfg(test)] @@ -122,11 +138,12 @@ mod tests { #[test] fn test_reset_only_unstaged() { - let (_td, repo) = repo_init(); + let (_td, repo) = repo_init().unwrap(); let root = repo.path().parent().unwrap(); let repo_path = root.as_os_str().to_str().unwrap(); - let res = get_status(repo_path, StatusType::WorkingDir); + let res = + get_status(repo_path, StatusType::WorkingDir).unwrap(); assert_eq!(res.len(), 0); let file_path = root.join("bar.txt"); @@ -138,11 +155,11 @@ mod tests { .unwrap(); } - debug_cmd_print(repo_path, "git status"); + debug_cmd_print(repo_path, "git status").unwrap(); - stage_add_file(repo_path, Path::new("bar.txt")); + stage_add_file(repo_path, Path::new("bar.txt")).unwrap(); - debug_cmd_print(repo_path, "git status"); + debug_cmd_print(repo_path, "git status").unwrap(); // overwrite with next content { @@ -152,21 +169,21 @@ mod tests { .unwrap(); } - debug_cmd_print(repo_path, "git status"); + debug_cmd_print(repo_path, "git status").unwrap(); - assert_eq!(get_statuses(repo_path), (1, 1)); + assert_eq!(get_statuses(repo_path).unwrap(), (1, 1)); - let res = reset_workdir_file(repo_path, "bar.txt"); + let res = reset_workdir_file(repo_path, "bar.txt").unwrap(); assert_eq!(res, true); - debug_cmd_print(repo_path, "git status"); + debug_cmd_print(repo_path, "git status").unwrap(); - assert_eq!(get_statuses(repo_path), (0, 1)); + assert_eq!(get_statuses(repo_path).unwrap(), (0, 1)); } #[test] fn test_reset_untracked_in_subdir() { - let (_td, repo) = repo_init(); + let (_td, repo) = repo_init().unwrap(); let root = repo.path().parent().unwrap(); let repo_path = root.as_os_str().to_str().unwrap(); @@ -178,21 +195,22 @@ mod tests { .unwrap(); } - debug_cmd_print(repo_path, "git status"); + debug_cmd_print(repo_path, "git status").unwrap(); - assert_eq!(get_statuses(repo_path), (1, 0)); + assert_eq!(get_statuses(repo_path).unwrap(), (1, 0)); - let res = reset_workdir_file(repo_path, "foo/bar.txt"); + let res = + reset_workdir_file(repo_path, "foo/bar.txt").unwrap(); assert_eq!(res, true); - debug_cmd_print(repo_path, "git status"); + debug_cmd_print(repo_path, "git status").unwrap(); - assert_eq!(get_statuses(repo_path), (0, 0)); + assert_eq!(get_statuses(repo_path).unwrap(), (0, 0)); } #[test] fn test_reset_folder() -> Result<(), Error> { - let (_td, repo) = repo_init(); + let (_td, repo) = repo_init().unwrap(); let root = repo.path().parent().unwrap(); let repo_path = root.as_os_str().to_str().unwrap(); @@ -206,7 +224,7 @@ mod tests { .write_all(b"file3")?; } - assert!(stage_add_all(repo_path, "*")); + assert!(stage_add_all(repo_path, "*").unwrap()); commit(repo_path, "msg").unwrap(); { @@ -221,22 +239,23 @@ mod tests { .write_all(b"file3\nadded line")?; } - assert_eq!(get_statuses(repo_path), (5, 0)); + assert_eq!(get_statuses(repo_path).unwrap(), (5, 0)); - stage_add_file(repo_path, Path::new("foo/file5.txt")); + stage_add_file(repo_path, Path::new("foo/file5.txt")) + .unwrap(); - assert_eq!(get_statuses(repo_path), (4, 1)); + assert_eq!(get_statuses(repo_path).unwrap(), (4, 1)); - assert!(reset_workdir_folder(repo_path, "foo")); + assert!(reset_workdir_folder(repo_path, "foo").unwrap()); - assert_eq!(get_statuses(repo_path), (1, 1)); + assert_eq!(get_statuses(repo_path).unwrap(), (1, 1)); Ok(()) } #[test] fn test_reset_untracked_in_subdir_and_index() { - let (_td, repo) = repo_init(); + let (_td, repo) = repo_init().unwrap(); let root = repo.path().parent().unwrap(); let repo_path = root.as_os_str().to_str().unwrap(); let file = "foo/bar.txt"; @@ -249,11 +268,11 @@ mod tests { .unwrap(); } - debug_cmd_print(repo_path, "git status"); + debug_cmd_print(repo_path, "git status").unwrap(); - debug_cmd_print(repo_path, "git add ."); + debug_cmd_print(repo_path, "git add .").unwrap(); - debug_cmd_print(repo_path, "git status"); + debug_cmd_print(repo_path, "git status").unwrap(); { File::create(&root.join(file)) @@ -262,22 +281,22 @@ mod tests { .unwrap(); } - debug_cmd_print(repo_path, "git status"); + debug_cmd_print(repo_path, "git status").unwrap(); - assert_eq!(get_statuses(repo_path), (1, 1)); + assert_eq!(get_statuses(repo_path).unwrap(), (1, 1)); - let res = reset_workdir_file(repo_path, file); + let res = reset_workdir_file(repo_path, file).unwrap(); assert_eq!(res, true); - debug_cmd_print(repo_path, "git status"); + debug_cmd_print(repo_path, "git status").unwrap(); - assert_eq!(get_statuses(repo_path), (0, 1)); + assert_eq!(get_statuses(repo_path).unwrap(), (0, 1)); } #[test] fn unstage_in_empty_repo() { let file_path = Path::new("foo.txt"); - let (_td, repo) = repo_init_empty(); + let (_td, repo) = repo_init_empty().unwrap(); let root = repo.path().parent().unwrap(); let repo_path = root.as_os_str().to_str().unwrap(); @@ -286,14 +305,17 @@ mod tests { .write_all(b"test\nfoo") .unwrap(); - assert_eq!(get_statuses(repo_path), (1, 0)); + assert_eq!(get_statuses(repo_path).unwrap(), (1, 0)); - assert_eq!(stage_add_file(repo_path, file_path), true); + assert_eq!( + stage_add_file(repo_path, file_path).unwrap(), + true + ); - assert_eq!(get_statuses(repo_path), (0, 1)); + assert_eq!(get_statuses(repo_path).unwrap(), (0, 1)); - assert_eq!(reset_stage(repo_path, file_path), true); + assert_eq!(reset_stage(repo_path, file_path).unwrap(), true); - assert_eq!(get_statuses(repo_path), (1, 0)); + assert_eq!(get_statuses(repo_path).unwrap(), (1, 0)); } } diff --git a/asyncgit/src/sync/status.rs b/asyncgit/src/sync/status.rs index a3cfb54788..85a97edfd3 100644 --- a/asyncgit/src/sync/status.rs +++ b/asyncgit/src/sync/status.rs @@ -1,6 +1,6 @@ //! sync git api for fetching a status -use crate::sync::utils; +use crate::{error::Error, sync::utils}; use git2::{Status, StatusOptions, StatusShow}; use scopetime::scope_time; use std::path::Path; @@ -67,32 +67,35 @@ impl Into for StatusType { pub fn get_status( repo_path: &str, status_type: StatusType, -) -> Vec { +) -> Result, Error> { scope_time!("get_index"); - let repo = utils::repo(repo_path); + let repo = utils::repo(repo_path)?; - let statuses = repo - .statuses(Some( - StatusOptions::default() - .show(status_type.into()) - .include_untracked(true) - .renames_head_to_index(true) - .recurse_untracked_dirs(true), - )) - .unwrap(); + let statuses = repo.statuses(Some( + StatusOptions::default() + .show(status_type.into()) + .include_untracked(true) + .renames_head_to_index(true) + .recurse_untracked_dirs(true), + ))?; let mut res = Vec::with_capacity(statuses.len()); for e in statuses.iter() { let status: Status = e.status(); - let path = if let Some(diff) = e.head_to_index() { - String::from( - diff.new_file().path().unwrap().to_str().unwrap(), - ) - } else { - e.path().unwrap().to_string() + let path = match e.head_to_index() { + Some(diff) => diff + .new_file() + .path() + .and_then(|x| x.to_str()) + .map(String::from) + .ok_or_else(|| Error::Generic("".to_string()))?, + None => e + .path() + .map(String::from) + .ok_or_else(|| Error::Generic("".to_string()))?, }; res.push(StatusItem { @@ -105,5 +108,5 @@ pub fn get_status( Path::new(a.path.as_str()).cmp(Path::new(b.path.as_str())) }); - res + Ok(res) } diff --git a/asyncgit/src/sync/tags.rs b/asyncgit/src/sync/tags.rs index e9a0f18bc8..feb84b1b76 100644 --- a/asyncgit/src/sync/tags.rs +++ b/asyncgit/src/sync/tags.rs @@ -1,5 +1,5 @@ use super::utils::repo; -use git2::Error; +use crate::error::Returns; use scopetime::scope_time; use std::collections::HashMap; @@ -7,12 +7,12 @@ use std::collections::HashMap; pub type Tags = HashMap; /// returns `Tags` type filled with all tags found in repo -pub fn get_tags(repo_path: &str) -> Result { +pub fn get_tags(repo_path: &str) -> Returns { scope_time!("get_tags"); let mut res = Tags::new(); - let repo = repo(repo_path); + let repo = repo(repo_path)?; for name in repo.tag_names(None)?.iter() { if let Some(name) = name { diff --git a/asyncgit/src/sync/utils.rs b/asyncgit/src/sync/utils.rs index 009890185e..8e3b744d4d 100644 --- a/asyncgit/src/sync/utils.rs +++ b/asyncgit/src/sync/utils.rs @@ -1,8 +1,7 @@ //! sync git api (various methods) -use git2::{ - Error, IndexAddOption, Oid, Repository, RepositoryOpenFlags, -}; +use crate::error::{Error, Returns}; +use git2::{IndexAddOption, Oid, Repository, RepositoryOpenFlags}; use scopetime::scope_time; use std::path::Path; @@ -17,26 +16,25 @@ pub fn is_repo(repo_path: &str) -> bool { } /// -pub fn repo(repo_path: &str) -> Repository { +pub fn repo(repo_path: &str) -> Returns { let repo = Repository::open_ext( repo_path, RepositoryOpenFlags::empty(), Vec::<&Path>::new(), - ) - .unwrap(); + )?; if repo.is_bare() { panic!("bare repo") } - repo + Ok(repo) } /// this does not run any git hooks -pub fn commit(repo_path: &str, msg: &str) -> Result { +pub fn commit(repo_path: &str, msg: &str) -> Returns { scope_time!("commit"); - let repo = repo(repo_path); + let repo = repo(repo_path)?; let signature = repo.signature()?; let mut index = repo.index()?; @@ -44,7 +42,14 @@ pub fn commit(repo_path: &str, msg: &str) -> Result { let tree = repo.find_tree(tree_id)?; let parents = if let Ok(reference) = repo.head() { - let parent = repo.find_commit(reference.target().unwrap())?; + let parent = repo.find_commit( + reference.target().ok_or_else(|| { + Error::Generic( + "failed to get the target for reference" + .to_string(), + ) + })?, + )?; vec![parent] } else { Vec::new() @@ -52,65 +57,71 @@ pub fn commit(repo_path: &str, msg: &str) -> Result { let parents = parents.iter().collect::>(); - repo.commit( + Ok(repo.commit( Some("HEAD"), &signature, &signature, msg, &tree, parents.as_slice(), - ) + )?) } /// add a file diff from workingdir to stage (will not add removed files see `stage_addremoved`) -pub fn stage_add_file(repo_path: &str, path: &Path) -> bool { +pub fn stage_add_file(repo_path: &str, path: &Path) -> Returns { scope_time!("stage_add_file"); - let repo = repo(repo_path); + let repo = repo(repo_path)?; - let mut index = repo.index().unwrap(); + let mut index = repo.index()?; if index.add_path(path).is_ok() { - index.write().unwrap(); - return true; + index.write()?; + return Ok(true); } - false + Ok(false) } /// like `stage_add_file` but uses a pattern to match/glob multiple files/folders -pub fn stage_add_all(repo_path: &str, pattern: &str) -> bool { +pub fn stage_add_all( + repo_path: &str, + pattern: &str, +) -> Returns { scope_time!("stage_add_all"); - let repo = repo(repo_path); + let repo = repo(repo_path)?; - let mut index = repo.index().unwrap(); + let mut index = repo.index()?; if index .add_all(vec![pattern], IndexAddOption::DEFAULT, None) .is_ok() { - index.write().unwrap(); - return true; + index.write()?; + return Ok(true); } - false + Ok(false) } /// stage a removed file -pub fn stage_addremoved(repo_path: &str, path: &Path) -> bool { +pub fn stage_addremoved( + repo_path: &str, + path: &Path, +) -> Returns { scope_time!("stage_addremoved"); - let repo = repo(repo_path); + let repo = repo(repo_path)?; - let mut index = repo.index().unwrap(); + let mut index = repo.index()?; if index.remove_path(path).is_ok() { - index.write().unwrap(); - return true; + index.write()?; + return Ok(true); } - false + Ok(false) } #[cfg(test)] @@ -129,7 +140,7 @@ mod tests { #[test] fn test_commit() { let file_path = Path::new("foo"); - let (_td, repo) = repo_init(); + let (_td, repo) = repo_init().unwrap(); let root = repo.path().parent().unwrap(); let repo_path = root.as_os_str().to_str().unwrap(); @@ -138,56 +149,65 @@ mod tests { .write_all(b"test\nfoo") .unwrap(); - assert_eq!(get_statuses(repo_path), (1, 0)); + assert_eq!(get_statuses(repo_path).unwrap(), (1, 0)); - assert_eq!(stage_add_file(repo_path, file_path), true); + assert_eq!( + stage_add_file(repo_path, file_path).unwrap(), + true + ); - assert_eq!(get_statuses(repo_path), (0, 1)); + assert_eq!(get_statuses(repo_path).unwrap(), (0, 1)); commit(repo_path, "commit msg").unwrap(); - assert_eq!(get_statuses(repo_path), (0, 0)); + assert_eq!(get_statuses(repo_path).unwrap(), (0, 0)); } #[test] fn test_commit_in_empty_repo() { let file_path = Path::new("foo"); - let (_td, repo) = repo_init_empty(); + let (_td, repo) = repo_init_empty().unwrap(); let root = repo.path().parent().unwrap(); let repo_path = root.as_os_str().to_str().unwrap(); - assert_eq!(get_statuses(repo_path), (0, 0)); + assert_eq!(get_statuses(repo_path).unwrap(), (0, 0)); File::create(&root.join(file_path)) .unwrap() .write_all(b"test\nfoo") .unwrap(); - assert_eq!(get_statuses(repo_path), (1, 0)); + assert_eq!(get_statuses(repo_path).unwrap(), (1, 0)); - assert_eq!(stage_add_file(repo_path, file_path), true); + assert_eq!( + stage_add_file(repo_path, file_path).unwrap(), + true + ); - assert_eq!(get_statuses(repo_path), (0, 1)); + assert_eq!(get_statuses(repo_path).unwrap(), (0, 1)); commit(repo_path, "commit msg").unwrap(); - assert_eq!(get_statuses(repo_path), (0, 0)); + assert_eq!(get_statuses(repo_path).unwrap(), (0, 0)); } #[test] fn test_stage_add_smoke() { let file_path = Path::new("foo"); - let (_td, repo) = repo_init_empty(); + let (_td, repo) = repo_init_empty().unwrap(); let root = repo.path().parent().unwrap(); let repo_path = root.as_os_str().to_str().unwrap(); - assert_eq!(stage_add_file(repo_path, file_path), false); + assert_eq!( + stage_add_file(repo_path, file_path).unwrap(), + false + ); } #[test] fn test_staging_one_file() { let file_path = Path::new("file1.txt"); - let (_td, repo) = repo_init(); + let (_td, repo) = repo_init().unwrap(); let root = repo.path().parent().unwrap(); let repo_path = root.as_os_str().to_str().unwrap(); @@ -201,21 +221,24 @@ mod tests { .write_all(b"test file2 content") .unwrap(); - assert_eq!(get_statuses(repo_path), (2, 0)); + assert_eq!(get_statuses(repo_path).unwrap(), (2, 0)); - assert_eq!(stage_add_file(repo_path, file_path), true); + assert_eq!( + stage_add_file(repo_path, file_path).unwrap(), + true + ); - assert_eq!(get_statuses(repo_path), (1, 1)); + assert_eq!(get_statuses(repo_path).unwrap(), (1, 1)); } #[test] fn test_staging_folder() -> Result<(), Error> { - let (_td, repo) = repo_init(); + let (_td, repo) = repo_init().unwrap(); let root = repo.path().parent().unwrap(); let repo_path = root.as_os_str().to_str().unwrap(); let status_count = |s: StatusType| -> usize { - get_status(repo_path, s).len() + get_status(repo_path, s).unwrap().len() }; fs::create_dir_all(&root.join("a/d"))?; @@ -228,7 +251,7 @@ mod tests { assert_eq!(status_count(StatusType::WorkingDir), 3); - assert_eq!(stage_add_all(repo_path, "a/d"), true); + assert_eq!(stage_add_all(repo_path, "a/d").unwrap(), true); assert_eq!(status_count(StatusType::WorkingDir), 1); assert_eq!(status_count(StatusType::Stage), 2); @@ -239,12 +262,12 @@ mod tests { #[test] fn test_staging_deleted_file() { let file_path = Path::new("file1.txt"); - let (_td, repo) = repo_init(); + let (_td, repo) = repo_init().unwrap(); let root = repo.path().parent().unwrap(); let repo_path = root.as_os_str().to_str().unwrap(); let status_count = |s: StatusType| -> usize { - get_status(repo_path, s).len() + get_status(repo_path, s).unwrap().len() }; let full_path = &root.join(file_path); @@ -254,7 +277,10 @@ mod tests { .write_all(b"test file1 content") .unwrap(); - assert_eq!(stage_add_file(repo_path, file_path), true); + assert_eq!( + stage_add_file(repo_path, file_path).unwrap(), + true + ); commit(repo_path, "commit msg").unwrap(); @@ -264,7 +290,10 @@ mod tests { // deleted file in diff now assert_eq!(status_count(StatusType::WorkingDir), 1); - assert_eq!(stage_addremoved(repo_path, file_path), true); + assert_eq!( + stage_addremoved(repo_path, file_path).unwrap(), + true + ); assert_eq!(status_count(StatusType::WorkingDir), 0); assert_eq!(status_count(StatusType::Stage), 1); diff --git a/src/app.rs b/src/app.rs index 4ee249b554..5848846d10 100644 --- a/src/app.rs +++ b/src/app.rs @@ -220,13 +220,17 @@ impl App { if sync::reset_workdir_folder( CWD, reset_item.path.as_str(), - ) { + ) + .unwrap() + { flags.insert(NeedsUpdate::ALL); } } else if sync::reset_workdir_file( CWD, reset_item.path.as_str(), - ) { + ) + .unwrap() + { flags.insert(NeedsUpdate::ALL); } } @@ -239,10 +243,14 @@ impl App { self.status_tab.selected_path() { if is_stage { - if sync::unstage_hunk(CWD, path, hash) { + if sync::unstage_hunk(CWD, path, hash) + .unwrap() + { flags.insert(NeedsUpdate::ALL); } - } else if sync::stage_hunk(CWD, path, hash) { + } else if sync::stage_hunk(CWD, path, hash) + .unwrap() + { flags.insert(NeedsUpdate::ALL); } } diff --git a/src/components/changes.rs b/src/components/changes.rs index 6b79eaeb69..1d077ce49d 100644 --- a/src/components/changes.rs +++ b/src/components/changes.rs @@ -109,8 +109,10 @@ impl ChangesComponent { return match status { StatusItemType::Deleted => { sync::stage_addremoved(CWD, path) + .unwrap() } - _ => sync::stage_add_file(CWD, path), + _ => sync::stage_add_file(CWD, path) + .unwrap(), }; } } else { @@ -118,12 +120,13 @@ impl ChangesComponent { return sync::stage_add_all( CWD, tree_item.info.full_path.as_str(), - ); + ) + .unwrap(); } } else { let path = Path::new(tree_item.info.full_path.as_str()); - return sync::reset_stage(CWD, path); + return sync::reset_stage(CWD, path).unwrap(); } } diff --git a/src/components/commit.rs b/src/components/commit.rs index c47360c1f9..637fa3df2f 100644 --- a/src/components/commit.rs +++ b/src/components/commit.rs @@ -135,7 +135,9 @@ impl CommitComponent { } sync::commit(CWD, &self.msg).unwrap(); - if let HookResult::NotOk(e) = sync::hooks_post_commit(CWD) { + if let HookResult::NotOk(e) = + sync::hooks_post_commit(CWD).unwrap() + { error!("post-commit hook error: {}", e); self.queue.borrow_mut().push_back( InternalEvent::ShowMsg(format!( diff --git a/src/tabs/revlog/mod.rs b/src/tabs/revlog/mod.rs index e7ce013440..37b78e5698 100644 --- a/src/tabs/revlog/mod.rs +++ b/src/tabs/revlog/mod.rs @@ -80,7 +80,8 @@ impl Revlog { /// pub fn update(&mut self) { - self.selection_max = self.git_log.count().saturating_sub(1); + self.selection_max = + self.git_log.count().unwrap().saturating_sub(1); if self.items.needs_data(self.selection, self.selection_max) { self.fetch_commits(); @@ -96,7 +97,7 @@ impl Revlog { let commits = sync::get_commits_info( CWD, - &self.git_log.get_slice(want_min, SLICE_SIZE), + &self.git_log.get_slice(want_min, SLICE_SIZE).unwrap(), ); if let Ok(commits) = commits { @@ -343,7 +344,7 @@ impl Component for Revlog { if !self.first_open_done { self.first_open_done = true; - self.git_log.fetch(); + self.git_log.fetch().unwrap(); } } } diff --git a/src/tabs/status.rs b/src/tabs/status.rs index 97bf3bb1cd..63ca12073c 100644 --- a/src/tabs/status.rs +++ b/src/tabs/status.rs @@ -184,7 +184,7 @@ impl Status { /// pub fn update(&mut self) { self.git_diff.refresh(); - self.git_status.fetch(current_tick()); + self.git_status.fetch(current_tick().unwrap()).unwrap(); } /// @@ -202,7 +202,7 @@ impl Status { } fn update_status(&mut self) { - let status = self.git_status.last(); + let status = self.git_status.last().unwrap(); self.index.update(&status.stage); self.index_wd.update(&status.work_dir); @@ -217,7 +217,9 @@ impl Status { if self.diff.current() == (path.clone(), is_stage) { // we are already showing a diff of the right file // maybe the diff changed (outside file change) - if let Some((params, last)) = self.git_diff.last() { + if let Some((params, last)) = + self.git_diff.last().unwrap() + { if params == diff_params { self.diff.update(path, is_stage, last); } From ada39557e7c8cfd66f15095d226c5b9508ad6588 Mon Sep 17 00:00:00 2001 From: Mehran KORDI Date: Fri, 15 May 2020 00:27:42 +0200 Subject: [PATCH 09/26] removed unwrap from spawned code. --- .gitignore | 1 + asyncgit/src/diff.rs | 98 ++++++++++++++++++++++++------------------ asyncgit/src/revlog.rs | 63 +++++++++++++++------------ asyncgit/src/status.rs | 43 ++++++++++++------ src/tabs/status.rs | 5 ++- 5 files changed, 123 insertions(+), 87 deletions(-) diff --git a/.gitignore b/.gitignore index 1c60ceded3..47c1a2ea1f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ /target /release .DS_Store +/.idea/ diff --git a/asyncgit/src/diff.rs b/asyncgit/src/diff.rs index 28efbfc19e..a572cfb7c8 100644 --- a/asyncgit/src/diff.rs +++ b/asyncgit/src/diff.rs @@ -1,3 +1,4 @@ +use crate::error::Returns; use crate::{ error::Error, hash, sync, AsyncNotification, FileDiff, CWD, }; @@ -47,12 +48,7 @@ impl AsyncDiff { pub fn last( &mut self, ) -> Result, Error> { - let last = self.last.lock().or_else(|x| { - Err(Error::Generic(format!( - "failed to get last changes:{}", - x - ))) - })?; + let last = self.last.lock()?; Ok(match last.clone() { Some(res) => Some((res.params, res.result)), @@ -61,11 +57,12 @@ impl AsyncDiff { } /// - pub fn refresh(&mut self) { + pub fn refresh(&mut self) -> Returns<()> { if let Ok(Some(param)) = self.get_last_param() { - self.clear_current(); - self.request(param); + self.clear_current()?; + self.request(param)?; } + Ok(()) } /// @@ -77,16 +74,16 @@ impl AsyncDiff { pub fn request( &mut self, params: DiffParams, - ) -> Option { + ) -> Returns> { trace!("request"); let hash = hash(¶ms); { - let mut current = self.current.lock().unwrap(); + let mut current = self.current.lock()?; if current.0 == hash { - return current.1.clone(); + return Ok(current.1.clone()); } current.0 = hash; @@ -100,51 +97,66 @@ impl AsyncDiff { rayon_core::spawn(move || { arc_pending.fetch_add(1, Ordering::Relaxed); - let res = - sync::diff::get_diff(CWD, params.0.clone(), params.1) - .unwrap(); - let mut notify = false; - { - let mut current = arc_current.lock().unwrap(); - if current.0 == hash { - current.1 = Some(res.clone()); - notify = true; - } - } - - { - let mut last = arc_last.lock().unwrap(); - *last = Some(LastResult { - result: res, - hash, - params, - }); - } + let notify = AsyncDiff::get_diff_helper( + params, + arc_last, + arc_current, + hash, + ) + .expect("error getting diff"); arc_pending.fetch_sub(1, Ordering::Relaxed); if notify { - sender + let _ = sender .send(AsyncNotification::Diff) .expect("error sending diff"); } }); - None + Ok(None) + } + + fn get_diff_helper( + params: DiffParams, + arc_last: Arc< + Mutex>>, + >, + arc_current: Arc>>, + hash: u64, + ) -> Returns { + let res = + sync::diff::get_diff(CWD, params.0.clone(), params.1)?; + + let mut notify = false; + { + let mut current = arc_current.lock()?; + if current.0 == hash { + current.1 = Some(res.clone()); + notify = true; + } + } + + { + let mut last = arc_last.lock()?; + *last = Some(LastResult { + result: res, + hash, + params, + }); + } + + Ok(notify) } - fn get_last_param(&self) -> Result, Error> { - Ok(self - .last - .lock() - .map_err(|_| Error::Generic("".to_string()))? - .clone() - .map(|e| e.params)) + fn get_last_param(&self) -> Returns> { + Ok(self.last.lock()?.clone().map(|e| e.params)) } - fn clear_current(&mut self) { - let mut current = self.current.lock().unwrap(); + fn clear_current(&mut self) -> Returns<()> { + let mut current = self.current.lock()?; current.0 = 0; current.1 = None; + Ok(()) } } diff --git a/asyncgit/src/revlog.rs b/asyncgit/src/revlog.rs index 0b1474805d..ed3451cfa4 100644 --- a/asyncgit/src/revlog.rs +++ b/asyncgit/src/revlog.rs @@ -58,47 +58,54 @@ impl AsyncLog { /// pub fn fetch(&mut self) -> Returns<()> { if !self.is_pending() { - self.clear(); + self.clear()?; let arc_current = Arc::clone(&self.current); let sender = self.sender.clone(); let arc_pending = Arc::clone(&self.pending); - rayon_core::spawn(move || { - arc_pending.store(true, Ordering::Relaxed); + rayon_core::spawn(move || { scope_time!("async::revlog"); - - let mut entries = Vec::with_capacity(LIMIT_COUNT); - let r = repo(CWD).unwrap(); - let mut walker = LogWalker::new(&r); - loop { - entries.clear(); - let res_is_err = walker - .read(&mut entries, LIMIT_COUNT) - .is_err(); - - if !res_is_err { - let mut current = arc_current.lock().unwrap(); - current.extend(entries.iter()); - } - - if res_is_err || entries.len() <= 1 { - break; - } else { - Self::notify(&sender); - } - } - + arc_pending.store(true, Ordering::Relaxed); + AsyncLog::fetch_helper(arc_current, &sender) + .expect("failed to fetch"); arc_pending.store(false, Ordering::Relaxed); - Self::notify(&sender); }); } Ok(()) } - fn clear(&mut self) { - self.current.lock().unwrap().clear(); + fn fetch_helper( + arc_current: Arc>>, + sender: &Sender, + ) -> Returns<()> { + let mut entries = Vec::with_capacity(LIMIT_COUNT); + let r = repo(CWD)?; + let mut walker = LogWalker::new(&r); + loop { + entries.clear(); + let res_is_err = + walker.read(&mut entries, LIMIT_COUNT).is_err(); + + if !res_is_err { + let mut current = arc_current.lock()?; + current.extend(entries.iter()); + } + + if res_is_err || entries.len() <= 1 { + break; + } else { + Self::notify(&sender); + } + } + + Ok(()) + } + + fn clear(&mut self) -> Returns<()> { + self.current.lock()?.clear(); + Ok(()) } fn notify(sender: &Sender) { diff --git a/asyncgit/src/status.rs b/asyncgit/src/status.rs index 270b13276f..5a531fef2a 100644 --- a/asyncgit/src/status.rs +++ b/asyncgit/src/status.rs @@ -75,20 +75,12 @@ impl AsyncStatus { rayon_core::spawn(move || { arc_pending.fetch_add(1, Ordering::Relaxed); - let res = Self::get_status().unwrap(); - trace!("status fetched: {}", hash(&res)); - - { - let mut current = arc_current.lock().unwrap(); - if current.0 == hash_request { - current.1 = Some(res.clone()); - } - } - - { - let mut last = arc_last.lock().unwrap(); - *last = res; - } + AsyncStatus::fetch_helper( + hash_request, + arc_current, + arc_last, + ) + .expect("failed to fetch status"); arc_pending.fetch_sub(1, Ordering::Relaxed); @@ -100,6 +92,29 @@ impl AsyncStatus { Ok(None) } + fn fetch_helper( + hash_request: u64, + arc_current: Arc>>, + arc_last: Arc>, + ) -> Returns<()> { + let res = Self::get_status()?; + trace!("status fetched: {}", hash(&res)); + + { + let mut current = arc_current.lock()?; + if current.0 == hash_request { + current.1 = Some(res.clone()); + } + } + + { + let mut last = arc_last.lock()?; + *last = res; + } + + Ok(()) + } + fn get_status() -> Result { let work_dir = sync::status::get_status(CWD, StatusType::WorkingDir)?; diff --git a/src/tabs/status.rs b/src/tabs/status.rs index 63ca12073c..a63060c9cd 100644 --- a/src/tabs/status.rs +++ b/src/tabs/status.rs @@ -183,7 +183,7 @@ impl Status { /// pub fn update(&mut self) { - self.git_diff.refresh(); + self.git_diff.refresh().unwrap(); self.git_status.fetch(current_tick().unwrap()).unwrap(); } @@ -226,7 +226,8 @@ impl Status { } } else { // we dont show the right diff right now, so we need to request - if let Some(diff) = self.git_diff.request(diff_params) + if let Some(diff) = + self.git_diff.request(diff_params).unwrap() { self.diff.update(path, is_stage, diff); } else { From c326c9b8305467ef04c8455df10a78fca5bad3d8 Mon Sep 17 00:00:00 2001 From: Mehran KORDI Date: Fri, 15 May 2020 10:48:58 +0200 Subject: [PATCH 10/26] fixed broken linux tests. --- asyncgit/src/sync/hooks.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/asyncgit/src/sync/hooks.rs b/asyncgit/src/sync/hooks.rs index 2a6775466e..bdc55c7831 100644 --- a/asyncgit/src/sync/hooks.rs +++ b/asyncgit/src/sync/hooks.rs @@ -127,7 +127,7 @@ mod tests { #[test] #[cfg(not(windows))] fn test_hooks_commit_msg_ok() { - let (_td, repo) = repo_init(); + let (_td, repo) = repo_init().unwrap(); let root = repo.path().parent().unwrap(); let repo_path = root.as_os_str().to_str().unwrap(); @@ -149,7 +149,7 @@ exit 0 #[test] #[cfg(not(windows))] fn test_hooks_commit_msg() { - let (_td, repo) = repo_init(); + let (_td, repo) = repo_init().unwrap(); let root = repo.path().parent().unwrap(); let repo_path = root.as_os_str().to_str().unwrap(); @@ -176,7 +176,7 @@ exit 1 #[test] #[cfg(not(windows))] fn test_commit_msg_no_block_but_alter() { - let (_td, repo) = repo_init(); + let (_td, repo) = repo_init().unwrap(); let root = repo.path().parent().unwrap(); let repo_path = root.as_os_str().to_str().unwrap(); From da48385c96d91dc0ed7039c8eed1c18bc8c9d334 Mon Sep 17 00:00:00 2001 From: Mehran KORDI Date: Fri, 15 May 2020 10:54:53 +0200 Subject: [PATCH 11/26] fixed a clippy warning. --- asyncgit/src/diff.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/asyncgit/src/diff.rs b/asyncgit/src/diff.rs index a572cfb7c8..737e6531b6 100644 --- a/asyncgit/src/diff.rs +++ b/asyncgit/src/diff.rs @@ -108,7 +108,7 @@ impl AsyncDiff { arc_pending.fetch_sub(1, Ordering::Relaxed); if notify { - let _ = sender + sender .send(AsyncNotification::Diff) .expect("error sending diff"); } From 7cb91c8697bee0c96edbb3b98909644affbaac66 Mon Sep 17 00:00:00 2001 From: Mehran KORDI Date: Fri, 15 May 2020 11:16:41 +0200 Subject: [PATCH 12/26] use Returns every where. --- asyncgit/src/diff.rs | 6 ++---- asyncgit/src/status.rs | 5 ++--- asyncgit/src/sync/commits_info.rs | 9 +++------ asyncgit/src/sync/diff.rs | 11 ++++++----- asyncgit/src/sync/hooks.rs | 2 +- asyncgit/src/sync/hunks.rs | 5 +++-- asyncgit/src/sync/logwalker.rs | 15 ++++++--------- asyncgit/src/sync/mod.rs | 17 ++++++----------- asyncgit/src/sync/reset.rs | 5 +++-- asyncgit/src/sync/status.rs | 3 ++- asyncgit/src/sync/utils.rs | 4 ++-- 11 files changed, 36 insertions(+), 46 deletions(-) diff --git a/asyncgit/src/diff.rs b/asyncgit/src/diff.rs index 737e6531b6..6b3b4b2de3 100644 --- a/asyncgit/src/diff.rs +++ b/asyncgit/src/diff.rs @@ -1,7 +1,5 @@ use crate::error::Returns; -use crate::{ - error::Error, hash, sync, AsyncNotification, FileDiff, CWD, -}; +use crate::{hash, sync, AsyncNotification, FileDiff, CWD}; use crossbeam_channel::Sender; use log::trace; use std::{ @@ -47,7 +45,7 @@ impl AsyncDiff { /// pub fn last( &mut self, - ) -> Result, Error> { + ) -> Returns> { let last = self.last.lock()?; Ok(match last.clone() { diff --git a/asyncgit/src/status.rs b/asyncgit/src/status.rs index 5a531fef2a..e8e3c50555 100644 --- a/asyncgit/src/status.rs +++ b/asyncgit/src/status.rs @@ -1,6 +1,5 @@ use crate::{ - error::{Error, Returns}, - hash, sync, AsyncNotification, StatusItem, CWD, + error::Returns, hash, sync, AsyncNotification, StatusItem, CWD, }; use crossbeam_channel::Sender; use log::trace; @@ -115,7 +114,7 @@ impl AsyncStatus { Ok(()) } - fn get_status() -> Result { + fn get_status() -> Returns { let work_dir = sync::status::get_status(CWD, StatusType::WorkingDir)?; let stage = sync::status::get_status(CWD, StatusType::Stage)?; diff --git a/asyncgit/src/sync/commits_info.rs b/asyncgit/src/sync/commits_info.rs index 7d0ebcacc7..b3386760f5 100644 --- a/asyncgit/src/sync/commits_info.rs +++ b/asyncgit/src/sync/commits_info.rs @@ -71,17 +71,14 @@ fn limit_str(s: &str, limit: usize) -> String { mod tests { use super::get_commits_info; + use crate::error::Returns; use crate::sync::{ commit, stage_add_file, tests::repo_init_empty, }; - use std::{ - fs::File, - io::{Error, Write}, - path::Path, - }; + use std::{fs::File, io::Write, path::Path}; #[test] - fn test_log() -> Result<(), Error> { + fn test_log() -> Returns<()> { let file_path = Path::new("foo"); let (_td, repo) = repo_init_empty().unwrap(); let root = repo.path().parent().unwrap(); diff --git a/asyncgit/src/sync/diff.rs b/asyncgit/src/sync/diff.rs index 81270b2de7..f3080a48f6 100644 --- a/asyncgit/src/sync/diff.rs +++ b/asyncgit/src/sync/diff.rs @@ -1,6 +1,7 @@ //! sync git api for fetching a diff use super::utils; +use crate::error::Returns; use crate::{error::Error, hash}; use git2::{ Delta, Diff, DiffDelta, DiffFormat, DiffHunk, DiffOptions, Patch, @@ -79,7 +80,7 @@ pub(crate) fn get_diff_raw<'a>( p: &str, stage: bool, reverse: bool, -) -> Result, Error> { +) -> Returns> { let mut opt = DiffOptions::new(); opt.pathspec(p); opt.reverse(reverse); @@ -123,7 +124,7 @@ pub fn get_diff( repo_path: &str, p: String, stage: bool, -) -> Result { +) -> Returns { scope_time!("get_diff"); let repo = utils::repo(repo_path)?; @@ -256,6 +257,7 @@ fn new_file_content(path: &Path) -> Option { #[cfg(test)] mod tests { use super::get_diff; + use crate::error::Returns; use crate::sync::{ stage_add_file, status::{get_status, StatusType}, @@ -263,7 +265,7 @@ mod tests { }; use std::{ fs::{self, File}, - io::{Error, Write}, + io::Write, path::Path, }; @@ -422,8 +424,7 @@ mod tests { } #[test] - fn test_diff_new_binary_file_using_invalid_utf8( - ) -> Result<(), Error> { + fn test_diff_new_binary_file_using_invalid_utf8() -> Returns<()> { let file_path = Path::new("bar"); let (_td, repo) = repo_init_empty().unwrap(); let root = repo.path().parent().unwrap(); diff --git a/asyncgit/src/sync/hooks.rs b/asyncgit/src/sync/hooks.rs index bdc55c7831..943ae6b39b 100644 --- a/asyncgit/src/sync/hooks.rs +++ b/asyncgit/src/sync/hooks.rs @@ -15,7 +15,7 @@ const HOOK_COMMIT_MSG: &str = ".git/hooks/commit-msg"; pub fn hooks_commit_msg( repo_path: &str, msg: &mut String, -) -> Result { +) -> Returns { scope_time!("hooks_commit_msg"); if hook_runable(repo_path, HOOK_COMMIT_MSG) { diff --git a/asyncgit/src/sync/hunks.rs b/asyncgit/src/sync/hunks.rs index 2c39e67fc1..a04c6b8673 100644 --- a/asyncgit/src/sync/hunks.rs +++ b/asyncgit/src/sync/hunks.rs @@ -2,6 +2,7 @@ use super::{ diff::{get_diff_raw, HunkHeader}, utils::repo, }; +use crate::error::Returns; use crate::{error::Error, hash}; use git2::{ApplyLocation, ApplyOptions, Diff}; use log::error; @@ -12,7 +13,7 @@ pub fn stage_hunk( repo_path: &str, file_path: String, hunk_hash: u64, -) -> Result { +) -> Returns { scope_time!("stage_hunk"); let repo = repo(repo_path)?; @@ -61,7 +62,7 @@ pub fn unstage_hunk( repo_path: &str, file_path: String, hunk_hash: u64, -) -> Result { +) -> Returns { scope_time!("revert_hunk"); let repo = repo(repo_path)?; diff --git a/asyncgit/src/sync/logwalker.rs b/asyncgit/src/sync/logwalker.rs index 6f047f9b22..7cfe447f3c 100644 --- a/asyncgit/src/sync/logwalker.rs +++ b/asyncgit/src/sync/logwalker.rs @@ -1,4 +1,5 @@ -use git2::{Error, Oid, Repository, Revwalk}; +use crate::error::Returns; +use git2::{Oid, Repository, Revwalk}; /// pub struct LogWalker<'a> { @@ -20,7 +21,7 @@ impl<'a> LogWalker<'a> { &mut self, out: &mut Vec, limit: usize, - ) -> Result { + ) -> Returns { let mut count = 0_usize; if self.revwalk.is_none() { @@ -53,14 +54,10 @@ mod tests { commit, get_commits_info, stage_add_file, tests::repo_init_empty, }; - use std::{ - fs::File, - io::{Error, Write}, - path::Path, - }; + use std::{fs::File, io::Write, path::Path}; #[test] - fn test_limit() -> Result<(), Error> { + fn test_limit() -> Returns<()> { let file_path = Path::new("foo"); let (_td, repo) = repo_init_empty().unwrap(); let root = repo.path().parent().unwrap(); @@ -84,7 +81,7 @@ mod tests { } #[test] - fn test_logwalker() -> Result<(), Error> { + fn test_logwalker() -> Returns<()> { let file_path = Path::new("foo"); let (_td, repo) = repo_init_empty().unwrap(); let root = repo.path().parent().unwrap(); diff --git a/asyncgit/src/sync/mod.rs b/asyncgit/src/sync/mod.rs index c327c973f7..c9659b6a15 100644 --- a/asyncgit/src/sync/mod.rs +++ b/asyncgit/src/sync/mod.rs @@ -25,13 +25,13 @@ pub use utils::{ #[cfg(test)] mod tests { use super::status::{get_status, StatusType}; - use crate::error::Error; + use crate::error::Returns; use git2::Repository; use std::process::Command; use tempfile::TempDir; /// - pub fn repo_init_empty() -> Result<(TempDir, Repository), Error> { + pub fn repo_init_empty() -> Returns<(TempDir, Repository)> { let td = TempDir::new()?; let repo = Repository::init(td.path())?; { @@ -43,7 +43,7 @@ mod tests { } /// - pub fn repo_init() -> Result<(TempDir, Repository), Error> { + pub fn repo_init() -> Returns<(TempDir, Repository)> { let td = TempDir::new()?; let repo = Repository::init(td.path())?; { @@ -69,9 +69,7 @@ mod tests { } /// helper returning amount of files with changes in the (wd,stage) - pub fn get_statuses( - repo_path: &str, - ) -> Result<(usize, usize), Error> { + pub fn get_statuses(repo_path: &str) -> Returns<(usize, usize)> { Ok(( get_status(repo_path, StatusType::WorkingDir)?.len(), get_status(repo_path, StatusType::Stage)?.len(), @@ -79,16 +77,13 @@ mod tests { } /// - pub fn debug_cmd_print( - path: &str, - cmd: &str, - ) -> Result<(), Error> { + pub fn debug_cmd_print(path: &str, cmd: &str) -> Returns<()> { let cmd = debug_cmd(path, cmd)?; eprintln!("\n----\n{}", cmd); Ok(()) } - fn debug_cmd(path: &str, cmd: &str) -> Result { + fn debug_cmd(path: &str, cmd: &str) -> Returns { let output = if cfg!(target_os = "windows") { Command::new("cmd") .args(&["/C", cmd]) diff --git a/asyncgit/src/sync/reset.rs b/asyncgit/src/sync/reset.rs index 8fc8527c8c..ff2b95d6c8 100644 --- a/asyncgit/src/sync/reset.rs +++ b/asyncgit/src/sync/reset.rs @@ -97,6 +97,7 @@ mod tests { use super::{ reset_stage, reset_workdir_file, reset_workdir_folder, }; + use crate::error::Returns; use crate::sync::{ status::{get_status, StatusType}, tests::{ @@ -106,7 +107,7 @@ mod tests { }; use std::{ fs::{self, File}, - io::{Error, Write}, + io::Write, path::Path, }; @@ -209,7 +210,7 @@ mod tests { } #[test] - fn test_reset_folder() -> Result<(), Error> { + fn test_reset_folder() -> Returns<()> { let (_td, repo) = repo_init().unwrap(); let root = repo.path().parent().unwrap(); let repo_path = root.as_os_str().to_str().unwrap(); diff --git a/asyncgit/src/sync/status.rs b/asyncgit/src/sync/status.rs index 85a97edfd3..e4008fbc23 100644 --- a/asyncgit/src/sync/status.rs +++ b/asyncgit/src/sync/status.rs @@ -1,5 +1,6 @@ //! sync git api for fetching a status +use crate::error::Returns; use crate::{error::Error, sync::utils}; use git2::{Status, StatusOptions, StatusShow}; use scopetime::scope_time; @@ -67,7 +68,7 @@ impl Into for StatusType { pub fn get_status( repo_path: &str, status_type: StatusType, -) -> Result, Error> { +) -> Returns> { scope_time!("get_index"); let repo = utils::repo(repo_path)?; diff --git a/asyncgit/src/sync/utils.rs b/asyncgit/src/sync/utils.rs index 8e3b744d4d..cc5af05362 100644 --- a/asyncgit/src/sync/utils.rs +++ b/asyncgit/src/sync/utils.rs @@ -133,7 +133,7 @@ mod tests { }; use std::{ fs::{self, remove_file, File}, - io::{Error, Write}, + io::Write, path::Path, }; @@ -232,7 +232,7 @@ mod tests { } #[test] - fn test_staging_folder() -> Result<(), Error> { + fn test_staging_folder() -> Returns<()> { let (_td, repo) = repo_init().unwrap(); let root = repo.path().parent().unwrap(); let repo_path = root.as_os_str().to_str().unwrap(); From 1e5bf3eca17a506a055847741d618e8686335376 Mon Sep 17 00:00:00 2001 From: Mehran KORDI Date: Fri, 15 May 2020 11:27:48 +0200 Subject: [PATCH 13/26] renamed returns to result. --- asyncgit/src/diff.rs | 16 +++++++--------- asyncgit/src/error.rs | 13 +------------ asyncgit/src/lib.rs | 4 ++-- asyncgit/src/revlog.rs | 12 ++++++------ asyncgit/src/status.rs | 10 +++++----- asyncgit/src/sync/commits_info.rs | 10 +++++----- asyncgit/src/sync/diff.rs | 10 +++++----- asyncgit/src/sync/hooks.rs | 8 ++++---- asyncgit/src/sync/hunks.rs | 6 +++--- asyncgit/src/sync/logwalker.rs | 8 ++++---- asyncgit/src/sync/mod.rs | 12 ++++++------ asyncgit/src/sync/reset.rs | 12 ++++++------ asyncgit/src/sync/status.rs | 4 ++-- asyncgit/src/sync/tags.rs | 4 ++-- asyncgit/src/sync/utils.rs | 17 +++++++---------- 15 files changed, 65 insertions(+), 81 deletions(-) diff --git a/asyncgit/src/diff.rs b/asyncgit/src/diff.rs index 6b3b4b2de3..8bd0ee7c3d 100644 --- a/asyncgit/src/diff.rs +++ b/asyncgit/src/diff.rs @@ -1,4 +1,4 @@ -use crate::error::Returns; +use crate::error::Result; use crate::{hash, sync, AsyncNotification, FileDiff, CWD}; use crossbeam_channel::Sender; use log::trace; @@ -43,9 +43,7 @@ impl AsyncDiff { } /// - pub fn last( - &mut self, - ) -> Returns> { + pub fn last(&mut self) -> Result> { let last = self.last.lock()?; Ok(match last.clone() { @@ -55,7 +53,7 @@ impl AsyncDiff { } /// - pub fn refresh(&mut self) -> Returns<()> { + pub fn refresh(&mut self) -> Result<()> { if let Ok(Some(param)) = self.get_last_param() { self.clear_current()?; self.request(param)?; @@ -72,7 +70,7 @@ impl AsyncDiff { pub fn request( &mut self, params: DiffParams, - ) -> Returns> { + ) -> Result> { trace!("request"); let hash = hash(¶ms); @@ -122,7 +120,7 @@ impl AsyncDiff { >, arc_current: Arc>>, hash: u64, - ) -> Returns { + ) -> Result { let res = sync::diff::get_diff(CWD, params.0.clone(), params.1)?; @@ -147,11 +145,11 @@ impl AsyncDiff { Ok(notify) } - fn get_last_param(&self) -> Returns> { + fn get_last_param(&self) -> Result> { Ok(self.last.lock()?.clone().map(|e| e.params)) } - fn clear_current(&mut self) -> Returns<()> { + fn clear_current(&mut self) -> Result<()> { let mut current = self.current.lock()?; current.0 = 0; current.1 = None; diff --git a/asyncgit/src/error.rs b/asyncgit/src/error.rs index c9da4bd8a3..d56a4d5cc7 100644 --- a/asyncgit/src/error.rs +++ b/asyncgit/src/error.rs @@ -13,20 +13,9 @@ pub enum Error { #[error("encoding error:{0}")] Encoding(#[from] std::string::FromUtf8Error), - - #[error("unspecified error:{0}")] - Unspecified(Box), } -pub type Returns = std::result::Result; - -// impl From<&dyn std::error::Error> for Error { -// fn from(error: &dyn std::error::Error) -> Self { -// let e = error.clone().to_owned(); -// let b = Box::new(e); -// Error::Unspecified(b) -// } -// } +pub type Result = std::result::Result; impl From> for Error { fn from(error: std::sync::PoisonError) -> Self { diff --git a/asyncgit/src/lib.rs b/asyncgit/src/lib.rs index fbb672502c..d234cdb670 100644 --- a/asyncgit/src/lib.rs +++ b/asyncgit/src/lib.rs @@ -20,7 +20,7 @@ pub use crate::{ utils::is_repo, }, }; -use error::{Error, Returns}; +use error::{Error, Result}; use std::{ collections::hash_map::DefaultHasher, hash::{Hash, Hasher}, @@ -49,7 +49,7 @@ pub fn hash(v: &T) -> u64 { } /// helper function to return the current tick since unix epoch -pub fn current_tick() -> Returns { +pub fn current_tick() -> Result { Ok(SystemTime::now() .duration_since(UNIX_EPOCH) .map_err(|_| { diff --git a/asyncgit/src/revlog.rs b/asyncgit/src/revlog.rs index ed3451cfa4..f76ba5d6b1 100644 --- a/asyncgit/src/revlog.rs +++ b/asyncgit/src/revlog.rs @@ -1,4 +1,4 @@ -use crate::error::Returns; +use crate::error::Result; use crate::{sync, AsyncNotification, CWD}; use crossbeam_channel::Sender; use git2::Oid; @@ -32,7 +32,7 @@ impl AsyncLog { } /// - pub fn count(&mut self) -> Returns { + pub fn count(&mut self) -> Result { Ok(self.current.lock()?.len()) } @@ -41,7 +41,7 @@ impl AsyncLog { &self, start_index: usize, amount: usize, - ) -> Returns> { + ) -> Result> { let list = self.current.lock()?; let list_len = list.len(); let min = start_index.min(list_len); @@ -56,7 +56,7 @@ impl AsyncLog { } /// - pub fn fetch(&mut self) -> Returns<()> { + pub fn fetch(&mut self) -> Result<()> { if !self.is_pending() { self.clear()?; @@ -79,7 +79,7 @@ impl AsyncLog { fn fetch_helper( arc_current: Arc>>, sender: &Sender, - ) -> Returns<()> { + ) -> Result<()> { let mut entries = Vec::with_capacity(LIMIT_COUNT); let r = repo(CWD)?; let mut walker = LogWalker::new(&r); @@ -103,7 +103,7 @@ impl AsyncLog { Ok(()) } - fn clear(&mut self) -> Returns<()> { + fn clear(&mut self) -> Result<()> { self.current.lock()?.clear(); Ok(()) } diff --git a/asyncgit/src/status.rs b/asyncgit/src/status.rs index e8e3c50555..1ce628649b 100644 --- a/asyncgit/src/status.rs +++ b/asyncgit/src/status.rs @@ -1,5 +1,5 @@ use crate::{ - error::Returns, hash, sync, AsyncNotification, StatusItem, CWD, + error::Result, hash, sync, AsyncNotification, StatusItem, CWD, }; use crossbeam_channel::Sender; use log::trace; @@ -40,7 +40,7 @@ impl AsyncStatus { } /// - pub fn last(&mut self) -> Returns { + pub fn last(&mut self) -> Result { let last = self.last.lock()?; Ok(last.clone()) } @@ -51,7 +51,7 @@ impl AsyncStatus { } /// - pub fn fetch(&mut self, request: u64) -> Returns> { + pub fn fetch(&mut self, request: u64) -> Result> { let hash_request = hash(&request); trace!("request: {} [hash: {}]", request, hash_request); @@ -95,7 +95,7 @@ impl AsyncStatus { hash_request: u64, arc_current: Arc>>, arc_last: Arc>, - ) -> Returns<()> { + ) -> Result<()> { let res = Self::get_status()?; trace!("status fetched: {}", hash(&res)); @@ -114,7 +114,7 @@ impl AsyncStatus { Ok(()) } - fn get_status() -> Returns { + fn get_status() -> Result { let work_dir = sync::status::get_status(CWD, StatusType::WorkingDir)?; let stage = sync::status::get_status(CWD, StatusType::Stage)?; diff --git a/asyncgit/src/sync/commits_info.rs b/asyncgit/src/sync/commits_info.rs index b3386760f5..be734f0698 100644 --- a/asyncgit/src/sync/commits_info.rs +++ b/asyncgit/src/sync/commits_info.rs @@ -1,5 +1,5 @@ use super::utils::repo; -use crate::error::Returns; +use crate::error::Result; use git2::{Commit, Error, Oid}; use scopetime::scope_time; @@ -20,7 +20,7 @@ pub struct CommitInfo { pub fn get_commits_info( repo_path: &str, ids: &[Oid], -) -> Returns> { +) -> Result> { scope_time!("get_commits_info"); let repo = repo(repo_path)?; @@ -28,7 +28,7 @@ pub fn get_commits_info( let commits = ids .iter() .map(|id| repo.find_commit(*id)) - .collect::, Error>>()? + .collect::, Error>>()? .into_iter(); let res = commits @@ -71,14 +71,14 @@ fn limit_str(s: &str, limit: usize) -> String { mod tests { use super::get_commits_info; - use crate::error::Returns; + use crate::error::Result; use crate::sync::{ commit, stage_add_file, tests::repo_init_empty, }; use std::{fs::File, io::Write, path::Path}; #[test] - fn test_log() -> Returns<()> { + fn test_log() -> Result<()> { let file_path = Path::new("foo"); let (_td, repo) = repo_init_empty().unwrap(); let root = repo.path().parent().unwrap(); diff --git a/asyncgit/src/sync/diff.rs b/asyncgit/src/sync/diff.rs index f3080a48f6..9b4bb518d2 100644 --- a/asyncgit/src/sync/diff.rs +++ b/asyncgit/src/sync/diff.rs @@ -1,7 +1,7 @@ //! sync git api for fetching a diff use super::utils; -use crate::error::Returns; +use crate::error::Result; use crate::{error::Error, hash}; use git2::{ Delta, Diff, DiffDelta, DiffFormat, DiffHunk, DiffOptions, Patch, @@ -80,7 +80,7 @@ pub(crate) fn get_diff_raw<'a>( p: &str, stage: bool, reverse: bool, -) -> Returns> { +) -> Result> { let mut opt = DiffOptions::new(); opt.pathspec(p); opt.reverse(reverse); @@ -124,7 +124,7 @@ pub fn get_diff( repo_path: &str, p: String, stage: bool, -) -> Returns { +) -> Result { scope_time!("get_diff"); let repo = utils::repo(repo_path)?; @@ -257,7 +257,7 @@ fn new_file_content(path: &Path) -> Option { #[cfg(test)] mod tests { use super::get_diff; - use crate::error::Returns; + use crate::error::Result; use crate::sync::{ stage_add_file, status::{get_status, StatusType}, @@ -424,7 +424,7 @@ mod tests { } #[test] - fn test_diff_new_binary_file_using_invalid_utf8() -> Returns<()> { + fn test_diff_new_binary_file_using_invalid_utf8() -> Result<()> { let file_path = Path::new("bar"); let (_td, repo) = repo_init_empty().unwrap(); let root = repo.path().parent().unwrap(); diff --git a/asyncgit/src/sync/hooks.rs b/asyncgit/src/sync/hooks.rs index 943ae6b39b..5f5909ea75 100644 --- a/asyncgit/src/sync/hooks.rs +++ b/asyncgit/src/sync/hooks.rs @@ -1,4 +1,4 @@ -use crate::error::{Error, Returns}; +use crate::error::{Error, Result}; use is_executable::IsExecutable; use scopetime::scope_time; use std::{ @@ -15,7 +15,7 @@ const HOOK_COMMIT_MSG: &str = ".git/hooks/commit-msg"; pub fn hooks_commit_msg( repo_path: &str, msg: &mut String, -) -> Returns { +) -> Result { scope_time!("hooks_commit_msg"); if hook_runable(repo_path, HOOK_COMMIT_MSG) { @@ -42,7 +42,7 @@ pub fn hooks_commit_msg( } /// -pub fn hooks_post_commit(repo_path: &str) -> Returns { +pub fn hooks_post_commit(repo_path: &str) -> Result { scope_time!("hooks_post_commit"); if hook_runable(repo_path, HOOK_POST_COMMIT) { @@ -72,7 +72,7 @@ fn run_hook( path: &str, cmd: &str, args: &[&str], -) -> Returns { +) -> Result { let output = Command::new(cmd).args(args).current_dir(path).output(); diff --git a/asyncgit/src/sync/hunks.rs b/asyncgit/src/sync/hunks.rs index a04c6b8673..343cc43488 100644 --- a/asyncgit/src/sync/hunks.rs +++ b/asyncgit/src/sync/hunks.rs @@ -2,7 +2,7 @@ use super::{ diff::{get_diff_raw, HunkHeader}, utils::repo, }; -use crate::error::Returns; +use crate::error::Result; use crate::{error::Error, hash}; use git2::{ApplyLocation, ApplyOptions, Diff}; use log::error; @@ -13,7 +13,7 @@ pub fn stage_hunk( repo_path: &str, file_path: String, hunk_hash: u64, -) -> Returns { +) -> Result { scope_time!("stage_hunk"); let repo = repo(repo_path)?; @@ -62,7 +62,7 @@ pub fn unstage_hunk( repo_path: &str, file_path: String, hunk_hash: u64, -) -> Returns { +) -> Result { scope_time!("revert_hunk"); let repo = repo(repo_path)?; diff --git a/asyncgit/src/sync/logwalker.rs b/asyncgit/src/sync/logwalker.rs index 7cfe447f3c..b364db4da3 100644 --- a/asyncgit/src/sync/logwalker.rs +++ b/asyncgit/src/sync/logwalker.rs @@ -1,4 +1,4 @@ -use crate::error::Returns; +use crate::error::Result; use git2::{Oid, Repository, Revwalk}; /// @@ -21,7 +21,7 @@ impl<'a> LogWalker<'a> { &mut self, out: &mut Vec, limit: usize, - ) -> Returns { + ) -> Result { let mut count = 0_usize; if self.revwalk.is_none() { @@ -57,7 +57,7 @@ mod tests { use std::{fs::File, io::Write, path::Path}; #[test] - fn test_limit() -> Returns<()> { + fn test_limit() -> Result<()> { let file_path = Path::new("foo"); let (_td, repo) = repo_init_empty().unwrap(); let root = repo.path().parent().unwrap(); @@ -81,7 +81,7 @@ mod tests { } #[test] - fn test_logwalker() -> Returns<()> { + fn test_logwalker() -> Result<()> { let file_path = Path::new("foo"); let (_td, repo) = repo_init_empty().unwrap(); let root = repo.path().parent().unwrap(); diff --git a/asyncgit/src/sync/mod.rs b/asyncgit/src/sync/mod.rs index c9659b6a15..f16f0af0e4 100644 --- a/asyncgit/src/sync/mod.rs +++ b/asyncgit/src/sync/mod.rs @@ -25,13 +25,13 @@ pub use utils::{ #[cfg(test)] mod tests { use super::status::{get_status, StatusType}; - use crate::error::Returns; + use crate::error::Result; use git2::Repository; use std::process::Command; use tempfile::TempDir; /// - pub fn repo_init_empty() -> Returns<(TempDir, Repository)> { + pub fn repo_init_empty() -> Result<(TempDir, Repository)> { let td = TempDir::new()?; let repo = Repository::init(td.path())?; { @@ -43,7 +43,7 @@ mod tests { } /// - pub fn repo_init() -> Returns<(TempDir, Repository)> { + pub fn repo_init() -> Result<(TempDir, Repository)> { let td = TempDir::new()?; let repo = Repository::init(td.path())?; { @@ -69,7 +69,7 @@ mod tests { } /// helper returning amount of files with changes in the (wd,stage) - pub fn get_statuses(repo_path: &str) -> Returns<(usize, usize)> { + pub fn get_statuses(repo_path: &str) -> Result<(usize, usize)> { Ok(( get_status(repo_path, StatusType::WorkingDir)?.len(), get_status(repo_path, StatusType::Stage)?.len(), @@ -77,13 +77,13 @@ mod tests { } /// - pub fn debug_cmd_print(path: &str, cmd: &str) -> Returns<()> { + pub fn debug_cmd_print(path: &str, cmd: &str) -> Result<()> { let cmd = debug_cmd(path, cmd)?; eprintln!("\n----\n{}", cmd); Ok(()) } - fn debug_cmd(path: &str, cmd: &str) -> Returns { + fn debug_cmd(path: &str, cmd: &str) -> Result { let output = if cfg!(target_os = "windows") { Command::new("cmd") .args(&["/C", cmd]) diff --git a/asyncgit/src/sync/reset.rs b/asyncgit/src/sync/reset.rs index ff2b95d6c8..05d787ffc8 100644 --- a/asyncgit/src/sync/reset.rs +++ b/asyncgit/src/sync/reset.rs @@ -1,11 +1,11 @@ use super::utils::repo; -use crate::error::{Error, Returns}; +use crate::error::{Error, Result}; use git2::{build::CheckoutBuilder, ObjectType, Status}; use scopetime::scope_time; use std::{fs, path::Path}; /// -pub fn reset_stage(repo_path: &str, path: &Path) -> Returns { +pub fn reset_stage(repo_path: &str, path: &Path) -> Result { scope_time!("reset_stage"); let repo = repo(repo_path)?; @@ -35,7 +35,7 @@ pub fn reset_stage(repo_path: &str, path: &Path) -> Returns { pub fn reset_workdir_file( repo_path: &str, path: &str, -) -> Returns { +) -> Result { scope_time!("reset_workdir_file"); let repo = repo(repo_path)?; @@ -75,7 +75,7 @@ pub fn reset_workdir_file( pub fn reset_workdir_folder( repo_path: &str, path: &str, -) -> Returns { +) -> Result { scope_time!("reset_workdir_folder"); let repo = repo(repo_path)?; @@ -97,7 +97,7 @@ mod tests { use super::{ reset_stage, reset_workdir_file, reset_workdir_folder, }; - use crate::error::Returns; + use crate::error::Result; use crate::sync::{ status::{get_status, StatusType}, tests::{ @@ -210,7 +210,7 @@ mod tests { } #[test] - fn test_reset_folder() -> Returns<()> { + fn test_reset_folder() -> Result<()> { let (_td, repo) = repo_init().unwrap(); let root = repo.path().parent().unwrap(); let repo_path = root.as_os_str().to_str().unwrap(); diff --git a/asyncgit/src/sync/status.rs b/asyncgit/src/sync/status.rs index e4008fbc23..f0b4f3a55c 100644 --- a/asyncgit/src/sync/status.rs +++ b/asyncgit/src/sync/status.rs @@ -1,6 +1,6 @@ //! sync git api for fetching a status -use crate::error::Returns; +use crate::error::Result; use crate::{error::Error, sync::utils}; use git2::{Status, StatusOptions, StatusShow}; use scopetime::scope_time; @@ -68,7 +68,7 @@ impl Into for StatusType { pub fn get_status( repo_path: &str, status_type: StatusType, -) -> Returns> { +) -> Result> { scope_time!("get_index"); let repo = utils::repo(repo_path)?; diff --git a/asyncgit/src/sync/tags.rs b/asyncgit/src/sync/tags.rs index feb84b1b76..3ef2dc80f4 100644 --- a/asyncgit/src/sync/tags.rs +++ b/asyncgit/src/sync/tags.rs @@ -1,5 +1,5 @@ use super::utils::repo; -use crate::error::Returns; +use crate::error::Result; use scopetime::scope_time; use std::collections::HashMap; @@ -7,7 +7,7 @@ use std::collections::HashMap; pub type Tags = HashMap; /// returns `Tags` type filled with all tags found in repo -pub fn get_tags(repo_path: &str) -> Returns { +pub fn get_tags(repo_path: &str) -> Result { scope_time!("get_tags"); let mut res = Tags::new(); diff --git a/asyncgit/src/sync/utils.rs b/asyncgit/src/sync/utils.rs index cc5af05362..98f9eb1822 100644 --- a/asyncgit/src/sync/utils.rs +++ b/asyncgit/src/sync/utils.rs @@ -1,6 +1,6 @@ //! sync git api (various methods) -use crate::error::{Error, Returns}; +use crate::error::{Error, Result}; use git2::{IndexAddOption, Oid, Repository, RepositoryOpenFlags}; use scopetime::scope_time; use std::path::Path; @@ -16,7 +16,7 @@ pub fn is_repo(repo_path: &str) -> bool { } /// -pub fn repo(repo_path: &str) -> Returns { +pub fn repo(repo_path: &str) -> Result { let repo = Repository::open_ext( repo_path, RepositoryOpenFlags::empty(), @@ -31,7 +31,7 @@ pub fn repo(repo_path: &str) -> Returns { } /// this does not run any git hooks -pub fn commit(repo_path: &str, msg: &str) -> Returns { +pub fn commit(repo_path: &str, msg: &str) -> Result { scope_time!("commit"); let repo = repo(repo_path)?; @@ -68,7 +68,7 @@ pub fn commit(repo_path: &str, msg: &str) -> Returns { } /// add a file diff from workingdir to stage (will not add removed files see `stage_addremoved`) -pub fn stage_add_file(repo_path: &str, path: &Path) -> Returns { +pub fn stage_add_file(repo_path: &str, path: &Path) -> Result { scope_time!("stage_add_file"); let repo = repo(repo_path)?; @@ -84,10 +84,7 @@ pub fn stage_add_file(repo_path: &str, path: &Path) -> Returns { } /// like `stage_add_file` but uses a pattern to match/glob multiple files/folders -pub fn stage_add_all( - repo_path: &str, - pattern: &str, -) -> Returns { +pub fn stage_add_all(repo_path: &str, pattern: &str) -> Result { scope_time!("stage_add_all"); let repo = repo(repo_path)?; @@ -109,7 +106,7 @@ pub fn stage_add_all( pub fn stage_addremoved( repo_path: &str, path: &Path, -) -> Returns { +) -> Result { scope_time!("stage_addremoved"); let repo = repo(repo_path)?; @@ -232,7 +229,7 @@ mod tests { } #[test] - fn test_staging_folder() -> Returns<()> { + fn test_staging_folder() -> Result<()> { let (_td, repo) = repo_init().unwrap(); let root = repo.path().parent().unwrap(); let repo_path = root.as_os_str().to_str().unwrap(); From be70a2c7337ead30b9bc8b3bbb3d64578fd28b83 Mon Sep 17 00:00:00 2001 From: Mehran KORDI Date: Fri, 15 May 2020 11:29:56 +0200 Subject: [PATCH 14/26] current_tick should not return a Result. --- asyncgit/src/lib.rs | 11 ++++------- src/tabs/status.rs | 2 +- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/asyncgit/src/lib.rs b/asyncgit/src/lib.rs index d234cdb670..96214f5bc9 100644 --- a/asyncgit/src/lib.rs +++ b/asyncgit/src/lib.rs @@ -20,7 +20,6 @@ pub use crate::{ utils::is_repo, }, }; -use error::{Error, Result}; use std::{ collections::hash_map::DefaultHasher, hash::{Hash, Hasher}, @@ -49,11 +48,9 @@ pub fn hash(v: &T) -> u64 { } /// helper function to return the current tick since unix epoch -pub fn current_tick() -> Result { - Ok(SystemTime::now() +pub fn current_tick() -> u64 { + SystemTime::now() .duration_since(UNIX_EPOCH) - .map_err(|_| { - Error::Generic("can't get system time".to_string()) - })? - .as_millis() as u64) + .unwrap() + .as_millis() as u64 } diff --git a/src/tabs/status.rs b/src/tabs/status.rs index a63060c9cd..03b9c86b17 100644 --- a/src/tabs/status.rs +++ b/src/tabs/status.rs @@ -184,7 +184,7 @@ impl Status { /// pub fn update(&mut self) { self.git_diff.refresh().unwrap(); - self.git_status.fetch(current_tick().unwrap()).unwrap(); + self.git_status.fetch(current_tick()).unwrap(); } /// From 6aa7b74a19960a52e5c318fb78e2efcceefa2447 Mon Sep 17 00:00:00 2001 From: Mehran KORDI Date: Fri, 15 May 2020 11:35:46 +0200 Subject: [PATCH 15/26] changed an error message. --- asyncgit/src/sync/hooks.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/asyncgit/src/sync/hooks.rs b/asyncgit/src/sync/hooks.rs index 5f5909ea75..5b0517c120 100644 --- a/asyncgit/src/sync/hooks.rs +++ b/asyncgit/src/sync/hooks.rs @@ -24,7 +24,10 @@ pub fn hooks_commit_msg( write!(file, "{}", msg)?; let file_path = file.path().to_str().ok_or_else(|| { - Error::Generic("can't get temp file's path".to_string()) + Error::Generic( + "temp file path contains invalid unicode sequences." + .to_string(), + ) })?; let res = From 9b5082ba7a48fe4e953731e737dcf6029cd5fd82 Mon Sep 17 00:00:00 2001 From: Mehran KORDI Date: Fri, 15 May 2020 11:38:04 +0200 Subject: [PATCH 16/26] changed a method signature. --- asyncgit/src/sync/hunks.rs | 4 ++-- src/app.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/asyncgit/src/sync/hunks.rs b/asyncgit/src/sync/hunks.rs index 343cc43488..3a727b7f77 100644 --- a/asyncgit/src/sync/hunks.rs +++ b/asyncgit/src/sync/hunks.rs @@ -13,7 +13,7 @@ pub fn stage_hunk( repo_path: &str, file_path: String, hunk_hash: u64, -) -> Result { +) -> Result<()> { scope_time!("stage_hunk"); let repo = repo(repo_path)?; @@ -28,7 +28,7 @@ pub fn stage_hunk( repo.apply(&diff, ApplyLocation::Index, Some(&mut opt))?; - Ok(true) + Ok(()) } fn find_hunk_index(diff: &Diff, hunk_hash: u64) -> Option { diff --git a/src/app.rs b/src/app.rs index 5848846d10..1a00667bb9 100644 --- a/src/app.rs +++ b/src/app.rs @@ -248,8 +248,8 @@ impl App { { flags.insert(NeedsUpdate::ALL); } - } else if sync::stage_hunk(CWD, path, hash) - .unwrap() + } else if let Ok(()) = + sync::stage_hunk(CWD, path, hash) { flags.insert(NeedsUpdate::ALL); } From 6402ea76c832d92b81f217cc707b4bbb9ea03cad Mon Sep 17 00:00:00 2001 From: Mehran KORDI Date: Fri, 15 May 2020 11:43:14 +0200 Subject: [PATCH 17/26] changed a method signature. --- asyncgit/src/sync/reset.rs | 6 +++--- src/components/changes.rs | 3 ++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/asyncgit/src/sync/reset.rs b/asyncgit/src/sync/reset.rs index 05d787ffc8..4c5a010537 100644 --- a/asyncgit/src/sync/reset.rs +++ b/asyncgit/src/sync/reset.rs @@ -5,7 +5,7 @@ use scopetime::scope_time; use std::{fs, path::Path}; /// -pub fn reset_stage(repo_path: &str, path: &Path) -> Result { +pub fn reset_stage(repo_path: &str, path: &Path) -> Result<()> { scope_time!("reset_stage"); let repo = repo(repo_path)?; @@ -28,7 +28,7 @@ pub fn reset_stage(repo_path: &str, path: &Path) -> Result { repo.reset_default(None, &[path])?; } - Ok(true) + Ok(()) } /// @@ -315,7 +315,7 @@ mod tests { assert_eq!(get_statuses(repo_path).unwrap(), (0, 1)); - assert_eq!(reset_stage(repo_path, file_path).unwrap(), true); + reset_stage(repo_path, file_path).unwrap(); assert_eq!(get_statuses(repo_path).unwrap(), (1, 0)); } diff --git a/src/components/changes.rs b/src/components/changes.rs index 1d077ce49d..a692ddd4d9 100644 --- a/src/components/changes.rs +++ b/src/components/changes.rs @@ -126,7 +126,8 @@ impl ChangesComponent { } else { let path = Path::new(tree_item.info.full_path.as_str()); - return sync::reset_stage(CWD, path).unwrap(); + sync::reset_stage(CWD, path).unwrap(); + return true; } } From cf0735290e9c17aca25938f807ddb9d1db7a98a8 Mon Sep 17 00:00:00 2001 From: Mehran KORDI Date: Fri, 15 May 2020 11:56:00 +0200 Subject: [PATCH 18/26] changed a method signature. --- asyncgit/src/sync/reset.rs | 57 +++++++++++++++----------------------- src/app.rs | 6 ++-- 2 files changed, 24 insertions(+), 39 deletions(-) diff --git a/asyncgit/src/sync/reset.rs b/asyncgit/src/sync/reset.rs index 4c5a010537..f2225b4162 100644 --- a/asyncgit/src/sync/reset.rs +++ b/asyncgit/src/sync/reset.rs @@ -32,43 +32,34 @@ pub fn reset_stage(repo_path: &str, path: &Path) -> Result<()> { } /// -pub fn reset_workdir_file( - repo_path: &str, - path: &str, -) -> Result { +pub fn reset_workdir_file(repo_path: &str, path: &str) -> Result<()> { scope_time!("reset_workdir_file"); let repo = repo(repo_path)?; // Note: early out for removing untracked files, due to bug in checkout_head code: // see https://github.com/libgit2/libgit2/issues/5089 - if let Ok(status) = repo.status_file(Path::new(path)) { - let removed_file_wd = if status == Status::WT_NEW - || (status == Status::WT_MODIFIED | Status::INDEX_NEW) - { - Ok(fs::remove_file(Path::new(repo_path).join(path)) - .is_ok()) - } else { - Ok(false) - }; - - if status == Status::WT_NEW { - return removed_file_wd; - } + let status = repo.status_file(Path::new(path))?; - let mut checkout_opts = CheckoutBuilder::new(); - checkout_opts - .update_index(true) // windows: needs this to be true WTF?! - .allow_conflicts(true) - .force() - .path(path); + if status == Status::WT_NEW + || (status == Status::WT_MODIFIED | Status::INDEX_NEW) + { + fs::remove_file(Path::new(repo_path).join(path))?; + }; - Ok(repo - .checkout_index(None, Some(&mut checkout_opts)) - .is_ok()) - } else { - Ok(false) + if status == Status::WT_NEW { + return Ok(()); } + + let mut checkout_opts = CheckoutBuilder::new(); + checkout_opts + .update_index(true) // windows: needs this to be true WTF?! + .allow_conflicts(true) + .force() + .path(path); + + repo.checkout_index(None, Some(&mut checkout_opts))?; + Ok(()) } /// @@ -174,8 +165,7 @@ mod tests { assert_eq!(get_statuses(repo_path).unwrap(), (1, 1)); - let res = reset_workdir_file(repo_path, "bar.txt").unwrap(); - assert_eq!(res, true); + reset_workdir_file(repo_path, "bar.txt").unwrap(); debug_cmd_print(repo_path, "git status").unwrap(); @@ -200,9 +190,7 @@ mod tests { assert_eq!(get_statuses(repo_path).unwrap(), (1, 0)); - let res = - reset_workdir_file(repo_path, "foo/bar.txt").unwrap(); - assert_eq!(res, true); + reset_workdir_file(repo_path, "foo/bar.txt").unwrap(); debug_cmd_print(repo_path, "git status").unwrap(); @@ -286,8 +274,7 @@ mod tests { assert_eq!(get_statuses(repo_path).unwrap(), (1, 1)); - let res = reset_workdir_file(repo_path, file).unwrap(); - assert_eq!(res, true); + reset_workdir_file(repo_path, file).unwrap(); debug_cmd_print(repo_path, "git status").unwrap(); diff --git a/src/app.rs b/src/app.rs index 1a00667bb9..4391b23796 100644 --- a/src/app.rs +++ b/src/app.rs @@ -225,12 +225,10 @@ impl App { { flags.insert(NeedsUpdate::ALL); } - } else if sync::reset_workdir_file( + } else if let Ok(()) = sync::reset_workdir_file( CWD, reset_item.path.as_str(), - ) - .unwrap() - { + ) { flags.insert(NeedsUpdate::ALL); } } From 66ae8dcfd338d88dc7f76c55c2f77279e08fbaf3 Mon Sep 17 00:00:00 2001 From: Mehran KORDI Date: Fri, 15 May 2020 11:58:03 +0200 Subject: [PATCH 19/26] changed a method signature. --- asyncgit/src/sync/reset.rs | 6 +++--- src/app.rs | 6 ++---- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/asyncgit/src/sync/reset.rs b/asyncgit/src/sync/reset.rs index f2225b4162..a9fd087335 100644 --- a/asyncgit/src/sync/reset.rs +++ b/asyncgit/src/sync/reset.rs @@ -66,7 +66,7 @@ pub fn reset_workdir_file(repo_path: &str, path: &str) -> Result<()> { pub fn reset_workdir_folder( repo_path: &str, path: &str, -) -> Result { +) -> Result<()> { scope_time!("reset_workdir_folder"); let repo = repo(repo_path)?; @@ -80,7 +80,7 @@ pub fn reset_workdir_folder( .path(path); repo.checkout_index(None, Some(&mut checkout_opts))?; - Ok(true) + Ok(()) } #[cfg(test)] @@ -235,7 +235,7 @@ mod tests { assert_eq!(get_statuses(repo_path).unwrap(), (4, 1)); - assert!(reset_workdir_folder(repo_path, "foo").unwrap()); + reset_workdir_folder(repo_path, "foo").unwrap(); assert_eq!(get_statuses(repo_path).unwrap(), (1, 1)); diff --git a/src/app.rs b/src/app.rs index 4391b23796..8a9b4f98a3 100644 --- a/src/app.rs +++ b/src/app.rs @@ -217,12 +217,10 @@ impl App { match ev { InternalEvent::ResetItem(reset_item) => { if reset_item.is_folder { - if sync::reset_workdir_folder( + if let Ok(()) = sync::reset_workdir_folder( CWD, reset_item.path.as_str(), - ) - .unwrap() - { + ) { flags.insert(NeedsUpdate::ALL); } } else if let Ok(()) = sync::reset_workdir_file( From e3021594f62fabce783417ea03dbffd1e3b4249a Mon Sep 17 00:00:00 2001 From: Mehran KORDI Date: Fri, 15 May 2020 12:02:35 +0200 Subject: [PATCH 20/26] added missing error messages. --- asyncgit/src/sync/status.rs | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/asyncgit/src/sync/status.rs b/asyncgit/src/sync/status.rs index f0b4f3a55c..41b52fccd5 100644 --- a/asyncgit/src/sync/status.rs +++ b/asyncgit/src/sync/status.rs @@ -92,11 +92,18 @@ pub fn get_status( .path() .and_then(|x| x.to_str()) .map(String::from) - .ok_or_else(|| Error::Generic("".to_string()))?, - None => e - .path() - .map(String::from) - .ok_or_else(|| Error::Generic("".to_string()))?, + .ok_or_else(|| { + Error::Generic( + "failed to get path to diff's new file." + .to_string(), + ) + })?, + None => e.path().map(String::from).ok_or_else(|| { + Error::Generic( + "failed to get the path to indexed file." + .to_string(), + ) + })?, }; res.push(StatusItem { From df601f33e210dbdd9a6079fbc974afc5b7359b32 Mon Sep 17 00:00:00 2001 From: Mehran KORDI Date: Fri, 15 May 2020 12:11:19 +0200 Subject: [PATCH 21/26] use lossy utf8 conversion for standard io text. --- asyncgit/src/error.rs | 3 --- asyncgit/src/sync/hooks.rs | 4 ++-- asyncgit/src/sync/mod.rs | 4 ++-- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/asyncgit/src/error.rs b/asyncgit/src/error.rs index d56a4d5cc7..7312932ae3 100644 --- a/asyncgit/src/error.rs +++ b/asyncgit/src/error.rs @@ -10,9 +10,6 @@ pub enum Error { #[error("git error:{0}")] Git(#[from] git2::Error), - - #[error("encoding error:{0}")] - Encoding(#[from] std::string::FromUtf8Error), } pub type Result = std::result::Result; diff --git a/asyncgit/src/sync/hooks.rs b/asyncgit/src/sync/hooks.rs index 5b0517c120..95a8c9586a 100644 --- a/asyncgit/src/sync/hooks.rs +++ b/asyncgit/src/sync/hooks.rs @@ -84,8 +84,8 @@ fn run_hook( if output.status.success() { Ok(HookResult::Ok) } else { - let err = String::from_utf8(output.stderr)?; - let out = String::from_utf8(output.stdout)?; + let err = String::from_utf8_lossy(&output.stderr); + let out = String::from_utf8_lossy(&output.stdout); let formatted = format!("{}{}", out, err); Ok(HookResult::NotOk(formatted)) diff --git a/asyncgit/src/sync/mod.rs b/asyncgit/src/sync/mod.rs index f16f0af0e4..5c1a1e1867 100644 --- a/asyncgit/src/sync/mod.rs +++ b/asyncgit/src/sync/mod.rs @@ -97,8 +97,8 @@ mod tests { .output()? }; - let stdout = String::from_utf8(output.stdout)?; - let stderr = String::from_utf8(output.stderr)?; + let stdout = String::from_utf8_lossy(&output.stdout); + let stderr = String::from_utf8_lossy(&output.stderr); Ok(format!( "{}{}", if stdout.is_empty() { From 71187c01cfe9627f88bc07cc9104d7a15b67afef Mon Sep 17 00:00:00 2001 From: Mehran KORDI Date: Fri, 15 May 2020 12:17:24 +0200 Subject: [PATCH 22/26] us is_ok for results in conditions instead of let binding. --- src/app.rs | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/app.rs b/src/app.rs index 8a9b4f98a3..f0bcb9a2ff 100644 --- a/src/app.rs +++ b/src/app.rs @@ -217,16 +217,20 @@ impl App { match ev { InternalEvent::ResetItem(reset_item) => { if reset_item.is_folder { - if let Ok(()) = sync::reset_workdir_folder( + if sync::reset_workdir_folder( CWD, reset_item.path.as_str(), - ) { + ) + .is_ok() + { flags.insert(NeedsUpdate::ALL); } - } else if let Ok(()) = sync::reset_workdir_file( + } else if sync::reset_workdir_file( CWD, reset_item.path.as_str(), - ) { + ) + .is_ok() + { flags.insert(NeedsUpdate::ALL); } } @@ -244,8 +248,8 @@ impl App { { flags.insert(NeedsUpdate::ALL); } - } else if let Ok(()) = - sync::stage_hunk(CWD, path, hash) + } else if sync::stage_hunk(CWD, path, hash) + .is_ok() { flags.insert(NeedsUpdate::ALL); } From f91be921660e20892a22da362ce149666336b5bd Mon Sep 17 00:00:00 2001 From: Mehran KORDI Date: Fri, 15 May 2020 12:25:26 +0200 Subject: [PATCH 23/26] don't use result in test code. --- asyncgit/src/sync/diff.rs | 12 ++++++------ asyncgit/src/sync/hooks.rs | 15 +++++---------- asyncgit/src/sync/mod.rs | 12 +++++++----- asyncgit/src/sync/reset.rs | 24 ++++++++++++------------ asyncgit/src/sync/utils.rs | 18 +++++++++--------- 5 files changed, 39 insertions(+), 42 deletions(-) diff --git a/asyncgit/src/sync/diff.rs b/asyncgit/src/sync/diff.rs index 9b4bb518d2..7b65bfeb73 100644 --- a/asyncgit/src/sync/diff.rs +++ b/asyncgit/src/sync/diff.rs @@ -304,21 +304,21 @@ mod tests { let root = repo.path().parent().unwrap(); let repo_path = root.as_os_str().to_str().unwrap(); - assert_eq!(get_statuses(repo_path).unwrap(), (0, 0)); + assert_eq!(get_statuses(repo_path), (0, 0)); File::create(&root.join(file_path)) .unwrap() .write_all(b"test\nfoo") .unwrap(); - assert_eq!(get_statuses(repo_path).unwrap(), (1, 0)); + assert_eq!(get_statuses(repo_path), (1, 0)); assert_eq!( stage_add_file(repo_path, file_path).unwrap(), true ); - assert_eq!(get_statuses(repo_path).unwrap(), (0, 1)); + assert_eq!(get_statuses(repo_path), (0, 1)); let diff = get_diff( repo_path, @@ -362,7 +362,7 @@ mod tests { let root = repo.path().parent().unwrap(); let repo_path = root.as_os_str().to_str().unwrap(); - assert_eq!(get_statuses(repo_path).unwrap(), (0, 0)); + assert_eq!(get_statuses(repo_path), (0, 0)); let file_path = root.join("bar.txt"); @@ -381,7 +381,7 @@ mod tests { let res = stage_add_file(repo_path, Path::new("bar.txt")).unwrap(); assert_eq!(res, true); - assert_eq!(get_statuses(repo_path).unwrap(), (0, 1)); + assert_eq!(get_statuses(repo_path), (0, 1)); // overwrite with next content { @@ -391,7 +391,7 @@ mod tests { .unwrap(); } - assert_eq!(get_statuses(repo_path).unwrap(), (1, 1)); + assert_eq!(get_statuses(repo_path), (1, 1)); let res = get_diff(repo_path, "bar.txt".to_string(), false) .unwrap(); diff --git a/asyncgit/src/sync/hooks.rs b/asyncgit/src/sync/hooks.rs index 95a8c9586a..e72c8e9b71 100644 --- a/asyncgit/src/sync/hooks.rs +++ b/asyncgit/src/sync/hooks.rs @@ -30,8 +30,7 @@ pub fn hooks_commit_msg( ) })?; - let res = - run_hook(repo_path, HOOK_COMMIT_MSG, &[&file_path])?; + let res = run_hook(repo_path, HOOK_COMMIT_MSG, &[&file_path]); // load possibly altered msg let mut file = file.reopen()?; @@ -49,7 +48,7 @@ pub fn hooks_post_commit(repo_path: &str) -> Result { scope_time!("hooks_post_commit"); if hook_runable(repo_path, HOOK_POST_COMMIT) { - Ok(run_hook(repo_path, HOOK_POST_COMMIT, &[])?) + Ok(run_hook(repo_path, HOOK_POST_COMMIT, &[])) } else { Ok(HookResult::Ok) } @@ -71,24 +70,20 @@ pub enum HookResult { NotOk(String), } -fn run_hook( - path: &str, - cmd: &str, - args: &[&str], -) -> Result { +fn run_hook(path: &str, cmd: &str, args: &[&str]) -> HookResult { let output = Command::new(cmd).args(args).current_dir(path).output(); let output = output.expect("general hook error"); if output.status.success() { - Ok(HookResult::Ok) + HookResult::Ok } else { let err = String::from_utf8_lossy(&output.stderr); let out = String::from_utf8_lossy(&output.stdout); let formatted = format!("{}{}", out, err); - Ok(HookResult::NotOk(formatted)) + HookResult::NotOk(formatted) } } diff --git a/asyncgit/src/sync/mod.rs b/asyncgit/src/sync/mod.rs index 5c1a1e1867..13b5710a73 100644 --- a/asyncgit/src/sync/mod.rs +++ b/asyncgit/src/sync/mod.rs @@ -69,11 +69,13 @@ mod tests { } /// helper returning amount of files with changes in the (wd,stage) - pub fn get_statuses(repo_path: &str) -> Result<(usize, usize)> { - Ok(( - get_status(repo_path, StatusType::WorkingDir)?.len(), - get_status(repo_path, StatusType::Stage)?.len(), - )) + pub fn get_statuses(repo_path: &str) -> (usize, usize) { + ( + get_status(repo_path, StatusType::WorkingDir) + .unwrap() + .len(), + get_status(repo_path, StatusType::Stage).unwrap().len(), + ) } /// diff --git a/asyncgit/src/sync/reset.rs b/asyncgit/src/sync/reset.rs index a9fd087335..853ec818b5 100644 --- a/asyncgit/src/sync/reset.rs +++ b/asyncgit/src/sync/reset.rs @@ -163,13 +163,13 @@ mod tests { debug_cmd_print(repo_path, "git status").unwrap(); - assert_eq!(get_statuses(repo_path).unwrap(), (1, 1)); + assert_eq!(get_statuses(repo_path), (1, 1)); reset_workdir_file(repo_path, "bar.txt").unwrap(); debug_cmd_print(repo_path, "git status").unwrap(); - assert_eq!(get_statuses(repo_path).unwrap(), (0, 1)); + assert_eq!(get_statuses(repo_path), (0, 1)); } #[test] @@ -188,13 +188,13 @@ mod tests { debug_cmd_print(repo_path, "git status").unwrap(); - assert_eq!(get_statuses(repo_path).unwrap(), (1, 0)); + assert_eq!(get_statuses(repo_path), (1, 0)); reset_workdir_file(repo_path, "foo/bar.txt").unwrap(); debug_cmd_print(repo_path, "git status").unwrap(); - assert_eq!(get_statuses(repo_path).unwrap(), (0, 0)); + assert_eq!(get_statuses(repo_path), (0, 0)); } #[test] @@ -228,16 +228,16 @@ mod tests { .write_all(b"file3\nadded line")?; } - assert_eq!(get_statuses(repo_path).unwrap(), (5, 0)); + assert_eq!(get_statuses(repo_path), (5, 0)); stage_add_file(repo_path, Path::new("foo/file5.txt")) .unwrap(); - assert_eq!(get_statuses(repo_path).unwrap(), (4, 1)); + assert_eq!(get_statuses(repo_path), (4, 1)); reset_workdir_folder(repo_path, "foo").unwrap(); - assert_eq!(get_statuses(repo_path).unwrap(), (1, 1)); + assert_eq!(get_statuses(repo_path), (1, 1)); Ok(()) } @@ -272,13 +272,13 @@ mod tests { debug_cmd_print(repo_path, "git status").unwrap(); - assert_eq!(get_statuses(repo_path).unwrap(), (1, 1)); + assert_eq!(get_statuses(repo_path), (1, 1)); reset_workdir_file(repo_path, file).unwrap(); debug_cmd_print(repo_path, "git status").unwrap(); - assert_eq!(get_statuses(repo_path).unwrap(), (0, 1)); + assert_eq!(get_statuses(repo_path), (0, 1)); } #[test] @@ -293,17 +293,17 @@ mod tests { .write_all(b"test\nfoo") .unwrap(); - assert_eq!(get_statuses(repo_path).unwrap(), (1, 0)); + assert_eq!(get_statuses(repo_path), (1, 0)); assert_eq!( stage_add_file(repo_path, file_path).unwrap(), true ); - assert_eq!(get_statuses(repo_path).unwrap(), (0, 1)); + assert_eq!(get_statuses(repo_path), (0, 1)); reset_stage(repo_path, file_path).unwrap(); - assert_eq!(get_statuses(repo_path).unwrap(), (1, 0)); + assert_eq!(get_statuses(repo_path), (1, 0)); } } diff --git a/asyncgit/src/sync/utils.rs b/asyncgit/src/sync/utils.rs index 98f9eb1822..e891e96778 100644 --- a/asyncgit/src/sync/utils.rs +++ b/asyncgit/src/sync/utils.rs @@ -146,18 +146,18 @@ mod tests { .write_all(b"test\nfoo") .unwrap(); - assert_eq!(get_statuses(repo_path).unwrap(), (1, 0)); + assert_eq!(get_statuses(repo_path), (1, 0)); assert_eq!( stage_add_file(repo_path, file_path).unwrap(), true ); - assert_eq!(get_statuses(repo_path).unwrap(), (0, 1)); + assert_eq!(get_statuses(repo_path), (0, 1)); commit(repo_path, "commit msg").unwrap(); - assert_eq!(get_statuses(repo_path).unwrap(), (0, 0)); + assert_eq!(get_statuses(repo_path), (0, 0)); } #[test] @@ -167,25 +167,25 @@ mod tests { let root = repo.path().parent().unwrap(); let repo_path = root.as_os_str().to_str().unwrap(); - assert_eq!(get_statuses(repo_path).unwrap(), (0, 0)); + assert_eq!(get_statuses(repo_path), (0, 0)); File::create(&root.join(file_path)) .unwrap() .write_all(b"test\nfoo") .unwrap(); - assert_eq!(get_statuses(repo_path).unwrap(), (1, 0)); + assert_eq!(get_statuses(repo_path), (1, 0)); assert_eq!( stage_add_file(repo_path, file_path).unwrap(), true ); - assert_eq!(get_statuses(repo_path).unwrap(), (0, 1)); + assert_eq!(get_statuses(repo_path), (0, 1)); commit(repo_path, "commit msg").unwrap(); - assert_eq!(get_statuses(repo_path).unwrap(), (0, 0)); + assert_eq!(get_statuses(repo_path), (0, 0)); } #[test] @@ -218,14 +218,14 @@ mod tests { .write_all(b"test file2 content") .unwrap(); - assert_eq!(get_statuses(repo_path).unwrap(), (2, 0)); + assert_eq!(get_statuses(repo_path), (2, 0)); assert_eq!( stage_add_file(repo_path, file_path).unwrap(), true ); - assert_eq!(get_statuses(repo_path).unwrap(), (1, 1)); + assert_eq!(get_statuses(repo_path), (1, 1)); } #[test] From e9b5d4c26819f183e8c94ef4b058d1300b90b32b Mon Sep 17 00:00:00 2001 From: Mehran KORDI Date: Fri, 15 May 2020 12:26:53 +0200 Subject: [PATCH 24/26] don't use result in test code. --- asyncgit/src/sync/mod.rs | 5 ++--- asyncgit/src/sync/reset.rs | 22 +++++++++++----------- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/asyncgit/src/sync/mod.rs b/asyncgit/src/sync/mod.rs index 13b5710a73..1d4727872b 100644 --- a/asyncgit/src/sync/mod.rs +++ b/asyncgit/src/sync/mod.rs @@ -79,10 +79,9 @@ mod tests { } /// - pub fn debug_cmd_print(path: &str, cmd: &str) -> Result<()> { - let cmd = debug_cmd(path, cmd)?; + pub fn debug_cmd_print(path: &str, cmd: &str) { + let cmd = debug_cmd(path, cmd).unwrap(); eprintln!("\n----\n{}", cmd); - Ok(()) } fn debug_cmd(path: &str, cmd: &str) -> Result { diff --git a/asyncgit/src/sync/reset.rs b/asyncgit/src/sync/reset.rs index 853ec818b5..be8865e173 100644 --- a/asyncgit/src/sync/reset.rs +++ b/asyncgit/src/sync/reset.rs @@ -147,11 +147,11 @@ mod tests { .unwrap(); } - debug_cmd_print(repo_path, "git status").unwrap(); + debug_cmd_print(repo_path, "git status"); stage_add_file(repo_path, Path::new("bar.txt")).unwrap(); - debug_cmd_print(repo_path, "git status").unwrap(); + debug_cmd_print(repo_path, "git status"); // overwrite with next content { @@ -161,13 +161,13 @@ mod tests { .unwrap(); } - debug_cmd_print(repo_path, "git status").unwrap(); + debug_cmd_print(repo_path, "git status"); assert_eq!(get_statuses(repo_path), (1, 1)); reset_workdir_file(repo_path, "bar.txt").unwrap(); - debug_cmd_print(repo_path, "git status").unwrap(); + debug_cmd_print(repo_path, "git status"); assert_eq!(get_statuses(repo_path), (0, 1)); } @@ -186,13 +186,13 @@ mod tests { .unwrap(); } - debug_cmd_print(repo_path, "git status").unwrap(); + debug_cmd_print(repo_path, "git status"); assert_eq!(get_statuses(repo_path), (1, 0)); reset_workdir_file(repo_path, "foo/bar.txt").unwrap(); - debug_cmd_print(repo_path, "git status").unwrap(); + debug_cmd_print(repo_path, "git status"); assert_eq!(get_statuses(repo_path), (0, 0)); } @@ -257,11 +257,11 @@ mod tests { .unwrap(); } - debug_cmd_print(repo_path, "git status").unwrap(); + debug_cmd_print(repo_path, "git status"); - debug_cmd_print(repo_path, "git add .").unwrap(); + debug_cmd_print(repo_path, "git add ."); - debug_cmd_print(repo_path, "git status").unwrap(); + debug_cmd_print(repo_path, "git status"); { File::create(&root.join(file)) @@ -270,13 +270,13 @@ mod tests { .unwrap(); } - debug_cmd_print(repo_path, "git status").unwrap(); + debug_cmd_print(repo_path, "git status"); assert_eq!(get_statuses(repo_path), (1, 1)); reset_workdir_file(repo_path, file).unwrap(); - debug_cmd_print(repo_path, "git status").unwrap(); + debug_cmd_print(repo_path, "git status"); assert_eq!(get_statuses(repo_path), (0, 1)); } From d4e3a4fd7b51e7a21a49b16aa22033955a599ec7 Mon Sep 17 00:00:00 2001 From: Mehran KORDI Date: Fri, 15 May 2020 12:27:51 +0200 Subject: [PATCH 25/26] don't use result in test code. --- asyncgit/src/sync/mod.rs | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/asyncgit/src/sync/mod.rs b/asyncgit/src/sync/mod.rs index 1d4727872b..ab9ce899dc 100644 --- a/asyncgit/src/sync/mod.rs +++ b/asyncgit/src/sync/mod.rs @@ -80,27 +80,29 @@ mod tests { /// pub fn debug_cmd_print(path: &str, cmd: &str) { - let cmd = debug_cmd(path, cmd).unwrap(); + let cmd = debug_cmd(path, cmd); eprintln!("\n----\n{}", cmd); } - fn debug_cmd(path: &str, cmd: &str) -> Result { + fn debug_cmd(path: &str, cmd: &str) -> String { let output = if cfg!(target_os = "windows") { Command::new("cmd") .args(&["/C", cmd]) .current_dir(path) - .output()? + .output() + .unwrap() } else { Command::new("sh") .arg("-c") .arg(cmd) .current_dir(path) - .output()? + .output() + .unwrap() }; let stdout = String::from_utf8_lossy(&output.stdout); let stderr = String::from_utf8_lossy(&output.stderr); - Ok(format!( + format!( "{}{}", if stdout.is_empty() { String::new() @@ -112,6 +114,6 @@ mod tests { } else { format!("err:\n{}", stderr) } - )) + ) } } From cdcbf89dbd49ecbedb4b346cd58f5371ecdcd23d Mon Sep 17 00:00:00 2001 From: Mehran KORDI Date: Fri, 15 May 2020 12:46:06 +0200 Subject: [PATCH 26/26] handle hook failure case. --- asyncgit/src/sync/hooks.rs | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/asyncgit/src/sync/hooks.rs b/asyncgit/src/sync/hooks.rs index e72c8e9b71..8566fb2eef 100644 --- a/asyncgit/src/sync/hooks.rs +++ b/asyncgit/src/sync/hooks.rs @@ -71,19 +71,19 @@ pub enum HookResult { } fn run_hook(path: &str, cmd: &str, args: &[&str]) -> HookResult { - let output = - Command::new(cmd).args(args).current_dir(path).output(); - - let output = output.expect("general hook error"); - - if output.status.success() { - HookResult::Ok - } else { - let err = String::from_utf8_lossy(&output.stderr); - let out = String::from_utf8_lossy(&output.stdout); - let formatted = format!("{}{}", out, err); - - HookResult::NotOk(formatted) + match Command::new(cmd).args(args).current_dir(path).output() { + Ok(output) => { + if output.status.success() { + HookResult::Ok + } else { + let err = String::from_utf8_lossy(&output.stderr); + let out = String::from_utf8_lossy(&output.stdout); + let formatted = format!("{}{}", out, err); + + HookResult::NotOk(formatted) + } + } + Err(e) => HookResult::NotOk(format!("{}", e)), } }