From f90421a6bb307b720a308b91338ac736d3286ca6 Mon Sep 17 00:00:00 2001 From: Fintan Halpenny Date: Thu, 14 Dec 2023 15:05:28 +0000 Subject: [PATCH] cli: sync on patch and issue updates When we perform updates to cobs we tend to want to sync those changes to the network after. This patch automatically does this for operations that perform updates to issues and patches. Note that `--announce` becomes the default for the `rad patch` command. Signed-off-by: Fintan Halpenny X-Clacks-Overhead: GNU Terry Pratchett --- radicle-cli/examples/rad-issue.md | 10 ++-- radicle-cli/examples/rad-patch-draft.md | 4 +- radicle-cli/examples/rad-patch-update.md | 2 +- radicle-cli/examples/rad-patch.md | 12 ++--- radicle-cli/examples/rad-review-by-hunk.md | 14 ++--- .../workflow/4-patching-contributor.md | 1 + radicle-cli/src/commands/issue.rs | 10 ++-- radicle-cli/src/commands/patch.rs | 31 ++++++++++- radicle-cli/src/lib.rs | 1 + radicle-cli/src/node.rs | 51 +++++++++++++++++++ 10 files changed, 106 insertions(+), 30 deletions(-) create mode 100644 radicle-cli/src/node.rs diff --git a/radicle-cli/examples/rad-issue.md b/radicle-cli/examples/rad-issue.md index dfc6cdb8..3874b377 100644 --- a/radicle-cli/examples/rad-issue.md +++ b/radicle-cli/examples/rad-issue.md @@ -51,8 +51,8 @@ Let's assign ourselves to this one, this is to ensure work is not duplicated. While we're at it, let's add a label. ``` -$ rad issue assign d185ee1 --add did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi -$ rad issue label d185ee1 --add good-first-issue +$ rad issue assign d185ee1 --add did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi --no-announce +$ rad issue label d185ee1 --add good-first-issue --no-announce ``` It will now show in the list of issues assigned to us, along with the new label. @@ -69,7 +69,7 @@ $ rad issue list --assigned Note: this can always be undone with the `unassign` subcommand. ``` -$ rad issue assign d185ee1 --delete did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi +$ rad issue assign d185ee1 --delete did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi --no-announce ``` Great, now we have communicated to the world about our car's defect. @@ -78,9 +78,9 @@ But wait! We've found an important detail about the car's power requirements. It will help whoever works on a fix. ``` -$ rad issue comment d185ee16a00bac874c0bcbc2a8ad80fdce5e1e61 --message 'The flux capacitor needs 1.21 Gigawatts' -q +$ rad issue comment d185ee16a00bac874c0bcbc2a8ad80fdce5e1e61 --message 'The flux capacitor needs 1.21 Gigawatts' -q --no-announce 80ef590710edb64dfa57e8e940d6e4d0b0ae4217 -$ rad issue comment d185ee16a00bac874c0bcbc2a8ad80fdce5e1e61 --reply-to 80ef590710edb64dfa57e8e940d6e4d0b0ae4217 --message 'More power!' -q +$ rad issue comment d185ee16a00bac874c0bcbc2a8ad80fdce5e1e61 --reply-to 80ef590710edb64dfa57e8e940d6e4d0b0ae4217 --message 'More power!' -q --no-announce 91009820ca0996d93b9afd5739a4d2158a2ec898 ``` diff --git a/radicle-cli/examples/rad-patch-draft.md b/radicle-cli/examples/rad-patch-draft.md index 7bf8ad3f..34825114 100644 --- a/radicle-cli/examples/rad-patch-draft.md +++ b/radicle-cli/examples/rad-patch-draft.md @@ -36,7 +36,7 @@ $ rad patch show 193a2540ded82245b49971de8afc89a129502c6d Once the patch is ready for review, we can use the `ready` command: ``` -$ rad patch ready 193a2540ded82245b49971de8afc89a129502c6d +$ rad patch ready 193a2540ded82245b49971de8afc89a129502c6d --no-announce ``` ``` @@ -60,7 +60,7 @@ If for whatever reason, it needed to go back into draft mode, we could use the `--undo` flag: ``` -$ rad patch ready --undo 193a2540ded82245b49971de8afc89a129502c6d +$ rad patch ready --undo 193a2540ded82245b49971de8afc89a129502c6d --no-announce $ rad patch show 193a2540ded82245b49971de8afc89a129502c6d ╭────────────────────────────────────────────────────╮ │ Title Nothing yet │ diff --git a/radicle-cli/examples/rad-patch-update.md b/radicle-cli/examples/rad-patch-update.md index c5f60622..849d212b 100644 --- a/radicle-cli/examples/rad-patch-update.md +++ b/radicle-cli/examples/rad-patch-update.md @@ -46,7 +46,7 @@ Now, instead of using `git push` to update the patch, as we normally would, we run: ``` -$ rad patch update 8f5dcedc07a89928fd450bce1479f2559bcfd1d4 -m "Updated patch" +$ rad patch update 8f5dcedc07a89928fd450bce1479f2559bcfd1d4 -m "Updated patch" --no-announce 74d453f93d81bb535ffa4ef65c46e5bd0a76015d ``` diff --git a/radicle-cli/examples/rad-patch.md b/radicle-cli/examples/rad-patch.md index 64223e82..6388fc21 100644 --- a/radicle-cli/examples/rad-patch.md +++ b/radicle-cli/examples/rad-patch.md @@ -93,8 +93,8 @@ We can also label patches as well as assign DIDs to the patch to help organise your workflow: ``` -$ rad patch label 6ff4f09 --add fun -$ rad patch assign 6ff4f09 --add did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi +$ rad patch label 6ff4f09 --add fun --no-announce +$ rad patch assign 6ff4f09 --add did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi --no-announce $ rad patch show 6ff4f09 ╭────────────────────────────────────────────────────╮ │ Title Define power requirements │ @@ -134,12 +134,12 @@ To rad://z42hL2jL4XNk6K8oHQaSWfMgCL7ji/z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkE And let's leave a quick comment for our team: ``` -$ rad patch comment 6ff4f09 --message 'I cannot wait to get back to the 90s!' +$ rad patch comment 6ff4f09 --message 'I cannot wait to get back to the 90s!' --no-announce ╭───────────────────────────────────────╮ │ z6MknSL…StBU8Vi (you) now f5b4613 │ │ I cannot wait to get back to the 90s! │ ╰───────────────────────────────────────╯ -$ rad patch comment 6ff4f09 --message 'My favorite decade!' --reply-to f5b4613 -q +$ rad patch comment 6ff4f09 --message 'My favorite decade!' --reply-to f5b4613 -q --no-announce 611df66ccb3803b604a59f2efa9a42d72256dd49 ``` @@ -154,7 +154,7 @@ $ rad patch checkout 6ff4f09 We can also add a review verdict as such: ``` -$ rad patch review 6ff4f09 --accept --no-message +$ rad patch review 6ff4f09 --accept --no-message --no-announce ✓ Patch 6ff4f09 accepted ``` @@ -186,7 +186,7 @@ $ rad patch show 6ff4f09 If you make a mistake on the patch description, you can always change it! ``` -$ rad patch edit 6ff4f09 --message "Define power requirements" --message "Add requirements file" +$ rad patch edit 6ff4f09 --message "Define power requirements" --message "Add requirements file" --no-announce $ rad patch show 6ff4f09 ╭─────────────────────────────────────────────────────────────────────╮ │ Title Define power requirements │ diff --git a/radicle-cli/examples/rad-review-by-hunk.md b/radicle-cli/examples/rad-review-by-hunk.md index 53117104..f1ed8710 100644 --- a/radicle-cli/examples/rad-review-by-hunk.md +++ b/radicle-cli/examples/rad-review-by-hunk.md @@ -70,7 +70,7 @@ Finally, we do a review of the patch by hunk. The output of this command should match `git diff master -W100% -U5 --patience`: ``` -$ rad patch review --patch -U5 52da8356aa9beec08e6943cb3c4063fa37f3241b +$ rad patch review --patch -U5 52da8356aa9beec08e6943cb3c4063fa37f3241b --no-announce diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 7937fb3..0000000 @@ -116,7 +116,7 @@ rename to notes/INSTRUCTIONS.txt Now let's accept these hunks one by one.. ``` -$ rad patch review --patch --accept --hunk 1 52da8356aa9beec08e6943cb3c4063fa37f3241b +$ rad patch review --patch --accept --hunk 1 52da8356aa9beec08e6943cb3c4063fa37f3241b --no-announce ✓ Loaded existing review ([..]) for patch 52da8356aa9beec08e6943cb3c4063fa37f3241b diff --git a/.gitignore b/.gitignore deleted file mode 100644 @@ -127,7 +127,7 @@ index 7937fb3..0000000 -*.draft ``` ``` -$ rad patch review --patch --accept --hunk 1 52da8356aa9beec08e6943cb3c4063fa37f3241b +$ rad patch review --patch --accept --hunk 1 52da8356aa9beec08e6943cb3c4063fa37f3241b --no-announce ✓ Loaded existing review ([..]) for patch 52da8356aa9beec08e6943cb3c4063fa37f3241b diff --git a/DISCLAIMER.txt b/DISCLAIMER.txt new file mode 100644 @@ -138,7 +138,7 @@ index 0000000..2b5bd86 +All food is served as-is, with no warranty! ``` ``` -$ rad patch review --patch --accept -U3 --hunk 1 52da8356aa9beec08e6943cb3c4063fa37f3241b +$ rad patch review --patch --accept -U3 --hunk 1 52da8356aa9beec08e6943cb3c4063fa37f3241b --no-announce ✓ Loaded existing review ([..]) for patch 52da8356aa9beec08e6943cb3c4063fa37f3241b diff --git a/MENU.txt b/MENU.txt index 867958c..3af9741 100644 @@ -153,7 +153,7 @@ index 867958c..3af9741 100644 [..] ``` ``` -$ rad patch review --patch --accept -U3 --hunk 1 52da8356aa9beec08e6943cb3c4063fa37f3241b +$ rad patch review --patch --accept -U3 --hunk 1 52da8356aa9beec08e6943cb3c4063fa37f3241b --no-announce ✓ Loaded existing review ([..]) for patch 52da8356aa9beec08e6943cb3c4063fa37f3241b diff --git a/MENU.txt b/MENU.txt index 4e2e828..3af9741 100644 @@ -169,7 +169,7 @@ index 4e2e828..3af9741 100644 ``` ``` -$ rad patch review --patch --accept --hunk 1 52da8356aa9beec08e6943cb3c4063fa37f3241b +$ rad patch review --patch --accept --hunk 1 52da8356aa9beec08e6943cb3c4063fa37f3241b --no-announce ✓ Loaded existing review ([..]) for patch 52da8356aa9beec08e6943cb3c4063fa37f3241b diff --git a/INSTRUCTIONS.txt b/notes/INSTRUCTIONS.txt similarity index 100% @@ -178,7 +178,7 @@ rename to notes/INSTRUCTIONS.txt ``` ``` -$ rad patch review --patch --accept --hunk 1 52da8356aa9beec08e6943cb3c4063fa37f3241b +$ rad patch review --patch --accept --hunk 1 52da8356aa9beec08e6943cb3c4063fa37f3241b --no-announce ✓ Loaded existing review ([..]) for patch 52da8356aa9beec08e6943cb3c4063fa37f3241b ✓ All hunks have been reviewed ``` diff --git a/radicle-cli/examples/workflow/4-patching-contributor.md b/radicle-cli/examples/workflow/4-patching-contributor.md index 92a656be..a498afe8 100644 --- a/radicle-cli/examples/workflow/4-patching-contributor.md +++ b/radicle-cli/examples/workflow/4-patching-contributor.md @@ -87,4 +87,5 @@ And let's leave a quick comment for our team: ``` $ rad patch comment 3581e83ad18f5cdd806ab50fa11cfd5dd4e8ae1c --message 'I cannot wait to get back to the 90s!' -q b6711a58b45323f3ef2bb87cfb2b3b4d04c22a8b +✓ Synced with 1 node(s) ``` diff --git a/radicle-cli/src/commands/issue.rs b/radicle-cli/src/commands/issue.rs index 7cc2b806..34d5f287 100644 --- a/radicle-cli/src/commands/issue.rs +++ b/radicle-cli/src/commands/issue.rs @@ -9,7 +9,6 @@ use radicle::cob::issue; use radicle::cob::issue::{CloseReason, Issues, State}; use radicle::cob::thread; use radicle::crypto::Signer; -use radicle::node::Handle; use radicle::prelude::Did; use radicle::profile; use radicle::storage; @@ -18,6 +17,7 @@ use radicle::Profile; use radicle::{cob, Node}; use crate::git::Rev; +use crate::node; use crate::terminal as term; use crate::terminal::args::{Args, Error, Help}; use crate::terminal::format::Author; @@ -401,7 +401,6 @@ pub fn run(options: Options, ctx: impl term::Context) -> anyhow::Result<()> { | Operation::Label { .. } ); - let mut node = Node::new(profile.socket()); let mut issues = Issues::open(&repo)?; match options.op { @@ -528,11 +527,8 @@ pub fn run(options: Options, ctx: impl term::Context) -> anyhow::Result<()> { } if announce { - match node.announce_refs(rid) { - Ok(_) => {} - Err(e) if e.is_connection_err() => {} - Err(e) => return Err(e.into()), - } + let mut node = Node::new(profile.socket()); + node::sync(rid, &mut node)?; } Ok(()) diff --git a/radicle-cli/src/commands/patch.rs b/radicle-cli/src/commands/patch.rs index 73d2b5c8..6a6214f7 100644 --- a/radicle-cli/src/commands/patch.rs +++ b/radicle-cli/src/commands/patch.rs @@ -34,10 +34,11 @@ use anyhow::anyhow; use radicle::cob::patch::PatchId; use radicle::cob::{patch, Label}; -use radicle::prelude::*; use radicle::storage::git::transport; +use radicle::{prelude::*, Node}; use crate::git::Rev; +use crate::node; use crate::terminal as term; use crate::terminal::args::{string, Args, Error, Help}; use crate::terminal::patch::Message; @@ -134,6 +135,7 @@ Checkout options Other options + --[no-]announce Announce changes made to the network -q, --quiet Quiet output --help Print help "#, @@ -249,6 +251,25 @@ pub enum Operation { }, } +impl Operation { + fn is_announce(&self) -> bool { + match self { + Operation::Update { .. } + | Operation::Archive { .. } + | Operation::Ready { .. } + | Operation::Delete { .. } + | Operation::Comment { .. } + | Operation::Review { .. } + | Operation::Assign { .. } + | Operation::Label { .. } + | Operation::Edit { .. } + | Operation::Redact { .. } + | Operation::Set { .. } => true, + Operation::Show { .. } | Operation::Checkout { .. } | Operation::List { .. } => false, + } + } +} + #[derive(Debug)] pub struct Options { pub op: Operation, @@ -270,7 +291,7 @@ impl Args for Options { let mut quiet = false; let mut authored = false; let mut authors = vec![]; - let mut announce = false; + let mut announce = true; let mut patch_id = None; let mut revision_id = None; let mut message = Message::default(); @@ -604,6 +625,7 @@ pub fn run(options: Options, ctx: impl term::Context) -> anyhow::Result<()> { let profile = ctx.profile()?; let repository = profile.storage.repository(id)?; + let announce = options.announce && options.op.is_announce(); transport::local::register(profile.storage.clone()); @@ -720,5 +742,10 @@ pub fn run(options: Options, ctx: impl term::Context) -> anyhow::Result<()> { radicle::rad::setup_patch_upstream(&patch_id, *patch.head(), &workdir, true)?; } } + + if announce { + let mut node = Node::new(profile.socket()); + node::sync(id, &mut node)?; + } Ok(()) } diff --git a/radicle-cli/src/lib.rs b/radicle-cli/src/lib.rs index 3361d6ff..32019151 100644 --- a/radicle-cli/src/lib.rs +++ b/radicle-cli/src/lib.rs @@ -3,6 +3,7 @@ #![allow(clippy::too_many_arguments)] pub mod commands; pub mod git; +pub mod node; pub mod pager; pub mod project; pub mod terminal; diff --git a/radicle-cli/src/node.rs b/radicle-cli/src/node.rs new file mode 100644 index 00000000..667a2cef --- /dev/null +++ b/radicle-cli/src/node.rs @@ -0,0 +1,51 @@ +use std::time::Duration; + +use radicle::identity::Id; +use radicle::node; +use radicle::node::Handle as _; +use radicle::Node; + +use crate::terminal as term; + +pub fn sync(rid: Id, node: &mut Node) -> anyhow::Result<()> { + match sync_(rid, node) { + Ok(()) => Ok(()), + Err(e) if e.is_connection_err() => { + term::hint("Node is stopped. To announce changes to the network, start it with `rad node start`."); + Ok(()) + } + Err(e) => Err(e.into()), + } +} + +/// Sync with the network. +fn sync_(rid: Id, node: &mut Node) -> Result<(), radicle::node::Error> { + let seeds = node.seeds(rid)?; + let connected = seeds.connected().map(|s| s.nid).collect::>(); + + if connected.is_empty() { + term::info!("Not connected to any seeds."); + return Ok(()); + } + + let mut spinner = term::spinner(format!("Syncing with {} node(s)..", connected.len())); + let result = node.announce( + rid, + connected, + Duration::from_secs(9), + |event| match event { + node::AnnounceEvent::Announced => {} + node::AnnounceEvent::RefsSynced { remote } => { + spinner.message(format!("Synced with {remote}..")); + } + }, + )?; + + if result.synced.is_empty() { + spinner.failed(); + } else { + spinner.message(format!("Synced with {} node(s)", result.synced.len())); + spinner.finish(); + } + Ok(()) +}