cli: Make patch editable
Add `rad patch edit` to make the patch description editable.
This commit is contained in:
parent
c20421b0c6
commit
6bedb1256c
|
|
@ -140,3 +140,25 @@ $ rad patch show de3096d
|
|||
│ ✓ accepted by z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi (you) [ ... ]│
|
||||
╰─────────────────────────────────────────────────────────────────────────────────────────╯
|
||||
```
|
||||
|
||||
If you make a mistake on the patch description, you can always change it!
|
||||
|
||||
```
|
||||
$ rad patch edit de3096d --message "Define power requirements" --message "Add requirements file"
|
||||
$ rad patch show de3096d
|
||||
╭─────────────────────────────────────────────────────────────────────────────────────────╮
|
||||
│ Title Define power requirements │
|
||||
│ Patch de3096d5cc422136016ac210b870bfa9d0f11481 │
|
||||
│ Author did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi │
|
||||
│ Head 27857ec9eb04c69cacab516e8bf4b5fd36090f66 │
|
||||
│ Branches flux-capacitor-power, patch/de3096d │
|
||||
│ Commits ahead 2, behind 0 │
|
||||
│ Status open │
|
||||
│ │
|
||||
│ Add requirements file │
|
||||
├─────────────────────────────────────────────────────────────────────────────────────────┤
|
||||
│ ● opened by did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi (you) [ ... ]│
|
||||
│ ↑ updated to d00f978a43a255c7f2f9f23d39b555d103900c6d (27857ec) [ ... ]│
|
||||
│ ✓ accepted by z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi (you) [ ... ]│
|
||||
╰─────────────────────────────────────────────────────────────────────────────────────────╯
|
||||
```
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@ mod common;
|
|||
mod create;
|
||||
#[path = "patch/delete.rs"]
|
||||
mod delete;
|
||||
#[path = "patch/edit.rs"]
|
||||
mod edit;
|
||||
#[path = "patch/list.rs"]
|
||||
mod list;
|
||||
#[path = "patch/ready.rs"]
|
||||
|
|
@ -48,11 +50,16 @@ Usage
|
|||
rad patch checkout <patch-id> [<option>...]
|
||||
rad patch delete <patch-id> [<option>...]
|
||||
rad patch ready <patch-id> [--undo] [<option>...]
|
||||
rad patch edit <patch-id> [<option>...]
|
||||
|
||||
Show options
|
||||
|
||||
-p, --patch Show the actual patch diff
|
||||
|
||||
Edit options
|
||||
|
||||
-m, --message [<string>] Provide a comment message to the patch or revision (default: prompt)
|
||||
|
||||
Open/Update options
|
||||
|
||||
--draft Open patch in draft mode
|
||||
|
|
@ -91,6 +98,7 @@ pub enum OperationName {
|
|||
Ready,
|
||||
#[default]
|
||||
List,
|
||||
Edit,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
|
@ -125,6 +133,10 @@ pub enum Operation {
|
|||
List {
|
||||
filter: Option<patch::State>,
|
||||
},
|
||||
Edit {
|
||||
patch_id: Rev,
|
||||
message: Message,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
|
@ -240,6 +252,7 @@ impl Args for Options {
|
|||
"c" | "checkout" => op = Some(OperationName::Checkout),
|
||||
"a" | "archive" => op = Some(OperationName::Archive),
|
||||
"y" | "ready" => op = Some(OperationName::Ready),
|
||||
"e" | "edit" => op = Some(OperationName::Edit),
|
||||
unknown => anyhow::bail!("unknown operation '{}'", unknown),
|
||||
},
|
||||
Value(val)
|
||||
|
|
@ -251,6 +264,7 @@ impl Args for Options {
|
|||
Some(OperationName::Archive),
|
||||
Some(OperationName::Ready),
|
||||
Some(OperationName::Checkout),
|
||||
Some(OperationName::Edit),
|
||||
]
|
||||
.contains(&op) =>
|
||||
{
|
||||
|
|
@ -290,6 +304,10 @@ impl Args for Options {
|
|||
patch_id: patch_id.ok_or_else(|| anyhow!("a patch must be provided"))?,
|
||||
undo,
|
||||
},
|
||||
OperationName::Edit => Operation::Edit {
|
||||
patch_id: patch_id.ok_or_else(|| anyhow!("a patch must be provided"))?,
|
||||
message,
|
||||
},
|
||||
};
|
||||
|
||||
Ok((
|
||||
|
|
@ -376,6 +394,10 @@ pub fn run(options: Options, ctx: impl term::Context) -> anyhow::Result<()> {
|
|||
let patch_id = patch_id.resolve(&repository.backend)?;
|
||||
checkout::run(&repository, &workdir, &patch_id)?;
|
||||
}
|
||||
Operation::Edit { patch_id, message } => {
|
||||
let patch_id = patch_id.resolve(&repository.backend)?;
|
||||
edit::run(&repository, &profile, &patch_id, message)?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,18 @@ use crate::terminal::args::Error;
|
|||
|
||||
use super::Options;
|
||||
|
||||
pub const PATCH_MSG: &str = r#"
|
||||
<!--
|
||||
Please enter a patch message for your changes. An empty
|
||||
message aborts the patch proposal.
|
||||
|
||||
The first line is the patch title. The patch description
|
||||
follows, and must be separated with a blank line, just
|
||||
like a commit message. Markdown is supported in the title
|
||||
and description.
|
||||
-->
|
||||
"#;
|
||||
|
||||
/// Give the name of the branch or an appropriate error.
|
||||
#[inline]
|
||||
pub fn branch_name<'a>(branch: &'a git::raw::Branch) -> anyhow::Result<&'a str> {
|
||||
|
|
|
|||
|
|
@ -12,18 +12,6 @@ use crate::terminal as term;
|
|||
use super::common::*;
|
||||
use super::Options;
|
||||
|
||||
const PATCH_MSG: &str = r#"
|
||||
<!--
|
||||
Please enter a patch message for your changes. An empty
|
||||
message aborts the patch proposal.
|
||||
|
||||
The first line is the patch title. The patch description
|
||||
follows, and must be separated with a blank line, just
|
||||
like a commit message. Markdown is supported in the title
|
||||
and description.
|
||||
-->
|
||||
"#;
|
||||
|
||||
pub fn handle_patch_message(
|
||||
message: term::patch::Message,
|
||||
storage: &Repository,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,42 @@
|
|||
use super::common::*;
|
||||
use super::*;
|
||||
|
||||
use radicle::cob::patch;
|
||||
use radicle::prelude::*;
|
||||
use radicle::storage::git::Repository;
|
||||
|
||||
pub fn run(
|
||||
repository: &Repository,
|
||||
profile: &Profile,
|
||||
patch_id: &PatchId,
|
||||
message: term::patch::Message,
|
||||
) -> anyhow::Result<()> {
|
||||
let signer = term::signer(profile)?;
|
||||
let mut patches = patch::Patches::open(repository)?;
|
||||
let Ok(mut patch) = patches.get_mut(patch_id) else {
|
||||
anyhow::bail!("Patch `{patch_id}` not found");
|
||||
};
|
||||
|
||||
let title = patch.title();
|
||||
let description = patch.description();
|
||||
let message = message.get(&format!("{title}\n\n{description}\n\n{PATCH_MSG}"))?;
|
||||
let message = message.replace(PATCH_MSG.trim(), ""); // Delete help message.
|
||||
let (title, description) = message.split_once("\n\n").unwrap_or((&message, ""));
|
||||
let (title, description) = (title.trim(), description.trim());
|
||||
|
||||
if title.is_empty() {
|
||||
anyhow::bail!("a patch title must be provided");
|
||||
} else if title == patch.title() && description == patch.description() {
|
||||
// Nothing to do
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
patch.edit(
|
||||
title.to_string(),
|
||||
description.to_string(),
|
||||
patch.target(),
|
||||
&signer,
|
||||
)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
Loading…
Reference in New Issue