radicle/git/raw: Introduce `trait ErrorExt`
This extension trait is more ergonomic than what `radicle-git-ext` provides.
This commit is contained in:
parent
837f4694df
commit
ea562215ea
|
|
@ -13,6 +13,7 @@ use serde_json as json;
|
||||||
use radicle::crypto::ssh;
|
use radicle::crypto::ssh;
|
||||||
use radicle::explorer::ExplorerUrl;
|
use radicle::explorer::ExplorerUrl;
|
||||||
use radicle::git::raw;
|
use radicle::git::raw;
|
||||||
|
use radicle::git::raw::ErrorExt as _;
|
||||||
use radicle::git::RefString;
|
use radicle::git::RefString;
|
||||||
use radicle::identity::project::ProjectName;
|
use radicle::identity::project::ProjectName;
|
||||||
use radicle::identity::{Doc, RepoId, Visibility};
|
use radicle::identity::{Doc, RepoId, Visibility};
|
||||||
|
|
@ -189,7 +190,7 @@ pub fn run(options: Options, ctx: impl term::Context) -> anyhow::Result<()> {
|
||||||
let path = options.path.as_deref().unwrap_or(cwd.as_path());
|
let path = options.path.as_deref().unwrap_or(cwd.as_path());
|
||||||
let repo = match git::Repository::open(path) {
|
let repo = match git::Repository::open(path) {
|
||||||
Ok(r) => r,
|
Ok(r) => r,
|
||||||
Err(e) if radicle::git::ext::is_not_found_err(&e) => {
|
Err(e) if e.is_not_found() => {
|
||||||
anyhow::bail!("a Git repository was not found at the given path")
|
anyhow::bail!("a Git repository was not found at the given path")
|
||||||
}
|
}
|
||||||
Err(e) => return Err(e.into()),
|
Err(e) => return Err(e.into()),
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ use anyhow::anyhow;
|
||||||
use git_ref_format::Qualified;
|
use git_ref_format::Qualified;
|
||||||
use radicle::cob::patch;
|
use radicle::cob::patch;
|
||||||
use radicle::cob::patch::RevisionId;
|
use radicle::cob::patch::RevisionId;
|
||||||
|
use radicle::git::raw::ErrorExt as _;
|
||||||
use radicle::git::RefString;
|
use radicle::git::RefString;
|
||||||
use radicle::patch::cache::Patches as _;
|
use radicle::patch::cache::Patches as _;
|
||||||
use radicle::patch::PatchId;
|
use radicle::patch::PatchId;
|
||||||
|
|
@ -73,7 +74,7 @@ pub fn run(
|
||||||
}
|
}
|
||||||
head
|
head
|
||||||
}
|
}
|
||||||
Err(e) if radicle::git::is_not_found_err(&e) => {
|
Err(e) if e.is_not_found() => {
|
||||||
let commit = find_patch_commit(revision, stored, working)?;
|
let commit = find_patch_commit(revision, stored, working)?;
|
||||||
// Create patch branch and switch to it.
|
// Create patch branch and switch to it.
|
||||||
working.branch(patch_branch.as_str(), &commit, true)?;
|
working.branch(patch_branch.as_str(), &commit, true)?;
|
||||||
|
|
@ -128,7 +129,7 @@ fn find_patch_commit<'a>(
|
||||||
|
|
||||||
match working.find_commit(head) {
|
match working.find_commit(head) {
|
||||||
Ok(commit) => Ok(commit),
|
Ok(commit) => Ok(commit),
|
||||||
Err(e) if git::ext::is_not_found_err(&e) => {
|
Err(e) if e.is_not_found() => {
|
||||||
let output = git::process::fetch_pack(
|
let output = git::process::fetch_pack(
|
||||||
Some(working.path()),
|
Some(working.path()),
|
||||||
stored,
|
stored,
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ use std::{thread, time};
|
||||||
use anyhow::{anyhow, Context as _};
|
use anyhow::{anyhow, Context as _};
|
||||||
|
|
||||||
use radicle::git;
|
use radicle::git;
|
||||||
|
use radicle::git::raw::ErrorExt as _;
|
||||||
use radicle::prelude::{NodeId, RepoId};
|
use radicle::prelude::{NodeId, RepoId};
|
||||||
use radicle::storage::{ReadRepository, ReadStorage};
|
use radicle::storage::{ReadRepository, ReadStorage};
|
||||||
|
|
||||||
|
|
@ -169,7 +170,7 @@ fn reference<R: ReadRepository>(
|
||||||
) -> Result<Option<git::Oid>, git::raw::Error> {
|
) -> Result<Option<git::Oid>, git::raw::Error> {
|
||||||
match repo.reference_oid(nid, qual) {
|
match repo.reference_oid(nid, qual) {
|
||||||
Ok(oid) => Ok(Some(oid)),
|
Ok(oid) => Ok(Some(oid)),
|
||||||
Err(e) if git::ext::is_not_found_err(&e) => Ok(None),
|
Err(e) if e.is_not_found() => Ok(None),
|
||||||
Err(e) => Err(e),
|
Err(e) => Err(e),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
pub mod error;
|
pub mod error;
|
||||||
|
|
||||||
use either::Either;
|
use either::Either;
|
||||||
|
use radicle::git::raw::ErrorExt as _;
|
||||||
use radicle::git::{self, Namespaced, Oid, Qualified};
|
use radicle::git::{self, Namespaced, Oid, Qualified};
|
||||||
use radicle::storage::git::Repository;
|
use radicle::storage::git::Repository;
|
||||||
|
|
||||||
|
|
@ -53,7 +54,7 @@ fn find_and_peel(repo: &Repository, oid: Oid) -> Result<Oid, error::Ancestry> {
|
||||||
.map_err(|err| error::Ancestry::Peel { oid, err })?
|
.map_err(|err| error::Ancestry::Peel { oid, err })?
|
||||||
.id()
|
.id()
|
||||||
.into()),
|
.into()),
|
||||||
Err(e) if git::is_not_found_err(&e) => Err(error::Ancestry::Missing { oid }),
|
Err(e) if e.is_not_found() => Err(error::Ancestry::Missing { oid }),
|
||||||
Err(err) => Err(error::Ancestry::Object { oid, err }),
|
Err(err) => Err(error::Ancestry::Object { oid, err }),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,6 @@ use crate::storage;
|
||||||
use crate::storage::refs::Refs;
|
use crate::storage::refs::Refs;
|
||||||
use crate::storage::RemoteId;
|
use crate::storage::RemoteId;
|
||||||
|
|
||||||
pub use ext::is_not_found_err;
|
|
||||||
pub use ext::Error;
|
pub use ext::Error;
|
||||||
pub use ext::NotFound;
|
pub use ext::NotFound;
|
||||||
pub use ext::Oid;
|
pub use ext::Oid;
|
||||||
|
|
@ -31,6 +30,8 @@ pub use radicle_git_ext as ext;
|
||||||
pub use storage::git::transport::local::Url;
|
pub use storage::git::transport::local::Url;
|
||||||
pub use storage::BranchName;
|
pub use storage::BranchName;
|
||||||
|
|
||||||
|
use raw::ErrorExt as _;
|
||||||
|
|
||||||
/// Default port of the `git` transport protocol.
|
/// Default port of the `git` transport protocol.
|
||||||
pub const PROTOCOL_PORT: u16 = 9418;
|
pub const PROTOCOL_PORT: u16 = 9418;
|
||||||
/// Minimum required git version.
|
/// Minimum required git version.
|
||||||
|
|
@ -733,14 +734,14 @@ pub fn set_upstream(
|
||||||
let branch_merge = format!("branch.{branch}.merge");
|
let branch_merge = format!("branch.{branch}.merge");
|
||||||
|
|
||||||
config.remove_multivar(&branch_remote, ".*").or_else(|e| {
|
config.remove_multivar(&branch_remote, ".*").or_else(|e| {
|
||||||
if ext::is_not_found_err(&e) {
|
if e.is_not_found() {
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
Err(e)
|
Err(e)
|
||||||
}
|
}
|
||||||
})?;
|
})?;
|
||||||
config.remove_multivar(&branch_merge, ".*").or_else(|e| {
|
config.remove_multivar(&branch_merge, ".*").or_else(|e| {
|
||||||
if ext::is_not_found_err(&e) {
|
if e.is_not_found() {
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
Err(e)
|
Err(e)
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
use std::collections::{BTreeMap, BTreeSet};
|
use std::collections::{BTreeMap, BTreeSet};
|
||||||
|
|
||||||
use crate::git;
|
use crate::git;
|
||||||
|
use crate::git::raw::ErrorExt as _;
|
||||||
use crate::git::{Oid, Qualified};
|
use crate::git::{Oid, Qualified};
|
||||||
use crate::prelude::Did;
|
use crate::prelude::Did;
|
||||||
|
|
||||||
|
|
@ -215,7 +216,7 @@ impl FindObjects for git::raw::Repository {
|
||||||
let name = &refname.with_namespace(did.as_key().into());
|
let name = &refname.with_namespace(did.as_key().into());
|
||||||
let reference = match self.find_reference(name.as_str()) {
|
let reference = match self.find_reference(name.as_str()) {
|
||||||
Ok(reference) => reference,
|
Ok(reference) => reference,
|
||||||
Err(e) if git::ext::is_not_found_err(&e) => {
|
Err(e) if e.is_not_found() => {
|
||||||
missing_refs.insert(name.to_owned());
|
missing_refs.insert(name.to_owned());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
@ -235,7 +236,7 @@ impl FindObjects for git::raw::Repository {
|
||||||
object.kind().map(|kind| kind.to_string()),
|
object.kind().map(|kind| kind.to_string()),
|
||||||
)
|
)
|
||||||
}),
|
}),
|
||||||
Err(err) if git::ext::is_not_found_err(&err) => {
|
Err(err) if err.is_not_found() => {
|
||||||
missing_objects.insert(*did, oid);
|
missing_objects.insert(*did, oid);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,3 +32,27 @@ pub(crate) mod transport {
|
||||||
register, Service, SmartSubtransport, SmartSubtransportStream, Transport,
|
register, Service, SmartSubtransport, SmartSubtransportStream, Transport,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// An extension trait for [`git2::Error`] to more conveniently handle
|
||||||
|
/// errors with the code [`git2::ErrorCode::NotFound`].
|
||||||
|
pub trait ErrorExt {
|
||||||
|
/// Returns `true` if the error associated with this error is [`git2::ErrorCode::NotFound`].
|
||||||
|
fn is_not_found(&self) -> bool;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ErrorExt for git2::Error {
|
||||||
|
fn is_not_found(&self) -> bool {
|
||||||
|
self.code() == git2::ErrorCode::NotFound
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ErrorExt for git_ext::Error {
|
||||||
|
fn is_not_found(&self) -> bool {
|
||||||
|
use git_ext::Error::*;
|
||||||
|
match self {
|
||||||
|
Git(e) => e.is_not_found(),
|
||||||
|
NotFound(_) => true,
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ use crate::crypto;
|
||||||
use crate::crypto::Signature;
|
use crate::crypto::Signature;
|
||||||
use crate::git;
|
use crate::git;
|
||||||
use crate::git::canonical::rules;
|
use crate::git::canonical::rules;
|
||||||
|
use crate::git::raw::ErrorExt as _;
|
||||||
use crate::identity::{project::Project, Did};
|
use crate::identity::{project::Project, Did};
|
||||||
use crate::node::device::Device;
|
use crate::node::device::Device;
|
||||||
use crate::storage;
|
use crate::storage;
|
||||||
|
|
@ -71,9 +72,8 @@ impl DocError {
|
||||||
/// Whether this error is caused by the document not being found.
|
/// Whether this error is caused by the document not being found.
|
||||||
pub fn is_not_found(&self) -> bool {
|
pub fn is_not_found(&self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
Self::GitExt(git::Error::NotFound(_)) => true,
|
Self::GitExt(e) => e.is_not_found(),
|
||||||
Self::GitExt(git::Error::Git(e)) if git::is_not_found_err(e) => true,
|
Self::Git(e) => e.is_not_found(),
|
||||||
Self::Git(err) if git::is_not_found_err(err) => true,
|
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1160,7 +1160,10 @@ mod test {
|
||||||
let oid = git::raw::Oid::from_str("2d52a53ce5e4f141148a5f770cfd3ead2d6a45b8").unwrap();
|
let oid = git::raw::Oid::from_str("2d52a53ce5e4f141148a5f770cfd3ead2d6a45b8").unwrap();
|
||||||
|
|
||||||
let err = repo.identity_head_of(&remote).unwrap_err();
|
let err = repo.identity_head_of(&remote).unwrap_err();
|
||||||
matches!(err, git::ext::Error::NotFound(_));
|
{
|
||||||
|
use crate::git::raw::ErrorExt as _;
|
||||||
|
assert!(err.is_not_found());
|
||||||
|
}
|
||||||
|
|
||||||
let err = Doc::load_at(oid.into(), &repo).unwrap_err();
|
let err = Doc::load_at(oid.into(), &repo).unwrap_err();
|
||||||
assert!(err.is_not_found());
|
assert!(err.is_not_found());
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ pub use radicle_git_ext::Oid;
|
||||||
|
|
||||||
use crate::cob;
|
use crate::cob;
|
||||||
use crate::collections::RandomMap;
|
use crate::collections::RandomMap;
|
||||||
|
use crate::git::raw::ErrorExt as _;
|
||||||
use crate::git::{canonical, ext as git_ext};
|
use crate::git::{canonical, ext as git_ext};
|
||||||
use crate::git::{refspec::Refspec, PatternString, Qualified, RefError, RefStr, RefString};
|
use crate::git::{refspec::Refspec, PatternString, Qualified, RefError, RefStr, RefString};
|
||||||
use crate::identity::{doc, Did, PayloadError};
|
use crate::identity::{doc, Did, PayloadError};
|
||||||
|
|
@ -133,9 +134,9 @@ pub enum RepositoryError {
|
||||||
impl RepositoryError {
|
impl RepositoryError {
|
||||||
pub fn is_not_found(&self) -> bool {
|
pub fn is_not_found(&self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
Self::Storage(e) if e.is_not_found() => true,
|
Self::Storage(e) => e.is_not_found(),
|
||||||
Self::Git(e) if git_ext::is_not_found_err(e) => true,
|
Self::GitExt(e) => e.is_not_found(),
|
||||||
Self::GitExt(git_ext::Error::NotFound(_)) => true,
|
Self::Git(e) => e.is_not_found(),
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -167,7 +168,7 @@ impl Error {
|
||||||
pub fn is_not_found(&self) -> bool {
|
pub fn is_not_found(&self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
Self::Io(e) if e.kind() == io::ErrorKind::NotFound => true,
|
Self::Io(e) if e.kind() == io::ErrorKind::NotFound => true,
|
||||||
Self::Git(e) if git::ext::is_not_found_err(e) => true,
|
Self::Git(e) if e.is_not_found() => true,
|
||||||
Self::Doc(e) if e.is_not_found() => true,
|
Self::Doc(e) if e.is_not_found() => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ use std::{fs, io};
|
||||||
use crypto::Verified;
|
use crypto::Verified;
|
||||||
|
|
||||||
use crate::git::canonical::Quorum;
|
use crate::git::canonical::Quorum;
|
||||||
|
use crate::git::raw::ErrorExt as _;
|
||||||
use crate::identity::crefs::GetCanonicalRefs as _;
|
use crate::identity::crefs::GetCanonicalRefs as _;
|
||||||
use crate::identity::doc::DocError;
|
use crate::identity::doc::DocError;
|
||||||
use crate::identity::{CanonicalRefs, Doc, DocAt, RepoId};
|
use crate::identity::{CanonicalRefs, Doc, DocAt, RepoId};
|
||||||
|
|
@ -817,7 +818,7 @@ impl ReadRepository for Repository {
|
||||||
|
|
||||||
match result {
|
match result {
|
||||||
Ok(oid) => Ok(oid),
|
Ok(oid) => Ok(oid),
|
||||||
Err(err) if git::ext::is_not_found_err(&err) => self.canonical_identity_head(),
|
Err(err) if err.is_not_found() => self.canonical_identity_head(),
|
||||||
Err(err) => Err(err.into()),
|
Err(err) => Err(err.into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ use thiserror::Error;
|
||||||
|
|
||||||
use crate::git;
|
use crate::git;
|
||||||
use crate::git::ext as git_ext;
|
use crate::git::ext as git_ext;
|
||||||
|
use crate::git::raw::ErrorExt as _;
|
||||||
use crate::git::Oid;
|
use crate::git::Oid;
|
||||||
use crate::node::device::Device;
|
use crate::node::device::Device;
|
||||||
use crate::profile::env;
|
use crate::profile::env;
|
||||||
|
|
@ -64,9 +65,8 @@ impl Error {
|
||||||
/// Whether this error is caused by a reference not being found.
|
/// Whether this error is caused by a reference not being found.
|
||||||
pub fn is_not_found(&self) -> bool {
|
pub fn is_not_found(&self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
Self::GitExt(git::Error::NotFound(_)) => true,
|
Self::GitExt(e) => e.is_not_found(),
|
||||||
Self::GitExt(git::Error::Git(e)) if git::is_not_found_err(e) => true,
|
Self::Git(e) => e.is_not_found(),
|
||||||
Self::Git(e) if git::is_not_found_err(e) => true,
|
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -430,7 +430,7 @@ impl SignedRefsAt {
|
||||||
{
|
{
|
||||||
let at = match RefsAt::new(repo, remote) {
|
let at = match RefsAt::new(repo, remote) {
|
||||||
Ok(RefsAt { at, .. }) => at,
|
Ok(RefsAt { at, .. }) => at,
|
||||||
Err(e) if git::is_not_found_err(&e) => return Ok(None),
|
Err(e) if e.is_not_found() => return Ok(None),
|
||||||
Err(e) => return Err(e.into()),
|
Err(e) => return Err(e.into()),
|
||||||
};
|
};
|
||||||
Self::load_at(at, remote, repo).map(Some)
|
Self::load_at(at, remote, repo).map(Some)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue