cli: Improve patch command output

* Fix timeline ordering
* Remove spinner noise
* Add revisions to timeline
This commit is contained in:
Alexis Sellier 2023-03-23 15:24:33 +01:00 committed by Alexis Sellier
parent 40eb6f2a6e
commit 8dba01d6ae
No known key found for this signature in database
9 changed files with 131 additions and 165 deletions

View File

@ -26,11 +26,8 @@ Once the code is ready, we open (or create) a patch with our changes for the pro
``` ```
$ rad patch open --message "Define power requirements" --message "See details." $ rad patch open --message "Define power requirements" --message "See details."
✓ Pushing HEAD to storage...
✓ Analyzing remotes...
master <- z6MknSLStBU8Vi/flux-capacitor-power (3e674d1) master <- z6MknSLStBU8Vi/flux-capacitor-power (3e674d1)
1 commit(s) ahead, 0 commit(s) behind 1 commit(s) ahead, 0 commit(s) behind
3e674d1 Define power requirements 3e674d1 Define power requirements
@ -46,11 +43,11 @@ It will now be listed as one of the project's open patches.
``` ```
$ rad patch $ rad patch
╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── ╭─────────────────────────────────────────────────────────────────────────────────────────╮
│ Define power requirements 191a14e520f2eeff7c0e3ee0a5523c5217eecb89 R0 3e674d1 (flux-capacitor-power) ahead 1, behind 0 │ │ Define power requirements 191a14e R0 3e674d1 (flux-capacitor-power) ahead 1, behind 0
├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── ├─────────────────────────────────────────────────────────────────────────────────────────┤
│ ● opened by did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi (you) 3 months ago │ ● opened by did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi (you) 3 months ago │
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── ╰─────────────────────────────────────────────────────────────────────────────────────────╯
``` ```
``` ```
$ rad patch show 191a14e520f2eeff7c0e3ee0a5523c5217eecb89 $ rad patch show 191a14e520f2eeff7c0e3ee0a5523c5217eecb89
@ -85,18 +82,10 @@ $ git commit --message "Add README, just for the fun"
1 file changed, 0 insertions(+), 0 deletions(-) 1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 README.md create mode 100644 README.md
$ rad patch update --message "Add README, just for the fun" 191a14e520f2eeff7c0e3ee0a5523c5217eecb89 $ rad patch update --message "Add README, just for the fun" 191a14e520f2eeff7c0e3ee0a5523c5217eecb89
191a14e R0 (3e674d1) -> R1 (27857ec)
🌱 Updating patch for heartwood
✓ Pushing HEAD to storage...
✓ Analyzing remotes...
191a14e520f R0 (3e674d1) -> R1 (27857ec)
1 commit(s) ahead, 0 commit(s) behind 1 commit(s) ahead, 0 commit(s) behind
✓ Patch 191a14e updated to 56a5efc062b34a97a162a3a4d4468ce3e7ba1c84
✓ Patch 191a14e520f2eeff7c0e3ee0a5523c5217eecb89 updated 🌱
``` ```
And let's leave a quick comment for our team: And let's leave a quick comment for our team:
@ -112,24 +101,25 @@ Now, let's checkout the patch that we just created:
``` ```
$ rad patch checkout 191a14e52 $ rad patch checkout 191a14e52
✓ Switched to branch patch/191a14e520f ✓ Switched to branch patch/191a14e
``` ```
We can also add a review verdict as such: We can also add a review verdict as such:
``` ```
$ rad review 191a14e520f2eeff7c0e3ee0a5523c5217eecb89 --accept --no-confirm --no-message --no-sync $ rad review 191a14e520f2eeff7c0e3ee0a5523c5217eecb89 --accept --no-confirm --no-message --no-sync
✓ Patch 191a14e520f accepted ✓ Patch 191a14e accepted
``` ```
Showing the patch list now will reveal the favorable verdict: Showing the patch list now will reveal the favorable verdict:
``` ```
$ rad patch $ rad patch
╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ Define power requirements 191a14e520f2eeff7c0e3ee0a5523c5217eecb89 R1 27857ec (flux-capacitor-power, patch/191a14e520f) ahead 2, behind 0 │ │ Define power requirements 191a14e R1 27857ec (flux-capacitor-power, patch/191a14e) ahead 2, behind 0 │
├───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ ├──────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ ● opened by did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi (you) 3 months ago │ │ ● opened by did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi (you) 3 months ago │
│ ✓ accepted by z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi (you) 3 months ago │ │ ↑ updated to 191a14e520f2eeff7c0e3ee0a5523c5217eecb89 (3e674d1) 3 months ago │
╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │ ✓ accepted by z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi (you) 3 months ago │
╰──────────────────────────────────────────────────────────────────────────────────────────────────────╯
``` ```

