Radish alpha
h
Radicle Heartwood Protocol & Stack
Radicle
Git (anonymous pull)
Log in to clone via SSH
cli: Polish the `rad sync status` output
cloudhead committed 2 years ago
commit dfe0cb43429e3364872da505ccbe829be93a05cf
parent b64fc22c185291a5fc2d7396b88207bd62e89244
4 files changed +85 -32
modified radicle-cli/examples/rad-sync.md
@@ -13,13 +13,13 @@ It isn't aware of the updates to the repo.

```
$ rad sync status
-
╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
-
│ ●   NID                                                Address                  Status        At        Timestamp │
-
├───────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
-
│ ●   z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi   alice.radicle.xyz:8776   out-of-sync   f209c9f   [  ...  ] │
-
│ ●   z6Mkt67GdsW7715MEfRuP4pSZxJRJh6kj6Y48WRqVv4N1tRk   bob.radicle.xyz:8776     out-of-sync   f209c9f   [  ...  ] │
-
│ ●   z6Mkux1aUQD2voWWukVb5nNUR7thrHveQG4pDQua8nVhib7Z   eve.radicle.xyz:8776     out-of-sync   f209c9f   [  ...  ] │
-
╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
+
╭──────────────────────────────────────────────────────────────────────────────────────────╮
+
│ ●   NID               Alias   Address                  Status        At        Timestamp │
+
├──────────────────────────────────────────────────────────────────────────────────────────┤
+
│ ●   z6MknSL…StBU8Vi   alice   alice.radicle.xyz:8776   out-of-sync   f209c9f   [  ...  ] │
+
│ ●   z6Mkt67…v4N1tRk   bob     bob.radicle.xyz:8776     out-of-sync   f209c9f   [  ...  ] │
+
│ ●   z6Mkux1…nVhib7Z   eve     eve.radicle.xyz:8776     out-of-sync   f209c9f   [  ...  ] │
+
╰──────────────────────────────────────────────────────────────────────────────────────────╯
```

Now let's run `rad sync`. This will announce the issue refs to the network and
@@ -77,11 +77,11 @@ We can check the sync status again to make sure everything's in sync:

```
$ rad sync status
-
╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
-
│ ●   NID                                                Address                  Status   At        Timestamp │
-
├──────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
-
│ ●   z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi   alice.radicle.xyz:8776   synced   9f615f9   [  ...  ] │
-
│ ●   z6Mkt67GdsW7715MEfRuP4pSZxJRJh6kj6Y48WRqVv4N1tRk   bob.radicle.xyz:8776     synced   9f615f9   [  ...  ] │
-
│ ●   z6Mkux1aUQD2voWWukVb5nNUR7thrHveQG4pDQua8nVhib7Z   eve.radicle.xyz:8776     synced   9f615f9   [  ...  ] │
-
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
+
╭─────────────────────────────────────────────────────────────────────────────────────╮
+
│ ●   NID               Alias   Address                  Status   At        Timestamp │
+
├─────────────────────────────────────────────────────────────────────────────────────┤
+
│ ●   z6MknSL…StBU8Vi   alice   alice.radicle.xyz:8776   synced   9f615f9   [  ...  ] │
+
│ ●   z6Mkt67…v4N1tRk   bob     bob.radicle.xyz:8776     synced   9f615f9   [  ...  ] │
+
│ ●   z6Mkux1…nVhib7Z   eve     eve.radicle.xyz:8776     synced   9f615f9   [  ...  ] │
+
╰─────────────────────────────────────────────────────────────────────────────────────╯
```
modified radicle-cli/src/commands/sync.rs
@@ -5,6 +5,7 @@ use std::time;
use anyhow::{anyhow, Context as _};

