Radish alpha
h
Radicle Heartwood Protocol & Stack
Radicle
Git (anonymous pull)
Log in to clone via SSH
radicle/storage/sigrefs: Remove unused traits
✗ CI failure Fintan Halpenny committed 24 days ago
commit 33fd4967165aa7c99c8b28a301be05183e3a0941
parent c09f8a54bea8ca4098553c52ae8d3203bd858f74
1 failed (1 total) View logs
7 files changed +47 -540
modified crates/radicle/src/storage/git.rs
@@ -32,7 +32,7 @@ use crate::git::fmt::{
};
pub use crate::storage::{Error, RepositoryError};

-
use super::refs::{RefsAt, sigrefs};
+
use super::refs::RefsAt;
use super::{RemoteId, RemoteRepository, ValidateRepository};

pub static NAMESPACES_GLOB: LazyLock<PatternString> =
@@ -1074,59 +1074,6 @@ impl Repository {
    }
}

-
impl sigrefs::git::object::Reader for Repository {
-
    fn read_commit(
-
        &self,
-
        oid: &Oid,
-
    ) -> Result<Option<Vec<u8>>, sigrefs::git::object::error::ReadCommit> {
-
        self.backend.read_commit(oid)
-
    }
-

-
    fn read_blob(
-
        &self,
-
        commit: &Oid,
-
        path: &Path,
-
    ) -> Result<Option<sigrefs::git::object::Blob>, sigrefs::git::object::error::ReadBlob> {
-
        self.backend.read_blob(commit, path)
-
    }
-
}
-

-
impl sigrefs::git::object::Writer for Repository {
-
    fn write_tree(
-
        &self,
-
        refs: sigrefs::git::object::RefsEntry,
-
        signature: sigrefs::git::object::SignatureEntry,
-
    ) -> Result<Oid, sigrefs::git::object::error::WriteTree> {
-
        self.backend.write_tree(refs, signature)
-
    }
-

-
    fn write_commit(&self, bytes: &[u8]) -> Result<Oid, sigrefs::git::object::error::WriteCommit> {
-
        self.backend.write_commit(bytes)
-
    }
-
}
-

-
impl sigrefs::git::reference::Reader for Repository {
-
    fn find_reference(
-
        &self,
-
        reference: &git::fmt::Namespaced,
-
    ) -> Result<Option<Oid>, sigrefs::git::reference::error::FindReference> {
-
        sigrefs::git::reference::Reader::find_reference(&self.backend, reference)
-
    }
-
}
-

-
impl sigrefs::git::reference::Writer for Repository {
-
    fn write_reference(
-
        &self,
-
        reference: &git::fmt::Namespaced,
-
        commit: Oid,
-
        parent: Option<Oid>,
-
        reflog: String,
-
    ) -> Result<(), sigrefs::git::reference::error::WriteReference> {
-
        self.backend
-
            .write_reference(reference, commit, parent, reflog)
-
    }
-
}
-

impl crate::git::repository::ObjectReader for Repository {
    fn blob(
        &self,
modified crates/radicle/src/storage/refs/sigrefs/git.rs
@@ -2,13 +2,52 @@
//! This module provides traits for interacting with a Git
//! repository to read and write data for Signed References.

-
pub mod object;
-
pub mod reference;
+
use std::path::Path;

use crypto::PublicKey;
use radicle_git_metadata::author::Author;
use radicle_git_metadata::author::Time;

+
use crate::git::repository::types::TreeEntry;
+

+
/// A [`TreeEntry`] for the signed references payload blob.
+
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
+
pub struct RefsEntry(TreeEntry);
+

+
impl RefsEntry {
+
    /// Create a new entry with the canonical refs bytes.
+
    pub fn new(content: Vec<u8>) -> Self {
+
        Self(TreeEntry::Blob {
+
            path: Path::new(crate::storage::refs::REFS_BLOB_PATH).into(),
+
            content,
+
        })
+
    }
+

+
    /// Unwrap into the underlying [`TreeEntry`].
+
    pub fn into_inner(self) -> TreeEntry {
+
        self.0
+
    }
+
}
+

+
/// A [`TreeEntry`] for the cryptographic signature blob.
+
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
+
pub struct SignatureEntry(TreeEntry);
+

+
impl SignatureEntry {
+
    /// Create a new entry with the signature bytes.
+
    pub fn new(content: Vec<u8>) -> Self {
+
        Self(TreeEntry::Blob {
+
            path: Path::new(crate::storage::refs::SIGNATURE_BLOB_PATH).into(),
+
            content,
+
        })
+
    }
+

+
    /// Unwrap into the underlying [`TreeEntry`].
+
    pub fn into_inner(self) -> TreeEntry {
+
        self.0
+
    }
+
}
+

/// Convenience type that corresponds to an [`Author`].
///
/// Most users will want to instantiate this via [`Committer::from_env_or_now`],
@@ -102,142 +141,3 @@ impl Committer {
        })
    }
}
-

-
mod git2_impls {
-
    //! [`git2::Repository`] implementations of the [`object`] and [`reference`] traits.
-
    //!
-
    //! [`object`]: super::object
-
    //! [`reference`]: super::reference
-

-
    use std::path::Path;
-

-
    use radicle_oid::Oid;
-

-
    use crate::git;
-

-
    use super::object;
-
    use super::object::{RefsEntry, SignatureEntry};
-
    use super::reference;
-

-
    impl object::Reader for git2::Repository {
-
        fn read_commit(&self, oid: &Oid) -> Result<Option<Vec<u8>>, object::error::ReadCommit> {
-
            use object::error::ReadCommit;
-

-
            let odb = self.odb().map_err(ReadCommit::other)?;
-
            let object = odb.read(git2::Oid::from(*oid));
-
            match object {
-
                Ok(object) => {
-
                    if object.kind() != git2::ObjectType::Commit {
-
                        return Err(ReadCommit::incorrect_object_error(*oid, object.kind()));
-
                    }
-
                    Ok(Some(object.data().to_vec()))
-
                }
-
                Err(e) if e.code() == git2::ErrorCode::NotFound => Ok(None),
-
                Err(e) => Err(ReadCommit::other(e)),
-
            }
-
        }
-

-
        fn read_blob(
-
            &self,
-
            oid: &Oid,
-
            path: &Path,
-
        ) -> Result<Option<object::Blob>, object::error::ReadBlob> {
-
            use object::error::ReadBlob;
-

-
            let commit = match self.find_commit(git2::Oid::from(*oid)) {
-
                Ok(c) => c,
-
                Err(e) if e.code() == git2::ErrorCode::NotFound => {
-
                    return Err(ReadBlob::commit_not_found_error(*oid));
-
                }
-
                Err(e) => return Err(ReadBlob::other(e)),
-
            };
-

-
            let tree = commit.tree().map_err(ReadBlob::other)?;
-

-
            let entry = match tree.get_path(path) {
-
                Ok(e) => e,
-
                Err(e) if e.code() == git2::ErrorCode::NotFound => return Ok(None),
-
                Err(e) => return Err(ReadBlob::other(e)),
-
            };
-

-
            let object = entry.to_object(self).map_err(ReadBlob::other)?;
-
            let blob = object.as_blob().ok_or(ReadBlob::incorrect_object_error(
-
                *oid,
-
                path.to_path_buf(),
-
                object.kind().unwrap_or(git2::ObjectType::Any),
-
            ))?;
-

-
            Ok(Some(object::Blob {
-
                oid: blob.id().into(),
-
                bytes: blob.content().to_vec(),
-
            }))
-
        }
-
    }
-

-
    impl object::Writer for git2::Repository {
-
        fn write_tree(
-
            &self,
-
            refs: RefsEntry,
-
            signature: SignatureEntry,
-
        ) -> Result<Oid, object::error::WriteTree> {
-
            crate::git::repository::ObjectWriter::write_tree(
-
                self,
-
                &[refs.into_inner(), signature.into_inner()],
-
            )
-
            .map_err(|e| object::error::WriteTree::Write(Box::new(e)))
-
        }
-

-
        fn write_commit(&self, bytes: &[u8]) -> Result<Oid, object::error::WriteCommit> {
-
            use object::error::WriteCommit;
-

-
            let odb = self.odb().map_err(WriteCommit::other)?;
-

-
            let oid = odb
-
                .write(git2::ObjectType::Commit, bytes)
-
                .map_err(WriteCommit::other)?;
-

-
            Ok(Oid::from(oid))
-
        }
-
    }
-

-
    impl reference::Reader for git2::Repository {
-
        fn find_reference(
-
            &self,
-
            reference: &git::fmt::Namespaced,
-
        ) -> Result<Option<Oid>, reference::error::FindReference> {
-
            match self.refname_to_id(reference.as_str()) {
-
                Ok(oid) => Ok(Some(Oid::from(oid))),
-
                Err(e) if e.code() == git2::ErrorCode::NotFound => Ok(None),
-
                Err(e) => Err(reference::error::FindReference::other(e)),
-
            }
-
        }
-
    }
-

-
    impl reference::Writer for git2::Repository {
-
        fn write_reference(
-
            &self,
-
            reference: &git::fmt::Namespaced,
-
            commit: Oid,
-
            parent: Option<Oid>,
-
            reflog: String,
-
        ) -> Result<(), reference::error::WriteReference> {
-
            let new = git2::Oid::from(commit);
-

-
            match parent {
-
                Some(parent) => {
-
                    let old = git2::Oid::from(parent);
-
                    // The old OID provides a guard, which gives us a compare-and-swap —
-
                    // the write will fail if the ref has moved since we read it.
-
                    self.reference_matching(reference.as_str(), new, true, old, &reflog)
-
                        .map_err(reference::error::WriteReference::other)?;
-
                }
-
                None => {
-
                    self.reference(reference.as_str(), new, false, &reflog)
-
                        .map_err(reference::error::WriteReference::other)?;
-
                }
-
            }
-

-
            Ok(())
-
        }
-
    }
-
}
deleted crates/radicle/src/storage/refs/sigrefs/git/object.rs
@@ -1,116 +0,0 @@
-
//! Traits for interacting with Git objects, necessary for implementing Radicle
-
//! Signed References.
-
// TODO(finto): I think these are more generally useful than just being used for
-
// Signed References. They might be worth moving into a crate,
-
// `radicle-git-traits`, but for now they can live here.
-

