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) [ ... ]│
|
│ ✓ 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;
|
mod create;
|
||||||
#[path = "patch/delete.rs"]
|
#[path = "patch/delete.rs"]
|
||||||
mod delete;
|
mod delete;
|
||||||
|
#[path = "patch/edit.rs"]
|
||||||
|
mod edit;
|
||||||
#[path = "patch/list.rs"]
|
#[path = "patch/list.rs"]
|
||||||
mod list;
|
mod list;
|
||||||
#[path = "patch/ready.rs"]
|
#[path = "patch/ready.rs"]
|
||||||
|
|
@ -48,11 +50,16 @@ Usage
|
||||||
rad patch checkout <patch-id> [<option>...]
|
rad patch checkout <patch-id> [<option>...]
|
||||||
rad patch delete <patch-id> [<option>...]
|
rad patch delete <patch-id> [<option>...]
|
||||||
rad patch ready <patch-id> [--undo] [<option>...]
|
rad patch ready <patch-id> [--undo] [<option>...]
|
||||||
|
rad patch edit <patch-id> [<option>...]
|
||||||
|
|
||||||
Show options
|
Show options
|
||||||
|
|
||||||
-p, --patch Show the actual patch diff
|
-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
|
Open/Update options
|
||||||
|
|
||||||
--draft Open patch in draft mode
|
--draft Open patch in draft mode
|
||||||
|
|
@ -91,6 +98,7 @@ pub enum OperationName {
|
||||||
Ready,
|
Ready,
|
||||||
#[default]
|
#[default]
|
||||||
List,
|
List,
|
||||||
|
Edit,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
|
@ -125,6 +133,10 @@ pub enum Operation {
|
||||||
List {
|
List {
|
||||||
filter: Option<patch::State>,
|
filter: Option<patch::State>,
|
||||||
},
|
},
|
||||||
|
Edit {
|
||||||
|
patch_id: Rev,
|
||||||
|
message: Message,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
|
@ -240,6 +252,7 @@ impl Args for Options {
|
||||||
"c" | "checkout" => op = Some(OperationName::Checkout),
|
"c" | "checkout" => op = Some(OperationName::Checkout),
|
||||||
"a" | "archive" => op = Some(OperationName::Archive),
|
"a" | "archive" => op = Some(OperationName::Archive),
|
||||||
"y" | "ready" => op = Some(OperationName::Ready),
|
"y" | "ready" => op = Some(OperationName::Ready),
|
||||||
|
"e" | "edit" => op = Some(OperationName::Edit),
|
||||||
unknown => anyhow::bail!("unknown operation '{}'", unknown),
|
unknown => anyhow::bail!("unknown operation '{}'", unknown),
|
||||||
},
|
},
|
||||||
Value(val)
|
Value(val)
|
||||||
|
|
@ -251,6 +264,7 @@ impl Args for Options {
|
||||||
Some(OperationName::Archive),
|
Some(OperationName::Archive),
|
||||||
Some(OperationName::Ready),
|
Some(OperationName::Ready),
|
||||||
Some(OperationName::Checkout),
|
Some(OperationName::Checkout),
|
||||||
|
Some(OperationName::Edit),
|
||||||
]
|
]
|
||||||
.contains(&op) =>
|
.contains(&op) =>
|
||||||
{
|
{
|
||||||
|
|
@ -290,6 +304,10 @@ impl Args for Options {
|
||||||
patch_id: patch_id.ok_or_else(|| anyhow!("a patch must be provided"))?,
|
patch_id: patch_id.ok_or_else(|| anyhow!("a patch must be provided"))?,
|
||||||
undo,
|
undo,
|
||||||
},
|
},
|
||||||
|
OperationName::Edit => Operation::Edit {
|
||||||
|
patch_id: patch_id.ok_or_else(|| anyhow!("a patch must be provided"))?,
|
||||||
|
message,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok((
|
Ok((
|
||||||
|
|
@ -376,6 +394,10 @@ pub fn run(options: Options, ctx: impl term::Context) -> anyhow::Result<()> {
|
||||||
let patch_id = patch_id.resolve(&repository.backend)?;
|
let patch_id = patch_id.resolve(&repository.backend)?;
|
||||||
checkout::run(&repository, &workdir, &patch_id)?;
|
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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,18 @@ use crate::terminal::args::Error;
|
||||||
|
|
||||||
use super::Options;
|
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.
|
/// Give the name of the branch or an appropriate error.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn branch_name<'a>(branch: &'a git::raw::Branch) -> anyhow::Result<&'a str> {
|
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::common::*;
|
||||||
use super::Options;
|
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(
|
pub fn handle_patch_message(
|
||||||
message: term::patch::Message,
|
message: term::patch::Message,
|
||||||
storage: &Repository,
|
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