use std::time::Duration;
use anyhow::Result;
use clap::Args;
use colored::Colorize;
use crate::exec_client;
#[derive(Args)]
pub struct ExecArgs {
#[arg(long)]
pub host: String,
#[arg(long)]
pub port: u16,
#[arg(long, default_value = "root")]
pub user: String,
#[arg(long)]
pub pass: String,
#[arg(short, long)]
pub command: String,
#[arg(long, default_value_t = 60)]
pub timeout_secs: u64,
#[arg(long)]
pub working_dir: Option<String>,
#[arg(long)]
pub json: bool,
}
pub async fn execute(args: ExecArgs, _verbose: bool) -> Result<()> {
let total_timeout = Duration::from_secs(args.timeout_secs.saturating_add(5));
let resp = exec_client::call_exec(
&args.host,
args.port,
&args.user,
&args.pass,
&args.command,
Some(args.timeout_secs),
args.working_dir.as_deref(),
total_timeout,
)
.await?;
if args.json {
println!("{}", serde_json::to_string_pretty(&resp)?);
} else {
if !resp.stdout.is_empty() {
print!("{}", resp.stdout);
}
if !resp.stderr.is_empty() {
eprint!("{}", resp.stderr);
}
if resp.timed_out {
eprintln!(
"{} command timed out after {}s",
"[timeout]".yellow(),
args.timeout_secs
);
}
eprintln!(
"{} exit={} duration={}ms",
"[done]".dimmed(),
resp.exit_code,
resp.duration_ms
);
}
if resp.exit_code != 0 || resp.timed_out {
std::process::exit(if resp.timed_out { 124 } else { resp.exit_code });
}
Ok(())
}