cli: watch for upload-pack events in `rad init`

To improve the user experience of `rad init`, the events listener waits for
upload-pack messages indefinitely. The spinner reports back the upload progress
over time.

This process can be cancelled via Ctrl+C without affecting the announcement,
since that is happening in the background.

To also improve the experience, the remote NIDs that have successfully synced
are reported to the terminal.

Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com>
X-Clacks-Overhead: GNU Terry Pratchett
This commit is contained in:
Fintan Halpenny 2024-04-24 15:20:27 +01:00
parent 344fe3a901
commit f038b7ee5c
No known key found for this signature in database
GPG Key ID: C93C17467280C75B
2 changed files with 30 additions and 3 deletions

View File

@ -10,6 +10,7 @@ Initializing public radicle 👾 repository in [..]
Your Repository ID (RID) is rad:z3Rry7rpdWuGpfjPYGzdJKQADsoNW.
You can show it any time by running `rad .` from this directory.
✓ Repository successfully synced to z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
✓ Repository successfully synced to 1 node(s).
Your repository has been synced to the network and is now discoverable by peers.

View File

@ -2,10 +2,10 @@
#![allow(clippy::collapsible_else_if)]
use std::collections::HashSet;
use std::convert::TryFrom;
use std::env;
use std::ffi::OsString;
use std::path::PathBuf;
use std::str::FromStr;
use std::{env, time};
use anyhow::{anyhow, bail, Context as _};
use serde_json as json;
@ -14,8 +14,9 @@ use radicle::crypto::{ssh, Verified};
use radicle::explorer::ExplorerUrl;
use radicle::git::RefString;
use radicle::identity::{RepoId, Visibility};
use radicle::node::events::UploadPack;
use radicle::node::policy::Scope;
use radicle::node::{Event, Handle, NodeId};
use radicle::node::{Event, Handle, NodeId, DEFAULT_SUBSCRIBE_TIMEOUT};
use radicle::prelude::Doc;
use radicle::{profile, Node};
@ -364,7 +365,9 @@ fn sync(
return Ok(SyncResult::NodeStopped);
}
let mut spinner = term::spinner("Updating inventory..");
let events = node.subscribe(time::Duration::from_secs(3))?;
// N.b. indefinitely subscribe to events and set a lower timeout on events
// below.
let events = node.subscribe(DEFAULT_SUBSCRIBE_TIMEOUT)?;
let sessions = node.sessions()?;
node.update_inventory(rid)?;
@ -392,17 +395,40 @@ fn sync(
spinner.message("Syncing..");
let mut replicas = HashSet::new();
for e in events {
match e {
Ok(Event::RefsSynced {
remote, rid: rid_, ..
}) if rid == rid_ => {
term::success!("Repository successfully synced to {remote}");
replicas.insert(remote);
// If we manage to replicate to one of our preferred seeds, we can stop waiting.
if config.preferred_seeds.iter().any(|s| s.id == remote) {
break;
}
}
Ok(Event::UploadPack(UploadPack::Write {
rid: rid_,
remote,
progress,
})) if rid == rid_ => {
spinner.message(format!("Uploading {rid} to {remote} {progress}"));
}
Ok(Event::UploadPack(UploadPack::Done {
rid: rid_,
remote,
status,
})) if rid == rid_ => {
spinner.message(format!("Upload done for {rid} to {remote}: {status}"));
}
Ok(Event::UploadPack(UploadPack::Error {
rid: rid_,
remote,
err,
})) if rid == rid_ => {
spinner.message(format!("Upload error for {rid} to {remote}: {err}"));
}
Ok(_) => {
// Some other irrelevant event received.
}