cli: Polish the `rad sync status` output
This commit is contained in:
parent
b64fc22c18
commit
dfe0cb4342
|
|
@ -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 [ ... ] │
|
||||
╰─────────────────────────────────────────────────────────────────────────────────────╯
|
||||
```
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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")]
|
||||
|
|
|
|||
Loading…
Reference in New Issue