Radish alpha
h
Radicle Heartwood Protocol & Stack
Radicle
Git (anonymous pull)
Log in to clone via SSH
cli: Move common functionality out of the CLI
cloudhead committed 1 year ago
commit 81f94d0cff52fa750b66e8ee8fc17b126ae76715
parent a6b5c723c88aed4979708a7e7baf5a9f8681cc68
5 files changed +72 -86
modified 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)?;
                }
            }

modified 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")),
modified 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(())
modified 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<bool, anyhow::Error> {
-
    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<bool, anyhow::Error> {
-
    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<bool, anyhow::Error> {
-
    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()),
-
    }
-
}
modified 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<bool, Error> {
+
        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<bool, Error> {
+
        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<bool, Error> {
+
        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 {