-
pub mod error;
-

-
use std::path::Path;
-

-
use radicle_oid::Oid;
-

-
use crate::git::repository::types::TreeEntry;
-

-
/// A Git blob object, returned by [`Reader::read_blob`].
-
pub struct Blob {
-
    /// The [`Oid`] of the Git blob.
-
    pub oid: Oid,
-
    /// The contents of the Git blob.
-
    pub bytes: Vec<u8>,
-
}
-

-
/// Git object reader, generally a Git repository, or its corresponding Object
-
/// Database (ODB).
-
pub trait Reader {
-
    /// Read the raw bytes of a commit object identified by `oid`.
-
    ///
-
    /// Returns `None` if no such object exists.
-
    ///
-
    /// # Errors
-
    ///
-
    /// - [`error::ReadCommit::IncorrectObject`]: the object identified by the
-
    ///   [`Oid`] was found, but was not a commit.
-
    /// - [`error::ReadCommit::Other`]: failed to read the Git commit.
-
    fn read_commit(&self, oid: &Oid) -> Result<Option<Vec<u8>>, error::ReadCommit>;
-

-
    /// Read the raw bytes of the blob at `path` within the tree of `commit`.
-
    ///
-
    /// Returns `None` if the path does not exist in that tree.
-
    ///
-
    /// # Errors
-
    ///
-
    /// - [`error::ReadBlob::CommitNotFound`]: failed to find the commit
-
    ///   identified by the [`Oid`].
-
    /// - [`error::ReadBlob::IncorrectObject`]: the object identified by the
-
    ///   [`Oid`] was found, but was not a commit.
-
    /// - [`error::ReadBlob::Other`]: failed to read the Git blob.
-
    fn read_blob(&self, commit: &Oid, path: &Path) -> Result<Option<Blob>, error::ReadBlob>;
-
}
-

