diff --git a/radicle-cli/examples/rad-patch-via-push.md b/radicle-cli/examples/rad-patch-via-push.md index 9cb14a60..0eff3175 100644 --- a/radicle-cli/examples/rad-patch-via-push.md +++ b/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) ``` diff --git a/radicle-cli/src/commands/patch/update.rs b/radicle-cli/src/commands/patch/update.rs index 345862af..d3091002 100644 --- a/radicle-cli/src/commands/patch/update.rs +++ b/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#" - -"#; - 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)?; diff --git a/radicle-cli/src/terminal/patch.rs b/radicle-cli/src/terminal/patch.rs index 6aee1d87..e69ccb6f 100644 --- a/radicle-cli/src/terminal/patch.rs +++ b/radicle-cli/src/terminal/patch.rs @@ -63,6 +63,13 @@ and description. --> "#; +const REVISION_MSG: &str = r#" + +"#; + /// 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 { + 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(); diff --git a/radicle-remote-helper/src/lib.rs b/radicle-remote-helper/src/lib.rs index 6ebf54cd..7a6ba885 100644 --- a/radicle-remote-helper/src/lib.rs +++ b/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`). diff --git a/radicle-remote-helper/src/push.rs b/radicle-remote-helper/src/push.rs index 0b955630..280ffcd9 100644 --- a/radicle-remote-helper/src/push.rs +++ b/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( // 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( } /// Update an existing patch. -fn patch_update( +#[allow(clippy::too_many_arguments)] +fn patch_update( 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)?; + let reference = working.find_reference(src.as_str())?; + let commit = reference.peel_to_commit()?; + let patch_id = radicle::cob::ObjectId::from(oid); - // Patch ID. - let oid = radicle::cob::ObjectId::from(oid); - let stderr = io::stderr().as_raw_fd(); + push_ref(src, dst, force, nid, working, stored.raw())?; - // 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. + 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)?; - execute( - "rad", - ["patch", "update", "--quiet", "--no-push", &oid.to_string()], - unsafe { process::Stdio::from_raw_fd(stderr) }, - ) - .map(|_| ()) - .map_err(Error::from) + 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.