Radish alpha
h
rad:z3gqcJUoA1n9HaHKufZs5FCSGazv5
Radicle Heartwood Protocol & Stack
Radicle
Git
cli: Improve formatting of Node IDs and addresses
Merged lorenz opened 9 months ago

Pay more attention to when a Node ID is displayed in compact form. As this was sometimes used to save space, e.g. in rad node status in combination with long node addresses (like .onion names), also implement a compact format for node addresses and use that instead in some cases. Progress notifications in spinners keep the short form.

6 files changed +52 -17 010d5134 0e3f3f03
modified crates/radicle-cli/src/commands/node/control.rs
@@ -189,7 +189,7 @@ pub fn connect(
) -> anyhow::Result<()> {
    let spinner = term::spinner(format!(
        "Connecting to {}@{addr}...",
-
        term::format::node(&nid)
+
        term::format::node_short(&nid)
    ));
    match node.connect(
        nid,
@@ -217,7 +217,7 @@ pub fn connect_many(
    for addr in addrs {
        spinner.message(format!(
            "Connecting to {}@{addr}...",
-
            term::format::node(&nid)
+
            term::format::node_short(&nid)
        ));
        match node.connect(
            nid,
@@ -361,17 +361,17 @@ pub fn sessions(node: &Node) -> Result<Option<term::Table<5, term::Label>>, node
                term::Label::blank(),
            ),
            node::State::Attempted => (
-
                sess.addr.to_string().into(),
+
                term::format::addr_short(&sess.addr).into(),
                term::Label::from(state_attempted()),
                term::Label::blank(),
            ),
            node::State::Connected { since, .. } => (
-
                sess.addr.to_string().into(),
+
                term::format::addr_short(&sess.addr).into(),
                term::Label::from(state_connected()),
                term::format::dim(now - since).into(),
            ),
            node::State::Disconnected { since, .. } => (
-
                sess.addr.to_string().into(),
+
                term::format::addr_short(&sess.addr).into(),
                term::Label::from(state_disconnected()),
                term::format::dim(now - since).into(),
            ),
modified crates/radicle-cli/src/commands/sync.rs
@@ -674,8 +674,8 @@ impl FetcherSpinner {
            term::format::secondary(self.preferred_seeds),
            term::format::secondary(progress.succeeded()),
            term::format::secondary(self.replicas.lower_bound()),
-
            term::format::tertiary(term::format::node(node)),
-
            term::format::tertiary(addr),
+
            term::format::tertiary(term::format::node_short(node)),
+
            term::format::tertiary(term::format::addr_short(addr)),
        ))
    }

@@ -691,8 +691,8 @@ impl FetcherSpinner {
            term::format::secondary(self.preferred_seeds),
            term::format::secondary(progress.succeeded()),
            term::format::secondary(self.replicas.lower_bound()),
-
            term::format::tertiary(term::format::node(node)),
-
            term::format::tertiary(addr),
+
            term::format::tertiary(term::format::node_short(node)),
+
            term::format::tertiary(term::format::addr_short(addr)),
        ))
    }

modified crates/radicle-cli/src/node.rs
@@ -242,7 +242,7 @@ where
    match node.announce(rid, settings.timeout, announcer, |node, progress| {
        spinner.message(format!(
            "Synced with {}, {} of {} preferred seeds, and {} of at least {} replica(s).",
-
            term::format::node(node),
+
            term::format::node_short(node),
            term::format::secondary(progress.preferred()),
            term::format::secondary(n_preferred_seeds),
            term::format::secondary(progress.synced()),
modified crates/radicle-cli/src/terminal/format.rs
@@ -8,7 +8,7 @@ pub use radicle_term::{style, Paint};
use radicle::cob::ObjectId;
use radicle::identity::Visibility;
use radicle::node::policy::Policy;
-
use radicle::node::{Alias, AliasStore, NodeId};
+
use radicle::node::{Address, Alias, AliasStore, HostName, NodeId};
use radicle::prelude::Did;
use radicle::profile::{env, Profile};
use radicle::storage::RefUpdate;
@@ -16,8 +16,8 @@ use radicle_term::element::Line;

use crate::terminal as term;

-
/// Format a node id to be more compact.
-
pub fn node(node: &NodeId) -> Paint<String> {
+
/// Format a Node ID in its short form, removing the middle part.
+
pub fn node_short(node: &NodeId) -> Paint<String> {
    let node = node.to_human();
    let start = node.chars().take(7).collect::<String>();
    let end = node.chars().skip(node.len() - 7).collect::<String>();
@@ -25,6 +25,33 @@ pub fn node(node: &NodeId) -> Paint<String> {
    Paint::new(format!("{start}…{end}"))
}

+
/// Format a Node ID.
+
pub fn node(node: &NodeId) -> Paint<String> {
+
    Paint::new(node.to_human())
+
}
+

+
/// Format an Address in a short form, removing the middle part of the host if it's a Tor address.
+
pub fn addr_short(address: &Address) -> Paint<String> {
+
    let host = match address.host() {
+
        HostName::Ip(ip) => ip.to_string(),
+
        HostName::Dns(dns) => dns.clone(),
+
        HostName::Tor(onion) => {
+
            let onion = onion.to_string();
+
            let start = onion.chars().take(8).collect::<String>();
+
            let end = onion
+
                .chars()
+
                .skip(onion.len() - 8 - ".onion".len())
+
                .collect::<String>();
+
            format!("{start}…{end}")
+
        }
+
        _ => unreachable!(),
+
    };
+

+
    let port = address.port().to_string();
+

+
    Paint::new(format!("{host}:{port}"))
+
}
+

/// Format a git Oid.
pub fn oid(oid: impl Into<radicle::git::Oid>) -> Paint<String> {
    Paint::new(format!("{:.7}", oid.into()))
@@ -173,7 +200,7 @@ impl fmt::Display for Identity<'_> {
        let nid = self.profile.id();
        let alias = self.profile.aliases().alias(nid);
        let node_id = match self.short {
-
            true => self::node(nid).to_string(),
+
            true => self::node_short(nid).to_string(),
            false => nid.to_human(),
        };

@@ -231,13 +258,13 @@ impl<'a> Author<'a> {
    pub fn labels(self) -> (term::Label, term::Label) {
        let alias = match self.alias.as_ref() {
            Some(alias) => term::format::primary(alias).into(),
-
            None if self.you => term::format::primary(term::format::node(self.nid))
+
            None if self.you => term::format::primary(term::format::node_short(self.nid))
                .dim()
                .into(),
            None => term::Label::blank(),
        };
        let author = self.you().unwrap_or_else(|| {
-
            term::format::primary(term::format::node(self.nid))
+
            term::format::primary(term::format::node_short(self.nid))
                .dim()
                .into()
        });
modified crates/radicle-protocol/src/wire/message.rs
@@ -2,7 +2,7 @@ use std::{mem, net};

use bytes::Buf;
use bytes::BufMut;
-
use cyphernet::addr::{tor, Addr, HostName, NetAddr};
+
use cyphernet::addr::{tor, HostName, NetAddr};
use radicle::crypto::Signature;
use radicle::git::Oid;
use radicle::identity::RepoId;
modified crates/radicle/src/node.rs
@@ -573,6 +573,14 @@ impl Address {
            _ => true,
        }
    }
+

+
    pub fn host(&self) -> &HostName {
+
        &self.0.host
+
    }
+

+
    pub fn port(&self) -> u16 {
+
        self.0.port
+
    }
}

impl cyphernet::addr::Host for Address {