Radish alpha
h
Radicle Heartwood Protocol & Stack
Radicle
Git (anonymous pull)
Log in to clone via SSH
remote-helper: refactor pushing action
Fintan Halpenny committed 9 months ago
commit 14444a43eaaf3f0a446090a698e7be4d809f424a
parent a9f75d47ecca159383fd9df0c3a140f8c063eb57
2 files changed +74 -28
modified crates/radicle-remote-helper/src/push.rs
@@ -1,4 +1,7 @@
#![allow(clippy::too_many_arguments)]
+

+
mod error;
+

use std::collections::HashMap;
use std::io::IsTerminal;
use std::path::{Path, PathBuf};
@@ -66,9 +69,6 @@ pub enum Error {
    /// Invalid reference name.
    #[error("invalid ref: {0}")]
    InvalidRef(#[from] radicle::git::fmt::Error),
-
    /// Invalid reference name.
-
    #[error("invalid qualified ref: {0}")]
-
    InvalidQualifiedRef(git::RefString),
    /// Git error.
    #[error("git: {0}")]
    Git(#[from] git::raw::Error),
@@ -119,6 +119,8 @@ pub enum Error {
    Quorum(#[from] radicle::git::canonical::QuorumError),
    #[error(transparent)]
    CanonicalRefs(#[from] radicle::identity::doc::CanonicalRefsError),
+
    #[error(transparent)]
+
    PushAction(#[from] error::PushAction),
}

/// Push command.
@@ -196,6 +198,43 @@ impl Command {
    }
}

+
enum PushAction {
+
    OpenPatch,
+
    UpdatePatch {
+
        dst: git::Qualified<'static>,
+
        patch: patch::PatchId,
+
    },
+
    PushRef {
+
        dst: git::Qualified<'static>,
+
    },
+
}
+

+
impl PushAction {
+
    fn new(dst: &git::RefString) -> Result<Self, error::PushAction> {
+
        if dst == &*rad::PATCHES_REFNAME {
+
            Ok(Self::OpenPatch)
+
        } else {
+
            let dst = git::Qualified::from_refstr(dst)
+
                .ok_or_else(|| error::PushAction::InvalidRef {
+
                    refname: dst.clone(),
+
                })?
+
                .to_owned();
+

+
            if let Some(oid) = dst.strip_prefix(git::refname!("refs/heads/patches")) {
+
                let patch = git::Oid::from_str(oid)
+
                    .map_err(|err| error::PushAction::InvalidPatchId {
+
                        suffix: oid.to_string(),
+
                        err,
+
                    })
+
                    .map(patch::PatchId::from)?;
+
                Ok(Self::UpdatePatch { dst, patch })
+
            } else {
+
                Ok(Self::PushRef { dst })
+
            }
+
        }
+
    }
+
}
+

/// Run a git push command.
pub fn run(
    mut specs: Vec<String>,
@@ -268,9 +307,10 @@ pub fn run(
            }
            Command::Push(git::Refspec { src, dst, force }) => {
                let patches = crate::patches_mut(profile, stored)?;
+
                let action = PushAction::new(dst)?;

-
                if dst == &*rad::PATCHES_REFNAME {
-
                    patch_open(
+
                match action {
+
                    PushAction::OpenPatch => patch_open(
                        src,
                        &remote,
                        &nid,
@@ -280,27 +320,20 @@ pub fn run(
                        &signer,
                        profile,
                        opts.clone(),
-
                    )
-
                } else {
-
                    let dst = git::Qualified::from_refstr(dst)
-
                        .ok_or_else(|| Error::InvalidQualifiedRef(dst.clone()))?;
-

-
                    if let Some(oid) = dst.strip_prefix(git::refname!("refs/heads/patches")) {
-
                        let oid = git::Oid::from_str(oid)?;
-

-
                        patch_update(
-
                            src,
-
                            &dst,
-
                            *force,
-
                            &oid,
-
                            &nid,
-
                            &working,
-
                            stored,
-
                            patches,
-
                            &signer,
-
                            opts.clone(),
-
                        )
-
                    } else {
+
                    ),
+
                    PushAction::UpdatePatch { dst, patch } => patch_update(
+
                        src,
+
                        &dst,
+
                        *force,
+
                        patch,
+
                        &nid,
+
                        &working,
+
                        stored,
+
                        patches,
+
                        &signer,
+
                        opts.clone(),
+
                    ),
+
                    PushAction::PushRef { dst } => {
                        let identity = stored.identity()?;
                        let crefs = identity.canonical_refs_or_default(|| {
                            let rule = identity.doc().default_branch_rule()?;
@@ -573,7 +606,7 @@ fn patch_update<G>(
    src: &git::Oid,
    dst: &git::Qualified,
    force: bool,
-
    oid: &git::Oid,
+
    patch_id: patch::PatchId,
    nid: &NodeId,
    working: &git::raw::Repository,
    stored: &storage::git::Repository,
@@ -588,7 +621,6 @@ where
    G: crypto::signature::Signer<crypto::Signature>,
{
    let commit = *src;
-
    let patch_id = radicle::cob::ObjectId::from(oid);
    let dst = dst.with_namespace(nid.into());

    push_ref(src, &dst, force, working, stored.raw())?;
added crates/radicle-remote-helper/src/push/error.rs
@@ -0,0 +1,14 @@
+
use radicle::storage::git;
+
use thiserror::Error;
+

+
#[derive(Debug, Error)]
+
pub enum PushAction {
+
    #[error("invalid reference {refname}, expected qualified reference starting with `refs/`")]
+
    InvalidRef { refname: git::RefString },
+
    #[error("found refs/heads/patches/{suffix} where {suffix} was an invalid Patch ID")]
+
    InvalidPatchId {
+
        suffix: String,
+
        #[source]
+
        err: git::raw::Error,
+
    },
+
}