diff --git a/radicle-cli/examples/rad-patch-ahead-behind.md b/radicle-cli/examples/rad-patch-ahead-behind.md index 224b2324..6a02a10a 100644 --- a/radicle-cli/examples/rad-patch-ahead-behind.md +++ b/radicle-cli/examples/rad-patch-ahead-behind.md @@ -68,7 +68,7 @@ $ rad patch show -v -p 866f59c ├────────────────────────────────────────────────────────────────────┤ │ 5c88a79 Add Alan │ ├────────────────────────────────────────────────────────────────────┤ -│ ● opened by (you) (z6MknSL…StBU8Vi) [ ... ] │ +│ ● opened by (you) [ ... ] │ ╰────────────────────────────────────────────────────────────────────╯ commit 5c88a79d75f5c2b4cc51ee6f163d2db91ee198d7 @@ -115,7 +115,7 @@ $ rad patch show -v 57cb9b2758518e547de324456ac967fda456c6c1 │ 7f63fcb Add Mel │ │ 5c88a79 Add Alan │ ├────────────────────────────────────────────────────────────────────┤ -│ ● opened by (you) (z6MknSL…StBU8Vi) [ ... ] │ +│ ● opened by (you) [ ... ] │ ╰────────────────────────────────────────────────────────────────────╯ ``` @@ -149,6 +149,6 @@ $ rad patch show -v 395221c5b75fa9bc2de7909d03e69dfd606611c6 ├────────────────────────────────────────────────────────────────────┤ │ 7f63fcb Add Mel │ ├────────────────────────────────────────────────────────────────────┤ -│ ● opened by (you) (z6MknSL…StBU8Vi) [ ... ] │ +│ ● opened by (you) [ ... ] │ ╰────────────────────────────────────────────────────────────────────╯ ``` diff --git a/radicle-cli/examples/rad-patch-draft.md b/radicle-cli/examples/rad-patch-draft.md index f8ef6e4c..d1d0a6dc 100644 --- a/radicle-cli/examples/rad-patch-draft.md +++ b/radicle-cli/examples/rad-patch-draft.md @@ -29,7 +29,7 @@ $ rad patch show c639a0f9895a0fdf2ba2d04533290937cb6fd2f7 ├────────────────────────────────────────────────────────────────────┤ │ 2a46583 Nothing to see here.. │ ├────────────────────────────────────────────────────────────────────┤ -│ ● opened by (you) (z6MknSL…StBU8Vi) [ ... ] │ +│ ● opened by (you) [ ... ] │ ╰────────────────────────────────────────────────────────────────────╯ ``` @@ -52,7 +52,7 @@ $ rad patch show c639a0f9895a0fdf2ba2d04533290937cb6fd2f7 ├────────────────────────────────────────────────────────────────────┤ │ 2a46583 Nothing to see here.. │ ├────────────────────────────────────────────────────────────────────┤ -│ ● opened by (you) (z6MknSL…StBU8Vi) [ ... ] │ +│ ● opened by (you) [ ... ] │ ╰────────────────────────────────────────────────────────────────────╯ ``` @@ -73,5 +73,5 @@ $ rad patch show c639a0f9895a0fdf2ba2d04533290937cb6fd2f7 ├─────────────────────────────────────────────────────────────────────────────────────────┤ │ 2a46583 Nothing to see here.. │ ├─────────────────────────────────────────────────────────────────────────────────────────┤ -│ ● opened by (you) (z6MknSL…StBU8Vi) [ ... ] │ +│ ● opened by (you) [ ... ] │ ╰─────────────────────────────────────────────────────────────────────────────────────────╯ diff --git a/radicle-cli/examples/rad-patch-update.md b/radicle-cli/examples/rad-patch-update.md index 370ea7f4..ef0fc61d 100644 --- a/radicle-cli/examples/rad-patch-update.md +++ b/radicle-cli/examples/rad-patch-update.md @@ -24,7 +24,7 @@ $ rad patch show 51e0d0bc168ccdc541b7b1aeab2eb9e048c2fcdd ├────────────────────────────────────────────────────────────────────┤ │ 51b2f0f Not a real change │ ├────────────────────────────────────────────────────────────────────┤ -│ ● opened by (you) (z6MknSL…StBU8Vi) [ ... ] │ +│ ● opened by (you) [ ... ] │ ╰────────────────────────────────────────────────────────────────────╯ ``` @@ -66,7 +66,7 @@ $ rad patch show 51e0d0bc168ccdc541b7b1aeab2eb9e048c2fcdd │ 4d27214 Rename readme file │ │ 51b2f0f Not a real change │ ├──────────────────────────────────────────────────────────────────────────────┤ -│ ● opened by (you) (z6MknSL…StBU8Vi) [ ... ] │ +│ ● opened by (you) [ ... ] │ │ ↑ updated to c10012c2cb9c0c9bfeba7ef28cae10e4b8db3469 (4d27214) [ ... ] │ ╰──────────────────────────────────────────────────────────────────────────────╯ ``` diff --git a/radicle-cli/examples/rad-patch-via-push.md b/radicle-cli/examples/rad-patch-via-push.md index 892ba734..f36519c6 100644 --- a/radicle-cli/examples/rad-patch-via-push.md +++ b/radicle-cli/examples/rad-patch-via-push.md @@ -30,7 +30,7 @@ $ rad patch show 2647168 ├────────────────────────────────────────────────────────────────────┤ │ 42d894a Add things │ ├────────────────────────────────────────────────────────────────────┤ -│ ● opened by (you) (z6MknSL…StBU8Vi) [ ... ] │ +│ ● opened by (you) [ ... ] │ ╰────────────────────────────────────────────────────────────────────╯ ``` @@ -141,7 +141,7 @@ $ rad patch show b8ab1c9 │ 02bef3f Improve code │ │ 8b0ea80 Add more things │ ├──────────────────────────────────────────────────────────────────────────────┤ -│ ● opened by (you) (z6MknSL…StBU8Vi) [ ... ] │ +│ ● opened by (you) [ ... ] │ │ ↑ updated to 8767880c31b9e4a04cdb07ad6faa9ce453980399 (02bef3f) [ ... ] │ ╰──────────────────────────────────────────────────────────────────────────────╯ ``` @@ -217,7 +217,7 @@ $ rad patch show b8ab1c9 │ 9304dbc Amended commit │ │ 8b0ea80 Add more things │ ├──────────────────────────────────────────────────────────────────────────────┤ -│ ● opened by (you) (z6MknSL…StBU8Vi) [ ... ] │ +│ ● opened by (you) [ ... ] │ │ ↑ updated to 8767880c31b9e4a04cdb07ad6faa9ce453980399 (02bef3f) [ ... ] │ │ ↑ updated to f24334f8cea7b7a5bcaf3bc6deb1408c9bf507ad (9304dbc) [ ... ] │ ╰──────────────────────────────────────────────────────────────────────────────╯ diff --git a/radicle-cli/examples/rad-patch.md b/radicle-cli/examples/rad-patch.md index ccc3e551..d74572b9 100644 --- a/radicle-cli/examples/rad-patch.md +++ b/radicle-cli/examples/rad-patch.md @@ -56,7 +56,7 @@ $ rad patch show 077e4bbe9a6e5546f400ef5951768c37a76f13a4 -p ├────────────────────────────────────────────────────────────────────┤ │ 3e674d1 Define power requirements │ ├────────────────────────────────────────────────────────────────────┤ -│ ● opened by (you) (z6MknSL…StBU8Vi) [ ... ] │ +│ ● opened by (you) [ ... ] │ ╰────────────────────────────────────────────────────────────────────╯ commit 3e674d1a1df90807e934f9ae5da2591dd6848a33 @@ -137,9 +137,9 @@ $ rad patch show 077e4bb │ 27857ec Add README, just for the fun │ │ 3e674d1 Define power requirements │ ├──────────────────────────────────────────────────────────────────────────────┤ -│ ● opened by (you) (z6MknSL…StBU8Vi) [ ... ] │ +│ ● opened by (you) [ ... ] │ │ ↑ updated to 5cdcd2e14411e2bfec7b11bcf4667e2e0fc4d417 (27857ec) [ ... ] │ -│ ✓ accepted by (you) (z6MknSL…StBU8Vi) [ ... ] │ +│ ✓ accepted by (you) [ ... ] │ ╰──────────────────────────────────────────────────────────────────────────────╯ ``` @@ -162,8 +162,8 @@ $ rad patch show 077e4bb │ 27857ec Add README, just for the fun │ │ 3e674d1 Define power requirements │ ├──────────────────────────────────────────────────────────────────────────────┤ -│ ● opened by (you) (z6MknSL…StBU8Vi) [ ... ] │ +│ ● opened by (you) [ ... ] │ │ ↑ updated to 5cdcd2e14411e2bfec7b11bcf4667e2e0fc4d417 (27857ec) [ ... ] │ -│ ✓ accepted by (you) (z6MknSL…StBU8Vi) [ ... ] │ +│ ✓ accepted by (you) [ ... ] │ ╰──────────────────────────────────────────────────────────────────────────────╯ ``` diff --git a/radicle-cli/examples/workflow/4-patching-contributor.md b/radicle-cli/examples/workflow/4-patching-contributor.md index d22b4aea..e86378ac 100644 --- a/radicle-cli/examples/workflow/4-patching-contributor.md +++ b/radicle-cli/examples/workflow/4-patching-contributor.md @@ -54,7 +54,7 @@ $ rad patch show 50e29a111972f3b7d2123c5057de5bdf09bc7b1c ├────────────────────────────────────────────────────────────────────┤ │ 3e674d1 Define power requirements │ ├────────────────────────────────────────────────────────────────────┤ -│ ● opened by (you) (z6Mkt67…v4N1tRk) [ ... ] │ +│ ● opened by (you) [ ... ] │ ╰────────────────────────────────────────────────────────────────────╯ ``` diff --git a/radicle-cli/examples/workflow/5-patching-maintainer.md b/radicle-cli/examples/workflow/5-patching-maintainer.md index 8c513c20..73da84b2 100644 --- a/radicle-cli/examples/workflow/5-patching-maintainer.md +++ b/radicle-cli/examples/workflow/5-patching-maintainer.md @@ -112,7 +112,7 @@ $ rad patch show 50e29a1 │ ● opened by bob (z6Mkt67…v4N1tRk) [ ... ] │ │ ↑ updated to 3530243d46a2e7a8e4eac7afcbb17cc7c56b3d29 (27857ec) [ ... ] │ │ ↑ updated to 744c1f0a75b1c42833c9aa32f79cd40443925d66 (f567f69) [ ... ] │ -│ ✓ merged by (you) (z6MknSL…StBU8Vi) [ ... ] │ +│ ✓ merged by (you) [ ... ] │ ╰──────────────────────────────────────────────────────────────────────────────╯ ``` diff --git a/radicle-cli/src/commands/patch/list.rs b/radicle-cli/src/commands/patch/list.rs index 3014ef56..60f0a959 100644 --- a/radicle-cli/src/commands/patch/list.rs +++ b/radicle-cli/src/commands/patch/list.rs @@ -1,10 +1,12 @@ use radicle::cob::patch; use radicle::cob::patch::{Patch, PatchId, Patches, Verdict}; +use radicle::node::AliasStore; use radicle::prelude::*; use radicle::profile::Profile; use radicle::storage::git::Repository; use crate::terminal as term; +use term::format::Author; use term::table::{Table, TableOptions}; use term::Element as _; @@ -63,13 +65,13 @@ pub fn run( is_me.then(by_rev_time).then(by_id) }); - let store = profile.tracking()?; + let aliases = profile.aliases()?; let mut errors = Vec::new(); for (id, patch) in &mut all { let author_id = patch.author().id(); - let alias = store.node_policy(author_id)?.and_then(|node| node.alias); - match row(&me, alias, id, patch, repository) { + let alias = aliases.alias(author_id); + match row(profile, alias, id, patch, repository) { Ok(r) => table.push(r), Err(e) => errors.push((patch.title(), id, e.to_string())), } @@ -90,7 +92,7 @@ pub fn run( /// Patch row. pub fn row( - whoami: &PublicKey, + profile: &Profile, alias: Option, id: &PatchId, patch: &Patch, @@ -101,6 +103,7 @@ pub fn row( let (from, to) = patch.range(repository)?; let stats = common::diff_stats(repository.raw(), &from, &to)?; let author = patch.author().id; + let display = Author::new(&author, alias, profile); Ok([ match state { @@ -112,13 +115,7 @@ pub fn row( term::format::tertiary(term::format::cob(id)).into(), term::format::default(patch.title().to_owned()).into(), term::format::did(&author).dim().into(), - if author.as_key() == whoami { - term::format::primary("(you)".to_owned()).into() - } else if let Some(alias) = alias { - term::format::primary(alias).into() - } else { - term::format::default(String::new()).into() - }, + display.alias(), term::format::secondary(term::format::oid(revision.head())).into(), term::format::positive(format!("+{}", stats.insertions())).into(), term::format::negative(format!("-{}", stats.deletions())).into(), @@ -135,33 +132,14 @@ pub fn timeline( patch: &Patch, repository: &Repository, ) -> anyhow::Result> { - let whoami = profile.id(); - let store = profile.tracking()?; - let alias = if patch.author().id().as_key() == whoami { - Some("(you)".to_string()) - } else { - store - .node_policy(patch.author().id())? - .and_then(|node| node.alias) - }; - - let mut open = term::Line::spaced([ + let aliases = profile.aliases()?; + let alias = aliases.alias(patch.author().id()); + let open = term::Line::spaced([ term::format::positive("●").into(), term::format::default("opened by").into(), - ]); - - open.push(term::Label::space()); - - if let Some(ref alias) = alias { - open.push(term::format::primary(alias)); - open.push(term::Label::space()); - open.push(term::format::tertiary(format!( - "({})", - term::format::node(patch.author().id()) - ))); - } else { - open.push(term::format::tertiary(patch.author().id())); - } + ]) + .space() + .extend(Author::new(patch.author().id(), alias, profile)); let mut timeline = vec![(patch.timestamp(), open)]; @@ -187,37 +165,16 @@ pub fn timeline( for (nid, merge) in patch.merges().filter(|(_, m)| m.revision == *revision_id) { let peer = repository.remote(nid)?; - let alias = if peer.id == *whoami { - Some("(you)".to_string()) - } else { - store.node_policy(&peer.id)?.and_then(|node| node.alias) - }; + let alias = aliases.alias(&peer.id); + let line = term::Line::spaced([ + term::format::primary("✓").bold().into(), + term::format::default("merged").into(), + term::format::default("by").into(), + ]) + .space() + .extend(Author::new(&peer.id, alias, profile)); - timeline.push(( - merge.timestamp, - term::Line::spaced( - [ - term::format::primary("✓").bold().into(), - term::format::default("merged").into(), - term::format::default("by").into(), - if let Some(ref alias) = alias { - term::format::primary(alias).into() - } else { - term::format::default(String::new()).into() - }, - if alias.is_some() { - term::format::tertiary(format!( - "({})", - term::format::node(&Did::from(peer.id)) - )) - .into() - } else { - term::format::tertiary(Did::from(peer.id)).into() - }, - ] - .into_iter(), - ), - )); + timeline.push((merge.timestamp, line)); } for (reviewer, review) in revision.reviews() { let verdict = review.verdict(); @@ -232,37 +189,16 @@ pub fn timeline( None => term::format::default("reviewed"), }; let peer = repository.remote(reviewer)?; - let alias = if peer.id == *whoami { - Some("(you)".to_string()) - } else { - store.node_policy(&peer.id)?.and_then(|node| node.alias) - }; + let alias = aliases.alias(&peer.id); + let line = term::Line::spaced([ + verdict_symbol.into(), + verdict_verb.into(), + term::format::default("by").into(), + ]) + .space() + .extend(Author::new(&peer.id, alias, profile)); - timeline.push(( - review.timestamp(), - term::Line::spaced( - [ - verdict_symbol.into(), - verdict_verb.into(), - term::format::default("by").into(), - if let Some(ref alias) = alias { - term::format::primary(alias).into() - } else { - term::format::default(String::new()).into() - }, - if alias.is_some() { - term::format::tertiary(format!( - "({})", - term::format::node(&Did::from(reviewer)) - )) - .into() - } else { - term::format::tertiary(Did::from(reviewer)).into() - }, - ] - .into_iter(), - ), - )); + timeline.push((review.timestamp(), line)); } } timeline.sort_by_key(|(t, _)| *t); diff --git a/radicle-cli/src/terminal/format.rs b/radicle-cli/src/terminal/format.rs index 91dfa048..22a4e4cc 100644 --- a/radicle-cli/src/terminal/format.rs +++ b/radicle-cli/src/terminal/format.rs @@ -7,6 +7,7 @@ use radicle::cob::{ObjectId, Timestamp}; use radicle::node::{AliasStore, NodeId}; use radicle::prelude::Did; use radicle::profile::Profile; +use radicle_term::element::Line; use crate::terminal as term; @@ -138,6 +139,92 @@ impl<'a> fmt::Display for Identity<'a> { } } +/// This enum renders (nid, alias) in terminal depending on user variant. +pub enum Author<'a> { + Author { + nid: &'a NodeId, + alias: Option, + }, + Me { + alias: Option, + }, +} + +impl<'a> Author<'a> { + pub fn new(nid: &'a NodeId, alias: Option, me: &Profile) -> Author<'a> { + if nid == me.id() { + Self::Me { alias } + } else { + Self::Author { nid, alias } + } + } + + /// Author: `` || `` + /// Me : ` (you)` || `(you)` + pub fn alias(&self) -> Line { + match self { + Self::Me { alias } => { + if let Some(alias) = alias { + term::Line::spaced([ + term::format::primary(alias).into(), + term::format::primary("(you)").dim().into(), + ]) + } else { + term::format::primary("(you)").into() + } + } + + Self::Author { alias, .. } => { + if let Some(alias) = alias { + term::format::primary(alias).into() + } else { + term::format::default(String::new()).into() + } + } + } + } +} + +impl<'a> IntoIterator for Author<'a> { + type Item = term::Label; + type IntoIter = std::vec::IntoIter; + + /// Author : ` ()` || `` + /// Me : ` (you)` || `(you)` + fn into_iter(self) -> Self::IntoIter { + let mut line = Vec::new(); + + match self { + Self::Me { alias } => { + if let Some(alias) = alias { + line.push(term::format::primary(alias).into()); + line.push(term::Label::space()); + line.push(term::format::primary("(you)").dim().into()); + } else { + line.push(term::format::primary("(you)").into()); + } + } + + Self::Author { nid, alias } => { + if let Some(alias) = alias { + line.push(term::format::primary(alias).into()); + line.push(term::Label::space()); + line.push( + term::format::tertiary(term::format::parens( + term::format::node(nid).into(), + )) + .into(), + ); + } else { + line.push(term::format::tertiary(nid).into()); + } + } + } + + line.into_iter() + } +} + #[cfg(test)] mod test { use super::*; diff --git a/radicle-node/src/test/environment.rs b/radicle-node/src/test/environment.rs index ab305262..1b484f67 100644 --- a/radicle-node/src/test/environment.rs +++ b/radicle-node/src/test/environment.rs @@ -17,10 +17,11 @@ use radicle::crypto::{KeyPair, Seed, Signer}; use radicle::git; use radicle::git::refname; use radicle::identity::Id; +use radicle::node::address::Book; use radicle::node::routing::Store; use radicle::node::tracking::store as TrackingStore; use radicle::node::Handle as _; -use radicle::node::TRACKING_DB_FILE; +use radicle::node::{ADDRESS_DB_FILE, TRACKING_DB_FILE}; use radicle::profile::Home; use radicle::profile::Profile; use radicle::rad; @@ -78,6 +79,8 @@ impl Environment { let signer = MemorySigner::load(&profile.keystore, "radicle".to_owned().into()).unwrap(); let tracking_db = profile.home.node().join(TRACKING_DB_FILE); TrackingStore::Config::open(tracking_db).unwrap(); + let addresses_db = profile.home.node().join(ADDRESS_DB_FILE); + Book::open(addresses_db).unwrap(); Node { id: *profile.id(), @@ -96,6 +99,8 @@ impl Environment { let keypair = KeyPair::from_seed(Seed::from([!(self.users as u8); 32])); let tracking_db = home.node().join(TRACKING_DB_FILE); TrackingStore::Config::open(tracking_db).unwrap(); + let addresses_db = home.node().join(ADDRESS_DB_FILE); + Book::open(addresses_db).unwrap(); transport::local::register(storage.clone()); keystore