cli: allow editing patch revision descriptions
Allow `rad patch edit` to take a `--revision` option which will edit the description of the specified revision, rather than the root revision. If the flag is not specified, then the original behaviour of editing the root revision's title and description is used. Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com> X-Clacks-Overhead: GNU Terry Pratchett
This commit is contained in:
parent
a8cca57c0a
commit
b57099a0d0
|
|
@ -0,0 +1,116 @@
|
|||
If you ever want to change the title and descriptions associated with
|
||||
a patch and its revisions, we can always use the `rad patch edit`
|
||||
command.
|
||||
|
||||
First off, we'll have to set up a patch and an updated revision:
|
||||
|
||||
```
|
||||
$ git checkout -b changes
|
||||
$ touch README.md
|
||||
$ git add README.md
|
||||
$ git commit --message "Add README, just for the fun"
|
||||
[changes 03c02af] Add README, just for the fun
|
||||
1 file changed, 0 insertions(+), 0 deletions(-)
|
||||
create mode 100644 README.md
|
||||
```
|
||||
|
||||
``` (stderr)
|
||||
$ git push rad -o patch.message="Add README, just for the fun" HEAD:refs/patches
|
||||
✓ Patch 0631b2d1b5cd4ae44e92732ff3929528354a8405 opened
|
||||
To rad://z42hL2jL4XNk6K8oHQaSWfMgCL7ji/z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
|
||||
* [new reference] HEAD -> refs/patches
|
||||
```
|
||||
|
||||
```
|
||||
$ touch LICENSE
|
||||
$ git add LICENSE
|
||||
$ git commit -v -m "Define the LICENSE"
|
||||
[changes 8945f61] Define the LICENSE
|
||||
1 file changed, 0 insertions(+), 0 deletions(-)
|
||||
create mode 100644 LICENSE
|
||||
```
|
||||
|
||||
``` (stderr)
|
||||
$ git push -f -o patch.message="Add License"
|
||||
✓ Patch 0631b2d updated to revision bbc91fd4c74bfbbb162ec4b97cd8cefe623814d7
|
||||
To rad://z42hL2jL4XNk6K8oHQaSWfMgCL7ji/z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
|
||||
03c02af..8945f61 changes -> patches/0631b2d1b5cd4ae44e92732ff3929528354a8405
|
||||
```
|
||||
|
||||
Let's look at the patch, to see what it looks like before editing it:
|
||||
|
||||
```
|
||||
$ rad patch show 0631b2d
|
||||
╭─────────────────────────────────────────────────────────────────────╮
|
||||
│ Title Add README, just for the fun │
|
||||
│ Patch 0631b2d1b5cd4ae44e92732ff3929528354a8405 │
|
||||
│ Author z6MknSL…StBU8Vi (you) │
|
||||
│ Head 8945f6189adf027892c85ac57f7e9341049c2537 │
|
||||
│ Branches changes │
|
||||
│ Commits ahead 2, behind 0 │
|
||||
│ Status open │
|
||||
├─────────────────────────────────────────────────────────────────────┤
|
||||
│ 8945f61 Define the LICENSE │
|
||||
│ 03c02af Add README, just for the fun │
|
||||
├─────────────────────────────────────────────────────────────────────┤
|
||||
│ ● opened by z6MknSL…StBU8Vi (you) now │
|
||||
│ ↑ updated to bbc91fd4c74bfbbb162ec4b97cd8cefe623814d7 (8945f61) now │
|
||||
╰─────────────────────────────────────────────────────────────────────╯
|
||||
```
|
||||
|
||||
We can change the title and description of the patch itself by using a
|
||||
multi-line message (using two `--message` options here):
|
||||
|
||||
```
|
||||
$ rad patch edit 0631b2d --message "Add Metadata" --message "Add README & LICENSE" --no-announce
|
||||
$ rad patch show 0631b2d
|
||||
╭─────────────────────────────────────────────────────────────────────╮
|
||||
│ Title Add Metadata │
|
||||
│ Patch 0631b2d1b5cd4ae44e92732ff3929528354a8405 │
|
||||
│ Author z6MknSL…StBU8Vi (you) │
|
||||
│ Head 8945f6189adf027892c85ac57f7e9341049c2537 │
|
||||
│ Branches changes │
|
||||
│ Commits ahead 2, behind 0 │
|
||||
│ Status open │
|
||||
│ │
|
||||
│ Add README & LICENSE │
|
||||
├─────────────────────────────────────────────────────────────────────┤
|
||||
│ 8945f61 Define the LICENSE │
|
||||
│ 03c02af Add README, just for the fun │
|
||||
├─────────────────────────────────────────────────────────────────────┤
|
||||
│ ● opened by z6MknSL…StBU8Vi (you) now │
|
||||
│ ↑ updated to bbc91fd4c74bfbbb162ec4b97cd8cefe623814d7 (8945f61) now │
|
||||
╰─────────────────────────────────────────────────────────────────────╯
|
||||
```
|
||||
|
||||
Notice that the `Title` is now `Add Metadata`, and the patch now has a
|
||||
description `Add README & LICENSE`.
|
||||
|
||||
If we want to change a specific revision's description, we can use the
|
||||
`--revision` option:
|
||||
|
||||
```
|
||||
$ rad patch edit 0631b2d --revision bbc91fd --message "Changes: Adds LICENSE file" --no-announce
|
||||
$ rad patch show 0631b2d
|
||||
╭─────────────────────────────────────────────────────────────────────╮
|
||||
│ Title Add Metadata │
|
||||
│ Patch 0631b2d1b5cd4ae44e92732ff3929528354a8405 │
|
||||
│ Author z6MknSL…StBU8Vi (you) │
|
||||
│ Head 8945f6189adf027892c85ac57f7e9341049c2537 │
|
||||
│ Branches changes │
|
||||
│ Commits ahead 2, behind 0 │
|
||||
│ Status open │
|
||||
│ │
|
||||
│ Add README & LICENSE │
|
||||
├─────────────────────────────────────────────────────────────────────┤
|
||||
│ 8945f61 Define the LICENSE │
|
||||
│ 03c02af Add README, just for the fun │
|
||||
├─────────────────────────────────────────────────────────────────────┤
|
||||
│ ● opened by z6MknSL…StBU8Vi (you) now │
|
||||
│ ↑ updated to bbc91fd4c74bfbbb162ec4b97cd8cefe623814d7 (8945f61) now │
|
||||
╰─────────────────────────────────────────────────────────────────────╯
|
||||
```
|
||||
|
||||
We can see that this didn't affect the patch's description, but
|
||||
currently there's no way of seeing a revision's description in the
|
||||
CLI.
|
||||
|
|
@ -256,6 +256,7 @@ pub enum Operation {
|
|||
},
|
||||
Edit {
|
||||
patch_id: Rev,
|
||||
revision_id: Option<Rev>,
|
||||
message: Message,
|
||||
},
|
||||
Redact {
|
||||
|
|
@ -372,6 +373,14 @@ impl Args for Options {
|
|||
reply_to = Some(rev);
|
||||
}
|
||||
|
||||
// Edit options.
|
||||
Long("revision") | Short('r') if op == Some(OperationName::Edit) => {
|
||||
let val = parser.value()?;
|
||||
let rev = term::args::rev(&val)?;
|
||||
|
||||
revision_id = Some(rev);
|
||||
}
|
||||
|
||||
// Review/diff options.
|
||||
Long("revision") | Short('r')
|
||||
if op == Some(OperationName::Review) || op == Some(OperationName::Diff) =>
|
||||
|
|
@ -611,6 +620,7 @@ impl Args for Options {
|
|||
},
|
||||
OperationName::Edit => Operation::Edit {
|
||||
patch_id: patch_id.ok_or_else(|| anyhow!("a patch must be provided"))?,
|
||||
revision_id,
|
||||
message,
|
||||
},
|
||||
OperationName::Redact => Operation::Redact {
|
||||
|
|
@ -763,9 +773,17 @@ pub fn run(options: Options, ctx: impl term::Context) -> anyhow::Result<()> {
|
|||
.map(patch::RevisionId::from);
|
||||
review::run(patch_id, revision_id, opts, &profile, &repository)?;
|
||||
}
|
||||
Operation::Edit { patch_id, message } => {
|
||||
Operation::Edit {
|
||||
patch_id,
|
||||
revision_id,
|
||||
message,
|
||||
} => {
|
||||
let patch_id = patch_id.resolve(&repository.backend)?;
|
||||
edit::run(&patch_id, message, &profile, &repository)?;
|
||||
let revision_id = revision_id
|
||||
.map(|id| id.resolve::<radicle::git::Oid>(&repository.backend))
|
||||
.transpose()?
|
||||
.map(patch::RevisionId::from);
|
||||
edit::run(&patch_id, revision_id, message, &profile, &repository)?;
|
||||
}
|
||||
Operation::Redact { revision_id } => {
|
||||
redact::run(&revision_id, &profile, &repository)?;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
use super::*;
|
||||
|
||||
use radicle::cob::{patch, resolve_embed};
|
||||
use radicle::crypto;
|
||||
use radicle::prelude::*;
|
||||
use radicle::storage::git::Repository;
|
||||
|
||||
|
|
@ -8,18 +9,35 @@ use crate::terminal as term;
|
|||
|
||||
pub fn run(
|
||||
patch_id: &PatchId,
|
||||
revision_id: Option<patch::RevisionId>,
|
||||
message: term::patch::Message,
|
||||
profile: &Profile,
|
||||
repository: &Repository,
|
||||
) -> anyhow::Result<()> {
|
||||
let signer = term::signer(profile)?;
|
||||
let mut patches = patch::Patches::open(repository)?;
|
||||
let Ok(mut patch) = patches.get_mut(patch_id) else {
|
||||
let Ok(patch) = patches.get_mut(patch_id) else {
|
||||
anyhow::bail!("Patch `{patch_id}` not found");
|
||||
};
|
||||
|
||||
let (title, description) = term::patch::get_edit_message(message, &patch)?;
|
||||
|
||||
match revision_id {
|
||||
Some(id) => edit_revision(patch, id, title, description, repository, &signer),
|
||||
None => edit_root(patch, title, description, repository, &signer),
|
||||
}
|
||||
}
|
||||
|
||||
fn edit_root<G>(
|
||||
mut patch: patch::PatchMut<'_, '_, Repository>,
|
||||
title: String,
|
||||
description: String,
|
||||
repository: &Repository,
|
||||
signer: &G,
|
||||
) -> anyhow::Result<()>
|
||||
where
|
||||
G: crypto::Signer,
|
||||
{
|
||||
let title = if title != patch.title() {
|
||||
Some(title)
|
||||
} else {
|
||||
|
|
@ -44,7 +62,7 @@ pub fn run(
|
|||
.filter_map(|embed| resolve_embed(repository, embed.clone()))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
patch.transaction("Edit", &signer, |tx| {
|
||||
patch.transaction("Edit root", signer, |tx| {
|
||||
if let Some(t) = title {
|
||||
tx.edit(t, target)?;
|
||||
}
|
||||
|
|
@ -56,3 +74,33 @@ pub fn run(
|
|||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn edit_revision<G>(
|
||||
mut patch: patch::PatchMut<'_, '_, Repository>,
|
||||
revision: patch::RevisionId,
|
||||
mut title: String,
|
||||
description: String,
|
||||
repository: &Repository,
|
||||
signer: &G,
|
||||
) -> anyhow::Result<()>
|
||||
where
|
||||
G: crypto::Signer,
|
||||
{
|
||||
let embeds = patch
|
||||
.embeds()
|
||||
.iter()
|
||||
.filter_map(|embed| resolve_embed(repository, embed.clone()))
|
||||
.collect::<Vec<_>>();
|
||||
let description = if description.is_empty() {
|
||||
title
|
||||
} else {
|
||||
title.push('\n');
|
||||
title.push_str(&description);
|
||||
title
|
||||
};
|
||||
patch.transaction("Edit revision", signer, |tx| {
|
||||
tx.edit_revision(revision, description, embeds)?;
|
||||
Ok(())
|
||||
})?;
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -496,6 +496,20 @@ fn rad_patch_diff() {
|
|||
test("examples/rad-patch-diff.md", working.path(), Some(home), []).unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rad_patch_edit() {
|
||||
let mut environment = Environment::new();
|
||||
let profile = environment.profile(config::profile("alice"));
|
||||
let working = tempfile::tempdir().unwrap();
|
||||
let home = &profile.home;
|
||||
|
||||
// Setup a test repository.
|
||||
fixtures::repository(working.path());
|
||||
|
||||
test("examples/rad-init.md", working.path(), Some(home), []).unwrap();
|
||||
test("examples/rad-patch-edit.md", working.path(), Some(home), []).unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rad_patch_checkout() {
|
||||
let mut environment = Environment::new();
|
||||
|
|
|
|||
Loading…
Reference in New Issue