use radicle::node;
+
use radicle::node::AliasStore as _;
use radicle::node::{FetchResult, FetchResults, Handle as _, Node, SyncStatus};
use radicle::prelude::{Id, NodeId, Profile};
use radicle::storage::{ReadRepository, ReadStorage};
@@ -243,7 +244,7 @@ pub fn run(options: Options, ctx: impl term::Context) -> anyhow::Result<()> {

    match options.op {
        Operation::Status => {
-
            sync_status(rid, &mut node)?;
+
            sync_status(rid, &mut node, &profile, &options)?;
        }
        Operation::Synchronize(SyncMode::Repo { mode, direction }) => {
            if [SyncDirection::Fetch, SyncDirection::Both].contains(&direction) {
@@ -271,14 +272,21 @@ pub fn run(options: Options, ctx: impl term::Context) -> anyhow::Result<()> {
    Ok(())
}

-
fn sync_status(rid: Id, node: &mut Node) -> anyhow::Result<()> {
-
    let mut table = Table::<6, term::Label>::new(TableOptions::bordered());
+
fn sync_status(
+
    rid: Id,
+
    node: &mut Node,
+
    profile: &Profile,
+
    options: &Options,
+
) -> anyhow::Result<()> {
+
    let mut table = Table::<7, term::Label>::new(TableOptions::bordered());
    let mut seeds: Vec<_> = node.seeds(rid)?.into();
    let local = node.nid()?;
+
    let aliases = profile.aliases();

    table.push([
        term::format::dim(String::from("●")).into(),
        term::format::bold(String::from("NID")).into(),
+
        term::format::bold(String::from("Alias")).into(),
        term::format::bold(String::from("Address")).into(),
        term::format::bold(String::from("Status")).into(),
        term::format::bold(String::from("At")).into(),
@@ -287,34 +295,43 @@ fn sync_status(rid: Id, node: &mut Node) -> anyhow::Result<()> {
    table.divider();

    // Always show our local node first.
-
    seeds.sort_by(|a, _| {
+
    seeds.sort_by(|a, b| {
        if a.nid == local {
            Ordering::Less
+
        } else if b.nid == local {
+
            Ordering::Greater
        } else {
-
            Ordering::Equal
+
            match (&a.sync, &b.sync) {
+
                (Some(_), None) => Ordering::Less,
+
                (None, Some(_)) => Ordering::Greater,
+
                (Some(a), Some(b)) => a.cmp(b).reverse(),
+
                (None, None) => Ordering::Equal,
+
            }
+
            .then(a.nid.cmp(&b.nid))
        }
    });

    for seed in seeds {
-
        let (icon, status, refs, time) = match seed.sync {
+
        let (icon, status, head, time) = match seed.sync {
            Some(SyncStatus::Synced { at }) => (
                term::format::positive("●"),
                term::format::positive("synced"),
-
                term::label(term::format::oid(at.oid)),
-
                term::format::timestamp(at.timestamp).into(),
+
                term::format::oid(at.oid),
+
                term::format::timestamp(at.timestamp),
            ),
            Some(SyncStatus::OutOfSync { remote, .. }) => (
                term::format::negative("●"),
                term::format::negative("out-of-sync"),
-
                term::label(term::format::oid(remote.oid)),
-
                term::format::timestamp(remote.timestamp).into(),
+
                term::format::oid(remote.oid),
+
                term::format::timestamp(remote.timestamp),
            ),
-
            None => (
-
                term::format::yellow("●"),
-
                term::format::yellow("?"),
-
                term::label("?"),
-
                term::label("?"),
+
            None if options.verbose => (
+
                term::format::dim("●"),
+
                term::format::dim("unknown"),
+
                term::paint(String::new()),
+
                term::paint(String::new()),
            ),
+
            None => continue,
        };
        let addr = seed
            .addrs
@@ -322,14 +339,19 @@ fn sync_status(rid: Id, node: &mut Node) -> anyhow::Result<()> {
            .map(|a| a.addr.to_string())
            .unwrap_or_default()
            .into();
+
        let alias = aliases
+
            .alias(&seed.nid)
+
            .map(|a| a.to_string())
+
            .unwrap_or_default();

        table.push([
            icon.into(),
-
            seed.nid.to_human().into(),
+
            term::format::primary(term::format::node(&seed.nid)).into(),
+
            term::format::primary(alias).dim().into(),
            addr,
            status.into(),
-
            refs,
-
            time,
+
            term::format::secondary(head).into(),
+
            time.dim().italic().into(),
        ]);
    }
    table.print();
modified radicle/src/node.rs
@@ -147,6 +147,25 @@ pub enum SyncStatus {
    },
}

+
impl Ord for SyncStatus {
+
    fn cmp(&self, other: &Self) -> std::cmp::Ordering {
+
        match (self, other) {
+
            (Self::Synced { at: left }, Self::Synced { at: right }) => left.cmp(right),
+
            (Self::Synced { at }, Self::OutOfSync { remote, .. }) => at.cmp(remote),
+
            (Self::OutOfSync { remote, .. }, Self::Synced { at }) => remote.cmp(at),
+
            (Self::OutOfSync { remote: left, .. }, Self::OutOfSync { remote: right, .. }) => {
+
                left.cmp(right)
+
            }
+
        }
+
    }
+
}
+

+
impl PartialOrd for SyncStatus {
+
    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
+
        Some(self.cmp(other))
+
    }
+
}
+

/// Node alias.
#[derive(Debug, PartialEq, Eq, Clone, serde::Serialize, serde::Deserialize)]
pub struct Alias(String);
modified radicle/src/node/address/types.rs
@@ -213,6 +213,18 @@ impl SyncedAt {
    }
}

+
impl Ord for SyncedAt {
+
    fn cmp(&self, other: &Self) -> std::cmp::Ordering {
+
        self.timestamp.cmp(&other.timestamp)
+
    }
+
}
+

+
impl PartialOrd for SyncedAt {
+
    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
+
        Some(self.cmp(other))
+
    }
+
}
+

/// Seed of a specific repository.
#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
#[serde(rename_all = "camelCase")]