use std::path::PathBuf;
use anyhow::Result;
use clap::Parser;
use serde_json::json;
use crate::cli::format::TableOrJson;
use crate::daemon::client::DaemonClient;
use crate::daemon::protocol::StatusReport;
use crate::daemon::server;
#[derive(Parser)]
pub struct StatusCommand {
#[arg(long, value_name = "PATH")]
pub socket: Option<PathBuf>,
#[arg(short = 'o', long, value_enum, default_value_t = TableOrJson::Table)]
pub output: TableOrJson,
#[arg(long, hide = true)]
pub json: bool,
}
impl StatusCommand {
pub async fn execute(mut self) -> Result<()> {
if self.json {
eprintln!("warning: --json is deprecated; use -o/--output json instead");
self.output = TableOrJson::Json;
}
let json_out = self.output == TableOrJson::Json;
let socket_path = server::resolve_socket(self.socket)?;
match DaemonClient::new(&socket_path).status().await {
Ok(report) => print_running(json_out, &report),
Err(_) => print_not_running(json_out),
}
}
}
fn print_running(json_out: bool, report: &StatusReport) -> Result<()> {
if json_out {
println!("{}", serde_json::to_string_pretty(report)?);
return Ok(());
}
match &report.version {
Some(version) => println!("daemon: running (v{version})"),
None => println!("daemon: running (version unknown)"),
}
if report.services.is_empty() {
println!(" (no services registered)");
}
for svc in &report.services {
let health = if svc.healthy { "ok" } else { "unhealthy" };
println!(" {:<16} {:<10} {}", svc.name, health, svc.summary);
}
super::warn_version_mismatch(report.version.as_deref());
Ok(())
}
fn print_not_running(json_out: bool) -> Result<()> {
if json_out {
println!(
"{}",
serde_json::to_string_pretty(&json!({ "running": false }))?
);
} else {
println!("daemon: not running");
}
Ok(())
}
#[cfg(test)]
#[allow(clippy::unwrap_used, clippy::expect_used)]
mod tests {
use super::*;
use crate::daemon::service::ServiceStatus;
fn report(version: Option<&str>) -> StatusReport {
StatusReport {
services: vec![ServiceStatus {
name: "browser-bridge".to_string(),
healthy: true,
summary: "no tab connected".to_string(),
detail: serde_json::Value::Null,
}],
version: version.map(str::to_string),
}
}
#[test]
fn print_running_renders_table_and_json_with_or_without_a_version() {
print_running(false, &report(Some("1.2.3"))).unwrap();
print_running(false, &report(None)).unwrap();
print_running(true, &report(Some("1.2.3"))).unwrap();
print_running(
false,
&StatusReport {
services: vec![],
version: Some("1.2.3".to_string()),
},
)
.unwrap();
}
#[test]
fn print_not_running_renders_table_and_json() {
print_not_running(false).unwrap();
print_not_running(true).unwrap();
}
}