diff --git a/radicle-cli/src/commands/init.rs b/radicle-cli/src/commands/init.rs index d752407d..8aa2cce7 100644 --- a/radicle-cli/src/commands/init.rs +++ b/radicle-cli/src/commands/init.rs @@ -20,7 +20,6 @@ use radicle::node::{Event, Handle, NodeId, DEFAULT_SUBSCRIBE_TIMEOUT}; use radicle::prelude::Doc; use radicle::{profile, Node}; -use crate as cli; use crate::commands; use crate::git; use crate::terminal as term; @@ -290,10 +289,10 @@ pub fn init(options: Options, profile: &profile::Profile) -> anyhow::Result<()> // It's important to seed our own repositories to make sure that our node signals // interest for them. This ensures that messages relating to them are relayed to us. if options.seed { - cli::project::seed(rid, options.scope, &mut node, profile)?; + profile.seed(rid, options.scope, &mut node)?; if doc.visibility.is_public() { - cli::project::add_inventory(rid, &mut node, profile)?; + profile.add_inventory(rid, &mut node)?; } } diff --git a/radicle-cli/src/commands/seed.rs b/radicle-cli/src/commands/seed.rs index f95a31ef..133dfd2f 100644 --- a/radicle-cli/src/commands/seed.rs +++ b/radicle-cli/src/commands/seed.rs @@ -10,8 +10,8 @@ use radicle_term::Element as _; use crate::commands::rad_sync as sync; use crate::node::SyncSettings; +use crate::terminal as term; use crate::terminal::args::{Args, Error, Help}; -use crate::{project, terminal as term}; pub const HELP: Help = Help { name: "seed", @@ -134,7 +134,7 @@ pub fn update( node: &mut Node, profile: &Profile, ) -> Result<(), anyhow::Error> { - let updated = project::seed(rid, scope, node, profile)?; + let updated = profile.seed(rid, scope, node)?; let outcome = if updated { "updated" } else { "exists" }; term::success!( @@ -145,17 +145,11 @@ pub fn update( Ok(()) } -pub fn delete(rid: RepoId, node: &mut Node, profile: &Profile) -> anyhow::Result<()> { - if project::unseed(rid, node, profile)? { - term::success!("Seeding policy for {} removed", term::format::tertiary(rid)); - } - Ok(()) -} - pub fn seeding(profile: &Profile) -> anyhow::Result<()> { let store = profile.policies()?; let storage = &profile.storage; let mut t = term::Table::new(term::table::TableOptions::bordered()); + t.header([ term::format::default(String::from("Repository")), term::format::default(String::from("Name")), diff --git a/radicle-cli/src/commands/unseed.rs b/radicle-cli/src/commands/unseed.rs index 15fe87d6..ca4c7df8 100644 --- a/radicle-cli/src/commands/unseed.rs +++ b/radicle-cli/src/commands/unseed.rs @@ -4,8 +4,8 @@ use anyhow::anyhow; use radicle::{prelude::*, Node}; +use crate::terminal as term; use crate::terminal::args::{Args, Error, Help}; -use crate::{project, terminal as term}; pub const HELP: Help = Help { name: "unseed", @@ -72,7 +72,7 @@ pub fn run(options: Options, ctx: impl term::Context) -> anyhow::Result<()> { } pub fn delete(rid: RepoId, node: &mut Node, profile: &Profile) -> anyhow::Result<()> { - if project::unseed(rid, node, profile)? { + if profile.unseed(rid, node)? { term::success!("Seeding policy for {} removed", term::format::tertiary(rid)); } Ok(()) diff --git a/radicle-cli/src/project.rs b/radicle-cli/src/project.rs index 1d472c72..3480c924 100644 --- a/radicle-cli/src/project.rs +++ b/radicle-cli/src/project.rs @@ -1,11 +1,8 @@ -use localtime::LocalTime; use radicle::prelude::*; use crate::git; use radicle::git::RefStr; -use radicle::node::policy::Scope; -use radicle::node::{routing, Handle, NodeId}; -use radicle::Node; +use radicle::node::NodeId; /// Setup a repository remote and tracking branch. pub struct SetupRemote<'a> { @@ -52,68 +49,3 @@ impl<'a> SetupRemote<'a> { Ok((remote, None)) } } - -/// Add the repo to our inventory. -pub fn add_inventory( - rid: RepoId, - node: &mut Node, - profile: &Profile, -) -> Result { - match node.add_inventory(rid) { - Ok(updated) => Ok(updated), - Err(e) if e.is_connection_err() => { - let now = LocalTime::now(); - let mut db = profile.database_mut()?; - let updates = - routing::Store::add_inventory(&mut db, [&rid], *profile.id(), now.into())?; - - Ok(!updates.is_empty()) - } - Err(e) => Err(e.into()), - } -} - -/// Seed a repository by first trying to seed through the node, and if the node isn't running, by -/// updating the policy database directly. If the repo is available locally, we also add it to our -/// inventory. -pub fn seed( - rid: RepoId, - scope: Scope, - node: &mut Node, - profile: &Profile, -) -> Result { - match node.seed(rid, scope) { - Ok(updated) => Ok(updated), - Err(e) if e.is_connection_err() => { - let mut config = profile.policies_mut()?; - let result = config.seed(&rid, scope)?; - - if result && profile.storage.contains(&rid)? { - let now = LocalTime::now(); - let mut db = profile.database_mut()?; - - routing::Store::add_inventory(&mut db, [&rid], *profile.id(), now.into())?; - } - Ok(result) - } - Err(e) => Err(e.into()), - } -} - -/// Unseed a repository by first trying to unseed through the node, and if the node isn't running, -/// by updating the policy database directly. -pub fn unseed(rid: RepoId, node: &mut Node, profile: &Profile) -> Result { - match node.unseed(rid) { - Ok(updated) => Ok(updated), - Err(e) if e.is_connection_err() => { - let mut config = profile.policies_mut()?; - let result = config.unseed(&rid)?; - - let mut db = profile.database_mut()?; - radicle::node::routing::Store::remove_inventory(&mut db, &rid, profile.id())?; - - Ok(result) - } - Err(e) => Err(e.into()), - } -} diff --git a/radicle/src/profile.rs b/radicle/src/profile.rs index e54ea4b3..535e7985 100644 --- a/radicle/src/profile.rs +++ b/radicle/src/profile.rs @@ -27,12 +27,12 @@ use crate::node::policy::config::store::Read; use crate::node::{ notifications, policy, policy::{Policy, Scope, SeedingPolicy}, - Alias, AliasStore, + Alias, AliasStore, Handle as _, Node, }; -use crate::prelude::{Did, NodeId}; +use crate::prelude::{Did, NodeId, RepoId}; use crate::storage::git::transport; use crate::storage::git::Storage; -use crate::storage::ReadRepository; +use crate::storage::{ReadRepository, ReadStorage}; use crate::{cli, cob, git, node, storage, web}; /// Environment variables used by radicle. @@ -158,6 +158,10 @@ pub enum Error { #[error(transparent)] Config(#[from] ConfigError), #[error(transparent)] + Node(#[from] node::Error), + #[error(transparent)] + Routing(#[from] node::routing::Error), + #[error(transparent)] Keystore(#[from] keystore::Error), #[error(transparent)] MemorySigner(#[from] keystore::MemorySignerError), @@ -423,6 +427,63 @@ impl Profile { Aliases { policies, db } } + + /// Add the repo to our inventory. + /// If the node is offline, adds it directly to the database. + pub fn add_inventory(&self, rid: RepoId, node: &mut Node) -> Result { + match node.add_inventory(rid) { + Ok(updated) => Ok(updated), + Err(e) if e.is_connection_err() => { + let now = LocalTime::now(); + let mut db = self.database_mut()?; + let updates = + node::routing::Store::add_inventory(&mut db, [&rid], *self.id(), now.into())?; + + Ok(!updates.is_empty()) + } + Err(e) => Err(e.into()), + } + } + + /// Seed a repository by first trying to seed through the node, and if the node isn't running, + /// by updating the policy database directly. If the repo is available locally, we also add it + /// to our inventory. + pub fn seed(&self, rid: RepoId, scope: Scope, node: &mut Node) -> Result { + match node.seed(rid, scope) { + Ok(updated) => Ok(updated), + Err(e) if e.is_connection_err() => { + let mut config = self.policies_mut()?; + let result = config.seed(&rid, scope)?; + + if result && self.storage.contains(&rid)? { + let now = LocalTime::now(); + let mut db = self.database_mut()?; + + node::routing::Store::add_inventory(&mut db, [&rid], *self.id(), now.into())?; + } + Ok(result) + } + Err(e) => Err(e.into()), + } + } + + /// Unseed a repository by first trying to unseed through the node, and if the node isn't + /// running, by updating the policy database directly. + pub fn unseed(&self, rid: RepoId, node: &mut Node) -> Result { + match node.unseed(rid) { + Ok(updated) => Ok(updated), + Err(e) if e.is_connection_err() => { + let mut config = self.policies_mut()?; + let result = config.unseed(&rid)?; + + let mut db = self.database_mut()?; + node::routing::Store::remove_inventory(&mut db, &rid, self.id())?; + + Ok(result) + } + Err(e) => Err(e.into()), + } + } } impl std::ops::Deref for Profile {