-
/// A [`TreeEntry`] for the signed references payload blob.
-
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
-
pub struct RefsEntry(TreeEntry);
-

-
impl RefsEntry {
-
    /// Create a new entry with the canonical refs bytes.
-
    pub fn new(content: Vec<u8>) -> Self {
-
        Self(TreeEntry::Blob {
-
            path: Path::new(crate::storage::refs::REFS_BLOB_PATH).into(),
-
            content,
-
        })
-
    }
-

-
    /// Unwrap into the underlying [`TreeEntry`].
-
    pub fn into_inner(self) -> TreeEntry {
-
        self.0
-
    }
-
}
-

-
/// A [`TreeEntry`] for the cryptographic signature blob.
-
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
-
pub struct SignatureEntry(TreeEntry);
-

-
impl SignatureEntry {
-
    /// Create a new entry with the signature bytes.
-
    pub fn new(content: Vec<u8>) -> Self {
-
        Self(TreeEntry::Blob {
-
            path: Path::new(crate::storage::refs::SIGNATURE_BLOB_PATH).into(),
-
            content,
-
        })
-
    }
-

-
    /// Unwrap into the underlying [`TreeEntry`].
-
    pub fn into_inner(self) -> TreeEntry {
-
        self.0
-
    }
-
}
-

-
/// Git object writer, generally a Git repository, or its corresponding Object
-
/// Database (ODB).
-
pub trait Writer {
-
    /// Write the [`RefsEntry`] and [`SignatureEntry`] to two separate Git blobs
-
    /// within a shared Git tree.
-
    ///
-
    /// Returns the [`Oid`] of the Git tree.
-
    ///
-
    /// # Errors
-
    ///
-
    /// - [`error::WriteTree::Refs`]: failed to write the references Git blob.
-
    /// - [`error::WriteTree::Signature`]: failed to write the signature Git blob.
-
    /// - [`error::WriteTree::Write`]: failed to write the Git tree.
-
    fn write_tree(
-
        &self,
-
        refs: RefsEntry,
-
        signature: SignatureEntry,
-
    ) -> Result<Oid, error::WriteTree>;
-

-
    /// Write the given Git commit, as bytes, to the Git object database.
-
    ///
-
    /// Returns the [`Oid`] of the Git commit.
-
    ///
-
    /// # Errors
-
    ///
-
    /// - [`error::WriteCommit`]: failed to write the Git commit.
-
    fn write_commit(&self, bytes: &[u8]) -> Result<Oid, error::WriteCommit>;
-
}
deleted crates/radicle/src/storage/refs/sigrefs/git/object/error.rs
@@ -1,146 +0,0 @@
-
use std::path::PathBuf;
-

-
use radicle_oid::Oid;
-
use thiserror::Error;
-

-
type StdError = dyn std::error::Error + Send + Sync + 'static;
-

-
#[derive(Debug, Error)]
-
#[non_exhaustive]
-
pub enum ReadCommit {
-
    #[error(transparent)]
-
    IncorrectObject(NotCommit),
-
    #[error(transparent)]
-
    Other(Box<StdError>),
-
}
-

-
impl ReadCommit {
-
    pub fn incorrect_object_error<K>(oid: Oid, kind: K) -> Self
-
    where
-
        K: ToString,
-
    {
-
        Self::IncorrectObject(NotCommit {
-
            oid,
-
            kind: kind.to_string(),
-
        })
-
    }
-

-
    pub fn other<E>(err: E) -> Self
-
    where
-
        E: std::error::Error + Send + Sync + 'static,
-
    {
-
        Self::Other(Box::new(err))
-
    }
-
}
-

