mod args; mod commands; pub mod control; mod events; mod logs; pub mod routing; use std::{process, time}; use radicle::node::Handle as _; use radicle::node::Node; use radicle::node::address::Store as AddressStore; use radicle::node::config::ConnectAddress; use radicle::node::routing::Store; use crate::commands::node::args::Only; use crate::terminal as term; use crate::terminal::Element as _; use crate::warning; pub use args::Args; use args::{Addr, Command}; pub fn run(args: Args, ctx: impl term::Context) -> anyhow::Result<()> { let profile = ctx.profile()?; let mut node = Node::new(profile.socket_from_env()); let command = args.command.unwrap_or_default(); match command { Command::Connect { addr, timeout } => { let timeout = timeout.unwrap_or(time::Duration::MAX); match addr { Addr::Peer(addr) => control::connect(&mut node, addr.id, addr.addr, timeout)?, Addr::Node(nid) => { let db = profile.database()?; let addresses = db .addresses_of(&nid)? .into_iter() .map(|ka| ka.addr) .collect(); control::connect_many(&mut node, nid, addresses, timeout)?; } } } Command::Config { addresses } => { if addresses { let cfg = node.config()?; for addr in cfg.external_addresses { term::println(ConnectAddress::from((*profile.id(), addr)).to_string()); } } else { control::config(&node)?; } } Command::Db(op) => { commands::db(&profile, op)?; } Command::Debug => { control::debug(&mut node)?; } Command::Sessions => { warning::deprecated("rad node sessions", "rad node status"); let sessions = control::sessions(&node)?; if let Some(table) = sessions { table.print(); } } Command::Events { timeout, count } => { let count = count.unwrap_or(usize::MAX); let timeout = timeout.unwrap_or(time::Duration::MAX); events::run(node, count, timeout)?; } Command::Routing { repo, nid, json } => { let store = profile.database()?; routing::run(&store, repo, nid, json)?; } Command::Logs { lines } => control::logs(lines, Some(time::Duration::MAX), &profile)?, Command::Start { foreground, options, path, verbose, } => { control::start(node, !foreground, verbose, options, &path, &profile)?; } Command::Inventory { nid } => { let nid = nid.as_ref().unwrap_or(profile.id()); for rid in profile.routing()?.get_inventory(nid)? { term::println(term::format::tertiary(rid)); } } Command::Status { only: Some(Only::Nid), } => { if node.is_running() { term::println(term::format::node_id_human(&node.nid()?)); } else { process::exit(2); } } Command::Status { only: None } => { control::status(&node, &profile)?; } Command::Stop => { control::stop(node, &profile); } } Ok(()) }