From 09debccace53b09bf4548b24bd12aae02d5ed43e Mon Sep 17 00:00:00 2001 From: Jiahao XU Date: Tue, 12 Dec 2023 00:08:13 +1000 Subject: [PATCH] freat: Avoid breaking changes due to gix upgrade (#1518) Wrap all error type in a new type so that we don't have to release new major versions after upgrading depoendency gix`. Signed-off-by: Jiahao XU --- crates/simple-git/src/error.rs | 67 ++++++++++++++++++++++++++++ crates/simple-git/src/lib.rs | 80 ++++++---------------------------- 2 files changed, 80 insertions(+), 67 deletions(-) create mode 100644 crates/simple-git/src/error.rs diff --git a/crates/simple-git/src/error.rs b/crates/simple-git/src/error.rs new file mode 100644 index 00000000..1aa6f17f --- /dev/null +++ b/crates/simple-git/src/error.rs @@ -0,0 +1,67 @@ +use gix::clone; +use thiserror::Error as ThisError; + +#[derive(Debug, ThisError)] +#[error(transparent)] +pub struct GitError(#[from] GitErrorInner); + +#[derive(Debug, ThisError)] +pub(super) enum GitErrorInner { + #[error("Failed to prepare for fetch: {0}")] + PrepareFetchError(#[source] Box), + + #[error("Failed to fetch: {0}")] + FetchError(#[source] Box), + + #[error("Failed to checkout: {0}")] + CheckOutError(#[source] Box), + + #[error("HEAD ref was corrupt in crates-io index repository clone")] + HeadCommit(#[source] Box), + + #[error("tree of head commit wasn't present in crates-io index repository clone")] + GetTreeOfCommit(#[source] Box), + + #[error("An object was missing in the crates-io index repository clone")] + ObjectLookup(#[source] Box), +} + +impl From for GitErrorInner { + fn from(e: clone::Error) -> Self { + Self::PrepareFetchError(Box::new(e)) + } +} + +impl From for GitErrorInner { + fn from(e: clone::fetch::Error) -> Self { + Self::FetchError(Box::new(e)) + } +} + +impl From for GitErrorInner { + fn from(e: clone::checkout::main_worktree::Error) -> Self { + Self::CheckOutError(Box::new(e)) + } +} + +impl From for GitErrorInner { + fn from(e: gix::reference::head_commit::Error) -> Self { + Self::HeadCommit(Box::new(e)) + } +} + +impl From for GitErrorInner { + fn from(e: gix::object::commit::Error) -> Self { + Self::GetTreeOfCommit(Box::new(e)) + } +} + +impl From for GitErrorInner { + fn from(e: gix::object::find::existing::Error) -> Self { + Self::ObjectLookup(Box::new(e)) + } +} + +#[derive(Debug, ThisError)] +#[error(transparent)] +pub struct GitUrlParseError(pub(super) gix::url::parse::Error); diff --git a/crates/simple-git/src/lib.rs b/crates/simple-git/src/lib.rs index 8ff64e39..e432baff 100644 --- a/crates/simple-git/src/lib.rs +++ b/crates/simple-git/src/lib.rs @@ -1,7 +1,6 @@ use std::{fmt, mem, num::NonZeroU32, path::Path, str::FromStr, sync::atomic::AtomicBool}; use gix::{clone, create, open, remote, Url}; -use thiserror::Error as ThisError; use tracing::debug; mod progress_tracing; @@ -10,65 +9,9 @@ use progress_tracing::TracingProgress; mod cancellation_token; pub use cancellation_token::{GitCancelOnDrop, GitCancellationToken}; -pub use gix::url::parse::Error as GitUrlParseError; - -#[derive(Debug, ThisError)] -#[non_exhaustive] -pub enum GitError { - #[error("Failed to prepare for fetch: {0}")] - PrepareFetchError(#[source] Box), - - #[error("Failed to fetch: {0}")] - FetchError(#[source] Box), - - #[error("Failed to checkout: {0}")] - CheckOutError(#[source] Box), - - #[error("HEAD ref was corrupt in crates-io index repository clone")] - HeadCommit(#[source] Box), - - #[error("tree of head commit wasn't present in crates-io index repository clone")] - GetTreeOfCommit(#[source] Box), - - #[error("An object was missing in the crates-io index repository clone")] - ObjectLookup(#[source] Box), -} - -impl From for GitError { - fn from(e: clone::Error) -> Self { - Self::PrepareFetchError(Box::new(e)) - } -} - -impl From for GitError { - fn from(e: clone::fetch::Error) -> Self { - Self::FetchError(Box::new(e)) - } -} - -impl From for GitError { - fn from(e: clone::checkout::main_worktree::Error) -> Self { - Self::CheckOutError(Box::new(e)) - } -} - -impl From for GitError { - fn from(e: gix::reference::head_commit::Error) -> Self { - Self::HeadCommit(Box::new(e)) - } -} - -impl From for GitError { - fn from(e: gix::object::commit::Error) -> Self { - Self::GetTreeOfCommit(Box::new(e)) - } -} - -impl From for GitError { - fn from(e: gix::object::find::existing::Error) -> Self { - Self::ObjectLookup(Box::new(e)) - } -} +mod error; +use error::GitErrorInner; +pub use error::{GitError, GitUrlParseError}; #[derive(Clone, Debug)] pub struct GitUrl(Url); @@ -86,7 +29,7 @@ impl FromStr for GitUrl { type Err = GitUrlParseError; fn from_str(s: &str) -> Result { - Url::try_from(s).map(Self) + Url::try_from(s).map(Self).map_err(GitUrlParseError) } } @@ -98,7 +41,7 @@ impl Repository { url: GitUrl, path: &Path, kind: create::Kind, - ) -> Result { + ) -> Result { Ok(clone::PrepareFetch::new( url.0, path, @@ -133,7 +76,8 @@ impl Repository { .as_ref() .map(GitCancellationToken::get_atomic) .unwrap_or(&AtomicBool::new(false)), - )? + ) + .map_err(GitErrorInner::from)? .0 .into(), )) @@ -154,7 +98,8 @@ impl Repository { Ok(Self( Self::prepare_fetch(url, path, create::Kind::WithWorktree)? - .fetch_then_checkout(&mut progress, &AtomicBool::new(false))? + .fetch_then_checkout(&mut progress, &AtomicBool::new(false)) + .map_err(GitErrorInner::from)? .0 .main_worktree( &mut progress, @@ -162,7 +107,8 @@ impl Repository { .as_ref() .map(GitCancellationToken::get_atomic) .unwrap_or(&AtomicBool::new(false)), - )? + ) + .map_err(GitErrorInner::from)? .0 .into(), )) @@ -173,7 +119,7 @@ impl Repository { &self, path: impl AsRef, ) -> Result>, GitError> { - fn inner(this: &Repository, path: &Path) -> Result>, GitError> { + fn inner(this: &Repository, path: &Path) -> Result>, GitErrorInner> { Ok( if let Some(entry) = this .0 @@ -189,6 +135,6 @@ impl Repository { ) } - inner(self, path.as_ref()) + Ok(inner(self, path.as_ref())?) } }