View File

@ -26,11 +26,8 @@ Once the code is ready, we open a patch with our changes.
``` ```
$ rad patch open --message "Define power requirements" --message "See details." $ rad patch open --message "Define power requirements" --message "See details."
✓ Pushing HEAD to storage...
✓ Analyzing remotes...
master <- z6Mkt67v4N1tRk/flux-capacitor-power (3e674d1) master <- z6Mkt67v4N1tRk/flux-capacitor-power (3e674d1)
1 commit(s) ahead, 0 commit(s) behind 1 commit(s) ahead, 0 commit(s) behind
3e674d1 Define power requirements 3e674d1 Define power requirements
@ -46,11 +43,11 @@ It will now be listed as one of the project's open patches.
``` ```
$ rad patch $ rad patch
╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── ╭─────────────────────────────────────────────────────────────────────────────────────────╮
│ Define power requirements a07ef7743a32a2e902672ea3526d1db6ee08108a R0 3e674d1 (flux-capacitor-power) ahead 1, behind 0 │ │ Define power requirements a07ef77 R0 3e674d1 (flux-capacitor-power) ahead 1, behind 0
├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── ├─────────────────────────────────────────────────────────────────────────────────────────┤
│ ● opened by did:key:z6Mkt67GdsW7715MEfRuP4pSZxJRJh6kj6Y48WRqVv4N1tRk (you) 3 months ago │ ● opened by did:key:z6Mkt67GdsW7715MEfRuP4pSZxJRJh6kj6Y48WRqVv4N1tRk (you) 3 months ago │
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── ╰─────────────────────────────────────────────────────────────────────────────────────────╯
$ rad patch show a07ef7743a32a2e902672ea3526d1db6ee08108a $ rad patch show a07ef7743a32a2e902672ea3526d1db6ee08108a
╭────────────────────────────────────────────────────────────────────╮ ╭────────────────────────────────────────────────────────────────────╮
│ Title Define power requirements │ │ Title Define power requirements │
@ -83,18 +80,10 @@ $ git commit --message "Add README, just for the fun"
1 file changed, 0 insertions(+), 0 deletions(-) 1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 README.md create mode 100644 README.md
$ rad patch update --message "Add README, just for the fun" a07ef7743a32a2e902672ea3526d1db6ee08108a $ rad patch update --message "Add README, just for the fun" a07ef7743a32a2e902672ea3526d1db6ee08108a
a07ef77 R0 (3e674d1) -> R1 (27857ec)
🌱 Updating patch for heartwood
✓ Pushing HEAD to storage...
✓ Analyzing remotes...
a07ef7743a3 R0 (3e674d1) -> R1 (27857ec)
1 commit(s) ahead, 0 commit(s) behind 1 commit(s) ahead, 0 commit(s) behind
✓ Patch a07ef77 updated to 4f15eb5c994edd0bb6be29cb4801aa74308cc628
✓ Patch a07ef7743a32a2e902672ea3526d1db6ee08108a updated 🌱
``` ```
And let's leave a quick comment for our team: And let's leave a quick comment for our team:

View File

@ -27,11 +27,12 @@ $ git branch -r
bob/master bob/master
rad/master rad/master
$ rad patch $ rad patch
╭─────────────────────────────────────────────────────────────────────────────────────────────────╮ ╭───────────────────────────────────────────────────────────────────────────────────╮
│ Define power requirements a07ef7743a32a2e902672ea3526d1db6ee08108a R1 27857ec ahead 2, behind 0 │ │ Define power requirements a07ef77 R1 27857ec ahead 2, behind 0 │
├─────────────────────────────────────────────────────────────────────────────────────────────────┤ ├───────────────────────────────────────────────────────────────────────────────────┤
│ ● opened by did:key:z6Mkt67GdsW7715MEfRuP4pSZxJRJh6kj6Y48WRqVv4N1tRk 3 months ago │ │ ● opened by did:key:z6Mkt67GdsW7715MEfRuP4pSZxJRJh6kj6Y48WRqVv4N1tRk 3 months ago │
╰─────────────────────────────────────────────────────────────────────────────────────────────────╯ │ ↑ updated to a07ef7743a32a2e902672ea3526d1db6ee08108a (3e674d1) 3 months ago │
╰───────────────────────────────────────────────────────────────────────────────────╯
``` ```
Wait! There's a mistake. The REQUIREMENTS should be a markdown file. Let's Wait! There's a mistake. The REQUIREMENTS should be a markdown file. Let's
@ -48,16 +49,8 @@ $ git commit --fixup HEAD~
1 file changed, 0 insertions(+), 0 deletions(-) 1 file changed, 0 insertions(+), 0 deletions(-)
rename REQUIREMENTS => REQUIREMENTS.md (100%) rename REQUIREMENTS => REQUIREMENTS.md (100%)
$ rad patch update --message "Define power requirements" --message "See details." a07ef7743a32a2e902672ea3526d1db6ee08108a $ rad patch update --message "Define power requirements" --message "See details." a07ef7743a32a2e902672ea3526d1db6ee08108a
a07ef77 R1 (27857ec) -> R2 (f6484e0)
🌱 Updating patch for heartwood
✓ Pushing HEAD to storage...
✓ Analyzing remotes...
a07ef7743a3 R1 (27857ec) -> R2 (f6484e0)
1 commit(s) ahead, 0 commit(s) behind 1 commit(s) ahead, 0 commit(s) behind
✓ Patch a07ef77 updated to 737dc47d9eba730c5db8a8e33c41c7955f9093de
✓ Patch a07ef7743a32a2e902672ea3526d1db6ee08108a updated 🌱
``` ```

View File

@ -195,12 +195,11 @@ pub fn run(options: Options, ctx: impl term::Context) -> anyhow::Result<()> {
} }
MergeStyle::Commit MergeStyle::Commit
} else if merge.is_up_to_date() { } else if merge.is_up_to_date() {
term::info!( term::success!(
"Patch {} is already part of {}", "Patch {} is already part of current branch {}",
term::format::tertiary(patch_id), term::format::tertiary(patch_id),
term::format::highlight(branch) term::format::parens(term::format::yellow(branch))
); );
return Ok(()); return Ok(());
} else if merge.is_unborn() { } else if merge.is_unborn() {
anyhow::bail!("HEAD does not point to a valid commit"); anyhow::bail!("HEAD does not point to a valid commit");
@ -223,14 +222,14 @@ pub fn run(options: Options, ctx: impl term::Context) -> anyhow::Result<()> {
}; };
term::info!( term::info!(
"{} {} {} ({}) by {} into {} ({}) via {}...", "{} {} {} {} by {} into {} {} via {}...",
term::format::bold("Merging"), term::format::bold("Merging"),
term::format::tertiary(term::format::cob(&patch_id)), term::format::tertiary(term::format::cob(&patch_id)),
term::format::dim(format!("R{revision_ix}")), term::format::dim(format!("R{revision_ix}")),
term::format::secondary(term::format::oid(revision.oid)), term::format::parens(term::format::secondary(term::format::oid(revision.oid))),
term::format::tertiary(patch.author().id), term::format::tertiary(patch.author().id),
term::format::highlight(branch), term::format::highlight(branch),
term::format::secondary(term::format::oid(head_oid)), term::format::parens(term::format::secondary(term::format::oid(head_oid))),
merge_style_pretty merge_style_pretty
); );

View File

