cli: add remaining patch actions
Add the remaining `Patch` actions to the CLI interface. These include: - React to a revision - Edit a comment - React to a comment - Redact a comment The `react` subcommand is added in a straight-forward manner. The comment commands are slightly less straight-forward. In order to keep to one layer of subcommands, these variants are done through the `rad patch comment` subcommand. They are accessed via options: `--edit`, `--react`, and `--redact`, respectively. Each of these options takes the `CommentId` for which the action is affecting. The `message`, `react` (introduced for `rad patch react`), and `undo` variables repurposed for this subset of actions.
This commit is contained in:
parent
7d28d1e648
commit
4cced3ddb8
|
|
@ -143,6 +143,23 @@ $ rad patch comment aa45913 --message 'My favorite decade!' --reply-to 686ec1c -
|
||||||
f4336e42daf76342f787d574b5ee779d89d05c7a
|
f4336e42daf76342f787d574b5ee779d89d05c7a
|
||||||
```
|
```
|
||||||
|
|
||||||
|
If we realize we made a mistake in the comment, we can go back and edit it:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ rad patch comment aa45913 --edit 686ec1c --message 'I cannot wait to get back to the 80s!' --no-announce
|
||||||
|
╭───────────────────────────────────────╮
|
||||||
|
│ alice (you) now 686ec1c │
|
||||||
|
│ I cannot wait to get back to the 80s! │
|
||||||
|
╰───────────────────────────────────────╯
|
||||||
|
```
|
||||||
|
|
||||||
|
And if we really made a mistake, then we can redact the comment entirely:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ rad patch comment aa45913 --redact f4336e4 --no-announce
|
||||||
|
✓ Redacted comment f4336e42daf76342f787d574b5ee779d89d05c7a
|
||||||
|
```
|
||||||
|
|
||||||
Now, let's checkout the patch that we just created:
|
Now, let's checkout the patch that we just created:
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,8 @@ mod edit;
|
||||||
mod label;
|
mod label;
|
||||||
#[path = "patch/list.rs"]
|
#[path = "patch/list.rs"]
|
||||||
mod list;
|
mod list;
|
||||||
|
#[path = "patch/react.rs"]
|
||||||
|
mod react;
|
||||||
#[path = "patch/ready.rs"]
|
#[path = "patch/ready.rs"]
|
||||||
mod ready;
|
mod ready;
|
||||||
#[path = "patch/redact.rs"]
|
#[path = "patch/redact.rs"]
|
||||||
|
|
@ -33,11 +35,12 @@ mod update;
|
||||||
|
|
||||||
use std::collections::BTreeSet;
|
use std::collections::BTreeSet;
|
||||||
use std::ffi::OsString;
|
use std::ffi::OsString;
|
||||||
|
use std::str::FromStr as _;
|
||||||
|
|
||||||
use anyhow::anyhow;
|
use anyhow::anyhow;
|
||||||
|
|
||||||
use radicle::cob::patch::PatchId;
|
use radicle::cob::patch::PatchId;
|
||||||
use radicle::cob::{patch, Label};
|
use radicle::cob::{patch, Label, Reaction};
|
||||||
use radicle::git::RefString;
|
use radicle::git::RefString;
|
||||||
use radicle::patch::cache::Patches as _;
|
use radicle::patch::cache::Patches as _;
|
||||||
use radicle::storage::git::transport;
|
use radicle::storage::git::transport;
|
||||||
|
|
@ -67,6 +70,7 @@ Usage
|
||||||
rad patch resolve <patch-id> [--review <review-id>] [--comment <comment-id>] [--unresolve] [<option>...]
|
rad patch resolve <patch-id> [--review <review-id>] [--comment <comment-id>] [--unresolve] [<option>...]
|
||||||
rad patch delete <patch-id> [<option>...]
|
rad patch delete <patch-id> [<option>...]
|
||||||
rad patch redact <revision-id> [<option>...]
|
rad patch redact <revision-id> [<option>...]
|
||||||
|
rad patch react <patch-id | revision-id> [--react <emoji>] [<option>...]
|
||||||
rad patch assign <revision-id> [--add <did>] [--delete <did>] [<option>...]
|
rad patch assign <revision-id> [--add <did>] [--delete <did>] [<option>...]
|
||||||
rad patch label <revision-id> [--add <label>] [--delete <label>] [<option>...]
|
rad patch label <revision-id> [--add <label>] [--delete <label>] [<option>...]
|
||||||
rad patch ready <patch-id> [--undo] [<option>...]
|
rad patch ready <patch-id> [--undo] [<option>...]
|
||||||
|
|
@ -89,6 +93,10 @@ Comment options
|
||||||
|
|
||||||
-m, --message <string> Provide a comment message via the command-line
|
-m, --message <string> Provide a comment message via the command-line
|
||||||
--reply-to <comment> The comment to reply to
|
--reply-to <comment> The comment to reply to
|
||||||
|
--edit <comment> The comment to edit (use --message to edit with the provided message)
|
||||||
|
--react <comment> The comment to react to
|
||||||
|
--emoji <char> The emoji to react with when --react is used
|
||||||
|
--redact <comment> The comment to redact
|
||||||
|
|
||||||
Edit options
|
Edit options
|
||||||
|
|
||||||
|
|
@ -163,6 +171,10 @@ Set options
|
||||||
|
|
||||||
--remote <string> Provide the git remote to use as the upstream
|
--remote <string> Provide the git remote to use as the upstream
|
||||||
|
|
||||||
|
React options
|
||||||
|
|
||||||
|
--emoji <char> The emoji to react to the patch or revision with
|
||||||
|
|
||||||
Other options
|
Other options
|
||||||
|
|
||||||
--repo <rid> Operate on the given repository (default: cwd)
|
--repo <rid> Operate on the given repository (default: cwd)
|
||||||
|
|
@ -182,6 +194,7 @@ pub enum OperationName {
|
||||||
Delete,
|
Delete,
|
||||||
Checkout,
|
Checkout,
|
||||||
Comment,
|
Comment,
|
||||||
|
React,
|
||||||
Ready,
|
Ready,
|
||||||
Review,
|
Review,
|
||||||
Resolve,
|
Resolve,
|
||||||
|
|
@ -194,6 +207,13 @@ pub enum OperationName {
|
||||||
Cache,
|
Cache,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
|
pub enum CommentOperation {
|
||||||
|
Edit,
|
||||||
|
React,
|
||||||
|
Redact,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default, PartialEq, Eq)]
|
#[derive(Debug, Default, PartialEq, Eq)]
|
||||||
pub struct AssignOptions {
|
pub struct AssignOptions {
|
||||||
pub add: BTreeSet<Did>,
|
pub add: BTreeSet<Did>,
|
||||||
|
|
@ -243,6 +263,26 @@ pub enum Operation {
|
||||||
message: Message,
|
message: Message,
|
||||||
reply_to: Option<Rev>,
|
reply_to: Option<Rev>,
|
||||||
},
|
},
|
||||||
|
CommentEdit {
|
||||||
|
revision_id: Rev,
|
||||||
|
comment_id: Rev,
|
||||||
|
message: Message,
|
||||||
|
},
|
||||||
|
CommentRedact {
|
||||||
|
revision_id: Rev,
|
||||||
|
comment_id: Rev,
|
||||||
|
},
|
||||||
|
CommentReact {
|
||||||
|
revision_id: Rev,
|
||||||
|
comment_id: Rev,
|
||||||
|
reaction: Reaction,
|
||||||
|
undo: bool,
|
||||||
|
},
|
||||||
|
React {
|
||||||
|
revision_id: Rev,
|
||||||
|
reaction: Reaction,
|
||||||
|
undo: bool,
|
||||||
|
},
|
||||||
Review {
|
Review {
|
||||||
patch_id: Rev,
|
patch_id: Rev,
|
||||||
revision_id: Option<Rev>,
|
revision_id: Option<Rev>,
|
||||||
|
|
@ -291,12 +331,16 @@ impl Operation {
|
||||||
| Operation::Ready { .. }
|
| Operation::Ready { .. }
|
||||||
| Operation::Delete { .. }
|
| Operation::Delete { .. }
|
||||||
| Operation::Comment { .. }
|
| Operation::Comment { .. }
|
||||||
|
| Operation::CommentEdit { .. }
|
||||||
|
| Operation::CommentRedact { .. }
|
||||||
|
| Operation::CommentReact { .. }
|
||||||
| Operation::Review { .. }
|
| Operation::Review { .. }
|
||||||
| Operation::Resolve { .. }
|
| Operation::Resolve { .. }
|
||||||
| Operation::Assign { .. }
|
| Operation::Assign { .. }
|
||||||
| Operation::Label { .. }
|
| Operation::Label { .. }
|
||||||
| Operation::Edit { .. }
|
| Operation::Edit { .. }
|
||||||
| Operation::Redact { .. }
|
| Operation::Redact { .. }
|
||||||
|
| Operation::React { .. }
|
||||||
| Operation::Set { .. } => true,
|
| Operation::Set { .. } => true,
|
||||||
Operation::Show { .. }
|
Operation::Show { .. }
|
||||||
| Operation::Diff { .. }
|
| Operation::Diff { .. }
|
||||||
|
|
@ -338,7 +382,9 @@ impl Args for Options {
|
||||||
let mut diff = false;
|
let mut diff = false;
|
||||||
let mut debug = false;
|
let mut debug = false;
|
||||||
let mut undo = false;
|
let mut undo = false;
|
||||||
|
let mut reaction: Option<Reaction> = None;
|
||||||
let mut reply_to: Option<Rev> = None;
|
let mut reply_to: Option<Rev> = None;
|
||||||
|
let mut comment_op: Option<(CommentOperation, Rev)> = None;
|
||||||
let mut checkout_opts = checkout::Options::default();
|
let mut checkout_opts = checkout::Options::default();
|
||||||
let mut remote: Option<RefString> = None;
|
let mut remote: Option<RefString> = None;
|
||||||
let mut assign_opts = AssignOptions::default();
|
let mut assign_opts = AssignOptions::default();
|
||||||
|
|
@ -394,6 +440,17 @@ impl Args for Options {
|
||||||
base_id = Some(rev);
|
base_id = Some(rev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// React options.
|
||||||
|
Long("emoji") if op == Some(OperationName::React) => {
|
||||||
|
if let Some(emoji) = parser.value()?.to_str() {
|
||||||
|
reaction =
|
||||||
|
Some(Reaction::from_str(emoji).map_err(|_| anyhow!("invalid emoji"))?);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Long("undo") if op == Some(OperationName::React) => {
|
||||||
|
undo = true;
|
||||||
|
}
|
||||||
|
|
||||||
// Comment options.
|
// Comment options.
|
||||||
Long("reply-to") if op == Some(OperationName::Comment) => {
|
Long("reply-to") if op == Some(OperationName::Comment) => {
|
||||||
let val = parser.value()?;
|
let val = parser.value()?;
|
||||||
|
|
@ -402,6 +459,42 @@ impl Args for Options {
|
||||||
reply_to = Some(rev);
|
reply_to = Some(rev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Long("edit") if op == Some(OperationName::Comment) => {
|
||||||
|
let val = parser.value()?;
|
||||||
|
let rev = term::args::rev(&val)?;
|
||||||
|
|
||||||
|
comment_op = Some((CommentOperation::Edit, rev));
|
||||||
|
}
|
||||||
|
|
||||||
|
Long("react") if op == Some(OperationName::Comment) => {
|
||||||
|
let val = parser.value()?;
|
||||||
|
let rev = term::args::rev(&val)?;
|
||||||
|
|
||||||
|
comment_op = Some((CommentOperation::React, rev));
|
||||||
|
}
|
||||||
|
Long("emoji")
|
||||||
|
if op == Some(OperationName::Comment)
|
||||||
|
&& matches!(comment_op, Some((CommentOperation::React, _))) =>
|
||||||
|
{
|
||||||
|
if let Some(emoji) = parser.value()?.to_str() {
|
||||||
|
reaction =
|
||||||
|
Some(Reaction::from_str(emoji).map_err(|_| anyhow!("invalid emoji"))?);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Long("undo")
|
||||||
|
if op == Some(OperationName::Comment)
|
||||||
|
&& matches!(comment_op, Some((CommentOperation::React, _))) =>
|
||||||
|
{
|
||||||
|
undo = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Long("redact") if op == Some(OperationName::Comment) => {
|
||||||
|
let val = parser.value()?;
|
||||||
|
let rev = term::args::rev(&val)?;
|
||||||
|
|
||||||
|
comment_op = Some((CommentOperation::Redact, rev));
|
||||||
|
}
|
||||||
|
|
||||||
// Edit options.
|
// Edit options.
|
||||||
Long("revision") | Short('r') if op == Some(OperationName::Edit) => {
|
Long("revision") | Short('r') if op == Some(OperationName::Edit) => {
|
||||||
let val = parser.value()?;
|
let val = parser.value()?;
|
||||||
|
|
@ -672,11 +765,38 @@ impl Args for Options {
|
||||||
revision_id,
|
revision_id,
|
||||||
opts: checkout_opts,
|
opts: checkout_opts,
|
||||||
},
|
},
|
||||||
OperationName::Comment => Operation::Comment {
|
OperationName::Comment => match comment_op {
|
||||||
|
Some((CommentOperation::Edit, comment)) => Operation::CommentEdit {
|
||||||
|
revision_id: patch_id
|
||||||
|
.ok_or_else(|| anyhow!("a patch or revision must be provided"))?,
|
||||||
|
comment_id: comment,
|
||||||
|
message,
|
||||||
|
},
|
||||||
|
Some((CommentOperation::React, comment)) => Operation::CommentReact {
|
||||||
|
revision_id: patch_id
|
||||||
|
.ok_or_else(|| anyhow!("a patch or revision must be provided"))?,
|
||||||
|
comment_id: comment,
|
||||||
|
reaction: reaction
|
||||||
|
.ok_or_else(|| anyhow!("a reaction emoji must be provided"))?,
|
||||||
|
undo,
|
||||||
|
},
|
||||||
|
Some((CommentOperation::Redact, comment)) => Operation::CommentRedact {
|
||||||
|
revision_id: patch_id
|
||||||
|
.ok_or_else(|| anyhow!("a patch or revision must be provided"))?,
|
||||||
|
comment_id: comment,
|
||||||
|
},
|
||||||
|
None => Operation::Comment {
|
||||||
|
revision_id: patch_id
|
||||||
|
.ok_or_else(|| anyhow!("a patch or revision must be provided"))?,
|
||||||
|
message,
|
||||||
|
reply_to,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
OperationName::React => Operation::React {
|
||||||
revision_id: patch_id
|
revision_id: patch_id
|
||||||
.ok_or_else(|| anyhow!("a patch or revision must be provided"))?,
|
.ok_or_else(|| anyhow!("a patch or revision must be provided"))?,
|
||||||
message,
|
reaction: reaction.ok_or_else(|| anyhow!("a reaction emoji must be provided"))?,
|
||||||
reply_to,
|
undo,
|
||||||
},
|
},
|
||||||
OperationName::Review => Operation::Review {
|
OperationName::Review => Operation::Review {
|
||||||
patch_id: patch_id
|
patch_id: patch_id
|
||||||
|
|
@ -963,6 +1083,52 @@ pub fn run(options: Options, ctx: impl term::Context) -> anyhow::Result<()> {
|
||||||
};
|
};
|
||||||
cache::run(mode, &profile)?;
|
cache::run(mode, &profile)?;
|
||||||
}
|
}
|
||||||
|
Operation::CommentEdit {
|
||||||
|
revision_id,
|
||||||
|
comment_id,
|
||||||
|
message,
|
||||||
|
} => {
|
||||||
|
let comment = comment_id.resolve(&repository.backend)?;
|
||||||
|
comment::edit::run(
|
||||||
|
revision_id,
|
||||||
|
comment,
|
||||||
|
message,
|
||||||
|
options.quiet,
|
||||||
|
&repository,
|
||||||
|
&profile,
|
||||||
|
)?;
|
||||||
|
}
|
||||||
|
Operation::CommentRedact {
|
||||||
|
revision_id,
|
||||||
|
comment_id,
|
||||||
|
} => {
|
||||||
|
let comment = comment_id.resolve(&repository.backend)?;
|
||||||
|
comment::redact::run(revision_id, comment, &repository, &profile)?;
|
||||||
|
}
|
||||||
|
Operation::CommentReact {
|
||||||
|
revision_id,
|
||||||
|
comment_id,
|
||||||
|
reaction,
|
||||||
|
undo,
|
||||||
|
} => {
|
||||||
|
let comment = comment_id.resolve(&repository.backend)?;
|
||||||
|
if undo {
|
||||||
|
comment::react::run(revision_id, comment, reaction, false, &repository, &profile)?;
|
||||||
|
} else {
|
||||||
|
comment::react::run(revision_id, comment, reaction, true, &repository, &profile)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Operation::React {
|
||||||
|
revision_id,
|
||||||
|
reaction,
|
||||||
|
undo,
|
||||||
|
} => {
|
||||||
|
if undo {
|
||||||
|
react::run(&revision_id, reaction, false, &repository, &profile)?;
|
||||||
|
} else {
|
||||||
|
react::run(&revision_id, reaction, true, &repository, &profile)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if announce {
|
if announce {
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,10 @@
|
||||||
|
#[path = "comment/edit.rs"]
|
||||||
|
pub mod edit;
|
||||||
|
#[path = "comment/react.rs"]
|
||||||
|
pub mod react;
|
||||||
|
#[path = "comment/redact.rs"]
|
||||||
|
pub mod redact;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
use radicle::cob;
|
use radicle::cob;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,49 @@
|
||||||
|
use anyhow::anyhow;
|
||||||
|
|
||||||
|
use radicle::cob;
|
||||||
|
use radicle::cob::patch;
|
||||||
|
use radicle::cob::thread;
|
||||||
|
use radicle::patch::cache::Patches as _;
|
||||||
|
use radicle::patch::ByRevision;
|
||||||
|
use radicle::storage::git::Repository;
|
||||||
|
use radicle::Profile;
|
||||||
|
|
||||||
|
use crate::git;
|
||||||
|
use crate::terminal as term;
|
||||||
|
use crate::terminal::Element as _;
|
||||||
|
|
||||||
|
pub fn run(
|
||||||
|
revision_id: git::Rev,
|
||||||
|
comment_id: thread::CommentId,
|
||||||
|
message: term::patch::Message,
|
||||||
|
quiet: bool,
|
||||||
|
repo: &Repository,
|
||||||
|
profile: &Profile,
|
||||||
|
) -> anyhow::Result<()> {
|
||||||
|
let signer = term::signer(profile)?;
|
||||||
|
let mut patches = profile.patches_mut(repo)?;
|
||||||
|
let revision_id = revision_id.resolve::<cob::EntryId>(&repo.backend)?;
|
||||||
|
let ByRevision {
|
||||||
|
id: patch_id,
|
||||||
|
patch,
|
||||||
|
revision_id,
|
||||||
|
revision,
|
||||||
|
} = patches
|
||||||
|
.find_by_revision(&patch::RevisionId::from(revision_id))?
|
||||||
|
.ok_or_else(|| anyhow!("Patch revision `{revision_id}` not found"))?;
|
||||||
|
let (body, _) = super::prompt(message, None, &revision, repo)?;
|
||||||
|
let mut patch = patch::PatchMut::new(patch_id, patch, &mut patches);
|
||||||
|
patch.comment_edit(revision_id, comment_id, body, vec![], &signer)?;
|
||||||
|
|
||||||
|
if !quiet {
|
||||||
|
let comment = patch
|
||||||
|
.revision(&revision_id)
|
||||||
|
.ok_or(anyhow!("error retrieving revision `{revision_id}`"))?
|
||||||
|
.discussion()
|
||||||
|
.comment(&comment_id)
|
||||||
|
.ok_or(anyhow!("error retrieving comment `{comment_id}`"))?;
|
||||||
|
|
||||||
|
term::comment::widget(&comment_id, comment, profile).print();
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
use anyhow::anyhow;
|
||||||
|
|
||||||
|
use radicle::cob;
|
||||||
|
use radicle::cob::patch;
|
||||||
|
use radicle::cob::thread;
|
||||||
|
use radicle::cob::Reaction;
|
||||||
|
use radicle::patch::cache::Patches as _;
|
||||||
|
use radicle::patch::ByRevision;
|
||||||
|
use radicle::storage::git::Repository;
|
||||||
|
use radicle::Profile;
|
||||||
|
|
||||||
|
use crate::git;
|
||||||
|
use crate::terminal as term;
|
||||||
|
|
||||||
|
pub fn run(
|
||||||
|
revision_id: git::Rev,
|
||||||
|
comment: thread::CommentId,
|
||||||
|
reaction: Reaction,
|
||||||
|
active: bool,
|
||||||
|
repo: &Repository,
|
||||||
|
profile: &Profile,
|
||||||
|
) -> anyhow::Result<()> {
|
||||||
|
let signer = term::signer(profile)?;
|
||||||
|
let mut patches = profile.patches_mut(repo)?;
|
||||||
|
let revision_id = revision_id.resolve::<cob::EntryId>(&repo.backend)?;
|
||||||
|
let ByRevision {
|
||||||
|
id: patch_id,
|
||||||
|
patch,
|
||||||
|
revision_id,
|
||||||
|
..
|
||||||
|
} = patches
|
||||||
|
.find_by_revision(&patch::RevisionId::from(revision_id))?
|
||||||
|
.ok_or_else(|| anyhow!("Patch revision `{revision_id}` not found"))?;
|
||||||
|
let mut patch = patch::PatchMut::new(patch_id, patch, &mut patches);
|
||||||
|
patch.comment_react(revision_id, comment, reaction, active, &signer)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
use anyhow::anyhow;
|
||||||
|
|
||||||
|
use radicle::cob;
|
||||||
|
use radicle::cob::patch;
|
||||||
|
use radicle::cob::thread;
|
||||||
|
use radicle::patch::cache::Patches as _;
|
||||||
|
use radicle::patch::ByRevision;
|
||||||
|
use radicle::storage::git::Repository;
|
||||||
|
use radicle::Profile;
|
||||||
|
|
||||||
|
use crate::git;
|
||||||
|
use crate::terminal as term;
|
||||||
|
|
||||||
|
pub fn run(
|
||||||
|
revision_id: git::Rev,
|
||||||
|
comment: thread::CommentId,
|
||||||
|
repo: &Repository,
|
||||||
|
profile: &Profile,
|
||||||
|
) -> anyhow::Result<()> {
|
||||||
|
let signer = term::signer(profile)?;
|
||||||
|
let mut patches = profile.patches_mut(repo)?;
|
||||||
|
let revision_id = revision_id.resolve::<cob::EntryId>(&repo.backend)?;
|
||||||
|
let ByRevision {
|
||||||
|
id: patch_id,
|
||||||
|
patch,
|
||||||
|
revision_id,
|
||||||
|
..
|
||||||
|
} = patches
|
||||||
|
.find_by_revision(&patch::RevisionId::from(revision_id))?
|
||||||
|
.ok_or_else(|| anyhow!("Patch revision `{revision_id}` not found"))?;
|
||||||
|
let mut patch = patch::PatchMut::new(patch_id, patch, &mut patches);
|
||||||
|
patch.comment_redact(revision_id, comment, &signer)?;
|
||||||
|
term::success!("Redacted comment {comment}");
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
|
||||||
|
|
@ -0,0 +1,35 @@
|
||||||
|
use anyhow::anyhow;
|
||||||
|
|
||||||
|
use radicle::cob;
|
||||||
|
use radicle::cob::{patch, Reaction};
|
||||||
|
use radicle::patch::cache::Patches as _;
|
||||||
|
use radicle::patch::ByRevision;
|
||||||
|
use radicle::storage::git::Repository;
|
||||||
|
use radicle::Profile;
|
||||||
|
|
||||||
|
use crate::git;
|
||||||
|
use crate::terminal as term;
|
||||||
|
|
||||||
|
pub fn run(
|
||||||
|
revision_id: &git::Rev,
|
||||||
|
reaction: Reaction,
|
||||||
|
active: bool,
|
||||||
|
repo: &Repository,
|
||||||
|
profile: &Profile,
|
||||||
|
) -> anyhow::Result<()> {
|
||||||
|
let signer = term::signer(profile)?;
|
||||||
|
let mut patches = profile.patches_mut(repo)?;
|
||||||
|
let revision_id = revision_id.resolve::<cob::EntryId>(&repo.backend)?;
|
||||||
|
let ByRevision {
|
||||||
|
id: patch_id,
|
||||||
|
patch,
|
||||||
|
revision_id,
|
||||||
|
..
|
||||||
|
} = patches
|
||||||
|
.find_by_revision(&patch::RevisionId::from(revision_id))?
|
||||||
|
.ok_or_else(|| anyhow!("Patch revision `{revision_id}` not found"))?;
|
||||||
|
let mut patch = patch::PatchMut::new(patch_id, patch, &mut patches);
|
||||||
|
patch.react(revision_id, reaction, None, active, &signer)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue