From b57099a0d000a5249495fb5c93b50a5649a78c84 Mon Sep 17 00:00:00 2001 From: Fintan Halpenny Date: Mon, 8 Jan 2024 14:23:57 +0000 Subject: [PATCH] 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 X-Clacks-Overhead: GNU Terry Pratchett --- radicle-cli/examples/rad-patch-edit.md | 116 +++++++++++++++++++++++++ radicle-cli/src/commands/patch.rs | 22 ++++- radicle-cli/src/commands/patch/edit.rs | 52 ++++++++++- radicle-cli/tests/commands.rs | 14 +++ 4 files changed, 200 insertions(+), 4 deletions(-) create mode 100644 radicle-cli/examples/rad-patch-edit.md diff --git a/radicle-cli/examples/rad-patch-edit.md b/radicle-cli/examples/rad-patch-edit.md new file mode 100644 index 00000000..e1b99be7 --- /dev/null +++ b/radicle-cli/examples/rad-patch-edit.md @@ -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. diff --git a/radicle-cli/src/commands/patch.rs b/radicle-cli/src/commands/patch.rs index 927947a5..ffed2b54 100644 --- a/radicle-cli/src/commands/patch.rs +++ b/radicle-cli/src/commands/patch.rs @@ -256,6 +256,7 @@ pub enum Operation { }, Edit { patch_id: Rev, + revision_id: Option, 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::(&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)?; diff --git a/radicle-cli/src/commands/patch/edit.rs b/radicle-cli/src/commands/patch/edit.rs index e033f935..3bd660e7 100644 --- a/radicle-cli/src/commands/patch/edit.rs +++ b/radicle-cli/src/commands/patch/edit.rs @@ -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, 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( + 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::>(); - 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( + 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::>(); + 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(()) +} diff --git a/radicle-cli/tests/commands.rs b/radicle-cli/tests/commands.rs index 8b95f558..f2b530a4 100644 --- a/radicle-cli/tests/commands.rs +++ b/radicle-cli/tests/commands.rs @@ -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();