From 5277028e1aced669dd5f099e55620ae76dafcb64 Mon Sep 17 00:00:00 2001 From: Sebastian Martinez Date: Wed, 23 Oct 2024 11:19:22 +0200 Subject: [PATCH] Add `edit_patch` tauri command --- .../radicle-tauri/src/commands/cob/patch.rs | 183 ++++++++++++++++ crates/radicle-tauri/src/lib.rs | 1 + crates/radicle-types/src/cobs/patch.rs | 204 ++++++++++++++++++ 3 files changed, 388 insertions(+) diff --git a/crates/radicle-tauri/src/commands/cob/patch.rs b/crates/radicle-tauri/src/commands/cob/patch.rs index 8bb749cc9..a14da2ad8 100644 --- a/crates/radicle-tauri/src/commands/cob/patch.rs +++ b/crates/radicle-tauri/src/commands/cob/patch.rs @@ -241,3 +241,186 @@ pub fn get_draft_review( review } + +#[tauri::command] +pub fn edit_patch( + ctx: tauri::State, + rid: identity::RepoId, + cob_id: git::Oid, + action: types::cobs::patch::Action, + opts: types::cobs::CobOptions, +) -> Result { + let mut node = Node::new(ctx.profile.socket()); + let repo = ctx.profile.storage.repository(rid)?; + let signer = ctx.profile.signer()?; + let aliases = ctx.profile.aliases(); + let mut patches = ctx.profile.patches_mut(&repo)?; + let mut patch = patches.get_mut(&cob_id.into())?; + + match action { + types::cobs::patch::Action::RevisionEdit { + revision, + description, + embeds, + } => { + patch.edit_revision( + revision, + description, + embeds.into_iter().map(|e| e.into()).collect::>(), + &signer, + )?; + } + types::cobs::patch::Action::RevisionCommentRedact { revision, comment } => { + patch.comment_redact(revision, comment, &signer)?; + } + types::cobs::patch::Action::ReviewCommentRedact { review, comment } => { + patch.redact_review_comment(review, comment, &signer)?; + } + types::cobs::patch::Action::ReviewCommentReact { + review, + comment, + reaction, + active, + } => { + patch.react_review_comment(review, comment, reaction, active, &signer)?; + } + types::cobs::patch::Action::ReviewCommentResolve { review, comment } => { + patch.resolve_review_comment(review, comment, &signer)?; + } + types::cobs::patch::Action::ReviewCommentUnresolve { review, comment } => { + patch.unresolve_review_comment(review, comment, &signer)?; + } + types::cobs::patch::Action::Edit { title, target } => { + patch.edit(title, target, &signer)?; + } + types::cobs::patch::Action::ReviewEdit { + review, + summary, + verdict, + labels, + } => { + patch.review_edit(review, verdict, summary, labels, &signer)?; + } + types::cobs::patch::Action::Review { + revision, + summary, + verdict, + labels, + } => { + patch.review(revision, verdict, summary, labels, &signer)?; + } + types::cobs::patch::Action::ReviewRedact { review } => { + patch.redact_review(review, &signer)?; + } + types::cobs::patch::Action::ReviewComment { + review, + body, + location, + reply_to, + embeds, + } => { + patch.review_comment( + review, + body, + location.map(|l| l.into()), + reply_to, + embeds.into_iter().map(|e| e.into()).collect::>(), + &signer, + )?; + } + types::cobs::patch::Action::ReviewCommentEdit { + review, + comment, + body, + embeds, + } => { + patch.edit_review_comment( + review, + comment, + body, + embeds.into_iter().map(|e| e.into()).collect::>(), + &signer, + )?; + } + types::cobs::patch::Action::Lifecycle { state } => { + patch.lifecycle(state, &signer)?; + } + types::cobs::patch::Action::Assign { assignees } => { + patch.assign(assignees, &signer)?; + } + types::cobs::patch::Action::Label { labels } => { + patch.label(labels, &signer)?; + } + types::cobs::patch::Action::RevisionReact { + revision, + reaction, + location, + active, + } => { + patch.react( + revision, + reaction, + location.map(|l| l.into()), + active, + &signer, + )?; + } + types::cobs::patch::Action::RevisionComment { + revision, + location, + body, + reply_to, + embeds, + } => { + patch.comment( + revision, + body, + reply_to, + location.map(|l| l.into()), + embeds.into_iter().map(|e| e.into()).collect::>(), + &signer, + )?; + } + types::cobs::patch::Action::RevisionCommentEdit { + revision, + comment, + body, + embeds, + } => { + patch.comment_edit( + revision, + comment, + body, + embeds.into_iter().map(|e| e.into()).collect::>(), + &signer, + )?; + } + types::cobs::patch::Action::RevisionCommentReact { + revision, + comment, + reaction, + active, + } => { + patch.comment_react(revision, comment, reaction, active, &signer)?; + } + types::cobs::patch::Action::RevisionRedact { revision } => { + patch.redact(revision, &signer)?; + } + types::cobs::patch::Action::Merge { .. } => { + unimplemented!("We don't support merging of patches through the desktop") + } + types::cobs::patch::Action::Revision { .. } => { + unimplemented!("We don't support creating new revisions through the desktop") + } + } + + if opts.announce() { + node.announce_refs(rid)?; + } + + Ok::<_, Error>(types::cobs::patch::Patch::new( + *patch.id(), + &patch, + &aliases, + )) +} diff --git a/crates/radicle-tauri/src/lib.rs b/crates/radicle-tauri/src/lib.rs index 01754e994..507567796 100644 --- a/crates/radicle-tauri/src/lib.rs +++ b/crates/radicle-tauri/src/lib.rs @@ -85,6 +85,7 @@ pub fn run() { cob::issue::edit_issue, cob::patch::list_patches, cob::patch::patch_by_id, + cob::patch::edit_patch, cob::patch::revisions_by_patch, cob::patch::revision_by_patch_and_id, cob::patch::create_draft_review, diff --git a/crates/radicle-types/src/cobs/patch.rs b/crates/radicle-types/src/cobs/patch.rs index 63149f981..7c03d4378 100644 --- a/crates/radicle-types/src/cobs/patch.rs +++ b/crates/radicle-types/src/cobs/patch.rs @@ -269,3 +269,207 @@ impl Review { } } +#[derive(Serialize, Deserialize, TS)] +#[serde(tag = "type", rename_all = "camelCase")] +#[ts(export)] +#[ts(export_to = "cob/patch/")] +pub enum Action { + #[serde(rename = "edit")] + Edit { + title: String, + #[ts(as = "String")] + target: patch::MergeTarget, + }, + #[serde(rename = "label")] + Label { + #[ts(as = "Vec")] + labels: BTreeSet, + }, + #[serde(rename = "lifecycle")] + Lifecycle { + #[ts(type = "{ status: 'draft' | 'open' | 'archived' }")] + state: patch::Lifecycle, + }, + #[serde(rename = "assign")] + Assign { + #[ts(as = "Vec")] + assignees: BTreeSet, + }, + #[serde(rename = "merge")] + Merge { + #[ts(as = "String")] + revision: patch::RevisionId, + #[ts(as = "String")] + commit: git::Oid, + }, + + #[serde(rename = "review")] + Review { + #[ts(as = "String")] + revision: patch::RevisionId, + #[serde(default, skip_serializing_if = "Option::is_none")] + #[ts(optional)] + summary: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + #[ts(as = "Option", optional)] + verdict: Option, + #[serde(default, skip_serializing_if = "Vec::is_empty")] + #[ts(as = "Option>", optional)] + labels: Vec, + }, + #[serde(rename = "review.edit")] + ReviewEdit { + #[ts(as = "String")] + review: patch::ReviewId, + #[serde(default, skip_serializing_if = "Option::is_none")] + #[ts(optional)] + summary: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + #[ts(as = "Option", optional)] + verdict: Option, + #[serde(default, skip_serializing_if = "Vec::is_empty")] + #[ts(as = "Option>", optional)] + labels: Vec, + }, + #[serde(rename = "review.redact")] + ReviewRedact { + #[ts(as = "String")] + review: patch::ReviewId, + }, + #[serde(rename = "review.comment")] + ReviewComment { + #[ts(as = "String")] + review: patch::ReviewId, + body: String, + #[serde(default, skip_serializing_if = "Option::is_none")] + #[ts(optional)] + location: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + #[ts(as = "Option", optional)] + reply_to: Option, + #[serde(default, skip_serializing_if = "Vec::is_empty")] + #[ts(as = "Option<_>", optional)] + embeds: Vec, + }, + #[serde(rename = "review.comment.edit")] + ReviewCommentEdit { + #[ts(as = "String")] + review: patch::ReviewId, + #[ts(as = "String")] + comment: cob::EntryId, + body: String, + #[ts(as = "Option<_>", optional)] + embeds: Vec, + }, + #[serde(rename = "review.comment.redact")] + ReviewCommentRedact { + #[ts(as = "String")] + review: patch::ReviewId, + #[ts(as = "String")] + comment: cob::EntryId, + }, + #[serde(rename = "review.comment.react")] + ReviewCommentReact { + #[ts(as = "String")] + review: patch::ReviewId, + #[ts(as = "String")] + comment: cob::EntryId, + #[ts(as = "String")] + reaction: cob::Reaction, + active: bool, + }, + #[serde(rename = "review.comment.resolve")] + ReviewCommentResolve { + #[ts(as = "String")] + review: patch::ReviewId, + #[ts(as = "String")] + comment: cob::EntryId, + }, + #[serde(rename = "review.comment.unresolve")] + ReviewCommentUnresolve { + #[ts(as = "String")] + review: patch::ReviewId, + #[ts(as = "String")] + comment: cob::EntryId, + }, + + #[serde(rename = "revision")] + Revision { + description: String, + #[ts(as = "String")] + base: git::Oid, + #[ts(as = "String")] + oid: git::Oid, + #[serde(default, skip_serializing_if = "BTreeSet::is_empty")] + #[ts(as = "Option>", optional)] + resolves: BTreeSet<(cob::EntryId, cob::thread::CommentId)>, + }, + #[serde(rename = "revision.edit")] + RevisionEdit { + #[ts(as = "String")] + revision: patch::RevisionId, + description: String, + #[serde(default, skip_serializing_if = "Vec::is_empty")] + #[ts(as = "Option<_>", optional)] + embeds: Vec, + }, + #[serde(rename = "revision.react")] + RevisionReact { + #[ts(as = "String")] + revision: patch::RevisionId, + #[serde(default, skip_serializing_if = "Option::is_none")] + #[ts(optional)] + location: Option, + #[ts(as = "String")] + reaction: cob::Reaction, + active: bool, + }, + #[serde(rename = "revision.redact")] + RevisionRedact { + #[ts(as = "String")] + revision: patch::RevisionId, + }, + #[serde(rename_all = "camelCase")] + #[serde(rename = "revision.comment")] + RevisionComment { + #[ts(as = "String")] + revision: patch::RevisionId, + #[serde(default, skip_serializing_if = "Option::is_none")] + #[ts(optional)] + location: Option, + body: String, + #[serde(default, skip_serializing_if = "Option::is_none")] + #[ts(as = "Option", optional)] + reply_to: Option, + #[serde(default, skip_serializing_if = "Vec::is_empty")] + #[ts(as = "Option<_>", optional)] + embeds: Vec, + }, + #[serde(rename = "revision.comment.edit")] + RevisionCommentEdit { + #[ts(as = "String")] + revision: patch::RevisionId, + #[ts(as = "String")] + comment: cob::thread::CommentId, + body: String, + #[ts(as = "Option<_>", optional)] + embeds: Vec, + }, + #[serde(rename = "revision.comment.redact")] + RevisionCommentRedact { + #[ts(as = "String")] + revision: patch::RevisionId, + #[ts(as = "String")] + comment: cob::thread::CommentId, + }, + #[serde(rename = "revision.comment.react")] + RevisionCommentReact { + #[ts(as = "String")] + revision: patch::RevisionId, + #[ts(as = "String")] + comment: cob::thread::CommentId, + #[ts(as = "String")] + reaction: cob::Reaction, + active: bool, + }, +}