Radish alpha
h
Radicle Heartwood Protocol & Stack
Radicle
Git (anonymous pull)
Log in to clone via SSH
cli: Use library for updating patch
Alexis Sellier committed 3 years ago
commit a9c0152a99539653819beec0b80ecae2aac4ce21
parent 51dced480853442d085747c262d2778a8e82ab26
5 files changed +55 -32
modified radicle-cli/examples/rad-patch-via-push.md
@@ -114,7 +114,7 @@ $ git commit -a -m "Improve code" -q --allow-empty

``` (stderr)
$ git push
-
4b6618a6ccb0b406659364a70a00bb60e4cd7cf0
+
✓ Patch 8678aaf updated to 4b6618a6ccb0b406659364a70a00bb60e4cd7cf0
To rad://z42hL2jL4XNk6K8oHQaSWfMgCL7ji/z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
   b94a835..662843e  feature/2 -> patches/8678aafff1d1e28430952abf431e60b87e28023c
```
@@ -203,7 +203,7 @@ use `--force` to force the update.

``` (stderr)
$ git push --force
-
983f2d21c9fbe91c21ddfbcd3e3d6cd13db0a944
+
✓ Patch 8678aaf updated to 983f2d21c9fbe91c21ddfbcd3e3d6cd13db0a944
To rad://z42hL2jL4XNk6K8oHQaSWfMgCL7ji/z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
 + 662843e...3507cd5 feature/2 -> patches/8678aafff1d1e28430952abf431e60b87e28023c (forced update)
```
modified radicle-cli/src/commands/patch/update.rs
@@ -7,13 +7,6 @@ use super::common::*;
use super::Options;
use crate::terminal as term;

-
const REVISION_MSG: &str = r#"
-
<!--
-
Please enter a comment for your patch update. Leaving this
-
blank is also okay.
-
-->
-
"#;
-

fn select_patch(
    patches: &patch::Patches,
    storage: &Repository,
@@ -100,9 +93,7 @@ pub fn run(

    let head_oid = branch_oid(&head_branch)?;
    let base_oid = storage.backend.merge_base(*target_oid, *head_oid)?;
-
    let message = message.get(REVISION_MSG)?;
-
    let message = message.replace(REVISION_MSG.trim(), "");
-
    let message = message.trim();
+
    let message = term::patch::get_update_message(message)?;
    let signer = term::signer(profile)?;
    let revision = patch.update(message, base_oid, *head_oid, &signer)?;

modified radicle-cli/src/terminal/patch.rs
@@ -63,6 +63,13 @@ and description.
-->
"#;

+
const REVISION_MSG: &str = r#"
+
<!--
+
Please enter a comment for your patch update. Leaving this
+
blank is also okay.
+
-->
+
"#;
+

/// Combine the title and description fields to display to the user.
#[inline]
pub fn message(title: &str, description: &str) -> String {
@@ -95,6 +102,15 @@ pub fn get_message(
    Ok((title, description))
}

+
/// Get a patch update message.
+
pub fn get_update_message(message: term::patch::Message) -> io::Result<String> {
+
    let message = message.get(REVISION_MSG)?;
+
    let message = message.replace(REVISION_MSG.trim(), "");
+
    let message = message.trim();
+

+
    Ok(message.to_owned())
+
}
+

/// List the given commits in a table.
pub fn list_commits(commits: &[git::raw::Commit]) -> anyhow::Result<()> {
    let mut table = term::Table::default();
modified radicle-remote-helper/src/lib.rs
@@ -1,3 +1,4 @@
+
#![warn(clippy::unwrap_used)]
//! The Radicle Git remote helper.
//!
//! Communication with the user is done via `stderr` (`eprintln`).
modified radicle-remote-helper/src/push.rs
@@ -58,6 +58,12 @@ pub enum Error {
    /// Patch COB error.
    #[error(transparent)]
    Patch(#[from] radicle::cob::patch::Error),
+
    /// Patch not found in store.
+
    #[error("patch `{0}` not found")]
+
    NotFound(patch::PatchId),
+
    /// COB store error.
+
    #[error(transparent)]
+
    Cob(#[from] radicle::cob::store::Error),
}

enum Command {
@@ -158,7 +164,7 @@ pub fn run(
                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.raw())
+
                    patch_update(src, dst, *force, &oid, &nid, &working, stored, &signer)
                } else if dst == &*rad::PATCHES_REFNAME {
                    patch_open(src, &nid, &working, stored, &signer)
                } else {
@@ -224,7 +230,7 @@ fn patch_open<G: Signer>(
    // not fail, since the reference will already exist with the correct OID.
    push_ref(src, dst, false, nid, working, stored.raw())?;

-
    let mut patches = patch::Patches::open(stored).unwrap();
+
    let mut patches = patch::Patches::open(stored)?;
    let message = commit.message().unwrap_or_default();
    let (title, description) = cli::patch::get_message(cli::patch::Message::Edit, message)?;
    let (_, target) = stored.canonical_head()?;
@@ -303,31 +309,40 @@ fn patch_open<G: Signer>(
}

/// Update an existing patch.
-
fn patch_update(
+
#[allow(clippy::too_many_arguments)]
+
fn patch_update<G: Signer>(
    src: &git::RefStr,
    dst: &git::RefStr,
    force: bool,
    oid: &git::Oid,
    nid: &NodeId,
    working: &git::raw::Repository,
-
    stored: &git::raw::Repository,
+
    stored: &storage::git::Repository,
+
    signer: &G,
) -> Result<(), Error> {
-
    push_ref(src, dst, force, nid, working, stored)?;
-

-
    // Patch ID.
-
    let oid = radicle::cob::ObjectId::from(oid);
-
    let stderr = io::stderr().as_raw_fd();
-

-
    // Nb. Git tooling checks that we aren't attempting a forced update without the `--force`
-
    // option of `git push`. There's no need for us to check here.
-

-
    execute(
-
        "rad",
-
        ["patch", "update", "--quiet", "--no-push", &oid.to_string()],
-
        unsafe { process::Stdio::from_raw_fd(stderr) },
-
    )
-
    .map(|_| ())
-
    .map_err(Error::from)
+
    let reference = working.find_reference(src.as_str())?;
+
    let commit = reference.peel_to_commit()?;
+
    let patch_id = radicle::cob::ObjectId::from(oid);
+

+
    push_ref(src, dst, force, nid, working, stored.raw())?;
+

+
    let mut patches = patch::Patches::open(stored)?;
+
    let Ok(mut patch) = patches.get_mut(&patch_id) else {
+
        return Err(Error::NotFound(patch_id));
+
    };
+
    let message = cli::patch::get_update_message(cli::patch::Message::Edit)?;
+
    let (_, target) = stored.canonical_head()?;
+
    let base = stored.backend.merge_base(*target, commit.id())?;
+
    let revision = patch.update(message, base, commit.id(), signer)?;
+

+
    eprintln!(
+
        "{} Patch {} updated to {}",
+
        cli::format::positive("✓"),
+
        cli::format::dim(cli::format::cob(&patch_id)),
+
        cli::format::tertiary(revision)
+
    );
+

+
    Ok(())
}

/// Push a single reference to storage.