-
#[derive(Debug, Error)]
-
#[non_exhaustive]
-
#[error("the object {oid} is a {kind}, not a commit")]
-
pub struct NotCommit {
-
    oid: Oid,
-
    kind: String,
-
}
-

-
#[derive(Debug, Error)]
-
#[non_exhaustive]
-
#[error(transparent)]
-
pub enum ReadBlob {
-
    #[error(transparent)]
-
    CommitNotFound(CommitNotFound),
-
    #[error(transparent)]
-
    IncorrectObject(NotBlob),
-
    #[error(transparent)]
-
    Other(Box<StdError>),
-
}
-

-
#[derive(Debug, Error)]
-
#[non_exhaustive]
-
#[error("could not find commit {oid}")]
-
pub struct CommitNotFound {
-
    oid: Oid,
-
}
-

-
#[derive(Debug, Error)]
-
#[non_exhaustive]
-
#[error("the object at {path:?} in commit {commit} is a {kind}, not a blob")]
-
pub struct NotBlob {
-
    commit: Oid,
-
    path: PathBuf,
-
    kind: String,
-
}
-

-
impl ReadBlob {
-
    pub fn commit_not_found_error(oid: Oid) -> Self {
-
        Self::CommitNotFound(CommitNotFound { oid })
-
    }
-

-
    pub fn incorrect_object_error<K>(commit: Oid, path: PathBuf, kind: K) -> Self
-
    where
-
        K: ToString,
-
    {
-
        Self::IncorrectObject(NotBlob {
-
            commit,
-
            path,
-
            kind: kind.to_string(),
-
        })
-
    }
-

-
    pub fn other<E>(err: E) -> Self
-
    where
-
        E: std::error::Error + Send + Sync + 'static,
-
    {
-
        Self::Other(Box::new(err))
-
    }
-
}
-

-
#[derive(Debug, Error)]
-
#[non_exhaustive]
-
pub enum WriteTree {
-
    #[error("failed to write reference blob for signed references")]
-
    Refs(Box<StdError>),
-
    #[error("failed to write signature blob for signed references")]
-
    Signature(Box<StdError>),
-
    #[error(transparent)]
-
    Write(Box<StdError>),
-
}
-

-
impl WriteTree {
-
    pub fn refs_error<E>(err: E) -> Self
-
    where
-
        E: std::error::Error + Send + Sync + 'static,
-
    {
-
        Self::Refs(Box::new(err))
-
    }
-

-
    pub fn signature_error<E>(err: E) -> Self
-
    where
-
        E: std::error::Error + Send + Sync + 'static,
-
    {
-
        Self::Signature(Box::new(err))
-
    }
-

-
    pub fn write_error<E>(err: E) -> Self
-
    where
-
        E: std::error::Error + Send + Sync + 'static,
-
    {
-
        Self::Write(Box::new(err))
-
    }
-
}
-

-
#[derive(Debug, Error)]
-
#[non_exhaustive]
-
#[error(transparent)]
-
pub struct WriteCommit {
-
    source: Box<StdError>,
-
}
-

-
impl WriteCommit {
-
    pub fn other<E>(err: E) -> Self
-
    where
-
        E: std::error::Error + Send + Sync + 'static,
-
    {
-
        Self {
-
            source: Box::new(err),
-
        }
-
    }
-
}
deleted crates/radicle/src/storage/refs/sigrefs/git/reference.rs
@@ -1,51 +0,0 @@
-
//! Traits for interacting with Git references, necessary for implementing
-
//! Radicle Signed References.
-
// TODO(finto): I think these are more generally useful than just being used for
-
// Signed References. They might be worth moving into a crate,
-
// `radicle-git-traits`, but for now they can live here.
-

-
pub mod error;
-

-
use radicle_oid::Oid;
-

