use Marker in place of Code::ProjectInvalid

That way, the frontend doesn't see internals.
This commit is contained in:
Sebastian Thiel 2024-05-31 15:46:04 +02:00
parent e7c1d6033a
commit f82d25741e
No known key found for this signature in database
GPG Key ID: 9CB5EE7895E8268B
9 changed files with 38 additions and 50 deletions

View File

@ -138,10 +138,6 @@ pub enum Code {
Unknown,
Validation,
ProjectGitAuth,
/// An indicator for a conflict in the project which is used for flow-control.
///
/// See usages for details on what these conflicts can be.
ProjectConflict,
}
impl std::fmt::Display for Code {
@ -150,7 +146,6 @@ impl std::fmt::Display for Code {
Code::Unknown => "errors.unknown",
Code::Validation => "errors.validation",
Code::ProjectGitAuth => "errors.projects.git.auth",
Code::ProjectConflict => "errors.projects.conflict",
};
f.write_str(code)
}

View File

@ -7,6 +7,7 @@ use std::{
use anyhow::{anyhow, Context, Result};
use super::conflicts;
use crate::virtual_branches::errors::Marker;
use crate::{
askpass, error,
git::{self, credentials::HelpError, Url},
@ -89,7 +90,7 @@ impl Repository {
pub fn assure_resolved(&self) -> Result<()> {
if self.is_resolving() {
Err(anyhow!("project has active conflicts")).context(Code::ProjectConflict)
Err(anyhow!("project has active conflicts")).context(Marker::ProjectConflict)
} else {
Ok(())
}
@ -97,7 +98,7 @@ impl Repository {
pub fn assure_unconflicted(&self) -> Result<()> {
if conflicts::is_conflicting(self, None)? {
Err(anyhow!("project has active conflicts")).context(Code::ProjectConflict)
Err(anyhow!("project has active conflicts")).context(Marker::ProjectConflict)
} else {
Ok(())
}

View File

@ -11,7 +11,7 @@ use super::{
},
target, BranchId, RemoteCommit, VirtualBranchHunk, VirtualBranchesHandle,
};
use crate::error::Code;
use crate::virtual_branches::errors::Marker;
use crate::{
git::{self, diff},
project_repository::{self, LogUntil},
@ -57,7 +57,7 @@ fn go_back_to_integration(
))
.context("failed to get status")?;
if !statuses.is_empty() {
return Err(anyhow!("current HEAD is dirty")).context(Code::ProjectConflict);
return Err(anyhow!("current HEAD is dirty")).context(Marker::ProjectConflict);
}
let vb_state = project_repository.project().virtual_branches();

View File

@ -630,7 +630,7 @@ impl ControllerInner {
self.with_verify_branch(project_id, |project_repository, user| {
let snapshot_tree = project_repository.project().prepare_snapshot();
let result =
super::apply_branch(project_repository, branch_id, user).map_err(Error::from_err);
super::apply_branch(project_repository, branch_id, user).map_err(Into::into);
let _ = snapshot_tree.and_then(|snapshot_tree| {
project_repository

View File

@ -1,6 +1,5 @@
use super::BranchId;
use crate::error::{AnyhowContextExt, Context, ErrorWithContext};
use crate::{git, project_repository::RemoteError, projects::ProjectId};
use crate::{project_repository::RemoteError, projects::ProjectId};
/// A way to mark errors using `[anyhow::Context::context]` for later retrieval.
///
@ -10,27 +9,21 @@ use crate::{git, project_repository::RemoteError, projects::ProjectId};
pub enum Marker {
/// Invalid state was detected, making the repository invalid for operation.
VerificationFailure,
/// An indicator for a conflict in the project.
///
/// See usages for details on what these conflicts can be.
ProjectConflict,
}
impl std::fmt::Display for Marker {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Marker::VerificationFailure => f.write_str("<verification-failed>"),
Marker::ProjectConflict => f.write_str("<project-conflict>"),
}
}
}
#[derive(Debug, thiserror::Error)]
pub enum ApplyBranchError {
// TODO(ST): use local Marker to detect this case, apply the same to ProjectConflict
#[error("branch {0} is in a conflicting state")]
BranchConflicts(BranchId),
#[error(transparent)]
GitError(#[from] git::Error),
#[error(transparent)]
Other(#[from] anyhow::Error),
}
#[derive(Debug, thiserror::Error)]
pub enum PushError {
#[error(transparent)]
@ -48,11 +41,6 @@ impl ErrorWithContext for PushError {
}
}
#[derive(Debug)]
pub struct ForcePushNotAllowed {
pub project_id: ProjectId,
}
#[derive(Debug, thiserror::Error)]
pub enum FetchFromTargetError {
#[error("failed to fetch")]

View File

@ -25,11 +25,12 @@ use super::{
},
branch_to_remote_branch, errors, target, RemoteBranch, VirtualBranchesHandle,
};
use crate::error::{self, AnyhowContextExt, Code};
use crate::error::Code;
use crate::git::diff::{diff_files_into_hunks, trees, FileDiff};
use crate::git::{CommitExt, RepositoryExt};
use crate::time::now_since_unix_epoch_ms;
use crate::virtual_branches::branch::HunkHash;
use crate::virtual_branches::errors::Marker;
use crate::{
dedup::{dedup, dedup_fmt},
git::{
@ -220,7 +221,7 @@ pub fn apply_branch(
project_repository: &project_repository::Repository,
branch_id: BranchId,
user: Option<&users::User>,
) -> Result<String, errors::ApplyBranchError> {
) -> Result<String> {
project_repository.assure_resolved()?;
let repo = &project_repository.git_repository;
@ -435,7 +436,8 @@ pub fn apply_branch(
.context("failed to merge trees")?;
if merge_index.has_conflicts() {
return Err(errors::ApplyBranchError::BranchConflicts(branch_id));
return Err(anyhow!("branch {branch_id} is in a conflicting state"))
.context(Marker::ProjectConflict);
}
// apply the branch
@ -1190,19 +1192,20 @@ pub fn integrate_upstream_commits(
// scenario we would need to "cherry rebase" new upstream commits onto the last rebased
// local commit.
if has_rebased_commits && !can_use_force {
let message = "Aborted because force push is disallowed and commits have been rebased.";
return Err(anyhow!("Cannot merge rebased commits without force push")
.context(error::Context::new(message).with_code(Code::ProjectConflict)));
.context("Aborted because force push is disallowed and commits have been rebased")
.context(Marker::ProjectConflict));
}
let integration_result = match can_use_force {
true => integrate_with_rebase(project_repository, &mut branch, &mut unknown_commits),
false => {
if has_rebased_commits {
let message =
"Aborted because force push is disallowed and commits have been rebased.";
return Err(anyhow!("Cannot merge rebased commits without force push")
.context(error::Context::new(message).with_code(Code::ProjectConflict)));
.context(
"Aborted because force push is disallowed and commits have been rebased",
)
.context(Marker::ProjectConflict));
}
integrate_with_merge(
project_repository,
@ -1215,8 +1218,8 @@ pub fn integrate_upstream_commits(
};
if integration_result.as_ref().err().map_or(false, |err| {
err.custom_context()
.is_some_and(|c| c.code == Code::ProjectConflict)
err.downcast_ref()
.is_some_and(|marker: &Marker| *marker == Marker::ProjectConflict)
}) {
return Ok(());
};
@ -1295,10 +1298,7 @@ pub fn integrate_with_merge(
.conflict_style_merge()
.force()
.checkout()?;
return Err(anyhow!("Merging")).context(error::Context::new_static(
Code::ProjectConflict,
"Merge problem",
));
return Err(anyhow!("merge problem")).context(Marker::ProjectConflict);
}
let merge_tree_oid = merge_index.write_tree_to(repo)?;
@ -3892,7 +3892,11 @@ pub fn create_virtual_branch_from_branch(
match apply_branch(project_repository, branch.id, user) {
Ok(_) => Ok(branch.id),
Err(errors::ApplyBranchError::BranchConflicts(_)) => {
Err(err)
if err
.downcast_ref()
.map_or(false, |marker: &Marker| *marker == Marker::ProjectConflict) =>
{
// if branch conflicts with the workspace, it's ok. keep it unapplied
Ok(branch.id)
}
@ -4023,7 +4027,7 @@ mod tests {
// let conflicts = merge_index.conflicts()?;
// let conflict_message = conflicts_to_string(conflicts)?;
// return Err(anyhow!("Merge failed")
// .context(error::Context::new(Code::ProjectConflict, conflict_message))
// .context(error::Context::new(Marker::ProjectConflict, conflict_message))
// .);
// fn conflicts_to_string(conflicts: IndexConflicts) -> Result<String> {

View File

@ -52,7 +52,7 @@ async fn deltect_conflict() {
.await
.unwrap_err()
.downcast_ref(),
Some(errors::ApplyBranchError::BranchConflicts(_))
Some(Marker::ProjectConflict)
));
}
}

View File

@ -1,12 +1,12 @@
use std::path::PathBuf;
use std::{fs, path, str::FromStr};
use gitbutler_core::error::Code;
use gitbutler_core::virtual_branches::errors::Marker;
use gitbutler_core::{
git,
projects::{self, Project, ProjectId},
users,
virtual_branches::{branch, errors, Controller},
virtual_branches::{branch, Controller},
};
use tempfile::TempDir;
@ -170,7 +170,7 @@ async fn resolve_conflict_flow() {
.await
.unwrap_err()
.downcast_ref(),
Some(Code::ProjectConflict)
Some(Marker::ProjectConflict)
));
}

View File

@ -123,7 +123,7 @@ mod go_back_to_integration {
.await
.unwrap_err()
.downcast_ref(),
Some(Code::ProjectConflict)
Some(Marker::ProjectConflict)
));
}
@ -159,7 +159,7 @@ mod go_back_to_integration {
.await
.unwrap_err()
.downcast_ref(),
Some(Code::ProjectConflict)
Some(Marker::ProjectConflict)
));
}