diff --git a/linkup-cli/src/commands/sessions/list.rs b/linkup-cli/src/commands/sessions/list.rs new file mode 100644 index 00000000..12334720 --- /dev/null +++ b/linkup-cli/src/commands/sessions/list.rs @@ -0,0 +1,39 @@ +use colored::Colorize; + +use crate::{ + Result, + services::local_server, + session::{list_session_rows, print_sessions_table}, +}; + +#[derive(clap::Args)] +pub struct Args { + #[arg(long)] + pub json: bool, +} + +pub async fn run(args: &Args) -> Result<()> { + if !local_server::is_reachable().await { + println!( + "{}", + "Seems like your local Linkup server is not running. Please run 'linkup start' first." + .yellow() + ); + + return Ok(()); + } + + let sessions_rows = list_session_rows().await; + + if args.json { + println!( + "{}", + serde_json::to_string_pretty(&sessions_rows) + .expect("Failed to serialize sessions rows") + ); + } else { + print_sessions_table(&sessions_rows, None); + } + + Ok(()) +} diff --git a/linkup-cli/src/commands/sessions/mod.rs b/linkup-cli/src/commands/sessions/mod.rs index dadfd8df..7977823c 100644 --- a/linkup-cli/src/commands/sessions/mod.rs +++ b/linkup-cli/src/commands/sessions/mod.rs @@ -1,6 +1,7 @@ mod create_isolated; mod create_preview; mod delete; +mod list; use clap::Subcommand; @@ -22,6 +23,9 @@ enum Command { #[clap(about = "Delete session")] Delete(delete::Args), + + #[clap(about = "List sessions", aliases = ["ls"])] + List(list::Args), } pub async fn sessions(args: &Args, config: &Option) -> Result<()> { @@ -29,5 +33,6 @@ pub async fn sessions(args: &Args, config: &Option) -> Result<()> { Command::CreatePreview(args) => create_preview::run(args, config).await, Command::CreateIsolated(args) => create_isolated::run(args, config).await, Command::Delete(args) => delete::run(args).await, + Command::List(args) => list::run(args).await, } } diff --git a/linkup-cli/src/commands/status/mod.rs b/linkup-cli/src/commands/status/mod.rs index 07427832..b064378c 100644 --- a/linkup-cli/src/commands/status/mod.rs +++ b/linkup-cli/src/commands/status/mod.rs @@ -17,7 +17,7 @@ use url::Url; use crate::{ commands, services::{self, local_server}, - session::{SessionRow, format_state_domains, print_sessions_table}, + session::{SessionRow, list_session_rows, print_sessions_table}, state::{State, get_config}, }; @@ -55,7 +55,7 @@ pub async fn status(args: &Args) -> anyhow::Result<()> { .unwrap_or(&state.linkup.session_name) .to_string(); - let all_sessions = fetch_sessions().await; + let all_sessions = list_session_rows().await; if args.session.is_some() && !all_sessions @@ -199,32 +199,6 @@ struct Output { services: Vec, } -async fn fetch_sessions() -> Vec { - let client = LocalServerClient::new(&services::local_server::url()); - - match client.list_sessions().await { - Ok(response) => { - let mut entries: Vec = response - .sessions - .into_iter() - .map(|(name, session)| { - let domains = format_state_domains(&name, &session.domains); - - SessionRow { - name, - kind: session.kind, - domains, - } - }) - .collect(); - - entries.sort_by(|a, b| a.kind.cmp(&b.kind).then(a.name.cmp(&b.name))); - entries - } - Err(_) => vec![], - } -} - async fn fetch_session_detail(session_name: &str) -> Option { let client = LocalServerClient::new(&services::local_server::url()); client.get_session(session_name).await.ok() diff --git a/linkup-cli/src/session.rs b/linkup-cli/src/session.rs index ba6c3a56..e3fe7546 100644 --- a/linkup-cli/src/session.rs +++ b/linkup-cli/src/session.rs @@ -1,8 +1,9 @@ use colored::Colorize; use linkup::{Domain, SessionKind}; +use linkup_clients::LocalServerClient; use serde::{Deserialize, Serialize}; -use crate::state::State; +use crate::{services::local_server, state::State}; #[derive(Debug, Clone, Deserialize, Serialize)] pub struct SessionRow { @@ -21,6 +22,32 @@ impl SessionRow { } } +pub async fn list_session_rows() -> Vec { + let client = LocalServerClient::new(&local_server::url()); + + match client.list_sessions().await { + Ok(response) => { + let mut entries: Vec = response + .sessions + .into_iter() + .map(|(name, session)| { + let domains = format_state_domains(&name, &session.domains); + + SessionRow { + name, + kind: session.kind, + domains, + } + }) + .collect(); + + entries.sort_by(|a, b| a.kind.cmp(&b.kind).then(a.name.cmp(&b.name))); + entries + } + Err(_) => vec![], + } +} + pub fn print_sessions_table(sessions: &[SessionRow], current: Option<&str>) { if sessions.is_empty() { return;