@ -43,7 +43,6 @@ pub fn get_merge_target(
storage: &Repository, storage: &Repository,
head_branch: &git::raw::Branch, head_branch: &git::raw::Branch,
) -> anyhow::Result<(git::RefString, git::Oid)> { ) -> anyhow::Result<(git::RefString, git::Oid)> {
let spinner = term::spinner("Analyzing remotes...");
let (qualified_ref, target_oid) = storage.canonical_head()?; let (qualified_ref, target_oid) = storage.canonical_head()?;
let head_oid = branch_oid(head_branch)?; let head_oid = branch_oid(head_branch)?;
let merge_base = storage.raw().merge_base(*head_oid, *target_oid)?; let merge_base = storage.raw().merge_base(*head_oid, *target_oid)?;
@ -52,11 +51,7 @@ pub fn get_merge_target(
anyhow::bail!("commits are already included in the target branch; nothing to do"); anyhow::bail!("commits are already included in the target branch; nothing to do");
} }
// TODO: Tell user how many peers don't have this change. Ok((get_branch(qualified_ref), (*target_oid).into()))
spinner.finish();
let branch = get_branch(qualified_ref);
Ok((branch, (*target_oid).into()))
} }
/// Return the [`Oid`] of the merge target. /// Return the [`Oid`] of the merge target.
@ -146,13 +141,8 @@ pub fn push_to_storage(
options: &Options, options: &Options,
) -> anyhow::Result<()> { ) -> anyhow::Result<()> {
let head_oid = branch_oid(head_branch)?; let head_oid = branch_oid(head_branch)?;
let mut spinner = term::spinner(format!(
"Looking for HEAD ({}) in storage...",
term::format::secondary(term::format::oid(head_oid))
));
if storage.commit(head_oid).is_err() { if storage.commit(head_oid).is_err() {
if !options.push { if !options.push {
spinner.failed();
term::blank(); term::blank();
return Err(Error::WithHint { return Err(Error::WithHint {
@ -161,7 +151,6 @@ pub fn push_to_storage(
} }
.into()); .into());
} }
spinner.message("Pushing HEAD to storage...");
let output = match head_branch.upstream() { let output = match head_branch.upstream() {
Ok(_) => git::run::<_, _, &str, &str>(Path::new("."), ["push", "rad"], [])?, Ok(_) => git::run::<_, _, &str, &str>(Path::new("."), ["push", "rad"], [])?,
@ -172,14 +161,11 @@ pub fn push_to_storage(
)?, )?,
}; };
if options.verbose { if options.verbose {
spinner.finish();
term::blob(output); term::blob(output);
return Ok(()); return Ok(());
} }
} }
spinner.finish();
Ok(()) Ok(())
} }

View File

@ -66,7 +66,6 @@ fn show_patch_commit_info(
term::format::highlight(branch_name(head_branch)?), term::format::highlight(branch_name(head_branch)?),
term::format::secondary(term::format::oid(head_oid)), term::format::secondary(term::format::oid(head_oid)),
); );
term::blank();
// TODO: Test case where the target branch has been re-written passed the merge-base, since the fork was created // TODO: Test case where the target branch has been re-written passed the merge-base, since the fork was created
// This can also happen *after* the patch is created. // This can also happen *after* the patch is created.

View File

@ -75,14 +75,14 @@ fn print(
&patch.timestamp(), &patch.timestamp(),
))); )));
let (_, revision) = patch let (latest, revision) = patch
.latest() .latest()
.ok_or_else(|| anyhow!("patch is malformed: no revisions found"))?; .ok_or_else(|| anyhow!("patch is malformed: no revisions found"))?;
let mut widget = term::VStack::default() let mut widget = term::VStack::default()
.child( .child(
term::Line::spaced([ term::Line::spaced([
term::format::bold(patch.title()).into(), term::format::bold(patch.title()).into(),
term::format::highlight(patch_id).into(), term::format::highlight(term::format::cob(patch_id)).into(),
term::format::dim(format!("R{}", patch.version())).into(), term::format::dim(format!("R{}", patch.version())).into(),
]) ])
.space() .space()
@ -99,62 +99,84 @@ fn print(
.border(Some(term::colors::FAINT)); .border(Some(term::colors::FAINT));
let mut timeline = Vec::new(); let mut timeline = Vec::new();
for merge in revision.merges.iter() { for (revision_id, revision) in patch.revisions() {
let peer = repository.remote(&merge.node)?; // Don't show an "update" line for the first revision.
let mut badges = Vec::new(); if revision_id != latest {
timeline.push((
if peer.delegate { revision.timestamp,
badges.push(term::format::secondary("(delegate)").into()); term::Line::spaced(
} [
if peer.id == *whoami { term::format::tertiary("").into(),
badges.push(term::format::primary("(you)").into()); term::format::default("updated to").into(),
term::format::dim(revision_id).into(),
term::format::parens(term::format::secondary(term::format::oid(
revision.oid,
)))
.into(),
]
.into_iter(),
),
));
} }
timeline.push(( for merge in revision.merges.iter() {
merge.timestamp, let peer = repository.remote(&merge.node)?;
term::Line::spaced( let mut badges = Vec::new();
[
term::format::secondary(term::format::dim("✓ merged")).into(),
term::format::default("by").into(),
term::format::tertiary(peer.id).into(),
]
.into_iter()
.chain(badges),
),
));
}
for (reviewer, review) in revision.reviews.iter() {
let verdict = match review.verdict() {
Some(Verdict::Accept) => term::format::positive(term::format::dim("✓ accepted")),
Some(Verdict::Reject) => term::format::negative(term::format::dim("✗ rejected")),
None => term::format::negative(term::format::dim("⋄ reviewed")),
};
let peer = repository.remote(reviewer)?;
let mut badges = Vec::new();
if peer.delegate { if peer.delegate {
badges.push(term::format::secondary("(delegate)").into()); badges.push(term::format::secondary("(delegate)").into());
} }
if peer.id == *whoami { if peer.id == *whoami {
badges.push(term::format::primary("(you)").into()); badges.push(term::format::primary("(you)").into());
} }
timeline.push(( timeline.push((
review.timestamp(), merge.timestamp,
term::Line::spaced( term::Line::spaced(
[ [
verdict.into(), term::format::primary("").bold().into(),
term::format::default("by").into(), term::format::default("merged").into(),
term::format::tertiary(reviewer).into(), term::format::default("by").into(),
] term::format::tertiary(Did::from(peer.id)).into(),
.into_iter() ]
.chain(badges), .into_iter()
), .chain(badges),
)); ),
));
}
for (reviewer, review) in revision.reviews.iter() {
let verdict = match review.verdict() {
Some(Verdict::Accept) => term::format::positive(term::format::dim("✓ accepted")),
Some(Verdict::Reject) => term::format::negative(term::format::dim("✗ rejected")),
None => term::format::negative(term::format::dim("⋄ reviewed")),
};
let peer = repository.remote(reviewer)?;
let mut badges = Vec::new();
if peer.delegate {
badges.push(term::format::secondary("(delegate)").into());
}
if peer.id == *whoami {
badges.push(term::format::primary("(you)").into());
}
timeline.push((
review.timestamp(),
term::Line::spaced(
[
verdict.into(),
term::format::default("by").into(),
term::format::tertiary(reviewer).into(),
]
.into_iter()
.chain(badges),
),
));
}
} }
timeline.sort_by_key(|(t, _)| *t); timeline.sort_by_key(|(t, _)| *t);
for (time, mut line) in timeline.into_iter().rev() { for (time, mut line) in timeline.into_iter() {
line.push(term::Label::space()); line.push(term::Label::space());
line.push(term::format::dim(term::format::timestamp(&time))); line.push(term::format::dim(term::format::timestamp(&time)));
widget.push(line); widget.push(line);

View File

@ -1,5 +1,3 @@
use anyhow::Context;
use radicle::cob::patch; use radicle::cob::patch;
use radicle::git; use radicle::git;
use radicle::prelude::*; use radicle::prelude::*;
@ -11,7 +9,7 @@ use crate::terminal as term;
const REVISION_MSG: &str = r#" const REVISION_MSG: &str = r#"
<!-- <!--
Please enter a comment message for your patch update. Leaving this Please enter a comment for your patch update. Leaving this
blank is also okay. blank is also okay.
--> -->
"#; "#;
@ -26,27 +24,18 @@ fn select_patch(
let head_oid = branch_oid(head_branch)?; let head_oid = branch_oid(head_branch)?;
let base_oid = workdir.merge_base(*target_oid, *head_oid)?; let base_oid = workdir.merge_base(*target_oid, *head_oid)?;
let mut spinner = term::spinner("Finding patches to update...");
let mut result = let mut result =
find_unmerged_with_base(*head_oid, *target_oid, base_oid, patches, workdir, whoami)?; find_unmerged_with_base(*head_oid, *target_oid, base_oid, patches, workdir, whoami)?;
let Some((id, patch, _)) = result.pop() else { let Some((id, _, _)) = result.pop() else {
spinner.failed();
term::blank(); term::blank();
anyhow::bail!("No patches found that share a base, please create a new patch or specify the patch id manually"); anyhow::bail!("No patches found to update, please open a new patch or specify the patch id manually");
}; };
if !result.is_empty() { if !result.is_empty() {
spinner.failed();
term::blank(); term::blank();
anyhow::bail!("More than one patch available to update, please specify an id with `rad patch --update <id>`"); anyhow::bail!("More than one patch available to update, please specify an id with `rad patch --update <id>`");
} }
spinner.message(format!(
"Found existing patch {} {}",
term::format::tertiary(term::format::cob(&id)),
term::format::italic(patch.title())
));
spinner.finish();
term::blank(); term::blank();
Ok(id) Ok(id)
@ -63,20 +52,20 @@ fn show_update_commit_info(
let current_version = patch.version(); let current_version = patch.version();
let head_oid = branch_oid(head_branch)?; let head_oid = branch_oid(head_branch)?;
term::blank();
term::info!( term::info!(
"{} {} ({}) -> {} ({})", "{} {} {} -> {} {}",
term::format::tertiary(term::format::cob(patch_id)), term::format::tertiary(term::format::cob(patch_id)),
term::format::dim(format!("R{current_version}")), term::format::dim(format!("R{current_version}")),
term::format::secondary(term::format::oid(current_revision.oid)), term::format::parens(term::format::secondary(term::format::oid(
current_revision.oid
))),
term::format::dim(format!("R{}", current_version + 1)), term::format::dim(format!("R{}", current_version + 1)),
term::format::secondary(term::format::oid(*head_oid)), term::format::parens(term::format::secondary(term::format::oid(*head_oid))),
); );
// Difference between the two revisions. // Difference between the two revisions.
let head_oid = branch_oid(head_branch)?; let head_oid = branch_oid(head_branch)?;
term::patch::print_commits_ahead_behind(workdir, *head_oid, *current_revision.oid)?; term::patch::print_commits_ahead_behind(workdir, *head_oid, *current_revision.oid)?;
term::blank();
Ok(()) Ok(())
} }
@ -90,18 +79,9 @@ pub fn run(
message: term::patch::Message, message: term::patch::Message,
options: &Options, options: &Options,
) -> anyhow::Result<()> { ) -> anyhow::Result<()> {
let project = storage.project_of(&profile.public_key).context(format!(
"couldn't load project {} from local state",
storage.id
))?;
// `HEAD`; This is what we are proposing as a patch. // `HEAD`; This is what we are proposing as a patch.
let head_branch = try_branch(workdir.head()?)?; let head_branch = try_branch(workdir.head()?)?;
term::headline(format!(
"🌱 Updating patch for {}",
term::format::highlight(project.name())
));
push_to_storage(storage, &head_branch, options)?; push_to_storage(storage, &head_branch, options)?;
let (_, target_oid) = get_merge_target(storage, &head_branch)?; let (_, target_oid) = get_merge_target(storage, &head_branch)?;
@ -128,11 +108,14 @@ pub fn run(
let base_oid = workdir.merge_base(*target_oid, *head_oid)?; let base_oid = workdir.merge_base(*target_oid, *head_oid)?;
let message = message.get(REVISION_MSG); let message = message.get(REVISION_MSG);
let signer = term::signer(profile)?; let signer = term::signer(profile)?;
patch.update(message, base_oid, *head_oid, &signer)?; let revision = patch.update(message, base_oid, *head_oid, &signer)?;
term::blank(); term::blank();
term::success!("Patch {} updated 🌱", term::format::highlight(patch_id)); term::success!(
term::blank(); "Patch {} updated to {}",
term::format::highlight(term::format::cob(&patch_id)),
term::format::tertiary(revision),
);
if options.announce { if options.announce {
// TODO // TODO

View File

@ -23,9 +23,14 @@ pub fn oid(oid: impl Into<radicle::git::Oid>) -> String {
format!("{:.7}", oid.into()) format!("{:.7}", oid.into())
} }
/// Wrap parenthesis around styled input, eg. `"input"` -> `"(input)"`.
pub fn parens<D: fmt::Display>(input: Paint<D>) -> Paint<String> {
Paint::new(format!("({})", input.item)).with_style(input.style)
}
/// Format a COB id. /// Format a COB id.
pub fn cob(id: &ObjectId) -> String { pub fn cob(id: &ObjectId) -> String {
format!("{:.11}", id.to_string()) format!("{:.7}", id.to_string())
} }
/// Format a timestamp. /// Format a timestamp.