Merge pull request #4849 from Byron/nicer-clone

refactor clone for clarity
This commit is contained in:
Sebastian Thiel 2024-09-09 06:56:31 +02:00 committed by GitHub
commit ee083deada
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 45 additions and 16 deletions

View File

@ -13,7 +13,7 @@
//! //!
//! The values in these fields are controlled by attaching context, please [see the `error` docs](gitbutler_error::error)) //! The values in these fields are controlled by attaching context, please [see the `error` docs](gitbutler_error::error))
//! on how to do this. //! on how to do this.
pub(crate) use frontend::Error; pub(crate) use frontend::{Error, UnmarkedError};
mod frontend { mod frontend {
use std::borrow::Cow; use std::borrow::Cow;
@ -21,6 +21,39 @@ mod frontend {
use gitbutler_error::error::AnyhowContextExt; use gitbutler_error::error::AnyhowContextExt;
use serde::{ser::SerializeMap, Serialize}; use serde::{ser::SerializeMap, Serialize};
/// An error type for serialization which isn't expected to carry a code.
#[derive(Debug)]
pub struct UnmarkedError(anyhow::Error);
impl<T> From<T> for UnmarkedError
where
T: std::error::Error + Send + Sync + 'static,
{
fn from(err: T) -> Self {
Self(err.into())
}
}
impl Serialize for UnmarkedError {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
let ctx = self.0.custom_context_or_root_cause();
let mut map = serializer.serialize_map(Some(2))?;
map.serialize_entry("code", &ctx.code.to_string())?;
let message = ctx.message.unwrap_or_else(|| {
self.0
.source()
.map(|err| Cow::Owned(err.to_string()))
.unwrap_or_else(|| Cow::Borrowed("Something went wrong"))
});
map.serialize_entry("message", &message)?;
map.end()
}
}
/// An error type for serialization, dynamically extracting context information during serialization, /// An error type for serialization, dynamically extracting context information during serialization,
/// meant for consumption by the frontend. /// meant for consumption by the frontend.
#[derive(Debug)] #[derive(Debug)]

View File

@ -1,16 +1,15 @@
pub mod commands { pub mod commands {
use anyhow::{Context, Result}; use anyhow::Result;
use gitbutler_branch_actions::RemoteBranchFile; use gitbutler_branch_actions::RemoteBranchFile;
use gitbutler_project as projects; use gitbutler_project as projects;
use gitbutler_project::ProjectId; use gitbutler_project::ProjectId;
use gitbutler_repo::RepoCommands; use gitbutler_repo::RepoCommands;
use gix::progress::Discard;
use std::path::Path; use std::path::Path;
use std::sync::atomic::AtomicBool; use std::sync::atomic::AtomicBool;
use tauri::State; use tauri::State;
use tracing::instrument; use tracing::instrument;
use crate::error::Error; use crate::error::{Error, UnmarkedError};
#[tauri::command(async)] #[tauri::command(async)]
#[instrument(skip(projects), err(Debug))] #[instrument(skip(projects), err(Debug))]
@ -46,19 +45,16 @@ pub mod commands {
} }
#[tauri::command(async)] #[tauri::command(async)]
pub fn git_clone_repository(repository_url: &str, target_dir: &Path) -> Result<(), Error> { pub fn git_clone_repository(
let url = repository_url: &str,
gix::url::parse(repository_url.into()).context("Failed to parse repository URL")?; target_dir: &Path,
) -> Result<(), UnmarkedError> {
let should_interrupt = AtomicBool::new(false); let should_interrupt = AtomicBool::new(false);
let mut prepared_clone =
gix::prepare_clone(url, target_dir).context("Failed to prepare clone")?; gix::prepare_clone(repository_url, target_dir)?
let (mut prepared_checkout, _) = prepared_clone .fetch_then_checkout(gix::progress::Discard, &should_interrupt)
.fetch_then_checkout(Discard, &should_interrupt) .map(|(checkout, _outcome)| checkout)?
.context("Failed to fetch")?; .main_worktree(gix::progress::Discard, &should_interrupt)?;
let should_interrupt = AtomicBool::new(false);
prepared_checkout
.main_worktree(Discard, &should_interrupt)
.context("Failed to checkout main worktree")?;
Ok(()) Ok(())
} }