Add patch deletion

This commit is contained in:
Brandon Oxendine
2026-08-10 12:54:39 +02:00
committed by Rūdolfs Ošiņš
parent 62e150c29a
commit d19d1f21f1
6 changed files with 185 additions and 1 deletions
@@ -85,6 +85,16 @@ pub fn edit_patch(
ctx.edit_patch(rid, cob_id, action, opts)
}
#[tauri::command]
pub fn delete_patch(
ctx: tauri::State<AppState>,
rid: identity::RepoId,
cob_id: git::Oid,
opts: cobs::CobOptions,
) -> Result<(), Error> {
ctx.delete_patch(rid, cob_id, opts)
}
#[tauri::command]
pub fn create_patch_review(
ctx: tauri::State<AppState>,
+1 -1
View File
@@ -43,10 +43,10 @@ pub fn run() {
cob::issue::rebuild_issue_cache,
cob::job::list_jobs,
cob::patch::activity_by_patch,
cob::patch::delete_patch,
cob::patch::edit_patch,
cob::patch::list_patches,
cob::patch::patch_by_id,
cob::patch::edit_patch,
cob::patch::create_patch_review,
cob::patch::rebuild_patch_cache,
cob::patch::review_by_patch_and_revision_and_id,
+4
View File
@@ -179,6 +179,10 @@ pub enum Error {
#[error(transparent)]
Node(#[from] radicle::node::Error),
/// Cob remove error.
#[error(transparent)]
CobRemove(#[from] radicle::cob::error::Remove),
/// Serde JSON error.
#[error(transparent)]
SerdeJSON(#[from] serde_json::error::Error),
+33
View File
@@ -332,4 +332,37 @@ pub trait PatchesMut: Profile {
&aliases,
))
}
/// Remove a patch COB. Equivalent to `rad patch delete`.
///
/// Only the COB ref under our own namespace is dropped. On a patch we did
/// not author we hold no such ref, so this returns `Ok` having deleted
/// nothing — while still evicting the cache entry, hiding the patch until
/// the next rebuild. Callers must restrict this to our own patches.
fn delete_patch(
&self,
rid: identity::RepoId,
cob_id: git::Oid,
opts: cobs::CobOptions,
) -> Result<(), Error> {
let profile = self.profile();
let mut node = Node::new(profile.home().socket_from_env());
let repo = profile.storage.repository(rid)?;
let signer = profile.signer()?;
// Remove via the cache-backed store so the patch is dropped from both
// the git refs and the COB cache that listings read from; otherwise the
// deleted patch keeps showing up in the patch list.
let mut patches = profile.patches_mut(&repo, &signer)?;
patches.remove(&cob_id.into())?;
drop(patches);
if opts.announce()
&& let Err(e) = node.announce_refs_for(rid, [profile.public_key])
{
log::error!("Not able to announce changes: {}", e)
}
Ok(())
}
}
+18
View File
@@ -114,6 +114,7 @@ pub fn router(ctx: Context) -> Router {
.route("/revisions_by_patch", post(revision_handler))
.route("/edit_patch", post(edit_patch_handler))
.route("/create_patch_review", post(create_patch_review_handler))
.route("/delete_patch", post(delete_patch_handler))
.route("/get_embed", post(get_embeds_handler))
.route("/save_embed_by_path", post(save_embed_handler))
.route("/save_embed_by_clipboard", post(save_embed_handler))
@@ -715,6 +716,23 @@ async fn create_patch_review_handler(
Ok::<_, Error>(Json(review_id))
}
#[derive(Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
struct DeletePatchBody {
pub rid: identity::RepoId,
pub cob_id: git::Oid,
pub opts: CobOptions,
}
async fn delete_patch_handler(
State(ctx): State<Context>,
Json(DeletePatchBody { rid, cob_id, opts }): Json<DeletePatchBody>,
) -> impl IntoResponse {
ctx.delete_patch(rid, cob_id, opts)?;
Ok::<_, Error>(Json(()))
}
#[derive(Serialize, Deserialize)]
struct JobsBody {
pub rid: identity::RepoId,