-
use crate::git;
-

-
/// Git reference reader, generally a Git repository, or its corresponding Reference
-
/// Database (Ref DB).
-
pub trait Reader {
-
    /// Find the head [`Oid`] of the sigrefs reference for the given namespace.
-
    ///
-
    /// Returns `None` if the reference does not yet exist.
-
    /// # Errors
-
    ///
-
    /// - [`error::FindReference`]: failed to write the Git reference.
-
    fn find_reference(
-
        &self,
-
        reference: &git::fmt::Namespaced,
-
    ) -> Result<Option<Oid>, error::FindReference>;
-
}
-

-
/// Git reference writer, generally a Git repository, or its corresponding Reference
-
/// Database (Ref DB).
-
pub trait Writer {
-
    /// Write the given commit [`Oid`], and its parent, to the given
-
    /// `reference`.
-
    ///
-
    /// The `reflog` given can used as the Git reflog message of the reference.
-
    ///
-
    /// # Concurrency
-
    ///
-
    /// It is up to the implementer to ensure the safety of writing the
-
    /// reference safely in a concurrent environment.
-
    ///
-
    /// # Errors
-
    ///
-
    /// - [`error::WriteReference`]: failed to write the Git reference.
-
    fn write_reference(
-
        &self,
-
        reference: &git::fmt::Namespaced,
-
        commit: Oid,
-
        parent: Option<Oid>,
-
        reflog: String,
-
    ) -> Result<(), error::WriteReference>;
-
}
deleted crates/radicle/src/storage/refs/sigrefs/git/reference/error.rs
@@ -1,29 +0,0 @@
-
use thiserror::Error;
-

-
#[derive(Debug, Error)]
-
#[non_exhaustive]
-
#[error(transparent)]
-
pub struct FindReference(Box<dyn std::error::Error + Send + Sync + 'static>);
-

-
impl FindReference {
-
    pub fn other<E>(err: E) -> Self
-
    where
-
        E: std::error::Error + Send + Sync + 'static,
-
    {
-
        Self(Box::new(err))
-
    }
-
}
-

-
#[derive(Debug, Error)]
-
#[non_exhaustive]
-
#[error(transparent)]
-
pub struct WriteReference(Box<dyn std::error::Error + Send + Sync + 'static>);
-

-
impl WriteReference {
-
    pub fn other<E>(err: E) -> Self
-
    where
-
        E: std::error::Error + Send + Sync + 'static,
-
    {
-
        Self(Box::new(err))
-
    }
-
}
modified crates/radicle/src/storage/refs/sigrefs/write.rs
@@ -13,11 +13,13 @@ use radicle_oid::Oid;
use crate::git;
use crate::git::repository::{ObjectReader, ObjectWriter, RefReader, RefTarget, RefWriter};
use crate::storage::refs::SignedRefs;
-
use crate::storage::refs::sigrefs::git::{Committer, object};
+
use crate::storage::refs::sigrefs::git::Committer;
use crate::storage::refs::sigrefs::read::CommitReader;
use crate::storage::refs::sigrefs::{VerifiedCommit, read};
use crate::storage::refs::{FeatureLevel, IDENTITY_ROOT, Refs, SIGREFS_BRANCH, SIGREFS_PARENT};

+
use super::git::{RefsEntry, SignatureEntry};
+

/// The result of attempting to write signed references using
/// [`SignedRefsWriter`].
#[derive(Clone, Debug, PartialEq, Eq)]
@@ -330,8 +332,8 @@ where
            .signer
            .try_sign(&canonical)
            .map_err(error::Tree::Sign)?;
-
        let refs = object::RefsEntry::new(canonical);
-
        let sig = object::SignatureEntry::new(signature.to_vec());
+
        let refs = RefsEntry::new(canonical);
+
        let sig = SignatureEntry::new(signature.to_vec());
        let oid = self
            .repository
            .write_tree(&[refs.into_inner(), sig.into_inner()])